This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Implementing OS_Tick API in RTX5 for Cortex-M3

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

Parents
  • 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"
      );
    }

Reply
  • 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"
      );
    }

Children