Heartbeat doesn't work while code is running
-
From the documentation: By default the heartbeat LED flashes in blue color once every 4s to signal that the system is alive. It seems to be the inverse case on my LoPy (both running latest 1.6.13.b1 and earlier firmware versions): The heartbeat only flashes when there's no code running!
I'd like to use this built-in heartbeat functionality to check whether the board is still running (to ensure it hasn't crashed on a level I cannot catch in MicroPython / check there ain't problems with the hardware). However, the heartbeat functionality doesn't work while code is running; for example when there's an infinite loop in the
main.py
code, a second thread is waiting on data from an UART. The LED state is never updated, so it just stays off.Was able to recreate this using a minimal testcase of having a
while True: pass
loop inmain.py
, or by running a completely stock board which just opens a REPL, and starting a second thread from there (def test(): while True: pass
,_thread.start_new_thread(test, ())
). In both cases, the heartbeat LED isn't updated: In themain.py
infinite loop case, it might get stuck on a permanent blue LED, in the second thread case the heartbeat LED just never flashes again.So it seems the only case in which the heartbeat LED works is if there isn't any code running at that moment! That means it works for example in applications which purely rely on callbacks from a network stack or timer alarms, but not for anything that actually keeps running (even though the process may be blocked reading from a stream, sleeping, or anything).
Given documentation, this doesn't seem like how it should be. Perhaps someone has some insights on this?
-
@DvdGiessen That's brilliant, thanks for bringing this to our attention! Would you mind opening an issue on the GitHub repo for this particular bug?
https://github.com/pycom/pycom-micropython-sigfox/issues
Thanks!
-
Hi @bucknall,
Sure. Both reduced to minimal testcases, using the fact that the heartbeat is enabled by default:
boot.py
:from machine import UART import os uart = UART(0, 115200) os.dupterm(uart)
main.py
:if __name__ == '__main__': while True: pass
Just to be overly exact: Only spaces for indent, newlines are Unix style (single
\n
), both files have a trailing newline.Same thing happens when using machine.idle or utime.sleep, like this:
main.py
:import machine if __name__ == '__main__': while True: machine.sleep()
Or, using a second thread:
main.py
:import _thread def test(): while True: pass if __name__ == '__main__': _thread.start_new_thread(test, ())
Toggling the heartbeat state using the
pycom.heartbeat(True|False)
method doesn't make any difference.Seen the problem both on latest .13 firmware and on the older versions (up to .9 iirc, but just tested it with .12 which also has the behaviour). Output, from boot, for the version running code in the main thread:
ets Jun 8 2016 00:22:57 rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0x00 clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:QIO, clock div:2 load:0x3fff9010,len:8 load:0x3fff9018,len:248 load:0x40078000,len:4056 load:0x4009fc00,len:920 entry 0x4009fde4 I (1551) wifi: wifi firmware version: 90b1b8b I (1551) wifi: config NVS flash: disabled I (1551) wifi: config nano formating: disabled I (1566) wifi: Init dynamic tx buffer num: 32 I (1567) wifi: wifi driver task: 3ffd62e0, prio:23, stack:3584 I (1567) wifi: Init static rx buffer num: 10 I (1569) wifi: Init dynamic rx buffer num: 0 I (1573) wifi: Init rx ampdu len mblock:7 I (1577) wifi: Init lldesc rx ampdu entry mblock:4 I (1581) wifi: wifi power manager task: 0x3ffdb69c prio: 21 stack: 2560 I (1588) wifi: sleep disable I (2577) wifi: wifi timer task: 3ffdc718, prio:22, stack:3584 I (2596) wifi: Init ampdu: 0 I (2596) wifi: mode : softAP (24:0a:c4:00:b7:0f) I (14497) wifi: n:6 1, o:6 0, ap:6 1, sta:255 255, prof:6 I (14498) wifi: station: 84:16:f9:19:76:74 join, AID=1, n, 40U
Heartbeat LED doesn't blink, until I hit Ctrl-C to break the loop in the main code file, which leaves just the REPL running, at which time the expected behaviour shows again.
When running code in a separate thread (last example
main.py
file):ets Jun 8 2016 00:22:57 rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0x00 clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:QIO, clock div:2 load:0x3fff9010,len:8 load:0x3fff9018,len:248 load:0x40078000,len:4056 load:0x4009fc00,len:920 entry 0x4009fde4 I (1551) wifi: wifi firmware version: 90b1b8b I (1551) wifi: config NVS flash: disabled I (1551) wifi: config nano formating: disabled I (1566) wifi: Init dynamic tx buffer num: 32 I (1567) wifi: wifi driver task: 3ffd62e0, prio:23, stack:3584 I (1567) wifi: Init static rx buffer num: 10 I (1569) wifi: Init dynamic rx buffer num: 0 I (1573) wifi: Init rx ampdu len mblock:7 I (1577) wifi: Init lldesc rx ampdu entry mblock:4 I (1581) wifi: wifi power manager task: 0x3ffdb69c prio: 21 stack: 2560 I (1588) wifi: sleep disable I (2577) wifi: wifi timer task: 3ffdc718, prio:22, stack:3584 I (2594) wifi: Init ampdu: 0 I (2594) wifi: mode : softAP (24:0a:c4:00:b7:0f) MicroPython v1.8.6-607-g9c8a0e9e on 2017-05-01; LoPy with ESP32 Type "help()" for more information. >>>
Non-working heartbeat also happens when running the examples from my previous post directly on the RELP with completely reset board (default code by formatting with
os.mkfs('/flash')
.
-
Hi @DvdGiessen,
Could you please share your boot.py and main.py files? I'm curious to feed this back to Daniel and the team!
Your interpretation of the documentation is correct, this behaviour doesn't align.
Thanks,
Alex