luat程序如何实现延时运行

某些时候,开发者的程序需要实现等待外部设备上报消息,或者延迟执行。但是Luat底层没有提供直接的wait函数,也不能用while(i–)这种形式实现延时,那么,如果遇到这种情况,怎么处理呢?

为什么不能用**while(i–)**呢?因为Luat的架构是这样的:硬件—底层—luavm—lua代码;如果底层检测到死循环,会认为代码出错,直接重启模块了。所以while循环的方式行不通。
lua的代码都是时间分片运行的,所以可以使用LuaTasK架构的协程实现近似的wait功能(是协程,不是线程哦)。
同时,由于通信模块中断优先级限制,小于10ms的延时,不会精准。

##硬阻塞rtos.sleep(time)
底层没有提供软sleep,调用该接口会硬阻塞直到计时结束。在此期间所有代码停止执行。使用方法如下:

1
2
3
print(“start test.”)
rtos.sleep(1000)
print(“test success.”)

##sys.wait(time)
这是LuaTasK架构提供的一个任务延时函数。它只能用于任务函数中。在其他地方中使用,会出现问题。在任务函数中执行这个函数,其他代码、任务的运行不受影响
它的原理就是挂起协程,当计时结束,再恢复协程。使用方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
require”sys”
--测试wait
sys.taskInit( function ()
print(“start test.”)
sys.wait(1000)
print(“test success.”)
end)

--测试任务函数的wait是否互相影响
sys.taskInit( function ()
while true do
print(“running…”)
sys.wait(100)
end
end)

##sys.waitUntil(msg, timeOut)
仅仅延时是不能满足需求的,LuaTasK架构还支持任务的消息等待。同样的,它只能用于任务函数中
当程序执行到此,自动停止,直到收到消息(或者超时),在任务函数中执行这个函数,其他代码、任务的运行不受影响
使用方法如下:

1
2
3
4
5
6
7
8
9
10
require”sys”
sys.taskInit( function()
print(“start test.”)
--收到消息“TEST”或者50s超时,则继续执行代码
sys.waitUntil(“TEST”, 50000)
print(“test success.”)
end)

--10秒后发布消息“TEST”
sys.timerStart(sys.publish, 10000, “TEST”)

##sys.timerStart(time) / sys.timerLoopStart(time)
LuaTasK还提供了timer可供开发者调用。其中timerStart是一次性定时器,timerLoopStart是循环定时器。不论定时器是否开启,均可使用sys.timerStop(id)停止定时器。

使用方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
require”sys”
function timerTest()
print(“timerTest succ.”)
end

function loopTimerTest()
print(“loopTimerTest succ.”)
end

--开启一次性定时器
sys.timerStart(timerTest, 10000)
--开启一个循环定时器
sys.timerLoopStart(loopTimerTest, 3000)
--如果关闭定时器,可以使用如下代码:
--sys.timerStop(timerTest)
--sys.timerStop(loopTimerTest)


--如果timer中是匿名函数,则可以用如下方法关闭:
--[[timerID = sys.timerLoopStart( function()
print(“loopTimer naked function test.”)
end, 3000)
sys.timerStop(timerID)]]

##os.time()
如果开发者不需要非常精确的定时器,但是需要长时间计时(譬如两个小时后关闭gpio输出),使用os.time()时间戳更好一些。

记录下当前时间戳os.time(),并存使用nvm demo存储到flash;然后使用sys.timerLoopStart去循环检查当前时间戳是否到达计时时间。这样可以避免意外重启等原因造成定时器失效的情况。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
require”nvm”
require”sys”
require"config"
nvm.init("config.lua")
nvm.set(“tmpStp”, os.time())

function timeChk()
--如果当前时间,大于保存的时间+60秒
if os.time() > nvm.get(“tmpStp”) + 60 then
print(“time up”)
sys.timerStop(timeChk)
end
end
sys.timerLoopStart(timeChk, 1000)

##rtos.tick()
这个函数返回开机上电后的ticks时间计数。
每 tick 时长:2G模块1/16384秒;4G模块5毫秒。
如果开发者需要开机时间,可以使用这个函数。

上次更新 2021-01-28