Hard time understanding 2.5 events

ChibiOS public support forum for all topics not covered by a specific support forum.

Moderators: RoccoMarco, lbednarz, tfAteba

Post Reply
trunet
Posts: 54
Joined: Fri Apr 06, 2012 7:18 pm

Hard time understanding 2.5 events

Post 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.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Hard time understanding 2.5 events

Post 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
trunet
Posts: 54
Joined: Fri Apr 06, 2012 7:18 pm

Re: Hard time understanding 2.5 events

Post 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)?
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Hard time understanding 2.5 events

Post 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
trunet
Posts: 54
Joined: Fri Apr 06, 2012 7:18 pm

Re: Hard time understanding 2.5 events

Post 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.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Hard time understanding 2.5 events

Post 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
trunet
Posts: 54
Joined: Fri Apr 06, 2012 7:18 pm

Re: Hard time understanding 2.5 events

Post by trunet »

Success. After this explanation I declared 5 eventsource and eventlisten for each one on my threads.

Thank you very much.
Post Reply