作者:王海洋
更新时间:2021年4月2日
关键词:延时,定时器,timer
在luat脚本程序中,往往需要用到延时和等待等逻辑功能。例如,你想得到每隔30秒查询当前内存,这里就需要用到延时和定时器。在每次打印后加上一个30秒的定时器或者30秒的延迟,既可以实现这个功能。本篇文章将介绍2个延时函数和4个定时器函数以及一个判定定时器激活状态的函数,讲解这些函数如何使用以及在什么环境下使用。
详细的API介绍见sys API章节和rtos API章节
sys.wait():
rtos.sleep():
接下来是介绍定时器,共有四种定时器,他们各有各的特点。所以我们在使用时一定要记清楚这些定时器的特点,挑选适合当前程序需求的定时器使用。在luat脚本程序中,同时运行的定时器是有数量限制的。8910平台的Luat最多支持50个定时器,如何理解50个定时器?在下面的知识扩展里详细讲解了。sys.timerStart()和function sys.timerLoopStart()的返回值是定时器ID,这个可以用来判断是否为同一个
定时器。或者也可以通过定时器的回调函数和回调参数是否相同来判断。
sys.timerStart():
function sys.timerLoopStart():
sys.wait()(仅适用于task):
sys.waitUntil()(仅适用于task):
手动消亡有两种方式:sys.timerstop()和sys.timerstopAll()
1.sys.timerstop(val,…)
参数是定时器ID或者定时器的回调函数和回调参数。使用这个函数可以关闭指定的一个定时器。
返回值为nil
2.sys.timerstopAll(fnc)
功能:关闭sys.timerStart和sys.timerLoopStart创建的某一个回调函数的所有定时器
参数:需要关闭的定时器回调函数。
返回值:nil
已经消亡的定时器,再去执行stop不会产生异常
sys.timerlsActive()
功能:判断“通过timerStart或者timerStart创建的定时器”是否处于激活状态
参数:通过timerStart或者timerStart创建的定时器返回的定时器id或者回调函数与回调参数。
参数:
参数为回调函数与回调参数时,如果处于激活状态,则返回bool类型的true,否则返回nil。
返回值:
参数为定时器ID时,如果处于激活状态,则返回function类型的定时器回调函数,否则返回nil
例子:
local function timerCbFnc2(tag)
log.info("timerCbFnc2",tag)
end
sys.timerStart(timerCbFnc2,5000,"test")
sys.taskInit(function()
sys.wait(3000)
log.info("after 3 senonds, timerCbFnc2 test isActive?",sys.timerIsActive(timerCbFnc2,"test"))
sys.wait(3000)
log.info("after 6 senonds, timerCbFnc2 test isActive?",sys.timerIsActive(timerCbFnc2,"test"))
end)
1.8910平台的Luat最多支持50个定时器,如何理解50个定时器?
看下列两端代码,猜测,最后分别还有几个定时器在运行。
sys.taskInit(function()
for i=1,50 do
sys.timerStart(function() end,1000)
end
log.info("不考虑其它代码中定时器的使用")
log.info("运行到这里,同时存在多少个定时器?")
end)
sys.taskInit(function()
for i=1,50 do
sys.wait(1000)
end
log.info("不考虑其它代码中定时器的使用")
log.info("运行到这里,同时存在多少个定时器?")
end)
第一段代码是创建50个回调函数相同,延时时间相同的单此定时器。通过前面的介绍可知, 如果回调函数和回调参数都相同的两个sys.timerStart()定时器,可视为同一定时器。当第一个sys.timerStart(function() end,1000)创建好后,再创建第二个sys.timerStart(function() end,1000)时,就会查找当前存在的定时器里,是否有相同的定时器,如果就就会将第一个关闭,创建第二个相同的定时器,并重新开始计时。所以第一个代码段最后吃剩一个定时器在运行。
第二段代码是创建50个sys.wait(1000)。当创建第一个sys.wait(1000)后,这个协程就会被挂起。1000ms后,继续执行剩下的程序,创建下一个sys.wait(1000)。所以,最后也只剩一个定时器。
下面这段代码,通过改变回调参数来同时创建50个sys.timerLoopStart(log.info,1000,“nCounter1”,i)。但看打印结果会发现,没到50个。因为打印出来的数量只是sys.timerLoopStart(log.info,1000,“nCounter1”,i)的数量,还有sys.wait(5000)等一些定时器没算在内。
local function wait1()
sys.wait(5000)
for i=1,50 do
sys.timerLoopStart(log.info,1000,"nCounter1",i)
end
end
sys.taskInit(wait1)
详细的API demo见The Timer demo章节
1.waitUntil()、wait()
local function IndirectCall()
sys.waitUntil("MSG_ID",5000)
end
sys.taskInit(function()
sys.wait(5000)
IndirectCall()
log.info("sys.wait和sys.waitUntil只能用在task中")
log.info("只能被task的主函数直接或者间接调用")
end)
2.timerStart()
local function publicTimerCbFnc(tag)
log.info("publicTimerCbFnc",tag)
end
sys.timerStart(publicTimerCbFnc,8000,"first")
local timerId2 = sys.timerStart(publicTimerCbFnc,8000,"second")
sys.timerStart(publicTimerCbFnc,8000,"third")
3.timerLoopStart()
local nCounter = 0
sys.taskInit(function ()
while true do
nCounter = nCounter+1
sys.wait(1000)
end
end)
sys.timerLoopStart(log.info,1000,"nCounter1",nCounter)
--sys.timerLoopStart(log.info,1000,"nCounter1",0)
sys.timerLoopStart(function() log.info("nCounter2",nCounter) end,1000)0,"first")
1,定时器精度问题
Luat开发最小仅支持5毫秒的定时器,超时时间最小1ms(实际支持的最小时间是5ms,小于5ms的时间都被转化为5ms) 超时间最大0x7FFFFFFF(24.85天)。
另外毫秒级的定时器的误差较大,原因可参考Luat应用脚本运行框架
延时和定时器 相关资料
sys API章节和rtos API章节
延时和定时器demo说明
相关开发板购买链接
Air724UG开发板
Air724 开发板使用说明