adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
Other
4.09k stars 1.21k forks source link

No autoreload when saving a file on SAMD21 sometimes #6007

Closed Neradoc closed 2 years ago

Neradoc commented 2 years ago

Since around 7.0 I have noticed on SAMD21 boards that sometimes the autoreload doesn't not happen. It is hard to reproduce and seems to happen randomly. But once the boards stops running autoreload:

I have seen the board enter that bad state:

I have done some of those tests on a freshly-flashed, latest-main, and erased-file-system CircuitPlayground Express with a simple neopixel animation code.

tannewt commented 2 years ago

I wonder what the state of these variables are: https://github.com/adafruit/circuitpython/blob/main/supervisor/shared/autoreload.c#L36

DavePutz commented 2 years ago

I reproduced this issue running CP 7.2.0-alpha.2. No autoreload occurred after editing code.py The stack from gdb and the variables you mentioned:

#0  0x0000a628 in common_hal_mcu_enable_interrupts ()
#1  0x0001ccf8 in port_idle_until_interrupt ()
#2  0x00015a36 in mp_hal_delay_ms ()
#3  0x000237cc in time_sleep ()
#4  0x000100ee in fun_builtin_1_call ()
#5  0x000140a0 in mp_call_function_n_kw ()
#6  0x000299e6 in mp_call_method_n_kw ()
#7  0x00015070 in mp_execute_bytecode ()
#8  0x00010078 in fun_bc_call ()
#9  0x000140a0 in mp_call_function_n_kw ()
#10 0x000299b6 in mp_call_function_0 ()
#11 0x0001c5b6 in parse_compile_execute ()
#12 0x00012548 in maybe_run_list ()
#13 0x000201a0 in run_code_py.constprop.0.isra ()
#14 0x00021522 in main ()

(gdb) x /d 0x000000002000134c
0x2000134c <autoreload_delay_ms>:       500
(gdb) x /d 0x0000000020001350
0x20001350 <autoreload_suspended>:      0
(gdb) x /x 0x0000000020001cac
0x20001cac <autoreload_enabled>:        0x00000c01
jerryneedell commented 2 years ago

Just another observation. This happened to me on a feather_m0_adalogger running 7.1.1. Auto reload stopped. I tried copying code.py several times. No auto reload, but on control_d the new file ran. The issue was resolved by a hard reset. I don't have any other details, sorry.

tannewt commented 2 years ago

Thanks for reproducing this @DavePutz! Nothing looks out of ordinary there. Maybe it isn't ticking and counting down?

DavePutz commented 2 years ago

Yes, when autoreload stops working autoreload_delay_ms is always stuck at 500. So, it's not running autoreload_tick(); which means supervisor_tick() isn't getting called from evsyshandler_common(). I am not sure how the interaction between tinyusb and the event subsystem is supposed to work, however.

tannewt commented 2 years ago

I think tinyusb should just start the tick using supervisor_enable_tick via autoreload_start(). It is interesting that there is a check that autoreload_delay_ms == 0 to start the tick. Here it is 500, so it must have tried and failed to start the tick. Or ticks were disabled separately while autoreload_delay_ms was non-zero.

dhalbert commented 2 years ago

I did some rework of the autoreload logic to make it a bit more straightforward, but I don't know if I've actually fixed anything. I've tried to reproduce this and have failed. I wrote a small LED blink program that doesn't use time.sleep(), and just counts in a for-loop for a delay. Then I either edit the program or just touch the file. It is always restarting.

For those of you that hit this problem, can you say anything about when it came about?

  1. Were you connected to USB REPL serial?
  2. Did it is seem to be completely random, and rare?
  3. etc.
ladyada commented 2 years ago

for me it was a prox trinkey, using the repl and doing some HID development. i plugged it back in and now auto-reload is working :/

FoamyGuy commented 2 years ago

I have an Itsy Bitsy M0 7.2.0 that I noticed this issue on the other day. I am able to reproduce it reliably with every code change currently using a basic code.py that prints different things. I can update code.py with new print messages and then save, IDE reports file saved (astrisk disappears) but code is not rerun. I can either reset button, or ctrl+c then ctrl+d to run the latest code.

FoamyGuy commented 2 years ago

The issue does seem to be tied to the ~REPL~ USB Serial connection. I disconnected tio and subsequent changes to code.py do get executed when the file is saved.

When the ~REPL~ USB Serial is connected via tio then it will consistently not update upon saving code.py. It seems to me like it is not sporadic. Not running any time that I save. When the ~REPL~ USB Serial connection is open I must use ctrl+C then ctrl+D to get the latest code to run at all.

tannewt commented 2 years ago

Do you mean serial? When the REPL is active (with >>> prompt) auto-reload is intentionally disabled.

FoamyGuy commented 2 years ago

Ah, yeah I did mean serial when connected via tio not specifically in the REPL.

dhalbert commented 2 years ago

I also meant serial, not specifically REPL.

dhalbert commented 2 years ago

I am reproducing this now with:

for j in range(10000):
    for i in range(1000):
        pass
    print("doing stuff", j) #

I am editing the last line in emacs and adding an additional # each time. The output pauses a bit during the write, but then just keeps on going.

dhalbert commented 2 years ago

Fixed by #6132, #6142, #6153.