如果NodeMCU定时器内的代码执行超过我设置的定时器间隔会发生什么?

时间:2017-05-31 08:07:41

标签: timer lua esp8266 nodemcu

使用NodeMCU,我们可以在esp8266芯片中轻松创建定时器功能。 但是,我想知道如果定时器内的代码超过我设置的定时器间隔会发生什么?

请参阅下面的代码。 如果我设置一个间隔为2秒的计时器,并且"要做的事情"在这个计时器内执行超过2秒,然后会发生什么?

tmr.alarm(0, 2000, 1, function ()
    --Something to do
end)

a)将"要做的事情"间隔达到2秒后终止?

b)或者"要做的事情"将继续执行直到完成,然后下一个"要做的事情"会被推迟吗?

c)或者这个计时器的每一轮都会等待"要做的事情"无论2秒间隔都能完成? (间隔自动扩展)

d)否则?

2 个答案:

答案 0 :(得分:0)

该功能的行为与您的想法不同。通常当您需要提供回调函数时,会在事件发生时执行回调;这就是这里发生的事情。 计时器到期后,执行回调函数。

tmr.alarm()的文档说该功能是tmr.register()tmr.start()的组合。 tmr.register()文档说

  

配置计时器并注册回调函数以在到期时调用。

所以,你的回答是“要做的事情”将会运行,直到它完成,调用tmr.alarm()函数后2秒

tmr.alarm()(以及它所基于的tmr.register())可以采用mode参数。我将描述它们的行为以及每个行为如何受回调函数执行时间的影响。

  • tmr.ALARM_SINGLE:在tmr.alarm()调用完成后n秒,仅运行一次回调函数。完全独立于回调函数的执行时间。
  • tmr.ALARM_AUTO:调用tmr.alarm()后,每隔n秒重复执行一次回调函数。重要的是要注意,无论回调的执行时间如何,下一个时间间隔都会在前一个时间段结束时立即开始。因此,如果回调需要0.5秒才能完成执行并且计时器是2秒,那么下一个调用将在回调函数完成后1.5秒发生。
  • tmr.ALARM_SEMI:在调用tmr.alarm()完成后n秒运行回调函数。与tmr.ALARM_AUTO不同,下一个时间间隔不会自动启动,而只会在您致电tmr.start()后启动;你应该在回调函数中做什么。这意味着您可以将计时器设置为取决于回调函数的执行时间。如果计时器是2秒并且您在回调函数结束时重新启动计时器,那么下次回调运行将是2秒。

正如您可能知道的那样,您不希望回调函数的执行时间大于计时器周期,回调将保持堆叠在彼此之上,永远不会完成。回调应该简单快速地执行,或许将其他工作安排为另一项任务。

答案 1 :(得分:0)

我认为对NodeMCU的固件类型或所需的编程模型存在误解。

  

NodeMCU编程模型类似于Node.js,仅在Lua中。它是异步和事件驱动的。因此,许多函数都有回调函数的参数。

来源:NodeMCU README, "Programming Model"

  

Lua库提供了一组函数,用于将应用程序函数(以Lua编写)声明为回调(存储在Lua注册表中),以将应用程序任务与特定的硬件和计时器事件相关联。这些在应用程序级别是非抢占式的* Lua库与SDK协同工作以排队挂起事件并调用任何已注册的Lua回调例程,然后不间断地运行完成。

来源:NodeMCU Lua开发者常见问题

有关完整说明,请参阅https://nodemcu.readthedocs.io/en/latest/en/lua-developer-faq/#so-how-does-the-sdk-event-tasking-system-work-in-lua

上的“事件任务系统”一章

你在说

  此计时器内的

和“要做的事情”执行超过2秒

但事实是它永远不会运行2s。实际上,任何运行超过几毫秒不间断的任务都可能导致Wifi和TCP堆栈失败。如果您编写违反此原则的代码,那么看门狗可能会随时重置您的设备。您的代码触发的事件只是添加到队列中并按顺序执行。

因此,在大多数情况下,正确答案是b)。