call portEND_SWITCHING_ISR when previous portEND_SWITCHING_ISR is still running

Hello, I’ve been stuck on a problem and I am a little bit clueless. I’m using a PIC32MX, FREERTOS version 9.0, MPlabX IDE v 5.00 and the XC32 compiler version 1.44. I’ve got a system with two interrupts, all implemented the RTOS style. RTOS wrapper, and very short. At the end of each interrupt, I preform the function portENDSWITCHINGISR( xHigherPriorityTaskWoken ); The two interrupt sources are one UART serial input and a pulse detect (I’m using a CCP input for that). Both interrupts gives a semaphore (of course with the FromISR after the function names). Two separate tasks takes the semaphore, read the byte from the UART or the pulse will be counted. The UART is continuously communicating with a speed of 9600bps and the pulses have a frequency of 4000 Hz. The Tickrate of the system is 1000 Hz. The UART interrupt has priority 3, the Pulse interrupt has priority 2. The configMAXSYSCALLINTERRUPT_PRIORITY is set to 7. But after a while something annoying happens. The DelayedTaskList becomes empty, resulting in one active running task: the Idle task. Every other task comes in the ready state but the tasks won’t become active. The PIC32 is still running because interrupts keep firing. But the application itself runs only on FREERTOS so the application itself isn’t running. When not applying the pulses OR the UART bytes, this problem won’t occur. To see something more, I’m using Percepio to view what’s happening. This problem only occurs when both interrupts fired at nearly the same time. The UART is first, giving a semaphore. But before the semaphore could be taken by the corresponding task, the pulse interrupt fires, also giving a semaphore. Both interrupt functions are very short, emptying a buffer, giving a semaphore (FromISR) and both end with the function portENDSWITCHINGISR( xHigherPriorityTaskWoken );. If I not end the interrupt function with the portENDSWITCHINGISR( xHigherPriorityTaskWoken ), everything goes well and the system keeps running without problems. Long story so far, but here is the real question: What happens if the portENDSWITCHINGISR( xHigherPriorityTaskWoken ) function is running, preforming a taskYield and at that moment, an another Interrupt fires and also performs a taskYield. I think this is the reason my FREERTOS stops running active tasks, resulting in an empty DelayedTaskList. But I’m not the FREERTOS designer, so I could be wrong. But if I’m right, what can I do about it. Just never let the scheduled Yield after a interrupt and let the Idle task preform the yield (configIDLESHOULDYIELD = 1)? Thanks in advance, Kees

call portEND_SWITCHING_ISR when previous portEND_SWITCHING_ISR is still running

I’ve been stuck on a problem and I am a little bit clueless.
I wouldn’t say that – sounds like you have done some excellent debugging here.
is 1000 Hz. The UART interrupt has priority 3, the Pulse interrupt has priority 2. The configMAXSYSCALLINTERRUPT_PRIORITY is set to 7.
Not really relevant to your question, but I’m curious, why have the UART interrupt priority above the pulse interrupt priority as the pulse is much faster than the UART. Now to the question: The portENDSWITCHINGISR() macro pends a software interrupt that will execute when all higher priority interrupts have completed. It does that by performing a read-modify-write on the CAUSE register – so the question in my mind (without the datasheet in front of me) is….could anything else have got set in the CAUSE register between the read and write portions of that operation. Also, can the bit in the CAUSE register get set with a simple bit set operation (don’t think so, as it is not a general purpose register). I will have to look up the answers to these and report back.

call portEND_SWITCHING_ISR when previous portEND_SWITCHING_ISR is still running

Having looked at the cauase register I think the portYIELD() code is ok as most fields in the CAUSE register are read only, and the bits that start/stop the clock or change whether interrupts go through the vectoring thing, etc. are not going to change at run time.

call portEND_SWITCHING_ISR when previous portEND_SWITCHING_ISR is still running

Hello, Thanks for your reaction, Richard. It took me a while, but I finally solved the problem :-). The problem was resetting the interrupt flags. I did it like this: ~~~ IFS0bits.IC2IF = 0; ~~~ but it should be like this: ~~~ IFS0CLR = IFS0IC2IF_MASK; ~~~ With the first method, when a new interrupt comes in, and the hardware doesn’t realy reset this interrupt flag yet, the FreeRTOS hangs when applying a context swith. With the second (correct) method, the interrupt is really resetted when applying a context switch. So there is no problem at all. btw, the pulse interrupt has a lower priority because in the real world, the pulserate is much lower, but the problem occured once in a day. To have this problem every 1-3 minutes, I increased the pulserate.