I am trying to use FreeRTOS on Cortex M0 controer from ST. I am facing the issue with binarty semaphore used in timer ISR.
I have intitialised the timer overflow interruot with priority 3 (Lowest). two tasks with priority: osPriorityNormal, and created one binary semphore all are created using CMSIS OS API with FreeRTOS version V8.2.1.
when i am using the osSemaphoreRelease(myBinarySem01Handle); from one task and waiting for getting semphore in another task it is working fine.
when i am using the same osSemaphoreRelease(myBinarySem01Handle); in ISR it is getting stuck in queue.c file at asser mentioned below:
/* Similar to xQueueGenericSendFromISR() but used with semaphores where the
item size is 0. Don't directly wake a task that was blocked on a queue
read, instead return a flag to say whether a context switch is required or
not (i.e. has a task with a higher priority than us been woken by this
post). */
configASSERT( pxQueue );
I am not able to find where i am doing wrong.
Please help me out how i can get out of this issue.I have created this project in true studio and IAR. I am facing the issue in both the projects.
For referecne i have uploaded the files on one drive. Download link is http://1drv.ms/1QHgZ3X
I’m afraid I’m not familiar with osSemaphoreRelease(), or how it is implemented, but that assert() is telling you the first parameter passed into xQueueGiveFromISR() [which is also used by the semaphore give from ISR macro) is NULL.
thanks for your quick reply. I tried using the native APIs, I am still getting the same issue. Can you share any example. I tried the similar way as given on the link provided by you.
The assert occurs because the semaphore handle is NULL. When you are
using the native API the semaphore handle is the first parameter. Can
you pause the debugger on the ‘give’ function and see the value of the
handle. Is it NULL? If so, then the problem is the fact it is NULL,
rather than the way the API function is being used.
/*TIMer6 ISR*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
static unsigned char ucLocalTickCount = 0;
static signed long xHigherPriorityTaskWoken;
/* Is it time for vATask() to run? */
xHigherPriorityTaskWoken = pdFALSE;
ucLocalTickCount++;
if( ucLocalTickCount >= 2 )
{
xSemaphoreGiveFromISR( myBinarySem01Handle,&xHigherPriorityTaskWoken );
__NOP();
/* Reset the count so we release the semaphore again in 10 ticks
time. */
ucLocalTickCount = 0;
}
/* If xHigherPriorityTaskWoken was set to true you
we should yield. The actual macro used here is
port specific. */
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
but if i am comparing ucLocalTickCount >=1 in if condition it is again not working.
I will appreciate if you make me understand where I am wrong and why it is so.
It should also work if i am using only
xSemaphoreGiveFromISR( myBinarySem01Handle,&xHigherPriorityTaskWoken );
in ISR.
What is not working if you use (>= 1)? Do you mean myBinarySem01Handle becomes NULL? That would seem unlikely.
You only need to call portYIELD_FROM_ISR() or portEND_SWITCHING_ISR(), not both. They equate to exactly the same thing.
By the way - if you are always unblocking the same task, or you can store the task’s handle if it is sometimes a different task, then you can achieve the same thing 40% faster and with less RAM using a task notification: http://www.freertos.org/RTOS_Task_Notification_As_Counting_Semaphore.html
I could able to locate the issue, it is with timer initalization. Actually timer inturrept was comming before execution of myBinarySem01Handle = xSemaphoreCreateBinary();.
Because of that i was getting NULL in the handle. Now I make sure that in the Binary semaphore should be created before passing it in
xSemaphoreGiveFromISR( myBinarySem01Handle,&xHigherPriorityTaskWoken );
Thanks once again for your support and giving me the hints to debug this issue.