众所周知,os.time()输出的是时间戳,而rtos.tick()是每秒16384个tick。那么这二者有什么用途呢?
通常而言,如果是需要严格的时间认证,那么必须使用os.time(),至于说同步时钟的方法有很多,可以参考:http://oldask.openluat.com/article/30
但是,不论使用哪个方法,都会出现一个问题:同步成功前后产生巨大的差值,可能导致程序逻辑运行错误。
如何避免时钟同步前后产生的差值,导致程序错误呢?
方法一、使用rtos.tick()
之前的方式:
a=os.time()
-- 时钟同步后,os.time()瞬间增加成千上万,后边的if会判断为true,并执行
if os.time()-a>20 then xxxx end
现在的方式:
a=rtos.tick()
-- 时钟同步后,os.time()瞬间增加成千上万,但是并不影响rtos.tick(),后边的if逻辑不会出错,程序正常执行
if rtos.tick()-a>20*16384 then xxxx
如此一来,使用rtos就可以完美的计时,且不用担心时钟同步后导致错误了。
但是需要注意,rtos.tick(),根据底层和模块不同,脉冲次数与归零周期不同。其中非float底层,rtos.tick()默认归零时间是38小时,float底层rtos.tick()是72小时。
方法二、使用os.time()
如果程序需要稳定运行,无法接收rtos.tick()定期归零,那么有两个方法避免:
1、记录rtos.tick()归零行为,并把原值做处理
local iLstTick=0 --记录最后一次tick值,开机默认是0
local bTickReset=false --记录刚刚是否tick重置过
sys.timerStart(function() --timer,用于判断tick是否重置
if rtos.tick()<25000 and iLstTick~=0 then
bTickReset=true
end
iLstTick=rtos.tick()
end, 1000)
local iRecTick --设置变量,记录tick
--判断间隔时间是否符合条件,并执行代码
if bTickReset==true then
--需要根据底层判断最长,否则可能出错,这里用的是72小时,即4,294,967,295
iRecTick = iRecTick-4294967295
bTickReset=false
endif rtos.tick()-iRecTick>30*16384 then
--your code
end
2、记录os.time()同步前后的差值,并将它加入到运算中
local iOldTimeStamp,iLastTimeStamp=0, 0
sys.timerStart(function()
if os.time()<1500000000 then --如果ntp同步成功,肯定大于150000000
iOldTimeStamp=os.time()
iLastTimeStamp=os.time()
else
if iLastTimeStamp<1500000000 then iLastTimeStamp=os.time() end
end
end, 1000)
--现在获得了同步前后的差值就是iLastTimeStamp-iOldTimeStamp
local a --假设a是标的
if a <1500000000 then a=a+iLastTimeStamp-iOldTimeStamp end --这里加上同步前后的差值,就不会影响a的值
if os.time()-a>30 then
--your code
end
43 篇文章
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!