Hi,
So, going back to my problematic case, chEvtWaitOne returns immediately because when it gets called the pending flag for the events seems to be already set. I set a breakpoint at chevents.c line 390 and it's never hit. Although when it returns ctp->p_epending has the event reset, as it should.
Code: Select all
eventmask_t chEvtWaitOne(eventmask_t events) {
384│ thread_t *ctp = currp;
385│ eventmask_t m;
386│
387│ chSysLock();
388│ m = ctp->p_epending & events;
389│ if (m == (eventmask_t)0) {
390│ ctp->p_u.ewmask = events;
391│ chSchGoSleepS(CH_STATE_WTOREVT);
392│ m = ctp->p_epending & events;
393│ }
394| m ^= m & (m - (eventmask_t)1);
395│ ctp->p_epending &= ~m;
396│ chSysUnlock();
397│
398│ return m;
399│ }
After that finding I decided to perform sdWrites only if there are no pending event flags, and if there were any I would clear them explicitly and return. See below.
Every single time trySend is called it evaluates ctp->p_epending with a set event mask, at this point I get very confused, note that sd write operations are not happening in this case. A silly question, that could explain it all, if data is received by the same serial drive. Would it also trigger an event 0 even though only the CHN_TRANSMISSION_END event flag is registered?
Code: Select all
bool trySend (uint8_t *data, uint8_t n)
{
thread_t *ctp = currp;
chSysLock ();
eventmask_t s = ctp->p_epending;
chSysUnlock ();
if (s == EVENT_MASK (0))
{
chSysLock ();
ctp->p_epending = 0;
chSysUnlock ();
return false;
}
sdWrite (&SD2, data, n);
chEvtWaitOne (EVENT_MASK (0));
eventflags_t f = chEvtGetAndClearFlags (&txComplete);
return f & CHN_TRANSMISSION_END;
}
Update, If I clear the flags as well as the pending events it only meets the first if condition once. The system works as expected from that point onwards. So, I would answer my previous question with a no, as subsequent events and activity don't trigger event 0.
Now here is THE question, why do you guys think it is doing it initially? At that point some data would have been received but nothing transmitted.
Code: Select all
bool trySend (uint8_t *data, uint8_t n)
{
thread_t *ctp = currp;
chSysLock ();
eventmask_t s = ctp->p_epending;
chSysUnlock ();
// It gets here only once, the first time it gets called, and after the system becomes "synced up".
if (s == EVENT_MASK (0))
{
chSysLock ();
txComplete.el_flags = 0;
ctp->p_epending = 0;
chSysUnlock ();
return false;
}
sdWrite (&SD2, data, n);
chEvtWaitOne (EVENT_MASK (0));
eventflags_t f = chEvtGetAndClearFlags (&txComplete);
return f & CHN_TRANSMISSION_END;
}
Thanks