Quality RTOS & Embedded Software

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




Loading

Proper use of a semaphore

Posted by Scott Nortman on January 8, 2007
Is this the correct use of a semaphore to sync with an ISR:

void aTask( void *pv ){

____for(;;){
________xSemaphoreTake( aSemaphore, 10 );
________<cause ISR in a few ms >
________xSemaphoreTake( aSemaphore, 10 );
________<rest of code>
____}
}

ISR( INT0_vect )
{
____xSemaphoreGiveFromISR( aSemaphore );
}

Comments?

Thanks,
Scott

RE: Proper use of a semaphore

Posted by Nobody/Anonymous on January 8, 2007
This is the way it is done in some applications included in the download, and the way I do it.

The semaphore can be used to wake a high priority task to process the data obtained by the interrupt removing the need for the data to be processed in the interrupt itself.

In your example I presume the interrupt is guaranteed to occur within 10 ticks, or that you handle the case when this does not happen?

RE: Proper use of a semaphore

Posted by Scott Nortman on January 8, 2007
How can a task be suspended indefinitly until a semaphore is given?

RE: Proper use of a semaphore

Posted by Richard on January 8, 2007
When calling xSemaphoreTake() a block time is specified. The maximum block time that can be specified depends on the data type used for portTickType. If portTickType is 32 bits, and the tick is set to 1KHz (too fast for most applications) then the maximum block period is 0xffffffff or equivalent to approximately 40 days.

In FreeRTOS.org versions prior to V4.1.3 blocking for longer periods than this required the return value to be checked in a loop. For example:

while( xSemaphoreTake( aSemaphore, portMAX_DELAY ) != pdPASS );

would block the task indefinitely (pseudo indefinitely).



From V4.1.3 the behaviour can be changed depending on the value of configINCLUDE_vTaskSuspend. If configINCLUDE_vTaskSuspend is 0 then the behaviour is as per described above. If configINCLUDE_vTaskSuspend is 1 then a delay period of portMAX_DEALY is taken to mean that the task should block indefinitely and the while loop is not necessary.

This has not made it into the docs yet, other than the change history - sorry :-(

Regards.

RE: Proper use of a semaphore

Posted by Scott Nortman on January 19, 2007
Thanks for the suggestions. So, just to confirm, assuming that I am using v4.1.3, I expect the following code to perform the following:

1. Take the semaphore
2. Cause an ISR to occur later in time
3. Start waiting for the semaphore
4. ISR gives the semaphore after a period of time
5. Calling task processes the data
6. Give the semaphore
7. Go to 1

/* Start of file */

static xSemaphoreHandle aTaskSemaphore;

void aTask( void * pv )
{

____vSemaphoreCreateBinary( aTaskSemaphore );

____for(;;){

________if( xSemaphoreTake( aTaskSemaphore, portMAX_DELAY ) == pdTRUE ){

____________Trigger_ISR_Soon();

____________if( xSemaphoreTake( aTaskSemaphore, portMAX_DELAY ) == pdTRUE ){

________________ProcessDataFromISR();

________________xSemaphoreGive( aTaskSemaphore );

____________}

________}

____}

} /* end aTask */


/* This is the ISR that will trigger and give the semaphore */
ISR( INT0_vect )
{
____portBASE_TYPE xTaskWoken = pdFALSE;

____if( xSemaphoreGiveFromISR( aTaskSemaphore, xTaskWoken ){

________taskYEILD();

____}

}

RE: Proper use of a semaphore

Posted by Richard on January 20, 2007
Which port are you using? Some ports do not permit taskYELD() to be called directly in an ISR, and a different macro is provided for this purpose. If this is how it is done in the demo serial port driver that came with the port then it will be ok.

I'm not sure of the structure of your task, because I'm not sure what it is you are trying to do exactly. I understand steps 2 to 5, but not the bit around it. You seem to be synchronising with the ISR in two places. Is this correct? I'm also not sure about the call to xSemaphoreGive() in the task.


In its simplest for, where a task wants to execute each time an ISR executes, the code would take the following structure:

void vTask( void *pvParameters )
{
____for( ;; )
____{
________if( xSemaphoreTake( aTaskSemaphore, portMAX_DELAY ) == pdTRUE )
________{
____________/* Got the semaphore, the ISR must have fired. Do the work
____________here. */
____________
____________/* We do not have to give the semaphore back. The semaphore
____________is 'empty' because of our call to xSemaphoreTake(). We go
____________back to block again waiting for it to be given again by the
____________ISR. The task takes it, the ISR gives it. */
________}
____}
}

void vISR( void )
{
portBASE_TYPE xYieldRequired = pdFALSE;

____/* ISR fired. Wake the task. */
____if( xSemaphoreGiveFromISR( aTaskSemaphore, FALSE ) )
____{
________xYieldRequired = true;
____}
____
____/* Clear the interrupt. */
____
____if( xYieldRequired )
____{
________/* Yield here using whatever macro is required by the port
________being used. */
____}
}

Regards.


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




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

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

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

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

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists