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 in main.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 the main.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


Log in to reply
 

Pycom on Twitter