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

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) 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