mutex never giving

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 *)"STARTn", sizeof("STARTn"));
      /* 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

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

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

mutex never giving

Hi, after some trials I can confirm that the problem was that you showed. Regards, vm