IPC problem xQueueSend, xSemaphoreTake, ExitCriticalSection

Hello all I need your advices and opinion about IPC. The project run on STM32, in IAR with FreeRTOS. I have 2 tasks (there are a lot of tasks in the project but I speak about two) : ModbusMasterTask with priority 5 and IOTask with priority 7. When IO task want to get any information from modbus, it connect TransmitCallbackFunction to modbusMasterObject and wait for message on xQueueReceive method from modbusMasterTask. IOTask: ReadInputRegisters: SetTransmitCallbackFunction if xQueueReceive return true; return false; Delay(30) ModbusMasterTask a little more complicated : it checks TransmitCallbackFunction if it is NULL task does nothing. IF ( NULL != TransmitCallbackFunction ) { EnterCriticalSection; Send request Get answer from slave SetTransmitCallbackFunction to NULL xQueueSend transmitEndMessage to IOTask ExitCriticalSection } Delay(30) So, here is the FIRST question: It works good but I don’t understand how it works. The priority of the IOTask higher than ModbusMasterTask and I think that on xQueueSend OS immediately try to make run IOTask but it cann’t because the code in critical section. Probably after ExitCriticalSection OS make run IOTask ??? AM I RIGHT ? And now I need change existing code. Actually ModbusMasterTask always knows about start and end of transmission, so it doesn’t need to run always, but IOTask can trigger it and after ModbusMasterTask GetsAnswer from slave it can go to blocking state. I tryed to do this with Notify functions and BinarySemaphore, but it doesn’t work and I think that it is because of critical section. So, my pseudocode is IOTask: ReadInputRegisters: SetTransmitCallbackFunction xSemaphoreGive — new row PROBLEM !!! if xQueueReceive return true; return false; Delay(30) ModbusMasterTask: EnterCriticalSection; Send request Get answer from slave SetTransmitCallbackFunction to NULL xQueueSend transmitEndMessage to IOTask xSemaphoreTake with MAX DELAY — new row PROBLEM !!! ExitCriticalSection NO DELAY — PROBLEM !!! It is the SECOND question- problem Both of tasks enters there loops several times and stuck on ModbusMasterTask forever. Please help me to resolve this problem Thanks a lot for your time and consideration Valerie

IPC problem xQueueSend, xSemaphoreTake, ExitCriticalSection

IOTask: ReadInputRegisters: SetTransmitCallbackFunction if xQueueReceive return true; return false; Delay(30)
What does it do with the data obtained by the xQueueReceive() call? Can it block on the queue for 30 ticks, rather than calling delay for 30 ticks?
ModbusMasterTask a little more complicated : it checks TransmitCallbackFunction if it is NULL task does nothing. IF ( NULL != TransmitCallbackFunction ) { EnterCriticalSection; Send request Get answer from slave SetTransmitCallbackFunction to NULL xQueueSend transmitEndMessage to IOTask ExitCriticalSection } Delay(30)
I assume the critical section here is used to prevent a race condition on TransmitCallbackFunction, but FreeRTOS API functions (queue send and receive etc.) should not be performed in a critical section as to do so would generate logic errors if using the API unblocks a task but a switch to that task cannot be performed [some FreeRTOS ports can, and other can’t, the STM32 can’t]. Also, this critical section looks very long if it is sending something and then waiting for the answer. Where is the critical section actually required? By which I mean, other than when TransmitCallbackFunction is tested and reset, what else needs protecting? Try and come out of the critical section as soon as possible. I suspect a simpler (to structure, not to code) solution might be to make the Modbus comms interrupt driven.
So, here is the FIRST question: It works good but I don’t understand how it works. The priority of the IOTask higher than ModbusMasterTask and I think that on xQueueSend OS immediately try to make run IOTask but it cann’t because the code in critical section. Probably after ExitCriticalSection OS make run IOTask ??? AM I RIGHT ?
As per my comments above. It actually depends on the FreeRTOS port being used, and the STM32, being a Cortex-M, cannot context switch in a critical section. Try to restructure, then you can try the semaphore (or other signalling scheme) again.

IPC problem xQueueSend, xSemaphoreTake, ExitCriticalSection

Many many thanks to you !!!