Quality RTOS & Embedded Software

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




Loading

xSemaphoreTake/Give from ISR

Posted by alsaleem on July 30, 2017

I have a resource to be synchronized on task accesses. I made a code (in the resource driver) to use xSemaphoreTake/Give for this synchronization. I now have a case that this resource needs to be accessed from ISR. This requires that the lock process take/give be done in the calling function (instead of the driver) since it might be the task or isr. This adds a little complexity.

My question: Is there away in FreeRTOS to know if the code being executed is from a task or isr? If yes, is it going to take too much cpu time?

Thanks.


xSemaphoreTake/Give from ISR

Posted by richard_damon on July 30, 2017

FreeRTOS exposes no portable way to detect if yoou are in an ISR or not (and it may not be an easy thing to determine on all platforms it has been ported to). If you look in port.c, inside vPortEnterCritical there may be code to test this as part of a configASSERT statement, that code being very port specific.

Sometimes I do wonder if it would make sense for poort.c/portmacro.h to export this code as a callable function for those ports where it is something reasonable to test. I do find that there are a few cases where it could be useful.

One thing you are going need to watch out the way you are describing things, if a task has locked the resource, and an ISR that needs it gets invoked, there is no way for the ISR to do the equivalent of a block till available, so you may need to rethink your program structure. I rarely find that this sort of access can be made to look mostly the same between the ISR context and the Task Context, so the resource driver needs different code for the two cases, so the ISR can just call the FromISR version of the driver.

The point where having the test could be helpful is if the ISR needs to use a middle layer of code that then access the driver, and duplicating the middle layer may be a bit awkward. (But if the middle layer has much code, it probably shouldn't be called in the ISR anyway).


xSemaphoreTake/Give from ISR

Posted by alsaleem on July 30, 2017

if a task has locked the resource, and an ISR that needs it gets invoked, there is no way for the ISR to do the equivalent of a block till available,

yes. good point. However, if the isr is of a lower priority than systick, then it should be able to wait.

I will look into the code you mentioned and also see if i could do a work-around.

Thanks.


xSemaphoreTake/Give from ISR

Posted by richard_damon on July 30, 2017

First, I beleive SysTick needs to be the lowest priority of interrupt. (That is an assumption in most ports)

Second, if the ISR does try to wait, all it can do is spin its wheels, which means the task that has the lock will NEVER run, and never finish its operation and your program dies in a deadlock.

If your ISR tried to wait by going back to the task, nothing will ever resume the ISR, so it will never do its action.

Like I said, ISR access to shared resources is different than task level access.

One option is you could put the code that needs to accerss the resource into a Pended function, which will then mean it will run at 'Task Level' and is written very much like task code (uses non-FromISR routines).

Remember, xSemaphoreTakeFromISR does NOT block, and thus doesn't provide the same sort of exclusion that xSemaphoreTake does.


xSemaphoreTake/Give from ISR

Posted by alsaleem on July 30, 2017

I was confusing ~~~

define configLIBRARYLOWESTINTERRUPT_PRIORITY 0xf

~~~ and ~~~

define configLIBRARYMAXSYSCALLINTERRUPTPRIORITY 5

~~~ yes, systick has the lowest.

If your ISR tried to wait by going back to the task, nothing will ever resume the ISR, so it will never do its action.

Thanks for the explanation as it contains facts. What if the sysytick has mid-priority (e.g. 8 in 16-level)? Is there away to push isr's PC/SP into top of FreeRTOS's TCB list?

I managed to do work around, in my current case. I created a high priority task and used (xTaskNotifyFromISR/portYIELDFROMISR --> xTaskNotifyWait) to continue the work.

Thanks.


xSemaphoreTake/Give from ISR

Posted by richard_damon on July 30, 2017

The Tick Processing code assumes it is on the lowest priority interrupt, so moving it up is likely to cause problems.

Trying to add the ISR to the TCB list is basically trying to make it a task, actually making a task avoids a lot of problems, which is a good solution. I was suggesting using xTimerPendFunctionFromISR() which is a slightly lighter weight option (but might add some undesired interactions depending on who long some other task might be holding the resource).


xSemaphoreTake/Give from ISR

Posted by hs2sf on July 31, 2017

I'd propose to rethink your design. It's not the best idea trying to block in an ISR and also this is not supported by any other OS I'm aware of for a reason.


xSemaphoreTake/Give from ISR

Posted by alsaleem on August 1, 2017

Thanks. I already made a separate high priority task to continue the work. Maybe FreeRTOS team may think of this scenario. There might be a case to do that.


xSemaphoreTake/Give from ISR

Posted by rtel on August 1, 2017

Thanks. I already made a sepeare high priority task to continue the work. Maybe FreeRTOS team may think of this scenario. There might be a case to do that.

That is what xTimerPendFunctionFromISR() does, it takes the function you pass it as a parameter and runs it in the RTOS daemon task (also known as the timer service task) - the priority of which is set by the application writer.

Going back to answer the question at the top of the thread, if you are using a Cortex-M then there is a function xPortIsInsideInterrupt() that tells you if you are in an interrupt or not - but that would not help you in any case.


xSemaphoreTake/Give from ISR

Posted by alsaleem on August 1, 2017

Yes, indeed xTimerPendFunctionCallFromISR does exactly the work I wanted, although it adds a separate task (xTimer task) same as i did. Unfortunately, i am running V8.2.1, and could not find xPortIsInsideInterrupt in this version's code.

Is upgrade a seamless process? I mean, do I need to re-write some code to upgrade?

Thanks.


xSemaphoreTake/Give from ISR

Posted by rtel on August 1, 2017

The upgrade should be a drop in replacement.


xSemaphoreTake/Give from ISR

Posted by richard_damon on August 1, 2017

xTimerPendFunctinCallFromISR adds a single task, that allows you to create a number of ISR callbacks and/or Timer Call back routines. If you have no other use for the TImer/Service task, then it is extra overhead. Knowing it is there, can often simplify code and save tasks.

RTE can make a more diffinative comment, but I don't remember any incompatibility issues between v8 and v9 of FreeRTOS (lots of new features, but I don't remember anything breaking.


xSemaphoreTake/Give from ISR

Posted by alsaleem on August 2, 2017

Thanks. I assume it is 100% drop-in.


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




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

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

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

OpenRTOS and SafeRTOS