||
sys库是LuatOS的核心系统调度库,它基于Lua协程机制实现了实时多任务调度、定时器管理以及消息通信等功能。
在详细介绍sys库之前,我们先来补充一些关于实时操作系统RTOS的知识,方便大家更好地理解LuatOS的运行机制。
一、 RTOS实时操作系统
我们用一个简单的例子来看,对比经典的裸机开发和LuatOS开发的优势:
一位母亲,她需要同步做两件事情,一件是喂小孩吃饭,另一件事是回复朋友信息。
对裸机开发来说,这是两件任务,这位母亲一段时间内只能做一个任务,任务执行不连贯,等待时间长。
time1-5 :喂小孩吃饭,就无法回复信息,朋友就受到冷落;
time5-10 :回复信息,小孩吃不到饭,就会哭闹。
那RTOS是如何处理的呢?在RTOS里,这位母亲的大脑非常强大,切换得非常的快,她上一秒喂饭,下一秒回复信息,再下一秒再喂饭。
因为切换得非常快,小孩以为她在专心喂饭,朋友以为她在认真聊天。这两个任务看起来在同时进行。
这就是RTOS的本质——把一秒钟的时间切成多个时间片段,一个时间片段内干一件事情,一秒钟切换100个时间片就可以做100件事情。 RTOS通过快速切换任务,让多个任务看似在同时进行,提高了系统的并发处理能力和效率。
LuatOS通过Lua虚拟机封装了底层RTOS的API,向开发者提供高级抽象接口,而无需直接操作RTOS内核。
基于此LuatOS实现了一套多任务机制,允许开发者创建多个并行运行的任务。这些任务通过Lua语言的协程机制来实现,使得每个任务都可以在自己的执行上下文中运行,而不会相互干扰。
二、 sys库任务管理API函数
sys库是LuatOS的核心系统库,提供了任务调度、时间管理、消息传递等关键功能,本文主要介绍其任务管理相关API函数及其运用示例。
在程序的开头我们必须调用sys库;在程序的结尾,我们需要在代码的最后一行调用sys.run()函数来启动主程序,让框架内的任务代码会在 sys.run()中运行。
一个Lua程序的框架是这样的:
任务管理包含:创建任务sys.taskInit()、任务等待 sys.wait()和sys.waitUntil() 。
1)创建任务sys.taskInit()
在创建任务时,需要指定一个任务函数,该函数包含了任务要执行的代码。
比如,我们创建一个喂饭的任务feed。
代码示例:先定义“喂饭”函数,然后创建并启动“喂饭”任务。
2)任务等待sys.wait()
暂停当前任务的执行一段时间,单位为毫秒。在等待期间,系统会调度其他任务执行,实现多任务并发。
代码举例:
我们依旧利用上面的程序,我们在代码第三行后面,加一句sys.wait(1000) 即可。
每隔一秒,打印一次 I'm feeding.....
3)任务中断sys.waitUntil()
允许当前的Task协程暂停执行,进入等待状态。在等待过程中,它会监听指定名称的事件(即 topic)是否发生,同时会记录时间。
如果在指定的时间内,该事件发生了,协程会恢复执行; 如果超过了指定的时间,事件还未发生,协程也同样会恢复执行。
一般这里都会设置判断条件:指定时间内,事件发生执行A,超时未发生执行B。
一般和sys.waitUntil()配合使用的,是sys.publish():
sys.publish()它的作用就像是在系统里广播消息,让其他关注该消息的任务能够接收到并做出相应反应——比如,sys.waitUntil()。
我们利用一个示例来实际感受下这几个函数的用法:
一位女主人,在烧水的同时,还要扫地; 水烧开后,停止扫地去关火,并沏茶。
分析上述例子,女主人共有三个任务:烧水、扫地、沏茶
这三个任务分别运行如下:
接下来,我们来对这三个协程单独分析:
1)烧水协程:
烧水5秒后,sys.publish()发消息:“水烧开了”。
代码如下:
2)扫地协程:
扫地持续进行,sys.waitUntil()等待收到了:“水烧开的消息”,停止扫地;同时sys.publish()发送消息:水烧开了,不扫地了,去沏茶。
代码如下:
sys.waitUntil()如果在1s内接收到了水烧开的消息,则返回true给result,继续执行下面的if程序,打印“水烧开了:我去关火”;
如果超时1秒没有接收到,则返回false给result,继续执行下面的if程序,打印“水还没烧开,我要继续扫地”。
3)沏茶协程:
在烧水的5秒钟内,一直处于等待状态,直到水烧开后,sys.waitUntil()收到:“水烧开了,不扫地了去沏茶”这条消息,开始执行沏茶协程。
代码如下:
我们把完整代码下载到Air780EPM开发板上,看下运行效果:
这样,我们就利用sys.publish()和sys.waitUntil()完成了一个多任务协程程序。
附完整代码:
今天的内容就分享到这里了~