当NodeMCU定时器内的代码执行超过我设置的定时器间隔会发生什么?
在esp8266芯片中,我们可以很容易地创建计时器功能。但是,我想知道,如果定时器内的代码执行超过我设置的定时器间隔,会发生什么?
请参见下面的代码。 如果我设置一个2秒的定时器间隔,并且在此定时器内的“要做的事情”执行超过2秒,然后会发生什么?
tmr.alarm(0, 2000, 1, function ()
--要做的事情
end)
a)一旦定时器间隔达到2秒,“要做的事情”会被终止吗?
b)或者“要做的事情”将继续执行直到完成,并且下一个“要做的事情”将被延迟?
c)还是这个定时器的每一轮都会等待“要做的事情”完成而不管2秒的间隔?(间隔自动扩展)
d)还是其他情况?
我相信有一些误解关于 NodeMCU 是什么类型的固件或需要怎样的编程模型。
NodeMCU 的编程模型类似于 Node.js 的模型,只不过是用 Lua 完成的。它是异步和事件驱动的。因此,许多函数需要回调函数作为参数。
来源: NodeMCU README, "Programming Model"
Lua 库提供了一组函数,用于将应用程序功能(用 Lua 编写)声明为回调函数(存储在 Lua 注册表中),将应用程序任务与特定的硬件和定时器事件关联起来。它们是非抢占式的,位于应用程序级别 *。Lua 库与 SDK 协同工作,将待定事件排队,并调用任何已注册的 Lua 回调例程,然后不间断地运行到完成。
来源:NodeMCU Lua 开发人员 FAQ
完整的解释详见 https://nodemcu.readthedocs.io/en/latest/en/lua-developer-faq/#so-how-does-the-sdk-event-tasking-system-work-in-lua 中的 “事件任务系统” 章节。
你说:
这个计时器内的 “Something to do” 执行时间超过了 2 秒
但事实上它将 永远不会 运行 2 秒。实际上,任何运行超过几毫秒的未中断任务都可能导致 Wifi 和 TCP 栈失败。如果您编写违反此原则的代码,则看门狗可能会任何时间重置您的设备。您的代码触发的事件只是按顺序添加到队列中执行。
因此,在大多数情况下,正确答案是 b)。
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

该函数的行为可能与您想象的不同。通常,在需要提供回调函数时,回调函数将在事件发生时执行;这也是这里发生的情况。回调函数是在计时器到期后执行的。
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 秒后运行。正如您可能已经注意到的,您不希望回调函数的执行时间大于计时器周期,回调函数将始终堆叠在一起,永远不会完成。回调应该是简单且快速执行的,并可能将其他工作安排为另一个任务。