I have two devices that communicate via serial port in a master/slave configuration. The master sends a status command to the slave every 100 milliseconds and the slave must process the command and respond within 1 millisecond. When all is working well, the slave responds in 0.04 milliseconds.
The serial receive interrupt gets characters from the UART and sends them to the processing task via a queue. The processing task has the highest priority in the system, priority 10.
The device contains other tasks that access hardware in the system so a number of mutex semaphores are used to ensure that only one task can use a particular piece hardware at a time.
Occasionally, the serial communications fail. Instead of responding immediately to the status command, the slave device waits for up to 1 millisecond to respond to the command. Debugging shows that the task receiving the serial characters is not entered immediately upon exit from the serial interrupt, but gets entered after the next time tick. Closer inspection shows that both the base priority and priority of the receiving task have been set to 0 (the same level as the Idle task) so FreeRTOS delays processing because all other tasks now have a higher priority. My code doesn’t have any calls to set the priority of any task.
I changed the mutex semaphores to binary and the problem appears to have gone away.
Has anyone else seen a problem like this? Am I using mutex semaphores wrong?
STR750 processor, IAR compiler. (This is the syringe pump you saw at Harvard Apparatus a couple of weeks ago.)
Sorry, I don’t have a small program that replicates the problem. Our project is around 256K and it would take a lot of time to figure out how to reduce it to just the part that doesn’t work.
It appears to happen during the time when a lot of information is being received by the pump and used to initialize the hardware (semaphores are being taken at the same time data is being received by the serial interrupt).
Just in case it might be helpful, here’s a copy of my FreeRTOSConfig.h file:
I just saw it happen with the binary semaphore, and I managed to catch it in the debugger. It turns out it’s a stack overflow where the last word of the saved task context overwrote the task priority. I missed the end of the stack by only 4 bytes. Sheesh!