I have created a serial task for managing serial data of chipset. Once the task is created, in the task I create a mutex using “xSemaphoreCreateMutex” API.
Each time I get data on the serial line, the ISR gets fired and I try to put the data to a queue. The queue is protected by a mutex and since we are in the ISR context, I call the “xSemaphoreTakeFromISR” API to acquire the lock.
It always fails when I try to acquire the lock and the API returns with a failure case.
I was able to get it to work by adding the below code.
Requiring a locked mutex in an ISR fails because the ISR can”t block/wait for the mutex getting released (as documented).
But which bigger problem do you want to solve ?
Usually feeding a FreeRTOS queue from an ISR with e.g. serial data post-processed by a task doesn’t require a mutex.
I have an API called “EnqueueData” which puts data into a DS queue and then sends a task notify to the rxTask. Due to design choices, we are not using the FreeRtos Queue.
The “EnqueueData” function can be used by other tasks as well. Hence we are trying to use a lock in the form of a mutex.
Please refer the example below.
uint16_t enqueueComData(uint8_t *data, uint16_t len)
{
uint8_t ret = FAILURE;
if(xSemaphorTakeFromISR() == SUCCESS)
{
// copy data
// release the lock
xSemaphoreGiveFromISR();
}
return ret;
}
My query is that when no one else has acquired the mutex, why is it always failing at “xSemaphorTakeFromISR”
elaborating on what Hartmut wrote, mutual exclusion between and isrs (or multiple isrs) is inherently asymmetric. An ISR can never be preempted by a task, only by a higher priority isr, so once the isr executes, there is no need to protect any ressources it uses from concurrent access.
In the other direction - ie making sure that a task or lower priority isr is protected from concurrent access of a higher priority thread of execution - is accomplished by disabling the interrupts that compete with the lower priority. That sounds weird because that way, you prohibit all of the isr from executing even though only a portion of its code may access protected ressources, but normally that is not a problem because isrs are expected to run only as short as absolutely necessary.