esp-rs / esp-hal

no_std Hardware Abstraction Layers for ESP32 microcontrollers
https://docs.esp-rs.org/esp-hal/
Apache License 2.0
710 stars 195 forks source link

__user_exception at boot, RTC variables not persisted #1105

Closed blinry closed 7 months ago

blinry commented 8 months ago

I'm developing for an "Adafruit ESP32 Feather v2", and tried the esp-template with its default settings.

When I run cargo run, the output looks like this:

Finished dev [unoptimized + debuginfo] target(s) in 0.06s
     Running `espflash flash --monitor target/xtensa-esp32-none-elf/debug/esp-test`
[2024-01-21T12:33:32Z INFO ] Serial port: '/dev/ttyACM0'
[2024-01-21T12:33:32Z INFO ] Connecting...
[2024-01-21T12:33:32Z INFO ] Using flash stub
Chip type:         esp32 (revision v3.0)
Crystal frequency: 40MHz
Flash size:        8MB
Features:          WiFi, BT, Dual Core, 240MHz, Embedded Flash, Embedded PSRAM, VRef calibration in efuse, Coding Scheme None
MAC address:       ac:0b:fb:6b:43:d4
App/part. size:    184,016/8,323,072 bytes, 2.21%
[00:00:01] [========================================]      17/17      0x1000     [00:00:00] [========================================]       1/1       0x8000     [00:00:06] [========================================]      71/71      0x10000    [2024-01-21T12:33:41Z INFO ] Flashing has completed!
Commands:
    CTRL+R    Reset chip
    CTRL+C    Exit

ets Jul 29 2019 12:21:46

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 271414342, 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:0x3fff0030,len:7104
0x3fff0030 - _ESP_HAL_DEVICE_PERIPHERALS
    at ??:??
load:0x40078000,len:15576
0x40078000 - _ESP_HAL_DEVICE_PERIPHERALS
    at ??:??
load:0x40080400,len:4
0x40080400 - _DoubleExceptionVector
    at ??:??
ho 8 tail 4 room 4
load:0x40080404,len:3876
0x40080404 - _DoubleExceptionVector
    at ??:??
entry 0x4008064c
0x4008064c - __user_exception
    at /home/blinry/.cargo/registry/src/index.crates.io-6f17d22bba15001f/esp-backtrace-0.10.0/src/lib.rs:113
I (32) boot: ESP-IDF v5.1-beta1-378-gea5e0ff298-dirt 2nd stage bootloader
I (32) boot: compile time Jun  7 2023 07:48:23
I (34) boot: Multicore bootloader
I (38) boot: chip revision: v3.0
I (42) boot.esp32: SPI Speed      : 40MHz
I (47) boot.esp32: SPI Mode       : DIO
I (51) boot.esp32: SPI Flash Size : 8MB
I (56) boot: Enabling RNG early entropy source...
I (61) boot: Partition Table:
I (65) boot: ## Label            Usage          Type ST Offset   Length
I (72) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (79) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (87) boot:  2 factory          factory app      00 00 00010000 007f0000
I (94) boot: End of partition table
I (99) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=06b64h ( 27492) map
I (117) esp_image: segment 1: paddr=00016b8c vaddr=3ffb0000 size=00004h (     4) load
I (117) esp_image: segment 2: paddr=00016b98 vaddr=40080000 size=01860h (  6240) load
I (127) esp_image: segment 3: paddr=00018400 vaddr=00000000 size=07c18h ( 31768) 
I (144) esp_image: segment 4: paddr=00020020 vaddr=400d0020 size=1ce84h (118404) map
I (187) boot: Loaded app from partition at offset 0x10000
I (187) boot: Disabling RNG early entropy source...
Hello world!
Loop...

The program seems to work fine, but is the __user_exception an error, or something to be expected? (When I go into deep sleep, it happens for every wakeup.)

What could I do to help you debug this further? Also let me know if I should file this issue in another project. Thanks! :)

blinry commented 8 months ago

To add context, I'm trying to find out why my program doesn't keep variables in the RTC RAM during deep sleep. I'm declaring them like this:

#[link_section = ".rtc.data"]
static mut COUNTER: u32 = 0;

But changes to it are not visible after a deep sleep. I figured the above "harder-than-expected-reboot" could be related?

bjoernQ commented 8 months ago
entry 0x4008064c
0x4008064c - __user_exception

esp-flash tried to resolve hex values which look like an address and in this case, it resolved the entry point logged by the bootloader as the symbol __user_exception. Not really something to worry about

As for the RTC data: We have a macro ram which should place data into RTC RAM, e.g. https://github.com/esp-rs/esp-hal/blob/c4486800548aaacec26883a6f4491ad6860388ab/esp32-hal/examples/ram.rs#L23-L30

blinry commented 8 months ago

Thanks, those macros seem really helpful!

Persisting these variables through a deep sleep doesn't seem to work for me, though. I made a minimal project to reproduce this: https://github.com/blinry/esp32-deep-sleep-rtc-test

It contains all three variants:

#[ram(rtc_fast)]
static mut RTC_FAST_DATA: u32 = 42;

#[ram(rtc_fast, uninitialized)]
static mut RTC_FAST_NOINIT: u32 = 42;

#[ram(rtc_fast, zeroed)]
static mut RTC_FAST_BSS: u32 = 42;

When I run it (both on an Adafruit ESP32 Feather v2, as well as another random ESP32-WROOM-32 devboard), it shows values like these on the first run:

Value of RTC_FAST_DATA: 42
Value of RTC_FAST_NOINIT: 1644341610
Value of RTC_FAST_BSS: 0

Which is what I'd expect. The code then increments all three variables.

When the deep sleep ends, I get the the above output about __user_exception and _ESP_HAL_DEVICE_PERIPHERALS; the chip seems to reboot. Then, I get outputs like these:

Value of RTC_FAST_DATA: 2914262833
Value of RTC_FAST_NOINIT: 1644210282
Value of RTC_FAST_BSS: 0

So none of the values is persisted. Do you have an idea why?

bjoernQ commented 8 months ago

sleep_deep will power down RTC memory during sleep.

You can do something like this

    let mut cfg = RtcSleepConfig::deep();
    cfg.set_rtc_fastmem_pd_en(false);
    cfg.set_rtc_slowmem_pd_en(false);

    let timer = TimerWakeupSource::new(Duration::from_secs(3));
    rtc.sleep(&cfg, &[&timer], &mut delay);

    loop {}

instead to prevent RTC memory from getting powered down

blinry commented 8 months ago

Whoa, that's the solution! Thank you! I updated my minimal project.

Maybe something like this should be an additional example in the examples directory? I wasn't able to figure this out on my own.

MabezDev commented 8 months ago

@blinry Would you mind PRing an example? Totally okay if not, but like you said it would be helpful for others :).

MabezDev commented 7 months ago

I think this is solved now. @blinry it would still be really nice to have an example in esp-hal itself, if you find some free time :).