FreeRTOS built using arm-none-eabi-gcc got stuck when calls osSemaphoreAcquire

Hello, everyone.
I am new to this forum and post this by the weird issue when build my firmware by using arm-none-eabi-gcc. but when I am using Keil v5, it runs successfully.
I have found the reason after digging for a long time and that’s for osSemaphoreAcquire.
If built using arm-none-eabi-gcc, MCU stops at the function osSemaphoreAcquire.
I couldn’t understand this situation and what am I missing for FreeRTOS or compiler?
Who did meet this compiler issue ever and what would be a workaround for this?

I am using FreeRTOS 10.2.1 and CMSIS-RTOS v2.00 for STM32WL55xx.

My code scenario is as follows.

  • app_freertos.c

    void MX_FREERTOS_Init(void) {
      adc_semHandle = osSemaphoreNew(1, 1, &adc_sem_attributes);
      mainTaskHandle = osThreadNew(mainThread, NULL, &mainTask_attributes);
    void mainThread(void *argument)
      /* Initial work */
        if (osSemaphoreAcquire(adc_semHandle, 5000) == osOK)
          /* ADC work */
          LOG_DBG("Couldn't take a semaphore\n");

Thanks in advance.

First you should now that you are asking about third party code here as we don’t provide a CMSIS wrapper ourselves - so I can only offer general advice. First I would need to know what “stops at the function” means. What is the code doing when it stops? For example, is it stuck in an assert()?

Thanks, @rtel and sorry I’m asking third-party code, but I’ve tried with xSemaphoreTake as well.
But it seems like the same.

For some reason, I couldn’t debug now, but I’ve checked the couldn’t see the log even if put the log output function after xSemaphoreTake(). And the MCU draws the same current forever and never enters STOP2 mode.

One quick question, has anyone given the semaphore?

Another thought - as it runs with one compiler and not the other - have you installed the FreeRTOS interrupt handers in your GCC startup code? See “special note for ARM Cortex-M users” on this page:

If possible I would suggest to use the STM32Cube IDE or CubeMX to generate the initial project which ensures that you have correct startup code and interrupt handlers installed.


I am sorry that I didn’t mention CubeMX. The project has been generated from CubeMX, so I think there isn’t an issue with the startup code.

It’s created at startup and taken at mainThread, then will be given. Another access to this semaphore will be in GPIO interrupt handler. But I didn’t raise it yet.

FreeRTOS creates binary semaphores in the taken state, so you have to give first.

I can’t understand you, but tried to give it once created.
It doesn’t help anything.

And it says I don’t need to give it at first.

I tried a similar code block on a different STM32 hardware and the call to osSemaphoreAcquire works as expected. I never signaled/released the semaphore, and therefore the call returned after the block time. So, osSemaphoreAcquire is probably not your problem. Can you break the code and see where is it stuck?


I found the stopped line after hard debugging, it’s here.

so pxQueue->uxItemSize equals 0x80132bb.

Here are the contents of pxQueue.
pxQueue Queue_t * const 0x20000e70 <ucHeap+100>
pcHead int8_t * 0x20000f09 <ucHeap+253> "\017"
pcWriteTo int8_t * 0x6 ""
u union {...} {...}
xTasksWaitingToSend List_t {...}
xTasksWaitingToReceive List_t {...}
uxMessagesWaiting volatile UBaseType_t 0x8013afe (Hex)
uxLength UBaseType_t 1
uxItemSize UBaseType_t 0x80132bb (Hex)
cRxLock volatile int8_t 119 'w'
cTxLock volatile int8_t 32 ' '
ucStaticallyAllocated uint8_t 1 '\001'
uxQueueNumber UBaseType_t 536874692
ucQueueType uint8_t 26 '\032'

It seems that the semaphore hasn’t been created successfully but the semaphore handler was not NULL as you see.
If I used the static semaphore, MCU drops to HardFault_Handler.
I am not sure what would be wrong now.


Sounds like something has overwritten the memory of the semaphore (or the value of the handle so you are pointing to random memory.

was a symptom for stack overflows/memory corruption a couple of times here in the forum.
Which stack size do you set in mainTask_attributes ?
Besides defining configASSERT do you have also stack overflow checking enabled (for development/debugging) ?
Usually having configASSERT defined makes debugging a lot easier by stopping the debugger (there) and check the call stack for the cause of the assertion.

Thanks for the best tip. @hs2
If configCHECK_FOR_STACK_OVER_FLOW set to 2, the code falls to vApplicationStackOverflowHook, but not for 1.
The osSempaphore functions work well now after increased the stack size of the main thread. :grinning:

Thanks for the forum.