FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [March 2017 Threads] Mutual exclusion between task and interruptPosted by npkz on March 27, 2017 Hello people,
there is a thing (amongst many) I don't completely understand regarding mutual exclusion between tasks and interrupts. If we have something like this:
TaskA()
SemTake(Mtx)
... access to shared data...
SemGive(Mtx)
ISR()
... access to shared data...
Since interrupts have higher priorities than taks, would that mean in this case that if interrupt happens while TaskA is inside of critical section, ISR will start executing and since inside of ISR we don't have a critical section, data race is possible to happen?
I assumed that this was going to happen, so I decided to put SemTakeFromISR() and SemGiveFromISR() around accessing shared data part in ISR. However, in ISR after some time SemTakeFromISR() doesn't return pdPASS, and I get deadlock, since it's waiting for semaphore to be released from the TaskA which has lower priority.
Do I understand this right or maybe the problem is more complicated? I suppose there is some general solution to these kind of problems.
Regards,
Nenad
Mutual exclusion between task and interruptPosted by aseris on March 27, 2017 The interrupts which can happened during critical section enabled can't use FREERTOS API. see configMAXSYSCALLINTERRUPT_PRIORITY config.
It is not good strategy to wait for sema/mutex inside ISR
I recommend to draw a flowchart of required logic and re do it in way without dead locks.
Mutual exclusion between task and interruptPosted by richard_damon on March 27, 2017 A semaphoretake inside an ISR does NOT block the ISR to wait for the semaphore to be raised, it just returns an error code that the take failed (note, the FromISR routines do NOT take a timeout parameter, but a pointer to a variable to indicate if they woke up a task),
If you need to protect a data structure from an ISR, then you need to use a critical secton. This is what FreeRTOS does internally. These critical sections should be kept very short to avoid excessive interfearance with interrupt activity. If the access needs to be more complicated, so you need to use a semaphore (or better a mutex) to protect the update, then you should rework the ISR to trigger a task or call back hook via the service task to perform the update for the ISR and the ISR do the minimal work to provide that task with the data it needs.
Mutual exclusion between task and interruptPosted by npkz on March 27, 2017 Thanks for answers guys. So, Damon, if I understood you well, all that needs to be done is the first thing I already described. Create critical section in TaskA, and do nothing considering mutual exclusion inside of ISR since FreeRTOS will internally take care of that?
Mutual exclusion between task and interruptPosted by rtel on March 27, 2017 When Richard Damon talks about a critical section, he is not talking
about protecting code with a semaphore as you did in your original post,
he is talking about using the taskENTERCRITICAL() and
taskEXITCRITICAL() function.
http://www.freertos.org/taskENTERCRITICALtaskEXIT_CRITICAL.html They
will disable interrupts, hence your problem goes away, because the
interrupt that attempts to access the shared resource won't even run.
If the code that needs to be protected is too long to keep interrupts
disabled while it is being accessed then just set a flag while the code
needs to be protected, and have the interrupt code check the flag is not
set before it accesses the shared resource.
Mutual exclusion between task and interruptPosted by npkz on March 27, 2017 Ok, I understand now. So, basically what I have described in original post, the thing with mutexes in TaskA means absolutely nothing in this context? I mean if I don't have any other Task that shares the same data...
Mutual exclusion between task and interruptPosted by richarddamon on March 27, 2017 Yes, Mutexes, and semaphores being used for exclusion, are basically a Task-to-Task entity, and don't affect interrupts, as the ISR cant 'wait' and let the task finish the operation. If you need to block out an interupt for a short period of time, This can be done with a critical section (which blocks all interrupts that are allowed in interract with the FreeRTOS API), or if it is just a single interrupt you need to worry about, on most machines you could turn off that one interrupt (FreeRTOS doesn't provide code for that, as it is very processor specific, and generally to write the ISR in the first place you needed to look up that code, which is normal provided by the chip manufacturer.
Sometimes, rather than having to actually block the ISR, you can split the ISR into two pieces, one that runs from the interrupt which does minimal work to service the interrupt and passes the information to the second half that runs as part of a task that the interrupt signals. If it is just this second part you need the sharing control with, now, since it is running as a task, you can use the mutex or semaphore.
Mutual exclusion between task and interruptPosted by npkz on March 28, 2017 Thanks most kind for your help, I've got it now.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|