2022-10-31 03:26 AM
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__);
}
Solved! Go to Solution.
2022-10-31 06:34 AM
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 ?
2022-10-31 06:34 AM
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 ?
2022-10-31 06:45 AM
That was it. I feel so stupid.
Thank you!