FreeRTOS: xSemaphoreGiveFromISR() not functional from ISR with STM32F746NG

sadakamath wrote on Monday, March 04, 2019:

Hi,
I see that xSemaphoreGiveFromISR() not functional from ISR with STM32F746NG.

HAL_GPIO_TogglePin is working fine when it is called in ISR. But, xSemaphoreGiveFromISR is not working.
Is there any STM32F746NG configuration is missing to make it work with STM32F746NG?

NOTE:

  1. Target board & CPU: STM32F746G-DISCO, STM32F746NG
  2. FreeRTOS project is created from STM32CubeMx
  3. Used TIM3 for Timebase Source and TIM2 for 1sec interrupt generation using internal clock
  4. Refer below section for definition of configKERNEL_INTERRUPT_PRIORITY and configMAX_SYSCALL_INTERRUPT_PRIORITY

References:

main()

void Thread2(void const * argument)
{
uint8_t txData[20] = “Hello from Thread2\r\n”;
while(1)
{
if(xSemaphoreTake(myBinarySem01Handle, portMAX_DELAY)) {
HAL_GPIO_TogglePin(GPIOI,GPIO_PIN_1);
HAL_UART_Transmit(&huart1, txData, 20, 5);
osDelay(100);
}
}
}

Timer Interrupt Callback

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef htim)
{
if (htim->Instance == TIM3) {
HAL_IncTick(); //TIM3 used for Timebase Source
}
else if(htim->Instance == TIM2) {
/
HAL_GPIO_TogglePin(GPIOI,GPIO_PIN_1);
LED blink working fine when below SemaphoreGiveFromISR commented */

  xSemaphoreGiveFromISR(myBinarySem01Handle,NULL);

}
}

define NVIC_PRIO_BITS 4
define configPRIO_BITS 4
define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5

define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

rtel wrote on Monday, March 04, 2019:

What makes you think it is not functional?

Have you created the semaphore? If so, please show that code to so we
can see if you are using the handle correctly.

You are not using the second parameter to xSemaphoreGiveFromISR(), so
the context switch will not happen until the next tick interrupt.

Using a direct to task notification in place of the semaphore will be
much faster and use less RAM.

sadakamath wrote on Monday, March 04, 2019:

Thanks Richard, See my answers below -

What makes you think it is not functional?
Ans: LED blink is not happening when I used xSemaphoreGiveFromISR() in interrupt callback.

Have you created the semaphore?
Ans: Yes, see below -

/* definition and creation of myBinarySem01 */
osSemaphoreDef(myBinarySem01);
myBinarySem01Handle = osSemaphoreCreate(osSemaphore(myBinarySem01), 1);

I have removed second parameter to xSemaphoreGiveFromISR() today while debugging LED blink issue. Second parameter was there in my original code.

Let me know if any clue?

rtel wrote on Monday, March 04, 2019:

//definition and creation of myBinarySem01 //
osSemaphoreDef(myBinarySem01);
myBinarySem01Handle = osSemaphoreCreate(osSemaphore(myBinarySem01), 1);

Unfortunately this is not one of our API functions so I don’t know what
it is doing. Can you please try using xSemaphoreCreateBinary():

sadakamath wrote on Tuesday, March 05, 2019:

Same issue persists with new code -

SemaphoreHandle_t myBinarySem01Handle = 0;
main()
vSemaphoreCreateBinary(myBinarySem01Handle);

rtel wrote on Tuesday, March 05, 2019:

Please cut down your project to the very minimum that demonstrates this
problem (remove everything other than the code in question), zip it up,
then attached the zip file to a post in this forum.

sadakamath wrote on Tuesday, March 05, 2019:

Thanks, Attacted entire Atollic TrueSTUDIO project as size is 826KB. Let me know if you need only main.c.

LED blink and UART transmit is working fine when I call in ISR callback.
But, both are not working with xSemaphoreGiveFromISR()

rtel wrote on Tuesday, March 05, 2019:

There is a lot more in this project that just the part that is causing
the issue. Can you give me a clue where to look.

In the mean time, what does this line do?

osSemaphoreDef(myBinarySem01);

Looks like it might declare a semaphore on the stack of main(), which
won’t exist when the scheduler starts, but I’m not familiar with this
API. Could be the issue though.

sadakamath wrote on Wednesday, March 06, 2019:

  1. I have replaced semaphore declaration and vSemaphoreCreateBinary. But, same issue persists. see updated code below under “Reference” section -
  2. Problamatic area is xSemaphoreGiveFromISR inside ISR callback. xSemaphoreGive is working fine when it is called outside ISR

//-------------Reference --------------//
outside main()
//osSemaphoreId myBinarySem01Handle;
xSemaphoreHandle myBinarySem01Handle;

main()
// osSemaphoreDef(myBinarySem01);
// myBinarySem01Handle = osSemaphoreCreate(osSemaphore(myBinarySem01), 1);
vSemaphoreCreateBinary(myBinarySem01Handle);

rtel wrote on Wednesday, March 06, 2019:

Try the following:

  1. Put a break point on the call to xSemaphoreGiveFromISR() inside
    HAL_TIM_PeriodElapsedCallback().

  2. If the breakpoint isn’t hit, then that is the problem, otherwise if
    the breakpoint is hit inspect the variable myBinarySem01Handle in the
    debugger. It should be a pointer to a structure, but you might have to
    cast it to a xQUEUE* to see the structure members (so you would add
    “((xQUEUE*) myBinarySem01Handle” to the debugger’s watch window). Take
    a screen shot of the debugger so we can see the values inside the
    structure and post the screen shot here.

  3. Step into the xSemaphoreGiveFromISR() function line by line in the
    debugger, and see what path it takes through the function.

sadakamath wrote on Friday, March 08, 2019:

I’m able to resolve this issue.

I have moved 1 sec interrupt HAL_TIM_Base_Start_IT to just before osKernelStart(). It was earlier before the creation of Semaphore & tasks.

I din’t noticed earlier that vSemaphoreCreateBinary() calls for xSemaphoreGive()

Thanks for your support…!