machine.reset_cause() appears to be broken

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
paulg
Posts: 29
Joined: Fri Oct 23, 2015 1:06 pm

machine.reset_cause() appears to be broken

Post by paulg » Wed Oct 23, 2019 4:37 pm

Hi guys,

I have a TinyPICO board (based on ESP32-PICO-D4). I have wired a normally open pushbutton switch between the RST and GND pins. I am using rshell to talk to the board. My test program is as follows. This is copied to main.py on the TinyPICO.

# Test program 7: Test if machine.reset_cause() is working

import machine

print('\nHello. This is test 7')

rc = machine.reset_cause()
print('Reset Cause = ', rc)

print('Goodbye!\n')

With rshell connected, if I press the reset button I get the following:

>>> ets Jun 8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 188777542, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:5068
load:0x40078000,len:11408
load:0x40080400,len:6136
entry 0x400806c0
I (582) psram: This chip is ESP32-PICO
I (582) spiram: Found 64MBit SPI RAM device
I (582) spiram: SPI RAM mode: flash 40m sram 40m
I (585) spiram: PSRAM initialized, cache is in low/high (2-core) mode.
I (592) cpu_start: Pro cpu up.
I (596) cpu_start: Application information:
I (601) cpu_start: Compile time: Oct 11 2019 00:38:26
I (607) cpu_start: ELF file SHA256: 0000000000000000...
I (613) cpu_start: ESP-IDF: v4.0-beta1
I (618) cpu_start: Starting app cpu, entry point is 0x4008324c
I (0) cpu_start: App cpu up.
I (1493) spiram: SPI SRAM memory test OK
I (1494) heap_init: Initializing. RAM available for dynamic allocation:
I (1494) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM
I (1500) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM
I (1506) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM
I (1512) heap_init: At 3FFBDB5C len 00000004 (0 KiB): DRAM
I (1519) heap_init: At 3FFCC7D0 len 00013830 (78 KiB): DRAM
I (1525) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (1531) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (1538) heap_init: At 4009DEF8 len 00002108 (8 KiB): IRAM
I (1544) cpu_start: Pro cpu start user code
I (1562) spi_flash: detected chip: generic
I (1563) spi_flash: flash io: dio
I (1563) cpu_start: Chip Revision: 1
W (1565) cpu_start: Chip revision is higher than the one configured in menuconfig. Suggest to upgrade it.
I (1575) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.

Hello. This is test 7
Reset Cause = 1
Goodbye!

MicroPython v1.11-422-g98c2eabaf on 2019-10-11; ESP32 module (spiram) with ESP32
Type "help()" for more information.
>>>

If I then force a Soft Reset by typing Ctrl-D at the real prompt I get:

MPY: soft reboot

Hello. This is test 7
Reset Cause = 1
Goodbye!

MicroPython v1.11-422-g98c2eabaf on 2019-10-11; ESP32 module (spiram) with ESP32
Type "help()" for more information.
>>>

According to help(machine) Reset Cause should be 5 for a Soft Reset.

Can anybody confirm this (perhaps on a different ESP32 board) or am I doing something wrong?

Thanks,
Paul G

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: machine.reset_cause() appears to be broken

Post by jimmo » Thu Oct 24, 2019 10:43 am

Hi,

Sorry I'm less familiar overall with ESP32, so hopefully someone more knowledgeable will chime in, but I took a quick skim of the code and I think the issue here is that "soft reset" means two different things.

In MicroPython, what it calls a soft reset (i.e. ctrl-d) doesn't actually reset the CPU. The main() function just runs a loop that initialises the VM, runs boot.py/main.py, then runs the REPL. Ctrl-D terminates the loop and starts the repl again. So the hardware reset cause won't have changed as the CPU hasn't reset.

From ESP32's perspective (i.e the IDF), a soft reset is a software-initiated CPU reset. Which you could test from Python with machine.reset(), and I would imagine in that case you would see machine.SOFT_RESET as the cause.

However... my memory is that on STM32, it actually loads the reset cause on MicroPython soft reset, then clears it. So a MicroPython soft reset actually ends up looking the same as a hardware-level soft reset. So I think this is an API discrepancy between ESP32 and STM32. I will test this when I'm next at my desk with an ESP32 and STM32 board and raise a bug.

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: machine.reset_cause() appears to be broken

Post by Roberthh » Thu Oct 24, 2019 7:10 pm

Confirmed. I tested with an ESP32:

Reset causes:
Reset button or power on: 3
Wakeup after deepsleep: 4
machine.reset(): 5

No case of a reset_cause() 1.

paulg
Posts: 29
Joined: Fri Oct 23, 2015 1:06 pm

Re: machine.reset_cause() appears to be broken

Post by paulg » Thu Oct 24, 2019 7:46 pm

Thanks guys.

@Jimmo, I think your explanation is correct.

My experiments show Reset Cause:
Reset button: 1
Ctrl D at REPL: 1
machine.reset(): 5
I can't test Power On reset because the usb to serial port chip is on the TinyPICO so the serial port does not exist on my Mac until the TinyPICO is plugged in by which time it is running code.

@Roberthh, you seem to be getting a strange value for Reset button or power on. help(machine) shows:

reset_cause -- <function>
HARD_RESET -- 2
PWRON_RESET -- 1
WDT_RESET -- 3
DEEPSLEEP_RESET -- 4
SOFT_RESET -- 5

I think the fundamental problem is that the documentation is misleading. Typing help() at the REPL gives:

Control commands:
CTRL-A -- on a blank line, enter raw REPL mode
CTRL-B -- on a blank line, enter normal REPL mode
CTRL-C -- interrupt a running program
CTRL-D -- on a blank line, do a soft reset of the board
CTRL-E -- on a blank line, enter paste mode

The MicroPython documentation states:

2.3.6. Other control commands

There are four other control commands:

Ctrl-A on a blank line will enter raw REPL mode. This is like a permanent paste mode, except that characters are not echoed back.
Ctrl-B on a blank like goes to normal REPL mode.
Ctrl-C cancels any input, or interrupts the currently running code.
Ctrl-D on a blank line will do a soft reset.
Note that ctrl-A and ctrl-D do not work with WebREPL.

Perhaps instead of saying "soft reset" it would be more accurate to say "program restart".

Post Reply