2023-02-18 12:09 PM
I'm trying to inject a simple wrapper around my timer interrput handler written in C - primarily for debug purposes to simplify debugging the state of registers and stack before the C code gets in and messes up the stack and state pushing all the junk it pushes to selectively save registers it's going to mess with etc. I just injected a little assembly (below) to forward the exception to my "real" handler giving me a break point prior to the 'C' code (vector table set to point to this wrapper).
I can run this in the debugger and I can break on the ldr instruction but if I proceed from there (either continue or single step) I end up in the hard fault hander with HFSR: 0x40000000 and CFSR: 0x20000 which seems to indicate and "invalid state" fault.
I'm fairly new to ARM so I'm sure it's something simple but it's got me beat.
NOTE: If I just set the vector table to point directly to my 'C' function everything works just fine - I end up in the 'C' function and everything operates as expected.
Any help would be appreciated.
Shawn
.section .text.TIM6_IRQHandler_Wrapper
TIM6_IRQHandler_Wrapper:
ldr r0, =TIM6_IRQHandler
add r0, #1
bx r0
.size TIM6_IRQHandler_Wrapper, .-TIM6_IRQHandler_Wrapper
2023-02-18 12:41 PM
Doesn't TIM6_IRQHandler already load as an ODD number?
OR on 1, rather than ADD on 1
2023-02-18 12:53 PM
Yeah, you're probably right. But the original version of the code just had "bl TIM6_IRQHandler" - same result. So I figured I'd give adding 1 a shot. Then discovered I'm getting a hard fault even before getting to the branch - not even getting to the add instruction. BTW - based on your note I did two things 1) took out the add (same results) 2) changed add to ORR r0, #1 (same results)
2023-02-18 01:13 PM
What is the value of TIM6_IRQHandler ??
You said it worked when the value was in the Vector Table?
.word / dcd TIM6_IRQHandler
2023-02-18 01:15 PM
What are the first instructions in the TIM6_IRQHandler ?
2023-02-18 01:41 PM
Value of TIM6_IRQHandler = 0x8000dc0 - taken from disassembly in wrapper code. And also cofirmed in disassembly for actual code below.
in the vector table code there is no /dcd switch - just .word TIM6_IRQHandler
.word TIM4_IRQHandler
.word TIM5_IRQHandler
.word TIM6_IRQHandler_Wrapper
.word TIM7_IRQHandler
.word TIM8_BRK_IRQHandler
right now TIM6_IRQHandler looks like this - just handing off to HAL. Will be gettiner more complicated later hence my desire to get a shim in place before I hit the C code.
void TIM6_IRQHandler(void)
{
/* USER CODE BEGIN TIM6_IRQn 0 */
/* USER CODE END TIM6_IRQn 0 */
HAL_TIM_IRQHandler(&htim6);
/* USER CODE BEGIN TIM6_IRQn 1 */
/* USER CODE END TIM6_IRQn 1 */
}
TIM6_IRQHandler:
08000dc0: push {r7, lr}
08000dc2: add r7, sp, #0
266 HAL_TIM_IRQHandler(&htim6);
08000dc4: ldr r0, [pc, #8] ; (0x8000dd0 <TIM6_IRQHandler+16>)
08000dc6: bl 0x80068bc <HAL_TIM_IRQHandler>
270 }
2023-02-18 02:31 PM
Solved it thanks to your questions!! Your /dcd switch question got me to thinking what setting / switches are needed to set the LSB on the address. Then I looked at the .weak and .thumb_set
.weak TIM6_IRQHandler
.thumb_set TIM6_IRQHandler,TIM6_IRQHandler_Wrapper
code in the startup module. Above is the "new" (working) version of the code and I set the vector table back to TIM6_IRQHandler and renamed the entry point in my C code to TIM6_IRQHandler_Main. Seems the .thumb_set statement sets the low bit in the vector. I had commented the .weak and .thumb_set statements out since I didn't need a weak label and I was setting the vector directly.
I need to do a bit more investigation to understand the full dynamics of the .weak, .thumb_set, the vector table and strong overrides. I think the linker somehow knows that when you override a weak address that the .thumb_set setting needs to be sticky.
Anyway, thanks a bunch for your help!!!
Shawn
2023-02-18 02:42 PM
DCD is the Keil/IAR equivalent to .word that GNU/GAS uses
Looking at the listing, or disassembly, file may show the bytes/words emitted by the Assembler. All the function addresses in the vector table should be odd.
On chips with an FPU watch for routines that push co-processor registers. These will fault if the co-processor is not enabled.
2023-02-19 04:08 AM
Someone already sorted it all out and reported:
https://community.st.com/s/question/0D53W00000dS8FcSAK/review-of-st-startup-code
Edited by moderation team to adjust to community guidelines