I can see from the OS Tick API docs that any clock source I use for RTX5 ticking must override the nine weak routines that comprise the API.
My question is then, how do I code up the interrupt handler itself? I'm trying this on an EFM32GG, using the RTC peripheral to replace the Systick used by RTX5 as default.
Can I implement my ISR in C, or does it have to follow the form of RTX5's own SysTick_Handler (in RTX/Source/GCC/irq_cm3.S):
SysTick_Handler: PUSH {R0,LR} // Save EXC_RETURN BL osRtxTick_Handler // Call osRtxTick_Handler POP {R0,LR} // Restore EXC_RETURN MRS R12,PSP B SVC_Context
If I implement my handler in C and just call osRtxTick_Handler, I'd be missing out on the
MRS R12, PSP
B SVC_Context
which I imagine are crucial for correct operation.
I am also unclear how the second parameter to OS_Tick_Setup is used. In RTX5, this function is called by svcRtxKernelStart, passing OS_TICK_HANDLER which is a define for SysTick_Handler? So I have to redefine OS_TICK_HANDLER to be MY isr, i.e. RTC_IRQHandler?
I have been unable to find ANY non-SysTick impl for RTX5 using Cortex-M3, if anyone knows of one, please share.
Stuart
I was a bit too quick with my previous reply and did not explain correctly the last part. So let me try again.
User IRQ handler calls the SysTick handler with the following C code:
void IRQ_Handler (void) { SysTick_Handler(); }
This typically leads to the following instruction being generated:
IRQ_Handler: b SysTick_Handler
This is fine seem it is just a branch.
However compiler might generate the following code when lower optimization is used:
IRQ_Handler: push {r7, lr} bl SysTick_Handler pop {r7, pc}
This is however not ok and can lead to RTX crash for targets that have FPU.
When exception occurs the LR contains the EXC_RETURN value which encodes also if Basic or Extended Stack Frame is being used. RTX context switcher that is called within SysTick_Handler expects that LR contains the mentioned EXC_RETURN value and performs the stack handling on thread switch based on that value.
When IRQ_Handler is invoked LR contains EXC_RETURN. This value is pushed in the above problematic IRQ_Handler and then overridden by the return value when executing “bl SysTick_Handler”. Therefore within SysTick_Handler (and later SVC_Context) a wrong LR value will lead to RTX failing to correctly perform a thread switch (eventually leading to a crash).
So again, it is not safe to call SysTick_Handler for RTX with C code unless you ensure that only branch instruction is generated.
Safe would be to use inline assembly within C code:
void IRQ_Handler (void) { __ASM volatile ( "B SysTick_Handler" ); }
Yes, I understand now, that's a very detailed and informative explanation. I re-coded my RTC IRQ as simply 'B SysTick_Handler' and all is good.