cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F429VIT6 + Mbed-os 5.12: RTC Backup data register read causes fatal error

Turo
Associate

I have this really weird problem that has something to do with the RTC Backup data registers. I was testing the bootloaders ability to fall back to previous version of the firmware by letting IWDT reboot the device. Bootloader has a counter that uses RTC backup register, which is zeroed in the main-program when it starts, and if it counts to three as an indication that the main-program never runs, bootloader falls back. There is also another RTC backup register in use to save the reboot reason flag. I commented this zeroing out in main, to let the bootloader fall back. But when i tried to run the program it now fails to the previous rtc backup read function on the second boot cycle. This can be reset by full power cycle, i mean it does the same thing every time after power cycle. If i comment out the RTC backup register read function, everything works fine.

This is my firs post here, so i will be modifying this. This posting-interface is really un-intuitive for me. Lets see how this post looks.

/* 1. run after flashing */

[DBG ][boot]: RCC_FLAG_PORRST

uint32_t rtc_read_backup_reg(uint32_t). Enter

uint32_t rtc_read_backup_reg(uint32_t). Handle instance initialized

uint32_t rtc_read_backup_reg(uint32_t). Value returned from f() = 0

uint32_t rtc_read_backup_reg(uint32_t). Return

[DBG ][main]: Bootloader has rebooted: 0 times

uint32_t rtc_read_backup_reg(uint32_t). Enter

uint32_t rtc_read_backup_reg(uint32_t). Handle instance initialized

uint32_t rtc_read_backup_reg(uint32_t). Value returned from f() = 0

uint32_t rtc_read_backup_reg(uint32_t). Return

[DBG ][main]: Fault flag: reset_normal

void rtc_write_backup_reg(uint32_t, uint32_t). Enter

void rtc_write_backup_reg(uint32_t, uint32_t). Handle instance initialized

void rtc_write_backup_reg(uint32_t, uint32_t). Access enabled

void rtc_write_backup_reg(uint32_t, uint32_t). Value updated

void rtc_write_backup_reg(uint32_t, uint32_t). Access disabled

void rtc_write_backup_reg(uint32_t, uint32_t). Return

/* Here the WDT is initialized and wait-function set as long to trigger it */

[DBG ][main]: Now get stuck in run version waiting for bootloader bootloop

/* 2. run: IWDT resets MCU */

[DBG ][boot]: RCC_FLAG_IWDGRST

uint32_t rtc_read_backup_reg(uint32_t). Enter

uint32_t rtc_read_backup_reg(uint32_t). Handle instance initialized

uint32_t rtc_read_backup_reg(uint32_t). Value returned from f() = 1

uint32_t rtc_read_backup_reg(uint32_t). Return

[DBG ][main]: Bootloader has rebooted: 1 times

uint32_t rtc_read_backup_reg(uint32_t). Enter

uint32_t rtc_read_backup_reg(uint32_t). Handle instance initialized

uint32_t rtc_read_backup_reg(uint32_t). Value returned from f() = 128

uint32_t rtc_read_backup_reg(uint32_t). Return

/* Fatal error on what seems to be the return from rtc_read_backup_reg() */

++ MbedOS Error Info ++

Error Status: 0x8001012F Code: 303 Module: 1

Error Message: Error - writing to a file in an ISR or critical section

Location: 0x80316C7

Error Value: 0x1

Current Thread: main Id: 0x20005F10 Entry: 0x80321C3 StackSize: 0x1000 StackMem: 0x20010628 SP: 0x2002F

D6C

For more info, visit: ...

-- MbedOS Error Info --

int main () {
    // Initialize priting ...
 
    uint32_t reset_amount = rtc_read_backup_reg(MBED_CONF_APP_RESET_COUNTER_REGISTER);
    tr_info("Bootloader has rebooted: %lu times", reset_amount);
    /* On the second run, does not return (or at least seems like it). If commented out, works fine */
    uint32_t rtc_reg = rtc_read_backup_reg(MBED_CONF_APP_RESET_FLAGS_REGISTER);
    tr_debug("Fault flag: %s", reset_error_str[rtc_reg]);
    /* Commented out to let the bootloader fall back */
    // rtc_write_backup_reg(MBED_CONF_APP_RESET_COUNTER_REGISTER, 0);
    rtc_write_backup_reg(MBED_CONF_APP_RESET_FLAGS_REGISTER, reset_normal);
    // ...
    // ...
}

  

uint32_t rtc_read_backup_reg(uint32_t BackupRegister) {
    printf("%s. Enter\n", __PRETTY_FUNCTION__);
    RTC_HandleTypeDef RtcHandle;
    RtcHandle.Instance = RTC;
    printf("%s. Handle instance initialized\n", __PRETTY_FUNCTION__);
    uint32_t register_value = HAL_RTCEx_BKUPRead(&RtcHandle, BackupRegister);
    printf("%s. Value returned from f() = %lu\n", __PRETTY_FUNCTION__, register_value);
    printf("%s. Return\n", __PRETTY_FUNCTION__);
    return register_value;
}

void rtc_write_backup_reg(uint32_t BackupRegister, uint32_t data) {
    printf("%s. Enter\n", __PRETTY_FUNCTION__);
    RTC_HandleTypeDef RtcHandle;
    RtcHandle.Instance = RTC;
    printf("%s. Handle instance initialized\n", __PRETTY_FUNCTION__);
    HAL_PWR_EnableBkUpAccess();
    printf("%s. Access enabled\n", __PRETTY_FUNCTION__);
    HAL_RTCEx_BKUPWrite(&RtcHandle, BackupRegister, data);
    printf("%s. Value updated\n", __PRETTY_FUNCTION__);
    HAL_PWR_DisableBkUpAccess();
    printf("%s. Access disabled\n", __PRETTY_FUNCTION__);
    printf("%s. Return\n", __PRETTY_FUNCTION__);
}

1 ACCEPTED SOLUTION

Accepted Solutions
Pavel A.
Evangelist III

tr_debug("Fault flag: %s", reset_error_str[rtc_reg]);

What if the value of rtc_reg is not a valid index in reset_error_str ?

View solution in original post

2 REPLIES 2
Pavel A.
Evangelist III

tr_debug("Fault flag: %s", reset_error_str[rtc_reg]);

What if the value of rtc_reg is not a valid index in reset_error_str ?

That was it. I feel so stupid.

Thank you!