Interrupts under ThreadX

I require a number of high priority ISR ,which do not interact with the main application threads, that cannot be delayed by the RTOS.

Please can you clarify how the SSP / ThreadX can be configured to achieve this on an S7?

Can nested interrupts be supported?

What is the relevance of the text in the SSP dropdown for setting interrupt priorities eg '(CM4:valid, CM0+:lowest-not valid if using ThreadX)?

 

Regards

David

  • Hello David,

    ThreadX and other X-Ware and SSP components are optimised to spend as little time in the interrupt context as possible. When CPU is executing a thread (i.e. it's in the process context) and interrupt will suspend thread operation to execute your ISR, before returning to the process. Interrupts are nested based on priority levels (this holds true for any Cortex-M core, not just Synergy) if they occur in the same time frame, so selecting the right priority level is crucial to the responsiveness of your solution.

    ThreadX uses following interrupts: SysTick, PendSV and SVCall with the last two being invoked exclusively from process context, to my understanding. The only one occurring asynchronously to the thread execution is periodic SysTick interrupt, which will fire every 10ms by default. This interrupt drives the timeouts, time-slicing and some pre-emption cases. Because a fair bit of RTOS housekeeping is handled inside its context, we recommend that any user-configured interrupts are set to the higher priority so that they're executed first (hence the lowest interrupt for CM4 and CM0+ is said to be "not valid if using ThreadX").

    Regards
  • In reply to Renesas Karol:

    Hello Karol,

    Accepting my lack of familiarity with the various ARM cores supported by the SSP, please confirm my conclusions from you reply.

    The CM4 core support 16 interrupt levels, 15 being the lowest.
    The CM0 core support 4 interrupt levels, 3 being the lowest.
    ThreadX uses the lowest interrupt level to operate the RTOS so is unavailable to the user application.
    All other interrupt levels will cause a switch from the user application which will include ThreadX code.
    Interrupt routines with a higher priority will interrupt lower priority interrupt routines.

    I also believe that the IR bit is not cleared by entering an ISR so must be cleared using R_BSP_IrqStatusClear().

    Regards
    David
  • In reply to dburch:

    Hello David,

    All of your statements are correct. The number of priorities in Cortex-M cores is vendor-configurable ( https://community.arm.com/iot/embedded/b/embedded-blog/posts/cutting-through-the-confusion-with-arm-cortex-m-interrupt-priorities ) but on Synergy the relationship is as you described.

    The bear minimum for an ISR implementation is following:

    Although most peripherals will also require the interrupt flag to be cleared in their respective registers, before R_BSP_IrqStatusClear is invoked.

    Regards

  • In reply to Renesas Karol:

    Hello Karol,

    Now that we both are in general agreement, can I throw a few spanners in the works?

    Firstly, the SF_CONTEXT_SAVE and SF_CONTEXT_RESTORE macros only appear to provide some trace features for ThreadX, which in normal configuration are defined out to produce empty function calls.

    More to the point, ThreadX wraps interrupt protected code with TX_DISABLE and TX_RESTORE macros These expand out to assembly code which set the PRIMASK and CPSID registers. If I understand the discussion in the link above, this will indiscriminately disable all interrupts. The BASPRI register would require setting to allow interrupts to continue operating above a pre-set level.

    Further, the SSP code uses ThreadX queue calls both in application code and ISRs. This would only be safe if interrupts were disabled in application code and other ISRs that share the same queue.

    Regards
    David
  • In reply to dburch:

    Hello David,

    Your concerns are valid however by default we build ThreadX with TX_ENABLE_EXECUTION_CHANGE_NOTIFY undefined. According to the short description above the source, this is used purely for diagnostics so I wouldn't expect this to be enabled in a standard application. We always recommend keeping the SF_CONTEXT_xxx macros as they're SSP-defined and in the future they may invoke other function calls also (not just ThreadX diagnostics).

    Configuring BASEPRI register would not be a good solution for protecting critical sections since it will cause a concurrency problem once low-priority interrupt is preempted by a high-priority interrupt that accesses the same resource in non-atomic fashion (and there's no way for ThreadX to know if that's the case). This also applies to queues and other RTOS objects where several operations are required to be performed in an uninterrupted state.

    I would agree that using BASEPRI instead of PRIMASK would enable you to use some critical interrupts (say, priority 0) while ThreadX is going through its "critical section" however there would need to be a guarantee that this interrupt does not access any of the shared resources. This also goes back to the RTOS system design principles where quite often disabling interrupts is done to provide deterministic execution in terms of processing time.

    You can modify the TX_DISABLE and TX_RESTORE macros to implement this however that's not the recommended approach. I highly suggest that you use ELC with transfer drivers to offload as much time-critical processing to hardware as possible.

    Regards
  • In reply to Renesas Karol:

    Hello Karol,

    Thank you for your suggestions.

    As I am attempting to transfer an application from an RX, which has several bits running using the processor hardware features, I was keen to ensure I understood the limitations of the SSP and RTOS.

    Earlier investigations of the GPT have confirmed the ELC has a shorter latency than ISRs.
    I will also be using the DTC to make a block of 1us ADC reading on an external bus which I assume will also not be delayed by other interrupts.

    Thanks again
    David