Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

mutex never giving

Posted by thyanger on September 15, 2015

Hi,

I have a synchronization problem. There are two tasks, say A and B, which both use the same UART for receiving and transmitting to a bluetooth module. Particularly, task A only transmits information, task B receives and transmits. The bluetooth module is meant to connect to a remote device, i.e. a tablet. So task B receive some commands from the tablet, as an ack transmit their echo, then changes the state of task A by properly setting a variable, say taskSts, to a given value. Following, task A is supposed to send other information to the tablet as a consequence of the new value of taskSts. Task A collects these information from another task, say task C, via a queue. Since task A and task B access the same UART, in order to avoid collisions, I have protected each I/O operation related to task A and B with a mutex. That is, in task A there is

:::c
osMutexWait(uartMutexId, osWaitForever);
HAL_UART_Transmit_IT(&UartHandle, (uint8_t *)&btTx, sizeof(btTx));
osMutexRelease(uartMutexId);

where

:::c
osWaitForever = 0xFFFFFFFF,

and in task B there is something like

:::c
HAL_UART_Receive_IT(&UartHandle, &btRx, 5);
/* some code... */
if(buffCmp("START", &btRxBuffer))
   {
      osMutexWait(uartMutexId, osWaitForever);
     HAL_UART_Transmit_IT(&UartHandle, (uint8_t *)"START\n", sizeof("START\n"));
      /* some other code... */
      osMutexRelease(uartMutexId);
      btTaskSts = RUNNING;
    }.

Notice that I am using the CMSIS-RTOS API

:::c
osMutexWait(mutex_id, ticks),

and

:::c
osMutexRelease(mutex_id),

provided by ST within STM32Cube. Such APIs wrap

:::c
xSemaphoreTake(mutex_id, ticks),

and

:::c
xSemaphoreGive(mutex_id),

respectively.

It happens that when I increase the speed which task C sends the information to task A to, task B never manages to take the mutex, waiting for it to be released by task A.

The first solution which comes in my mind is not to "wait forever". But I am not aware of all the things that such choice would imply. Since both task A and B have, at this stage, the same priority, another solutions would be making task B priority higher than that of task A. However I am not an expert so I am wondering what is the best choice.

Thank you and regards, vm


mutex never giving

Posted by rtel on September 15, 2015

It is not always easy to provide support when the native API is not being used, especially as there are a few different versions of the CMSIS wrapper floating around, none of which were created by us. In this case, are you use the CMSIS versions are doing nothing but calling the FreeRTOS equivalent?

Are your tasks running at the same priority? If so, then you might simply be locking out one of the tasks. For example, consider the following scenario, where Task A and Task B have the same priority:

1) Task A takes a mutex. 2) Task B attempts to take the mutex, but can't so blocks. 3) Task A gives the mutex back, unblocking Task B. However Task B, being equal priority to Task A, will not pre-empt Task A, and instead will not run until the next time slice. 4) Task A continues running, and takes the mutex again. 5) A new time slice starts to Task B starts running. Task B tries to take the mutex, but can't because it is held by Task A, and so re-enteres the Blocked state (that happens within the FreeRTOS API function). 6) Task B is in the Blocked state, so Task A re-enters the Running state.

In this scenario it appears as if Task A is the only task that runs, and that will be the case until a new time slice (tick interrupt) co-incides with the very short time that Task A is not holding the mutex.

If this is what is occurring, then an easy way around it is to call taskYIELD() after giving the mutex back - volunteering a context switch while the mutex is not being held. A more sophisticated and more efficient way (to stop fast thrashing between tasks) is to call taskYIELD() if the tick count changed while the mutex was being held.

Regards.


mutex never giving

Posted by thyanger on September 15, 2015

Thank you for the response.

It is not always easy to provide support when the native API is not being used, especially as there are a few different versions of the CMSIS wrapper floating around, none of which were created by us. In this case, are you use the CMSIS versions are doing nothing but calling the FreeRTOS equivalent?

Yes, I understand what you are saying. The CMSIS provided by ST basicly wraps FreeRTOS functions in the meaning that, osMutexWait(), which wraps xSemaphoreTake() does a tick conversion to milliseconds and few checks (to know whether it has been called from ISR or not), see the attachment if you want to give a look. osMutexRelease(), which wraps xSemaphoreGive(), does only the checks instead.

Are your tasks running at the same priority?

Yes they are. But this is not necessary. That is, I must confess that I still have not well in my mind how to properly arrange each task priorty to make them all working the best way. So, it is not necessary that task A and Task B run the same priority. Suggestions are welcomed.

1) Task A takes a mutex. 2) Task B attempts to take the mutex, but can't so blocks. 3) Task A gives the mutex back, unblocking Task B. However Task B, being equal priority to Task A, will not pre-empt Task A, and instead will not run until the next time slice. 4) Task A continues running, and takes the mutex again. 5) A new time slice starts to Task B starts running. Task B tries to take the mutex, but can't because it is held by Task A, and so re-enteres the Blocked state (that happens within the FreeRTOS API function). 6) Task B is in the Blocked state, so Task A re-enters the Running state.

Very clear, thank you for this explanation. I feel very confident that this is what is really going on.

If this is what is occurring, then an easy way around it is to call taskYIELD() after giving the mutex back - volunteering a context switch while the mutex is not being held. A more sophisticated and more efficient way (to stop fast thrashing between tasks) is to call taskYIELD() if the tick count changed while the mutex was being held.

I will give a try with this solution and make you aware of the result.

Thank you for the support.

Regards, vm

Attachments

cmsisAPI.c (1741 bytes)

mutex never giving

Posted by thyanger on September 16, 2015

Hi,

after some trials I can confirm that the problem was that you showed.

Regards, vm


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




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

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

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

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

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists