This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

RTX os_evt_get behaviour

Hi guys,

Just a quick one, can anyone confirm the behaviour of os_evt_get?

I'm wishing to share a buffer between two threads of different priority. When the thread of higher priority wishes to use the buffer, it sends a cease and desist event signal to the other thread.

I'm using Mutex locks but am concerned about the remote possibility of the cease and desist signal arriving in-between the lower priority thread waking up and locking the Mutex.

My thoughts were to lock the Mutex then re-check the event signaling, however the manual states:

"You can use the os_evt_get function to identify the event that caused the os_evt_wait_or function to complete."

Can I be sure that this function will always return the latest set of events, even if they've not yet been used to wake a thread?

Many thanks

Parents
  • I don't see what information you want clarified.

    The manual does say about os_evt_get() that:

    You can use the os_evt_get function to identify the event that caused the os_evt_wait_or
    function to complete.
    

    So the answer to your question

    Can I be sure that this function will always return the latest set of events, even if
    they've not yet been used to wake a thread?
    


    is no. The function will not return the latest set of events. It will return the event that woke up the thread. Any more events happening will (and must) be held back until next time you wait. Because you want to make sure that you don't accidentally lose events.

    os_evt_wait_or() should be seen as an "dequeue" function, that "checks out" pending events.

    The documentation for os_evt_wait_or() does say:

    The event flag or flags that caused the os_evt_wait_or function to complete are
    cleared before the function returns. You can identify those event flags with
    os_evt_get function later.
    

    If os_evt_get() could pick up extra flags, then they would not pass that "clear" stage. While os_evt_get() must return old events that has already been cleared by os_evt_wait_or().

    So the way to poll for current event state is to call os_evt_wait_or() with zero timeout and see if you got a timeout or not.

Reply
  • I don't see what information you want clarified.

    The manual does say about os_evt_get() that:

    You can use the os_evt_get function to identify the event that caused the os_evt_wait_or
    function to complete.
    

    So the answer to your question

    Can I be sure that this function will always return the latest set of events, even if
    they've not yet been used to wake a thread?
    


    is no. The function will not return the latest set of events. It will return the event that woke up the thread. Any more events happening will (and must) be held back until next time you wait. Because you want to make sure that you don't accidentally lose events.

    os_evt_wait_or() should be seen as an "dequeue" function, that "checks out" pending events.

    The documentation for os_evt_wait_or() does say:

    The event flag or flags that caused the os_evt_wait_or function to complete are
    cleared before the function returns. You can identify those event flags with
    os_evt_get function later.
    

    If os_evt_get() could pick up extra flags, then they would not pass that "clear" stage. While os_evt_get() must return old events that has already been cleared by os_evt_wait_or().

    So the way to poll for current event state is to call os_evt_wait_or() with zero timeout and see if you got a timeout or not.

Children
  • Makes sense, hadn't occurred to me os_evt_wait_or() could be used with zero timeout.

  • FYI: Remember also that only 1 wait/delay RTOS routine can be used per task:

    You cannot mix the wait method os_itv_wait and os_dly_wait (or any other delay wait method) in the same task."

    http://www.keil.com/support/man/docs/rlarm/rlarm_os_dly_wait.htm

    Although this statement does not specifically state os_evt_wait_or() it does have a generic disclaimer within the parenthesis (and os_evt_wait_or() DOES require some type of RTOS timer).

  • reading through this stuff I come to think of one REAL concern re comms: "You can NOT pause reading" In most cases you can pause sending. I have seen schemes that were guaranteed to allowpausing reading and all have failed

    Erik

  • Thanks for the concern, but no problem, there's a hardware fifo of 16 bytes and receive has priority over send, the only task that's of a higher priority is triggered only when the fifo is empty and sleeps within O(1) time, which is considerably less than the time it takes to fill the FIFO.

    Originally I was using DMA, which was so much simpler, however I had a need to detect parity bits and so had to avoid this ultimately :S

  • You can have multiple wait/delay routines in the task.

    But os_itv_wait() consumes the only timing resource for the thread, disallowing any other delay methods for the task. But a task that doesn't use os_itv_set()/os_itv_wait() and have multiple os_dly_wait(), os_evt_wait_or(), ... without a problem. This is because os_dly_wait(), os_evt_wait_or(), ... only needs a timing resource during that specific function call. After call ends, the task-specific variables are available for reuse.

    os_itv_set()/os_itv_wait() on the other hand makes permanent use of the task-specific delay variables, to make sure that the thread gets a wake up call again and again and again like a metronome. So when os_itv_wait() returns, the task variables are still used to keep track of when the task should wake up next time.