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

Function didn't get past xSemaphoreTake ... sometimes

Posted by jon20015 on January 22, 2015

Hi,

I just started my first freeRTOS project, but I have some behavior I can't solve. In my task I alternately call a read and a write function. Both should wait/block until an special interrupt occurs. On first call I create a binary semaphore (one per function, read as an example):

~~~~~~ :::c if (NULL == ReadSyncObj) { if (NULL == (ReadSyncObj = xSemaphoreCreateBinary())) { return (RES_NOTRDY); } xSemaphoreTake(ReadSyncObj, 10 ); } ~~~~~~

The interrupt handler is shared for both:

~~~~~~ :::c static void _ISRHandler() { status = GetIntStatus();

xHigherPTaskWokenRead  = pdFALSE;
xHigherPTaskWokenWrite = pdFALSE;

if (status & READ_READY) {
    ClearInterrupt(READ_READY);
    (void)xSemaphoreGiveFromISR(ReadSyncObj, &xHigherPTaskWokenRead);
    portYIELD_FROM_ISR(xHigherPTaskWokenRead);
    return;
}

if (status & WRITE_READY) {
    ClearInterrupt(WRITE_READY);
    (void)xSemaphoreGiveFromISR(WriteSyncObj, &xHigherPTaskWokenWrite);
    portYIELD_FROM_ISR(xHigherPTaskWokenWrite);
    return;
}

} ~~~~~~

In the read and write functions I have the transfer started and the I take the semaphore:

~~~~~~ :::c startReadOperation();

//fprintf(stdout, "r1\r\n");

(void)xSemaphoreTake(ReadSyncObj, portMAX_DELAY);

//fprintf(stdout, "r2\r\n");

~~~~~~

My problem is, that I can't get past the xSemaphoreTake very often and never leave the idle task again. This behavior never occurrs if the fprintf functions are used, everything is working fine then.

My task has a priority of one and should meet the

~~~~~~ :::c

define configMAXSYSCALLINTERRUPT_PRIORITY ( 1 << 5 )

~~~~~~

requirement.

I am grateful for any suggestion Jon


Function didn't get past xSemaphoreTake ... sometimes

Posted by davedoors on January 22, 2015

Nothing obviously wrong. Do you have configASSERT() defined?

Is it possible both READREADY and WRITEREADY get set at the same time in your interrupt handler? If so it would be better to remove the return calls. You can then use the same HigherPriorityTaskWoken variable in both xSemaphoreGiveFromISR() calls and only call portYIELDFROMISR() once at the end of the function.

If you are stuck on xSemaphoreTake() I guess the interrupt just has not executed. Is that the case? It is best not to use portMAX_DELAY in this case because your program will hang if the interrupt does not execute. Better to use a finite delay then clean up if xSemaphoreTake() times out without taking the semaphore.

In the latest FreeRTOS you can use a task notification instead of a semaphore http://www.freertos.org/RTOSTaskNotificationAsBinary_Semaphore.html


Function didn't get past xSemaphoreTake ... sometimes

Posted by jon20015 on January 23, 2015

Hi Dave,

thanks for your response!

Nothing obviously wrong. Do you have configASSERT() defined?

No, it is not defined.

Is it possible both READREADY and WRITEREADY get set at the same time in your interrupt handler? If so it would be better to remove the return calls. You can then use the same HigherPriorityTaskWoken variable in both xSemaphoreGiveFromISR() calls and only call portYIELDFROMISR() once at the end of the function.

They should never appear at the same time. But who knows? ;-)

If you are stuck on xSemaphoreTake() I guess the interrupt just has not executed. Is that the case? It is best not to use portMAX_DELAY in this case because your program will hang if the interrupt does not execute. Better to use a finite delay then clean up if xSemaphoreTake() times out without taking the semaphore.

I believe, that's not the case. If I delay the execution with "fprintf" everything is fine. It feels like some kind of timing problem, the interrupt might happen while xSemaphoreTake is in progress. Could that be a problem?

In the latest FreeRTOS you can use a task notification instead of a semaphore http://www.freertos.org/RTOSTaskNotificationAsBinary_Semaphore.html

Unfortunately I can't update my freeRTOS (8.0.1) at the moment.

Thanks again Jon


Function didn't get past xSemaphoreTake ... sometimes

Posted by rtel on January 23, 2015

Semaphores are designed to be accessible from interrupts and tasks simultaneously - but that will only work if you interrupt priorities are set correctly, so that is the first thing to double check.

Please defined configASSERT() (http://www.freertos.org/a00110.html#configASSERT) as a first step. In V8.0.1 that should trap and incorrect priority - let us know if that is hit or not.

Regards.


Function didn't get past xSemaphoreTake ... sometimes

Posted by jon20015 on January 23, 2015

Had to find a solution working with ccs, but it's up now. Unfortunately I have no clue about the assembler part and what's going on. I get an assertion at "configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );" with ucCurrentPriority = 0x00 and ucMaxSysCallPriority = 32.

freeRTOSConfig.h:

~~~~~~ :::c

ifdef ccs

void vAssertCalled(const char *pcFile, unsigned long ulLine ); #define configASSERT(expr) if ( (expr) == 0) { vAssertCalled( FILE , LINE ); }

endif

~~~~~~

port.c:

~~~~~~ :::c

if( configASSERT_DEFINED == 1 )

extern unsigned long ipsrFunc(void); __asm(" .sect ".text:ipsrFunc"n" " .clinkn" " .thumbfunc ipsrFuncn" " .thumbn" " .global ipsrFuncn" "ipsrFunc:n" " mrs r0, ipsrn" " bx lrn");

void vPortValidateInterruptPriority( void )
{
uint32_t ulCurrentInterrupt;
uint8_t ucCurrentPriority;

	/* Obtain the number of the currently executing interrupt. */
    #if defined(ccs)
        ulCurrentInterrupt = ipsrFunc();
    #else
        /* Obtain the number of the currently executing interrupt. */
            __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );
    #endif

	/* Is the interrupt number a user defined interrupt? */
	if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
	{

~~~~~~


Function didn't get past xSemaphoreTake ... sometimes

Posted by rtel on January 23, 2015

There isn't an official CCS port so I can tell you if your use of ipsrFunc() is correct or not, but if it is then it looks as if interrupt priorities are indeed your problem.

As different Cortex-M devices have a different number of priority bits the first thing to do is ensure the hardware is described correctly in the FreeRTOSConfig.h file. You can see an example between the lines 53 and 176 in this file:

http://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Demo/CORTEXM4FATSAM4EAtmelStudio/src/config/FreeRTOSConfig.h

Next ensure you have read http://www.freertos.org/RTOS-Cortex-M3-M4.html - especially the bits about ensuring you don't leave an interrupt priority at its default value.

Regards.


Function didn't get past xSemaphoreTake ... sometimes

Posted by jon20015 on January 23, 2015

Sorry for the following noob question, but how do I actually set the interrupt priority?


Function didn't get past xSemaphoreTake ... sometimes

Posted by rtel on January 23, 2015

If you system is using CMSIS compatible libraries then there is a function NVIC_SetPriority(). If you are using propriatory libraries supplied by your chip or compiler vendor then check whatever documentation they supplied. You can of course reference the Cortex-M hardware manual, then peek and poke the priority registers yourself, but I would not recommend that.

All the demos supplied by FreeRTOS will set a priority somewhere, so that provides another reference.

Regards.


Function didn't get past xSemaphoreTake ... sometimes

Posted by jon20015 on January 23, 2015

Ok thanks. I thought there has to be some kind of vPortSetInterruptPriority I have to modify/find/use.


Function didn't get past xSemaphoreTake ... sometimes

Posted by jon20015 on January 23, 2015

I've managed to set the priority level of my interrupt handler and the assert is gone. Unfortunately the original problem still exists.


Function didn't get past xSemaphoreTake ... sometimes

Posted by jon20015 on January 27, 2015

Sorry, I have forgotten to mention my current interrupt priority

~~~~~~ :::c

define INTPRIORITYLVL_1 0x20

~~~~~~

on Cortex M4. Any ideas are welcome.


[ 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