How does a mutex work when an ISR using the protected variable triggers?

Hi,
I have been looking at mutex examples online including in the API page here: This page describes the xSemaphoreTake() FreeRTOS API function which is part of the RTOS semaphore API source code function set.

What is not clear to me is, how do you mutex a protect a specific variable especially during an ISR call?

Lets say the code is executing inside a mutex (i.e. the mutex has granted access) modifying a non-atomic variable and right in the middle of it an ISR which access the same variable is called…
My understanding is that the ISR is entered immediately and executed immediately regardless of the fact that the variable is half-way through being modified in the task. Is that correct?

Would the mutexTake from the ISR fail (return pdFALSE)? I assume not because it would make the ISR pointless and lose the event.

Thank you :slight_smile:

1 Like

Rik,

you should be able to answer this yourself!

An ISR CAN NOT block on a mutex, nor on anything else.

Mutual exclusion between ISRs and task/other ISRs is asymmetric. An ISR by definition runs uninterrupted, so the only way to prevent an ISR from interrupting a lower pri ISR or a task is to enter a critical section (= inhibit interrupts) if there is any code in the ISR that competes with the lower pri thread of execution.

An ISR may ATTEMPT to claim a synchronization object (ie call xxxTakeFromISR()), but only with an immediate return (0) timeout. If a task is inedeed half way through manipulating an object, the ISR must return and wait for a subsequent invocation to touch the data.

The normal flow of mutual exclusion between an ISR and a lower priority thread of execution is for the lower pri to inhibit interrupts and the higher pri ISR to run uniterrupted.

Edit: Also note that FreeRTOS muteces can NEVER be claimed by ISRs, not even through a …FromISR() call with 0 timeout because muteces track ownership, and the owners can only be tasks.

2 Likes

A bit fuller answer, if you need to protection from access to include ISRs, then you need to use a critical section, as ISRs can not ‘block’ to wait for the resource to be free. The one exception would be if the ISR has a way to handle not being able to get access and just skip the operation. There also must not be any ‘blocking’ code within that critical section.

Generally, this means that section of code needs to be kept as short as possible, to avoid affecting interrupt latency by too much. If there is only one (or maybe a small but known list of) interrupt that needs to be protected, you could use a semaphore/mutex combined with disabling that particular interrupt in that exclusive access area. I would probably define subroutines for the entry/exit of this sort of exclusion zone.

@Rik001 I think you should keep on this work. Thanks man for sharing this incredible work with us. :slightly_smiling_face:

1 Like

Thank you Greg.
Very much appreciated!! :slight_smile:

it is not good strategy to wait for sema/mutex inside ISR I recommend to so you need to use a semaphore to protect the update, then you should rework the ISR to trigger a task or call back hook via. for the ISR do the minimal work to provide that task with the data it needs.

Thank you Elaine but I don’t understand what you tried to explain. Also what has TalkToWendys got to do with anything?

It not only isn’t a good strategy, to wait for semaphore inside ISR, it can’t be done. The FromISR versions do have a ‘wait’ option, because waiting in the ISR often just won’t work. If you need to wait for some task to finish and give the semaphore, that won’t happen while an ISR is waiting (by looping) for it.

I think you meant do not here?

Yep. ISRs can not wait.

Thank you Richard and Gaurav :slight_smile: