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 );
}
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.
Nothing obviously wrong. Do you have configASSERT() defined?
Is it possible both READ_READY and WRITE_READY 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 portYIELD_FROM_ISR() 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.
Nothing obviously wrong. Do you have configASSERT() defined?
No, it is not defined.
Is it possible both READ_READY and WRITE_READY 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 portYIELD_FROM_ISR() 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?
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.
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.
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:
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.