cancel
Showing results for 
Search instead for 
Did you mean: 

FreeRTOS Signals issues (any vs all signals)

kevin2399
Associate III
Posted on March 28, 2016 at 23:46

I am trying to use the CMSIS interface to FreeRTOS that is generated by the Cube application.  Specifically, I am trying to use the osSignalWait, osSignalSet, and osSignalClear functions.

Problem 1: osSignalClear is only defined as a function prototype. There is no code for it.

Problem 2: My understanding from reading about osSignalWait is that if there are signal events returned, it will always clear them all automatically.  If you want to wait on ANY signal instead of all of the defined signals, you pass 0 in for the signals parameter, e.g. osSignalWait (0, osWaitForever).

What I am seeing is that the reported signals are not being cleared.  Is this the correct behavior for this function?  
10 REPLIES 10
Walid FTITI_O
Senior II
Posted on March 29, 2016 at 11:20

Hi wired,

For the osSignalClear , it is not supported by FreeRtos.

osSignalWait() is called to wait for one or more signal flags to become signaled (set) for the current running thread.

Refer to the ''FreeRTOS_signal example in the 

http://www.st.com/web/catalog/tools/FM147/CL1794/SC961/SS1743/LN1897/PF261909

in this path :

STM32Cube_FW_F7_V1.3.0\Projects\STM32756G_EVAL\Applications\FreeRTOS\FreeRTOS_Signal

-Hannibal-

kevin2399
Associate III
Posted on March 29, 2016 at 17:22

I get what osSignalWait is for. I am questioning whether it is functioning correctly.

A description of osSignalWait from the CMSIS-RTOS API description on Keil's web site:

Suspend the execution of the current RUNNING thread until all specified signal flags with the parameter signals are set. When the parameter signals is 0 the current RUNNING thread is suspended until any signal is set. When these signal flags are already set, the function returns instantly. Otherwise the thread is put into the state WAITING.

Signal flags that are reported as event are automatically cleared.

The last sentence implies to me that any reported signals are cleared no matter what. What I am seeing is that if I call the function with a signals value of 0 and one of those signals is already set (no waiting required), the signal is not cleared, and it causes the signal to be reported over and over again (this is in a task loop) when the signal was set only one time from another thread.

Concerning osSignalClear, it seems that to be CMSIS-compliant, it should be supported since signalling is supported according to cmsis_os.h.  If a signal can be set, I see no technical reason why it can't be cleared.

Walid FTITI_O
Senior II
Posted on March 29, 2016 at 18:19

Hi wired,

The osSignalWait() clears automatically the signal flag after it is set ( after getting the signal).

Infact, FreeRTOS tries to make all these operations pseudo atomic, rather than being done in two separate function calls.

It is  the intention that the reading task clears the bits after the read  (which can be done atomically) rather than have

a different task clear them for it in a separate and non-atomic way (when it might be too late or conflict with another operation). 

I hope that is clear now for you.

-Hannibal-

kevin2399
Associate III
Posted on March 29, 2016 at 23:42

I agree with you that that is how it should work. However, that is not how it is working.  I am setting two different signal flags, one from a GPIO EXTI ISR, and the other from a different thread than the one in which I am calling the osSignalWait.  The GPIO-based flag is set periodically, and the other flag is only set once.  The flag that is getting set once is properly returned as a signal event from osSignalWait(0, osWaitForever), but when I get the next GPIO signal on the next call to osSignalWait, the returned event shows both flags set, even though the osSignalSet was never called again for the other flag. 

In summary, osSignalSet is called once for flag 1 from a different thread, and osSignalSet is called periodically for flag 2 in response to a recurring GPIO EXTI. Flag 1 is returned as an event from osSignalWait after it occurs, and every subsequent call to osSignalWait  returns both flag 1 and flag 2 as events, even though only flag 2 is being set.  My question is why do I keep getting flag 1 as an event when it was only set once?

kevin2399
Associate III
Posted on March 31, 2016 at 15:29

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6WX&d=%2Fa%2F0X0000000bpt%2FCjXYyCaeCmtA.iIrqWY4KbFEVvbygsmdePBfEI5qaGE&asPdf=false
kevin2399
Associate III
Posted on April 04, 2016 at 14:40

Any signaling experts out there that would care to add to the discussion?  Do other CMSIS RTOS's return the signaling event when requesting 'any signal' to notify, e.g. osSignalWait(0, osWaitForever)? 

kevin2399
Associate III
Posted on April 07, 2016 at 15:03

Crickets...

BTW, my previous question was worded incorrectly. The event(s) from waiting on any signal are returned, but not cleared. It should have asked: Do other CMSIS RTOS's clear the returned signaling event when requesting 'any signal' to notify, e.g. osSignalWait(0, osWaitForever)?

Regardless, I'm going to have to declare the osSignalWait function provided by ST as non-CMSIS-compliant when used to request 'any signal' to notify, and request that STM32CubeMX be modified to generate compliant code.

Once again, the description of the osSignalWait function according to CMSIS documentation (bolded italics added for emphasis):

Suspend the execution of the current RUNNING thread until all specified signal flags with the parameter signals are set. When this signal flags are already set, the function returns instantly. Otherwise the thread is put into the state WAITING. Signal flags that are reported as event are automatically cleared.

 

I suppose a workaround is to have two osSignalWait functions immediately after one another, as so:

event = osSignalWait (0, osWaitForever);

if (event.status == osEventSignal)

{

    /* The only way to get the signal event cleared */

    osSignalWait (event.value.signals, 0);

}

However, this is not an atomic operation, and is cumbersome. Making the function work as defined would be preferable.

Walid FTITI_O
Senior II
Posted on April 07, 2016 at 18:54

Hi Wired,

I have tested the case that you are talking about and I find that flag 1 (which is set once) is correctly cleared and only flag 2 is set when the periodic thread is executed then.

You can see both attached file (''main.c'' and ''stm32f7xx_it.c'') of the test project that I did:

The GPIO-based flag (Bit_1) is set periodically (each time you press the buttom) by LED2_ThreadId, and the other flag (BIT_0) is only set once by Signal_Gen_Thread.

Same scenario can be done by using periodic systick interruption instead of GPIO_EXTI ( you have to uncomment the commented parts and comment the GPIO_EXTIO parts.)

To run this test project, you copy/paste these both file under this path: STM32Cube_FW_F7_V1.3.0\Projects\STM32756G_EVAL\Applications\FreeRTOS\FreeRTOS_SignalFromISR\Src

Try to run the project and compare thecode with yourown codeto figure out what is missing. Otherwise, come back and share with us your code/project.

-Hannibal

________________

Attachments :

main.c : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HzVj&d=%2Fa%2F0X0000000bN0%2FIDx0gexBTz_LBgzKvuA9PStYQcIoGbkQFjjyKexoaU0&asPdf=false

stm32f7xx_it.c : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HzVe&d=%2Fa%2F0X0000000bN1%2FrPgnW40d_bjQNOOmWBBRQaZj2ZW3iPZafx1ZGu9FXKE&asPdf=false
kevin2399
Associate III
Posted on April 07, 2016 at 22:56

I looked at your example files, and they do not test the problem I have described, which is calling osSignalWait with a zero as the first parameter to specify that you want to wait on ANY signal. You are explicitly waiting for specific signals, which I have already stated works fine. The idea behind a parameter of 0 is that there might be a number of occurrences which you might want to wait for, but you don't want to wait for all of them to occur.  Any one of them should take you out of the waiting state. This is specified by using a signals parameter value of 0.