• 欢迎大家分享资料!前往留言板评论即可!

luat程序如何实现延时运行

合宙 模组资料网 2年前 (2021-05-15) 314次浏览 0个评论 扫描二维码

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

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

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

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

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

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架构还支持任务的消息等待。同样的,它只能用于任务函数中
当程序执行到此,自动停止,直到收到消息(或者超时),在任务函数中执行这个函数,其他代码、任务的运行不受影响
使用方法如下:

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)停止定时器。

使用方法如下:

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去循环检查当前时间戳是否到达计时时间。这样可以避免意外重启等原因造成定时器失效的情况。

示例代码:

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毫秒。
如果开发者需要开机时间,可以使用这个函数。


转载请注明原文链接:luat程序如何实现延时运行
喜欢 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址