###### tags: `MicroPython` `ESP8266` # ESP8266 MicroPython reset() 的陷阱 如果你的程式需要強制重置, 像是底下這個簡單的範例: ```python= from machine import reset count = 0 while True: print(count) count = count + 1 if count == 10: reset() ``` 你可能會以為執行了 reset() 之後就會重置, 所以也不會再回到 while 迴圈中, 那你就錯了, 實際的執行結果如下: ``` 0 1 2 3 4 5 6 7 8 9 10 11 12 ... 278 279 280 281 ets Jan 8 2013,rst cause:2, boot mode:(3,6) load 0x40100000, len 30712, room 16 tail 8 chksum 0x16 load 0x3ffe8000, len 996, room 0 tail 4 chksum 0x70 load 0x3ffe83f0, len 1064, room 4 tail 4 chksum 0xa3 csum 0xa3 ��n�r��n|� l lll`�rl�l� l`�rl�l� l`�rl $� ll`rl$rl�bb Čb�b br�$ b�n'� MicroPython v1.15 on 2021-04-18; ESP module with ESP8266 Type "help()" for more information. >>> ``` 計數到 10 的時候的確執行了 reset(), 但這只是發出訊號通知系統重置, 實際上程式從 reset() 返回後還會繼續執行, 你可以看到程式一路列印到 281 才真的重置。根據 [MicroPython 的原始碼](https://github.com/micropython/micropython/blob/7408ca1d7857df5ea348da35c9ee12f70a024478/ports/esp8266/modmachine.c#L76): ```cpp=76 STATIC mp_obj_t machine_reset(void) { system_restart(); return mp_const_none; } ``` reset() 實際上會叫用 [ESP8266 SDK](https://www.espressif.com/sites/default/files/documentation/2c-esp8266_non_os_sdk_api_reference_en.pdf) 的 system_restart, 而 SDK 文件中特別表示: ``` The ESP8266 will not restart immediately. Please do not call other functions after calling this API. ``` 也就是說系統不會真的立即重置, 而且也不希望在此之後叫用其他函式。為了避免這個問題, 建議在 reset() 後加個無窮迴圈等待系統重置: ```python= from machine import reset count = 0 while True: print(count) count = count + 1 if count == 10: reset() while True: pass ``` 這樣就會正確執行了: ``` 0 1 2 3 4 5 6 7 8 9 ets Jan 8 2013,rst cause:2, boot mode:(3,6) load 0x40100000, len 30712, room 16 tail 8 chksum 0x16 load 0x3ffe8000, len 996, room 0 tail 4 chksum 0x70 load 0x3ffe83f0, len 1064, room 4 tail 4 chksum 0xa3 csum 0xa3 ��n�r��n|� l lll`�rl�l� l`�rl�l� l`�rl $� ll`rl$rl�2bb Čb�b br�$ b�n'� MicroPython v1.15 on 2021-04-18; ESP module with ESP8266 Type "help()" for more information. >>> ```