Function didn’t get past xSemaphoreTake … sometimes

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, "r1rn");

(void)xSemaphoreTake(ReadSyncObj, portMAX_DELAY);

//fprintf(stdout, "r2rn");
~~~~~~ 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

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

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

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

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

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

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

Function didn’t get past xSemaphoreTake … sometimes

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

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

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

Sorry, I have forgotten to mention my current interrupt priority ~~~~~~ :::c

define INTPRIORITYLVL_1 0x20

~~~~~~ on Cortex M4. Any ideas are welcome.