cancel
Showing results for 
Search instead for 
Did you mean: 

CMSIS RTOS feature osSignal incorrectly implemented on FreeRTOS

Oskar Weigl
Associate
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
17 REPLIES 17
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>,

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.

Posted on April 05, 2017 at 21:19

In my understanding, osSignalWait (0x00, osWaitForever) will not reset the

flags. But I did not test.

2017-04-05 14:24 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

<

MCUs Forum* - View the full discussion

<https://community.st.com/0D70X000006Sy3KSAS

Posted on April 05, 2017 at 22:04

Seems to clear in my application but...

pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnExit;�?�?

From the call to FreeRTOS:

xTaskNotifyWait

But you might be correct. A flag check of 0x00 might not clear the flag.

Posted on April 06, 2017 at 00:03

What is the value of ulBitsToClearOnExit ?

Il Mer 5 Apr 2017, 22:05 Richard Lowe <st-microelectronics@jiveon.com> ha

scritto:

STMicroelectronics Community

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

Re: CMSIS RTOS feature osSignal incorrectly implemented on FreeRTOS

reply from Richard Lowe

<

MCUs Forum* - View the full discussion

<https://community.st.com/0D70X000006T0IwSAK

George.P
Associate III

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.

Stm32User
Associate II

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;

}

NNagy.1
Senior

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?)