Page 1 of 1

Hard time understanding 2.5 events

Posted: Thu Jan 03, 2013 7:17 pm
by trunet
Hi again,

I think events is the most complicated thing on chibios, I'm having a really hard time on making it work properly. Sorry for the long post and codes. I have 5 events(0, 1, 2, 3 and 4). 0 and 1 are events from interrupts, 2 and 3 are polling threads from sensors(that only runs when interrupt AND EKF are fired) and 4 is the EKF algorithm state. Interrupts are being fired as verified in debug as the sensors are running perfectly. What is happening on the code below is that everything are being fired randomly instead of waiting proper events to run.

Initialize on main():

Code: Select all

chEvtInit(&imu_event);
chEvtBroadcastFlags(&imu_event, EVENT_MASK(4));


Take a look on these interrupts:

Code: Select all

void mpu6050_interrupt_handler(EXTDriver *extp, expchannel_t channel) {
   (void) extp;
   (void) channel;

   chSysLockFromIsr();
   chEvtBroadcastFlagsI(&imu_event, EVENT_MASK(0) );
   chSysUnlockFromIsr();
}

void hmc5883l_interrupt_handler(EXTDriver *extp, expchannel_t channel) {
   (void) extp;
   (void) channel;

   chSysLockFromIsr();
   chEvtBroadcastFlagsI(&imu_event, EVENT_MASK(1) );
   chSysUnlockFromIsr();
}


And these threads:

Code: Select all

static WORKING_AREA(PollIMUThreadWA, 512);
static msg_t PollIMUThread(void *arg){
   (void)arg;
   chRegSetThreadName("PollIMU");

   EventListener self_el1, self_el2;
   chEvtRegister(&imu_event, &self_el1, 0);
   chEvtRegister(&imu_event, &self_el2, 4);

   while (TRUE) {
      chEvtWaitAll(EVENT_MASK(0) | EVENT_MASK(4));
      // do stuff
      chEvtBroadcastFlags(&imu_event, EVENT_MASK(2));
   }
}

static WORKING_AREA(PollMagnThreadWA, 512);
static msg_t PollMagnThread(void *arg){
   (void)arg;
   chRegSetThreadName("PollMagn");

   EventListener self_el1, self_el2;
   chEvtRegister(&imu_event, &self_el1, 1);
   chEvtRegister(&imu_event, &self_el2, 4);

   while (TRUE) {
      chEvtWaitAll(EVENT_MASK(1) | EVENT_MASK(4));
      // do stuff
      chEvtBroadcastFlags(&imu_event, EVENT_MASK(3));
   }
}

static WORKING_AREA(PollEKFThreadWA, 512);
static msg_t PollEKFThread(void *arg){
   (void)arg;
   chRegSetThreadName("PollEKF");

   EventListener self_el1, self_el2;
   chEvtRegister(&imu_event, &self_el1, 2);
   chEvtRegister(&imu_event, &self_el2, 3);

   while (TRUE) {
      chEvtWaitAll(EVENT_MASK(2) | EVENT_MASK(3));
      // do stuff
      chEvtBroadcastFlags(&imu_event, EVENT_MASK(4));
   }
}


I read wiki documentation and a PDF that was attached to another post but I couldn't make it work.

Re: Hard time understanding 2.5 events

Posted: Thu Jan 03, 2013 7:25 pm
by Giovanni
Hi,

Probably it is true that events are complex...

Note that there are two typess flagsmask_t and eventmask_t, you are mixing things up. The macro EVENT_MASK is for eventmask_t types.

flagsmask_t are flags that the source is adding to the listener structure, those do not wake up the thread. The flags are retrieved by the thread using chEvtGetAndClearFlags().

eventmask_t are the event flags the thread waits for, those are associated to the listener when the listener is registered on the source.

Giovanni

Re: Hard time understanding 2.5 events

Posted: Thu Jan 03, 2013 8:08 pm
by trunet
I see. I will not use flagsmask_t at all. How can I send specific event_mask to all threads waiting? On documentation there're chEvtSignalI() but I have to give a pointer to the threads? Isn't possible to make a chEvtBroadcastI(&imu_event, EVENT_MASK(1)?

Re: Hard time understanding 2.5 events

Posted: Thu Jan 03, 2013 8:19 pm
by Giovanni
It is not the broadcaster to send events, it just broadcasts a source and knows nothing about event flags, it is each thread that associates the flags to its listeners when it does chEvtRegister().

Giovanni

Re: Hard time understanding 2.5 events

Posted: Thu Jan 03, 2013 9:00 pm
by trunet
Well, I give up on events. 4 hours working on that is too much for my patience. I'll use binary semaphores to handle my state machine.

Thanks for the patience.

Re: Hard time understanding 2.5 events

Posted: Thu Jan 03, 2013 9:17 pm
by Giovanni
Probably your decision is premature.

I think at the base of your problem is the assumption that all your thread share the same set of event flags, you have a thread that waits for 1 and 4 then tries broadcast 2 (on the same source), another thread that waits for 2 and so on.

Each thread has *its own* set of flags and the chEvtBroadcast() function cannot specify event flags like it was in 2.4.x.

You just need several event sources. An event source from ISR to thread1, another event source from thread1 to thread2 and so on. Each EventSource object *is* an event source and only one, don't try to make it do multiple things.

The purpose of event flags is just to let threads wait on multiple event sources.

Keep it simple and it will just work.

Giovanni

Re: Hard time understanding 2.5 events

Posted: Thu Jan 03, 2013 9:53 pm
by trunet
Success. After this explanation I declared 5 eventsource and eventlisten for each one on my threads.

Thank you very much.