【问题标题】:Interrupt during network I/O == crash?网络 I/O 期间中断 == 崩溃?
【发布时间】:2016-08-09 13:54:25
【问题描述】:

似乎在执行网络 I/O 时发生 I/O 引脚中断时,系统会重置——即使中断函数只声明一个局部变量并分配它(本质上是一个无操作例程。)所以我相当肯定这与在中断函数中花费太多时间无关。 (我实际工作的中断函数非常简陋,严格递增和赋值,甚至没有任何条件逻辑。)

这是一个已知的约束吗?我的解决方法是在使用网络时断开中断,但这当然会带来数据丢失的可能性。

function fnCbUp(level)
    lastTrig = rtctime.get()
    gpio.trig(pin, "down", fnCbDown)
end

function fnCbDown(level)
    local spin = rtcmem.read32(20)
    spin = spin + 1
    rtcmem.write32(20, spin)
    lastTrig = rtctime.get()
    gpio.trig(pin, "up", fnCbUp)
end

gpio.trig(pin, "down", fnCbDown)
gpio.mode(pin, gpio.INT, gpio.FLOAT)

分支:主

构建于:2016-03-15 10:39

由基于 SDK 1.4.0 的 Lua 5.1.4 提供支持

模块:adc,bit,file,gpio,i2c,net,node,pwm,rtcfifo,rtcmem,rtctime,sntp,tmr,uart,wifi

【问题讨论】:

  • 再次向我们展示代码和固件分支/修订版。这通常不是已知的限制,但我们会不断发现和修复原始网络模块中的错误(准备重新编写)。
  • 更新了 Q 以包含构建和源代码。

标签: esp8266 nodemcu


【解决方案1】:

不确定这应该是答案还是评论。不过评论可能有点长。

所以,问题是“这是一个已知的约束吗?”简短但不令人满意的答案是“不”。不能就这样……

代码摘录是否足以让您断定由于这几行中的某些事情而必须发生重置?我对此表示怀疑。 您似乎在做的是每个 GPIO 'down' 的简单“全局”增量,并带有一些去抖动逻辑。但是,我没有看到任何反跳,我错过了什么?你有时间进入全球lastTrig,但你没有用它做任何事情。只是为了去抖动,你不需要rtctime IMO,但我怀疑这与问题有关。

我有一个gist of a tmr.delay-based debounceone with tmr.now,这更像是一个油门。你可以像这样使用第一个:

GPIO14 = 5
spin

function down()
    spin = spin + 1
    tmr.delay(50)                    -- time delay for switch debounce
    gpio.trig(GPIO14, "up", up)      -- change trigger on falling edge
end

function up()
    tmr.delay(50)
    gpio.trig(GPIO14, "down", down)  -- trigger on rising edge
end

gpio.mode(GPIO14, gpio.INT)          -- gpio.FLOAT by default
gpio.trig(GPIO14, "down", down)

我还建议对 dev 分支运行此程序,因为您说它与中断期间的网络 I/O 有关。

【讨论】:

  • 不,我不认为问题出在我发布的代码中,这是为了响应您的请求。它实际上不是一个开关,它是一个霍尔效应传感器,所以我不确定我是否需要去抖动。 lastTrig 是一个全局变量,在代码的其他地方使用(测试一定长度的不活动状态。)我在网络调用之前和之后添加了打印语句,如 sntp.sync、net.dns.resolve、connection:send 等,以及他们的回调。系统没有给出任何指示问题出在哪里或出在哪里,但打印语句似乎描绘了一幅一致的画面。
  • 好的,抱歉,我没有其他工作要做。固件中的大量模块似乎表明您的 Lua 应用程序相当复杂(或过度设计)。您能否将其分解为创建一个仍然失败的最小、完整和可验证示例 (MCVE)?如果您的 MCVE 在 masterdev 上始终失败,则这可能表明固件中存在错误,然后您将在 GitHub 上报告。
【解决方案2】:

我几乎有同样的问题。 运行ESP8266Webserver,使用GPIO14 Interrupt,输入脉冲太快, 系统停止记录中断。 详情请看这里。

http://www.esp8266.com/viewtopic.php?f=28&t=9702

我使用的是 ARDUINO IDE 1.69,但问题似乎是一样的。 我使用ESP8266-07 作为生成器和计数器(没有 Web 服务器) 生成脉冲,连接到我的 ESP8266-Watersystem。

生成器工作得很好,比240 puls / sec,多了很多 生成和计数相同的 ESP。

但是ESP-Watersystem,在impuls > 50/ second: 处停止记录中断

/*************************************************/

/*  ISR Water pulse counter                      */

/*************************************************/

/**

 * Invoked by interrupt14 once per rotation of the hall-effect sensor. Interrupt

 * handlers should be kept as small as possible so they return quickly.

 */


 void ICACHE_RAM_ATTR pulseCounter()

    {

      // Increment the pulse Counter

      cli();

      G_pulseCount++;

     Serial.println ( "!" );

     sei();

    }

此处的串行输出仅用于显示正在发生的事情。 它显示正确计数的脉冲,直到网络服务器与网络交互。 比接缝中断被阻止。(这里没有串行输出) 通过强调系统,当我在短时间内多次刷新网站时, 中断计数开始了很短的时间,但又停止了很短的时间。

问题出在中断处理和 Web 服务的任何地方。 我希望我能帮助找到这个问题。

有兴趣获得一些解决方案。 谁能帮忙?

感谢 Mickbaer 柏林,德国 电子邮件:michael.lorenz@web.de

【讨论】:

  • 我们走在几乎平行的道路上!我的对托管服务器进行出站 WebAPI 调用以记录其数据,而您的则接受入站 Web 连接。当 ESP 进入配置模式时,我的确实提供了一个配置页面和作为 HTTP 的 WebAPI,但是该页面使用 AJAX 通过 WebAPI 读取/写入配置值,而不是向 ESP 发布表单
  • 至于崩溃,我想我已经将它与硬件隔离,特别是电源。我的电路在传感器空闲的服务器模式下消耗 80 mA。我使用的传感器最大消耗 15 mA。从逻辑上讲,它的脉冲越快,它吸收的电流就越多,它可能是感应的。因此,请确保您没有看到低于 3.1v 的电压下降,否则会在进行网络 i/o 时崩溃。
  • 请注意,我对您的开发环境一无所知(除了了解 C++),因此这可能毫无意义,但我的印象是 Espressiff 的底层 SDK 本质上是事件驱动的。所以我有点惊讶地看到你的代码(在 ESP 论坛上)你在循环中轮询 http 状态?在 nodemcu 中,我将使用计时器驱动它,因此我的主要处理函数返回以让异步任务完成。 (“wdt reset”表示您的代码已被看门狗定时器重置。)
猜你喜欢
  • 2013-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多