Skip to main content
Visitor II
December 6, 2016
Question

CMSIS RTOS feature osSignal incorrectly implemented on FreeRTOS

  • December 6, 2016
  • 8 replies
  • 5691 views
Posted on December 06, 2016 at 15:04

Hi,

I was checking through the implementation of osSignal in the file installed by STM32CubeMX to 'Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c'

The

http://www.keil.com/pack/doc/CMSIS/RTOS/html/group__CMSIS__RTOS__SignalMgmt.html

specifies that the call to osSignalWait will '

Suspend the execution of the current

running

thread until ALL specified signal flags with the parameter

signals

are set.'

This is exactly the behavior of the FreeRTOS function 

http://www.freertos.org/xEventGroupWaitBits.html

. However, in the osSignal implementation, the FreeRTOS primitive 'TaskNotify' is used. As noted on

http://www.freertos.org/RTOS_Task_Notification_As_Event_Group.html

, 'Unlike when using an event group the receiving task cannot specify that it only wants to leave the Blocked state when a combination of bits are active at the same time. Instead the task is unblocked when any bit becomes active, and must test for bit combinations itself.'

This means that the osSignal functionality does not behave as specified.

Please let me know if I have misunderstood the situation, or please let me know how this can be fixed?

Cheers,

Oskar

#cmsis-rtos #freertos
    This topic has been closed for replies.

    8 replies

    Visitor II
    December 21, 2016
    Posted on December 21, 2016 at 11:10

    Hi Oskar,

    Unfortunately the osSignalClear is not implemented in stm32Cubemx. Only he declaration is exists on cmsis_os.c

    by

    Zamek

    Technical Moderator
    December 21, 2016
    Posted on December 21, 2016 at 14:34

    Hello,

    osSignal functionality is not supported by STM

    32CubeMx

    .

    In fact, the osSignalClear

    function is specified in the generic cmsis_os wrapper for RTOS, but it is not supported by FreeRtos. 

    Maybe you can review the example in the Cube package firmware to

     get more details on how to use and apply

    osSignal functionality.

    Best Regards

    Imen

    Visitor II
    January 17, 2017
    Posted on January 17, 2017 at 19:29

    Hello,

    I do believe that you specify in your user manual

    http://www.st.com/content/ccc/resource/technical/document/user_manual/2d/60/ff/15/8c/c9/43/77/DM00105262.pdf/files/DM00105262.pdf/jcr:content/translations/en.DM00105262.pdf

    on page 14 that the osSignal functionality is available and supported.

    I do see that osSignalClear is not implemented, but it is the behaviour of osSignalWait (and by extension osSignalSet) that I am using, and which is incorrect. The specification says that ALL required bits have to be set for the control to be released, but the implementation by the ST MCD Application Team releases the control as soon as ANY signal is received.

    Cheers,

    Oskar

    Graduate
    January 20, 2017
    Posted on January 20, 2017 at 20:19

    Signals are supported but yes, the behavior is not what is to be expected. osSignalClear is there in prototype, but not implemented. What happens is the signal is clear and therefore runs the first time, then it behaves as expected.

    Graduate
    March 15, 2017
    Posted on March 15, 2017 at 09:59

    As of the most recent HAL version. osSignal functions (except clear) seem to be working as expected.

    Using signals is by far the fastest inter-thread communication scheme. Best when used to schedule high priority ISR callbacks:

    void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* hcan)
    {
    if( hcan->Instance == CAN1 )
    {
    osSignalSet(can_rx_taskHandle, CAN_RX_ISR_FLAG);
    }
    }�?�?�?�?�?�?�?

    Visitor II
    March 20, 2017
    Posted on March 20, 2017 at 18:42

    Which version of cmsis_os.c do you have? I have 'CMSIS-RTOS API implementation for FreeRTOS V8.2.3' and I still see the inconsistent implementation of osSignalWait, which will wake-up on ANY signal (regardless of the specified signals, which are only a clear mask but not a filter) instead of waiting for all specified signals to be set.

    Explorer
    February 1, 2017
    Posted on February 01, 2017 at 17:44

    I'm also suffering with issues regarding osSignal management in the cmsis_os abstraction layer (poorly) provided by ST, is there a way to remove the abstraction layer from the code generation in CubeMX? So the code will be generated with FreeRTOS calls instead of 

    cmsis_os calls?

    In this way, I can standardize the use of the FreeRTOS in my application, without mixing cmsis_os calls with direct FreeRTOS calls

    I can deal with the portability loss in order to keep my API calls standardized all over my application source.

    Graduate
    April 4, 2017
    Posted on April 04, 2017 at 22:47

    I've been using the signal flags extensively these past weeks and can proclaim they are working as desired.

    But...

    You have to use them like the

    http://www.disca.upv.es/aperles/arm_cortex_m3/curset/CMSIS/Documentation/RTOS/html/group___c_m_s_i_s___r_t_o_s___signal_mgmt.html

    states.

    Once you set a signal:

    osSignalSet(my_super_thread, MY_GO_FLAG);�?�?

    You need to check for it in the thread like so:

    osEvent evt;
    for(;;)
    {
     evt = osSignalWait(MY_GO_FLAG, osWaitForever);
     if( evt.value.signals & MY_GO_FLAG)
     {
     ...magic goes here.
     }
     
     if( evt.value.signals & MY_EXTRA_FLAG )
     {
     ... more magic happens.
     }
    }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

    I have a few threads with at least 4 signals on it and all works as advertised.

    Visitor II
    April 5, 2017
    Posted on April 05, 2017 at 11:15

     ,

     ,

    My understanding is that if you want to write code which is compatible with

    both official cmsis documentation and STM32 implementation, you must use

    this API 1 bit at a time when waiting and reading, and not use

    osSignalClear (which is not implemented, and I suspect it would not be safe

    anyway).

    Since osSignalClear

    <,http://www.disca.upv.es/aperles/arm_cortex_m3/curset/CMSIS/Documentation/RTOS/html/group___c_m_s_i_s___r_t_o_s___signal_mgmt.html ♯ gafcb3a9bd9a3c4c99f2f86d5d33faffd8>,

    unimplemented,

    the only chance to clear a signal is through osSignalWait

    <,http://www.disca.upv.es/aperles/arm_cortex_m3/curset/CMSIS/Documentation/RTOS/html/group___c_m_s_i_s___r_t_o_s___signal_mgmt.html ♯ ga38860acda96df47da6923348d96fc4c9>,

    .

    So, if you wait

    In your example, you must repeat the wait for MY_EXTRA_FLAG, or it will

    never be reset.

    2017-04-05 10:44 GMT+02:00 Richard Lowe <,st-microelectronics@jiveon.com>,:

    STMicroelectronics Community

    <,https://community.st.com/?et=watches.email.thread>,

    Re: CMSIS RTOS feature osSignal incorrectly implemented on FreeRTOS

    reply from Richard Lowe

    <,https://community.st.com/people/Lowe.Richard?et=watches.email.thread>, in *STM32

    MCUs Forum* - View the full discussion

    <,https://community.st.com/message/153480-re-cmsis-rtos-feature-ossignal-incorrectly-implemented-on-freertos?commentID=153480&,et=watches.email.thread ♯ comment-153480>,

    Graduate
    April 5, 2017
    Posted on April 05, 2017 at 13:13

    Well yes and no on the wait. For this example, I have a periodic task that happens after so much time has expired, but not time critical. So the timer expires and sets off the flag. Then when it gets around to it, the 'more magic' happens.

    You could do it this way:

    osEvent evt;
    for(;;)
    {
     evt = osSignalWait( 0x00, osWaitForever );
     if( evt.value.signals & MY_GO_FLAG)
     {
     ...magic goes here.
     }
     
     else if( evt.value.signals & MY_EXTRA_FLAG )
     {
     ... more magic happens.
     }
    }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

    That would wait for ANY flag and then you would check for that particular flag during execution.

    Explorer
    January 17, 2019

    Posting to update the status of this issue.

    ST's implementation still doesn't allow waiting for more than one signals at a time and will return with osEventSignal when even one is sent.

    Visitor II
    March 17, 2020

    Old thread, but I thought I would post this here in case this hasn't been fixed.

    I ran into this problem and made the following change to the Freertos call to xTaskNotifyWait in wrapper file cmsis_os.c

    The change to the first parameter clears any bits in the calling threads notification value on entry. The original call is commented out.

    In the original call no bits are cleared ( param 1 = 0 ) and as is mentioned above, the osSignalClear() function is not implemented.

    osEvent osSignalWait (int32_t signals, uint32_t millisec)

    {

     osEvent ret;

    #if( configUSE_TASK_NOTIFICATIONS == 1 )

     TickType_t ticks;

     ret.value.signals = 0; 

     ticks = 0;

     if (millisec == osWaitForever) {

       ticks = portMAX_DELAY;

     }

     else if (millisec != 0) {

       ticks = millisec / portTICK_PERIOD_MS;

       if (ticks == 0) {

         ticks = 1;

       }

     } 

     if (inHandlerMode())

     {

       ret.status = osErrorISR; /*Not allowed in ISR*/

     }

     else

     {

       //if(xTaskNotifyWait( 0,(uint32_t) signals, (uint32_t *)&ret.value.signals, ticks) != pdTRUE)

      if(xTaskNotifyWait( 0xFFFFFFFF,(uint32_t) signals, (uint32_t *)&ret.value.signals, ticks) != pdTRUE)

       {

         if(ticks == 0) ret.status = osOK;

         else ret.status = osEventTimeout;

       }

       else if(ret.value.signals < 0)

       {

         ret.status = osErrorValue;    

       }

       else ret.status = osEventSignal;

     }

    #else

     (void) signals;

     (void) millisec;

     ret.status = osErrorOS; /* Task Notification not supported */

    #endif

     return ret;

    }

    Visitor II
    November 27, 2021

    Discovering this thread 2 years later: so to clarify, does the above change remove the need for an osSignalClear() function/call? (does clearing all bits effectively clear the signal?)