Interrupt priority level and software interrupt

alexyann wrote on Wednesday, February 01, 2017:

Hello,

We’re using an interrupt with no kernel call with a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
This interrupt need a high priority.
My problem is that at the end of this interrupt we call a software interrupt with priority below configMAX_SYSCALL_INTERRUPT_PRIORITY and with kernel call API (From_ISR).
It seems that the software run better if we decrease the first interrupt priority.
I’m not sure to understand what is wrong

rtel wrote on Wednesday, February 01, 2017:

I’m not sure to understand what is wrong

Nor am I as you didn’t mention in your post what the problem you were
having was.

If you want to ‘call’ another lower priority interrupt then don’t call
the function, but just pend the interrupt (M3 interrupts can be pended
in software). Then when the high priority interrupt completes the lower
priority interrupt will execute automatically.

alexyann wrote on Thursday, February 02, 2017:

The problem is that we have some freeze for instance inside vListInsert or in other cases bad behaviour with other drivers just after several hours in load.
The configMAX_SYSCALL_INTERRUPT_PRIORITY is defined at 6, other driver have interrupt priorities between 1 and 4.
The problem is with our ARINC driver timer TPU which has interrupt priority of 10 but call a software interrupt of priority 4.
We use RX631 with FreeRTOS, the software interrupt is called with
__intrinsic void __software_interrupt(unsigned char);
which is in IAR/include/intrinsics.h in our project
The IPL is forced at 4 inside software interrupt with
__set_interrupt_level(4);

Without the “call” of software interrupt there is no more problem.
We don’t understand why the software interrupt is not pending until the CPU IPL allow execution. Maybe it is something with freertos, like bad use.
What do you mean with M3 interrupts?

rtel wrote on Thursday, February 02, 2017:

We use RX631 with FreeRTOS

What do you mean with M3 interrupts?

So you are not using a Cortex-M, which means you can discount my
previous reply. I was guessing what your platform was and guessing what
your problem was.

The problem is that we have some freeze for instance inside vListInsert
or in other cases bad behaviour with other drivers just after several
hours in load.

So that is normally a symptom of an incorrect priority assignment, as
you mention, but can also be caused by just a simple RAM corruption.

The configMAX_SYSCALL_INTERRUPT_PRIORITY is defined at 6, other driver
have interrupt priorities between 1 and 4.
The problem is with our ARINC driver timer TPU which has interrupt
priority of 10 but call a software interrupt of priority 4.

How are you ‘calling’ this interrupt?

alexyann wrote on Friday, February 03, 2017:

The code for the high priority interrupt was

//------------------------------------------------------------------------------
// Interrupt routine for detecting idle in reception
static void ArItIdleRxiHandler(UINT8 nSci) {

    if ( nSci < K_NbArincChannels ) {
        //Stop timer
        ArStopIdleDetection(nSci);
        //check interrupt request flag of reception
        if ( M_ArReadRxItFlag(nSci) ){
        }
        else {
            switch ( nSci) {
                #if ( K_NbArincChannels >= 1)
                    case 0:
                        __software_interrupt(K_ArSoftItVectNbr0);
                        break;
                        ...

It’s a TPU interrupt with only HW macros and the call of SW interrupt

The Software interrupt code was

//------------------------------------------------------------------------------
// Interrupt routine for loading received message after detecting idle
static void ArItLoadRxiMessageHandler(UINT8 nSci) {

    portBASE_TYPE xTaskWoken = pdFALSE;

    //Complete ARINC message reception
    if ( nSci < K_NbArincChannels ) {
        // Software interrupt used so set the IPL to under OS IPL
        __set_interrupt_level(K_ArRxiLoadMessageItPriority);
        // Reactivate interruption
        __enable_interrupt();

        if ( (t_ReceptionState[nSci] == K_ArFrameReception_OK )) {
            // Write reception time
            g_ArRxBuffer.recTime = xTaskGetTickCountFromISR();
            //Allow ARINC Transmission
            xSemaphoreGiveFromISR(g_ArTxSemaphore, &xTaskWoken);
            // Context Switch
            portYIELD_FROM_ISR(xTaskWoken);

...

The call of __set_interrupt_level(K_ArRxiLoadMessageItPriority); was maybe a bad idea since it only set the CPU IPL
But it was working if we only change the ArItIdleRxiHandler priority below configMAX_SYSCALL_INTERRUPT_PRIORITY so it seems to be a freeRTOS bad use.

As the ARINC idle detection is important. It is important for us to set a high priority. But it seems to work without SW interrupt mechanism. We have changed this way.