Events for serial driver transmission completion

Discussions and support about ChibiOS/RT, the free embedded RTOS.
Raul
Posts: 43
Joined: Thu Aug 13, 2015 5:15 pm
Has thanked: 3 times
Been thanked: 1 time

Events for serial driver transmission completion

Postby Raul » Mon Aug 07, 2017 6:59 pm

Hi all,

In order to get an acknowledgment of transmission transactions on a serial driver, is it common practice to have to clear the flags and events prior to waiting only for a CHN_TRANSMISSION_END flag associated to an event mask?

It seems odd based on what I've read on events and the related examples I could find (haven't actually encounter one based on Tx end notifications), but without those previous calls I can't get it to work.

In the snippet below if the clearing calls to the write aren't there, the thread doesn't wait and it is as if the pending mask already matches the registered mask for every iteration.

Code: Select all

 
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {

   event_listener_t listener;

   chEvtRegisterMaskWithFlags (chnGetEventSource (&SD2),
                                             &listener, EVENT_MASK (0),
                                             CHN_TRANSMISSION_END);
   while (true) {
            // These clearing actions seem required
            chEvtGetAndClearFlags (&listener);
            chEvtGetAndClearEvents (EVENT_MASK (0));
        
            sdWrite (&SD2, buff, sizeof (buf));
                 chEvtWaitOne (EVENT_MASK (0));
                 eventflags_t f = chEvtGetAndClearFlags (&listener);
 
             if (f & CHN_TRANSMISSION_END)
             {
                     // Actions after a guaranteed Tx transaction
             }
    }
 }


Thanks

steved
Posts: 825
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 12 times
Been thanked: 135 times

Re: Events for serial driver transmission completion

Postby steved » Wed Aug 09, 2017 8:55 am

I don't think you're looking at the correct event flag.

From hal_channels.h:

Code: Select all

/**
 * @name    I/O status flags added to the event listener
 * @{
 */
/** @brief No pending conditions.*/
#define CHN_NO_ERROR            (eventflags_t)0
/** @brief Connection happened.*/
#define CHN_CONNECTED           (eventflags_t)1
/** @brief Disconnection happened.*/
#define CHN_DISCONNECTED        (eventflags_t)2
/** @brief Data available in the input queue.*/
#define CHN_INPUT_AVAILABLE     (eventflags_t)4
/** @brief Output queue empty.*/
#define CHN_OUTPUT_EMPTY        (eventflags_t)8
/** @brief Transmission end.*/
#define CHN_TRANSMISSION_END    (eventflags_t)16
/** @} */

EVENT_MASK (0) is equivalent to CHN_NO_ERROR. You should set your event mask to CHN_TRANSMISSION_END

User avatar
FXCoder
Posts: 384
Joined: Sun Jun 12, 2016 4:10 am
Location: Sydney, Australia
Has thanked: 180 times
Been thanked: 130 times

Re: Events for serial driver transmission completion

Postby FXCoder » Wed Aug 09, 2017 9:43 am

Hi,
The event and flag settings do look correct.
Events do seem to be an ongoing source of confusion and as Giovanni has said explanations have not yet succeeded in making it all clear.

Anyway per chEvtRegisterMaskWithFlags...

Code: Select all

void chEvtRegisterMaskWithFlags   (   event_source_t *    esp,
event_listener_t *    elp,
eventmask_t    events,
eventflags_t    wflags
)   


So... events is the event ID to be added to the user thread via the registered listener when the event source broadcasts wflags (one or more).
and... wflags is/are the flag(s) of interest from the event source that will result in the user thread event ID being set (and the user thread woken up).

To get some more clarity can you be specific about what "I can't get it to work" means?
How is that being determined?
Also how/where is the buffer refilled, for the next sdWrite etc?

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Events for serial driver transmission completion

Postby Giovanni » Wed Aug 09, 2017 10:13 am

Hi,

The events are a source of confusion because there are two kind of masks:
1) Masks of events which are local to the thread (part of the thread structure), it is what the chEvtWait() functions wait for.
2) Masks of flags which are local to the listener structure and are originated by the sources.

Note that flags are not added to the listener until the listener is registered so any event broadcasted without listeners is "lost", not buffered in any way.

That code look correct but if you get events waiting before doing sdWrite() then those happened after registration (which is a bit strange considering that code). One possible cause is that you used event 0 previously then unregistered and registered again with an event 0 already pending. Hard to tell, you should use the debugger and verify.

Giovanni

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Events for serial driver transmission completion

Postby Giovanni » Wed Aug 09, 2017 10:22 am

While looking into this I noticed something not exactly right in the handling code, not sure if it is related to this issue but probably not:

The current code into the ISR looks like:

Code: Select all

  /* Physical transmission end.*/
  if (isr & USART_ISR_TC) {
 
    osalSysLockFromISR();
    if (oqIsEmptyI(&sdp->oqueue))
      chnAddFlagsI(sdp, CHN_TRANSMISSION_END);
    u->CR1 = cr1 & ~USART_CR1_TCIE;
    osalSysUnlockFromISR();
  }


I think it should be:

Code: Select all

  /* Physical transmission end.*/
  if (isr & USART_ISR_TC) {
    osalSysLockFromISR();
    if (oqIsEmptyI(&sdp->oqueue)) {
      chnAddFlagsI(sdp, CHN_TRANSMISSION_END);
      u->CR1 = cr1 & ~USART_CR1_TCIE;
    }
    osalSysUnlockFromISR();
  }


I'll open a ticket about this even if it is harmless, under a strange condition: TC interrupt triggered but queue non empty. I am not even sure if this can really happen.

Giovanni

Raul
Posts: 43
Joined: Thu Aug 13, 2015 5:15 pm
Has thanked: 3 times
Been thanked: 1 time

Re: Events for serial driver transmission completion

Postby Raul » Wed Aug 09, 2017 7:02 pm

Hi all,

Thanks for your replies, the event diagram in the wiki helped my understanding in events.
To get some more clarity can you be specific about what "I can't get it to work" means?
How is that being determined?
Also how/where is the buffer refilled, for the next sdWrite etc?


Right, so for my particular example I am disabling the transmission to the bus controlled through digital outputs to a driver, and I intend to do so right after a transmission event occurs. What I mean by not getting it work without is that I don't get the expected behavior without the explicit clearing. That is, no bytes make it to the bus, this is verified with a scope, because it gets disabled pretty much immediately after the sdWrite completes and chEvtWaitOne not waiting. My guess on the latter is because it thinks that the event is already true, need to support that with the debugger.
The buffer is refilled periodically, obviously at a rate lower than the bus capabilities.

That code look correct but if you get events waiting before doing sdWrite() then those happened after registration (which is a bit strange considering that code). One possible cause is that you used event 0 previously then unregistered and registered again with an event 0 already pending. Hard to tell, you should use the debugger and verify.


Im my case, I only call sdWrite at a single location (one thread that owns that serial driver) and event 0 is unique to that thread, the registration only happens once.

Giovanni I'll try that patch too, but agree, shouldn't affect it.

I'll try to capture of the event mask returned by the wait and will let you know.

steved
Posts: 825
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 12 times
Been thanked: 135 times

Re: Events for serial driver transmission completion

Postby steved » Wed Aug 09, 2017 7:45 pm

Another option is the modified serial drivers I've posted here - they use callbacks rather than events, which is potentially a bit less overhead and a bit more predictable on timing.

Bear in mind that the ST devices requiring the 'UART2' driver can be configured to auto-control RTS, including setup and hold times.

User avatar
FXCoder
Posts: 384
Joined: Sun Jun 12, 2016 4:10 am
Location: Sydney, Australia
Has thanked: 180 times
Been thanked: 130 times

Re: Events for serial driver transmission completion

Postby FXCoder » Thu Aug 10, 2017 7:47 am

Thanks for the explanation Raul.
So if I understand correctly this is a serial shared bus system you are implementing.
Steve has a good point about using RTS is you wish to set the registers appropriately and do more hands on that way.

For the current approach perhaps one way to get more information would be to remove the clearing calls, listen to all flags from the UART and debug print those out to another serial.
Then you could see the sequence of events and perhaps some more clues as to why the thread does not behave as expected.

Bob

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Events for serial driver transmission completion

Postby Giovanni » Thu Aug 10, 2017 7:59 am

Hi,

Those status bits are cleared by writing zero, I believe the & is not necessary because the original code writes zero only in the TC bit.

Giovanni

User avatar
FXCoder
Posts: 384
Joined: Sun Jun 12, 2016 4:10 am
Location: Sydney, Australia
Has thanked: 180 times
Been thanked: 130 times

Re: Events for serial driver transmission completion

Postby FXCoder » Thu Aug 10, 2017 8:47 am

Thanks.
I realized, in addition to your correct reply, that the sequence of handling of the interrupt status bits in the shared interrupt handler would also ensure correct handling.
So I removed that part of my post which I guess I did while you were typing a reply :D

In case Raul or Steve are mystified about these posts I had a case of brain fade which Giovanni set me straight on.

Bob


Return to “ChibiOS/RT”

Who is online

Users browsing this forum: No registered users and 8 guests