Binary Semaphore not working on STM32F03R* Cortex M0 Controller from ISR

mukeshtalks wrote on Thursday, February 04, 2016:

Hi,

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.

  1. when i am using the osSemaphoreRelease(myBinarySem01Handle); from one task and waiting for getting semphore in another task it is working fine.
  2. 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

Regards,
Mukesh

rtel wrote on Thursday, February 04, 2016:

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.

Could you try using the native API? http://www.freertos.org/a00124.html

mukeshtalks wrote on Thursday, February 04, 2016:

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.

rtel wrote on Thursday, February 04, 2016:

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.

mukeshtalks wrote on Thursday, February 04, 2016:

Yes am getting NULL over there. Why It is so, i am not able to understand.

mukeshtalks wrote on Thursday, February 04, 2016:

it is working if i am using the API as

/*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.

Thanks in advance.

rtel wrote on Thursday, February 04, 2016:

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

mukeshtalks wrote on Thursday, February 04, 2016:

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.