Open crasbe opened 1 week ago
Okay, so it appears that the Hard Fault happens in/before ztimer_handler()
is called. The _add_entry_to_list
function is executed completely and then the Hard Fault happens.
What's odd is that ISR -2
would be the PendSV_ISR, which is used for the scheduler. That means that the HardFault happened inside of the isr_pendsv
function, which is in cpu/cortexm_common/thread_arch.c
.
The STM32CubeProgrammer has a new feature called "Fault Analyzer" and it says the fault happened at address 0x8000A93.
With GDB I decompiled the binary and tadaaaa:
(gdb) x/16ib 0x8000A80
0x8000a80 <isr_svc+4>: ldr r3, [pc, #4] ; (0x8000a88 <isr_svc+12>)
0x8000a82 <isr_svc+6>: str r2, [r3, #4]
0x8000a84 <isr_svc+8>: bx lr
0x8000a86 <isr_svc+10>: nop
0x8000a88 <isr_svc+12>: stc 0, cr14, [r0, #-0]
0x8000a8c <sched_arch_idle>: push {r3, lr}
0x8000a8e <sched_arch_idle+2>: bl 0x8001608 <pm_set_lowest>
0x8000a92 <sched_arch_idle+6>: cpsie i
0x8000a94 <sched_arch_idle+8>: isb sy
0x8000a98 <sched_arch_idle+12>: cpsid i
0x8000a9a <sched_arch_idle+14>: pop {r3, pc}
0x8000a9c <hard_fault_default>: ldr r3, [pc, #52] ; (0x8000ad4 <hard_fault_default+56>)
0x8000a9e <hard_fault_default+2>: ldr r2, [pc, #56] ; (0x8000ad8 <hard_fault_default+60>)
0x8000aa0 <hard_fault_default+4>: ldr r1, [pc, #56] ; (0x8000adc <hard_fault_default+64>)
0x8000aa2 <hard_fault_default+6>: mov r0, sp
0x8000aa4 <hard_fault_default+8>: cmp r0, r2
The instruction where the Hard Fault happens is cpsie i
.
The fault that happened is "IBUSERR", which means the instruction prefetch failed. Looking at the RIOT trace, this makes sense, since 0x08783282 is an illegal address. However I don't know how that's related to the cpsie i
instruction (or anything around it).
ztimer_set(): After ztimer_update
ztimer_set(): After ztimer_update
sched_set_status: removing thread 1 from runqueue hu.
Context before hardfault:
r0: 0x00000002
r1: 0x200004a4
r2: 0x00000001
r3: 0x00000000
r12: 0x00000036
lr: 0x08001283
pc: 0x08783282
psr: 0x6100000e
FSR/FAR:
CFSR: 0x00000100
HFSR: 0x40000000
DFSR: 0x00000008
AFSR: 0x00000000
Misc
EXC_RET: 0xfffffff1
Hard fault occurred in ISR number -2
Attempting to reconstruct state for debugging...
In GDB:
set $pc=0x8783282
frame 0
bt
*** RIOT kernel panic:
HARD FAULT HANDLER
*** halted.
Inside isr -13
This is pretty much at the end of my knowledge (actually beyond that 😅 ).
Description
When programming the
tests/periph/adc
test program to the NUCLEO-L152RE board withmake flash
, the program crashes on the first call ofztimer_set
. After a power cycle, the program runs without any issues. Likewise, when the program is flashed using the builtin mass storage driver of the ST-Link, the program will start without any issues. Programming the chip with the STM32CubeProgrammer leads to the same result as OpenOCD.Steps to reproduce the issue
The program I used for testing is
tests/periph/adc
, maybe it can be reproduced with others well. Optionally you can apply the change described in https://github.com/RIOT-OS/RIOT/issues/20780#issuecomment-2482672894, but the unmodified master version works just as well.First the ISR stacksize has to be increased, otherwise the
printf
in the Hard Fault handler won't print out anything. Just addCFLAGS += -DISR_STACKSIZE=1024
totests/periph/adc/Makefile
.BOARD=nucleo-l152re make flash term
Usually the output won't be complete, so hit the reset button:With the ztimer ENABLE_DEBUG flag enabled in
sys/ztimer/core.c
, the output becomes the following:After a power cycle, this is the resulting output:
It looks like the program crashes either in
_add_entry_to_list()
or in theztimer_handler()
function.Maybe someone a bit more familiar with ztimer can have a look at this issue. My theory is that some register is not properly reset. I don't know which hardware timer
ztimer
uses on the STM32L152ZE, but there is a remark in the reference manual [1] on page 165, section 6.3.14:Does ztimer use the RTC or relies on the LSE-registers? Trying to access the write protected RTC registers would surely lead to a Hard Fault?
Expected results
Regardless of the flashing method, the program should not crash when using ztimer.
Actual results
The program crashes.
Versions
Note: I updated OpenOCD to see if that was the cause of the issue, but the same happens with OpenOCD 0.11 and 0.12.
[1] https://www.st.com/resource/en/reference_manual/cd00240193-stm32l100xx-stm32l151xx-stm32l152xx-and-stm32l162xx-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf