Quality RTOS & Embedded Software

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


Loading

Using semaphore problem

Posted by Greg on May 13, 2009
I init semaphore before scheduler starts:

vSemaphoreCreateBinary( xSPI0Semaphore );

in running task I take semaphore:

xSemaphoreTake( xSPI0Semaphore, portMAX_DELAY );

WHAT IS WRONG:
Semaphore is taken in first call, without giving anywhere before. So first taking procedure is not blocking.

TRY:
I check semaphore before taking:

q = uxQueueMessagesWaiting( xSPI0Semaphore );

and q value is "1", but should be "0".

Please help

RE: Using semaphore problem

Posted by Samuel Tardieu on May 13, 2009
This is the documented behaviour: binary semaphores are initially released. You might want to do a xSemaphoreTake(xSPIOSemaphore, 0) just after creating the semaphore if you want it to be taken before the scheduler starts (the 0 doesn't matter here, since you *will* get the semaphore immediately).

RE: Using semaphore problem

Posted by Greg on May 14, 2009
Thank you for your help. I have still a problem with using semaphore.

I wrote a task:

void vSPI0Task( void *pvParameters )
{
struct tspiIO spiIO;
portBASE_TYPE q;

xSemaphoreTake( xSPI0Semaphore, 0 );

for( ;; )
{
xQueueReceive( xSPIInputQueue, &spiIO, portMAX_DELAY );

SPI_AsyncWriteFirst( AT91C_BASE_SPI0, spiIO.DataToSend , spiIO.DataToSendLen, spiIO.WriteDummy );
SPI_AsyncReadNext( AT91C_BASE_SPI0, spiIO.ReceivedData, spiIO.ReceivedDataLen, spiIO.ReadDummy );

AT91C_BASE_SPI0->SPI_IER = AT91C_SPI_RXBUFF;
PDC_EnableWriteAndRead((AT91S_PDC*)((__u32)(AT91C_BASE_SPI0) + 0x100));

xSemaphoreTake( xSPI0Semaphore, portMAX_DELAY );
xQueueSendToBack( xSPIOutputQueue, &spiIO, portMAX_DELAY );
}
}

And a interrupt subroutine (I am using YAGARTO; interrupts without nesting):

void __attribute__ ((interrupt ("IRQ")))SPI0_irq_handler( void )
{
volatile __u32 spiSr;
portBASE_TYPE xHigherPriorityTaskWoken;

spiSr = AT91C_BASE_SPI0->SPI_SR;
xHigherPriorityTaskWoken = pdFALSE;
if ( spiSr & AT91C_SPI_RXBUFF )
{
AT91C_BASE_SPI0->SPI_IDR = AT91C_SPI_RXBUFF;

xSemaphoreGiveFromISR( xSPI0Semaphore, &xHigherPriorityTaskWoken );
}

AT91C_BASE_AIC->AIC_ISR;
AT91C_BASE_AIC->AIC_EOICR = 0;

if( xHigherPriorityTaskWoken == pdTRUE )
{
portYIELD_FROM_ISR();
}
}

The problem lies in the fact that when the task is blocked in "taking semaphore state", interrupt can't give it and the task is "blocked permanently". In debug mode (step run), when the interrupt comes before "taking semaphore state" and the semaphore is given, program works.

RE: Using semaphore problem

Posted by Greg on May 14, 2009
I found a solution:

void vSPI0_Wrapper() __attribute__((naked));
void vSPI0_Handler();

void vSPI0_Wrapper( void )
{
portSAVE_CONTEXT();
vSPI0_Handler();
portRESTORE_CONTEXT();

}

void vSPI0_Handler( void )
{
volatile __u32 spiSr;
portBASE_TYPE xHigherPriorityTaskWoken;

spiSr = AT91C_BASE_SPI0->SPI_SR;
xHigherPriorityTaskWoken = pdFALSE;
if ( spiSr & AT91C_SPI_RXBUFF )
{
AT91C_BASE_SPI0->SPI_IDR = AT91C_SPI_RXBUFF;
xSemaphoreGiveFromISR( xSPI0Semaphore, &xHigherPriorityTaskWoken );
}

AT91C_BASE_AIC->AIC_ISR;
AT91C_BASE_AIC->AIC_EOICR = 0;

if( xHigherPriorityTaskWoken == pdTRUE )
{
portYIELD_FROM_ISR();
}
}

RE: Using semaphore problem

Posted by Dave on May 14, 2009
You need to write your interrupt service routine as detailed on the documentation page and as detailed by the provided examples. See the "interrupt service routines" section of http://www.freertos.org/portlpc2106.html for a start.


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




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

Latest News

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

Video: Watch James Gosling & Richard Barry at re:Invent, Las Vegas 2017.

New FAQ page about the FreeRTOS kernel and Amazon FreeRTOS.


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

Xilinx Microblaze and Zynq partner