Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Loading

IPC problem xQueueSend, xSemaphoreTake, ExitCriticalSection

Posted by valeriv on December 11, 2017

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

Posted by rtel on December 11, 2017

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

Posted by valeriv on December 13, 2017

Many many thanks to you !!!


[ Back to the top ]    [ About FreeRTOS ]    [ Privacy ]    [ Sitemap ]    [ ]


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Careers

FreeRTOS and other careers at AWS.


Latest News

FreeRTOS kernel V10.0.1 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner