New event behaviour while busy

Discussions and support about ChibiOS/RT, the free embedded RTOS.
User avatar
FXCoder
Posts: 393
Joined: Sun Jun 12, 2016 4:10 am
Location: Sydney, Australia
Has thanked: 184 times
Been thanked: 131 times

Re: New event behaviour while busy

Postby FXCoder » Tue Oct 01, 2024 9:56 am

Maybe this would be useful for reference...
https://www.chibios.org/dokuwiki/doku.p ... nel_events

law
Posts: 12
Joined: Tue Jan 12, 2016 5:20 am
Been thanked: 1 time

Re: New event behaviour while busy

Postby law » Wed Oct 02, 2024 7:23 am

Hey Bob,

Thanks for that. I'm not quiet understanding your approach just yet, but I'll have a read and experiment and see how I get on.

User avatar
FXCoder
Posts: 393
Joined: Sun Jun 12, 2016 4:10 am
Location: Sydney, Australia
Has thanked: 184 times
Been thanked: 131 times

Re: New event behaviour while busy

Postby FXCoder » Wed Oct 02, 2024 8:48 am

The confusing part is perhaps that source events and the listener thread events are not the same.
Maybe this example will help (not complied but demonstrates the concept)...

Code: Select all

/*
 * event_example.c
 *
 *  Created on: 2 Oct 2024
 *      Author: Bob
 */

/* Define the events of interest from source.*/
#define BROADCAST_EVENTS    (EVENT_MASK(4) | EVENT_MASK(5))

/* Define local event(s) posted based on source event flag(s).*/
#define event_1             EVENT_MASK(0)
#define event_2             EVENT_MASK(1)
#define event_3             EVENT_MASK(2)
#define MY_LOCAL_EVENTS     (event_1 | event_2)

/* Commonly available source flags. Dispatch function does not allow passing
   of parameters other than event ID.*/
eventflags_t process1_flags;

/*
 * Event handler
 */
static void event_handler_1(eventid_t id) {

  //... do stuff for event_1
  //... flags are available in process1_flags
  //... if more to do {
    chEvtAddEvents(EVENT_MASK(id));
  // }
}

/*
 * Event handler
 */
static void event_handler_2(eventid_t id) {

  //... do stuff for event_2
  //... flags are available in process1_flags
  //... if more to do {
    chEvtAddEvents(EVENT_MASK(id));
  // }
}

/*
 * Event handler
 */
static void event_handler_3(eventid_t id) {

  //... do stuff for event_3
  //... flags are available in process1_flags
  //... if more to do {
    chEvtAddEvents(EVENT_MASK(id));
  // }
}

/* Event handler function table used by chEvtDispatch(...).*/
static evhandler_t handlers[] = {
              event_handler_1,
              event_handler_2,
              event_handler_3
};

/**
 * @brief   Process thread function.
 *
 * @param[in] p         pointer to a @p event_source_t object
 */
THD_FUNCTION(shellThread, p) {

  event_source_t *esp = p;

  /* The event listener for this thread.*/
  event_listener_t el;

  /* Register as a listener on the event source.*/
  chEvtRegisterMaskWithFlags(esp, &el, MY_LOCAL_EVENTS, BROADCAST_EVENTS);

  /* Start processing events from listener.*/
  while (!chThdShouldTerminateX()) {

    /* Wait for the broadcast to post to listener (set thread event(s)).*/
    chEvtWaitAny(BROADCAST_EVENTS);

    /* Get the flags from source in case workers need to use them. For
       example if subscribed to serial channel then we could get
       CHN_INPUT_AVAILABLE flags from serial and do conditional processing
       based on that or other source flags such as CHN_DISCONNECTED.*/
    process1_flags = chEvtGetAndClearFlags(&listener);

    /* Set lower priority for event processing.*/
    tprio_t priority = chThdSetPriority(LOWPRIO);

    /* Process worker events. Note this is a hard loop while any task is
       requesting more processing time.*/
    do {

      /* Get my thread event(s). Note these are independent of the source
         event flags and are local events for this thread.*/
      eventmask_t events = chEvtGetAndClearEvents(events);

      chEvtDispatch(handlers, events);

    } while (chEvtGetEventsX());

    /* Restore priority.*/
    (void) chThdSetPriority(priority);
  }

  /* Unregister from the event source.*/
  chEvtUnregister(esp, &el);
  chSysLock();
  chThdExitS(MSG_OK);
}

User avatar
FXCoder
Posts: 393
Joined: Sun Jun 12, 2016 4:10 am
Location: Sydney, Australia
Has thanked: 184 times
Been thanked: 131 times

Re: New event behaviour while busy

Postby FXCoder » Wed Oct 02, 2024 10:52 pm

Here is an expanded (and tidied - typos fixed) version which shows how multiple listeners can subscribe to a source.
Hope this helps...

Code: Select all

/*
 * event_example.c
 *
 *  Created on: 2 Oct 2024
 *      Author: Bob
 */

/* Define the events of interest from source.*/
#define BROADCAST_EVENTS1   (EVENT_MASK(4) | EVENT_MASK(5))
#define BROADCAST_EVENTS2   (EVENT_MASK(6) | EVENT_MASK(7))
#define BROADCAST_EVENTS3   (EVENT_MASK(8) | EVENT_MASK(9))

/* Define local event(s) posted by listeners.*/
#define MY_LOCAL_EVENT1             EVENT_MASK(0)
#define MY_LOCAL_EVENT2             EVENT_MASK(1)
#define MY_LOCAL_EVENT3             EVENT_MASK(2)

/* Commonly available source flags. Dispatch function does not allow passing
   of parameters other than event ID.*/
eventflags_t process1_flags;

/*
 * Event handler
 */
static void event_handler_1(eventid_t id) {

  //... do stuff for event_1
  //... flags are available in process1_flags
  //... if more to do {
    chEvtAddEvents(EVENT_MASK(id));
  // }
}

/*
 * Event handler
 */
static void event_handler_2(eventid_t id) {

  //... do stuff for event_2
  //... flags are available in process1_flags
  //... if more to do {
    chEvtAddEvents(EVENT_MASK(id));
  // }
}

/*
 * Event handler
 */
static void event_handler_3(eventid_t id) {

  //... do stuff for event_3
  //... flags are available in process1_flags
  //... if more to do {
    chEvtAddEvents(EVENT_MASK(id));
  // }
}

/* Event handler function table used by chEvtDispatch(...).*/
static evhandler_t handlers[] = {
              event_handler_1,
              event_handler_2,
              event_handler_3
};

/**
 * @brief   Process thread function.
 *
 * @param[in] p         pointer to a @p event_source_t object
 */
THD_FUNCTION(processThread, p) {

  event_source_t *esp = p;

  /* The event listeners for this thread.*/
  event_listener_t el1;
  event_listener_t el2;
  event_listener_t el3;

  /* Register as multiple listeners on the event source. Each listener has
     source event flags it is interested in and the local event(s) to be
     posted to this thread.*/
  chEvtRegisterMaskWithFlags(esp, &el1, MY_LOCAL_EVENT1, BROADCAST_EVENTS1);
  chEvtRegisterMaskWithFlags(esp, &el2, MY_LOCAL_EVENT2, BROADCAST_EVENTS2);
  chEvtRegisterMaskWithFlags(esp, &el3, MY_LOCAL_EVENT3, BROADCAST_EVENTS3);

  /* Start processing events from listeners.*/
  while (!chThdShouldTerminateX()) {

    /* Wait for a broadcast to post to a listener (set thread event(s)).*/
    chEvtWaitAny(ALL_EVENTS);

    /* Get the flags from source in case workers need to use them. For
       example if subscribed to a serial channel then we could get
       CHN_INPUT_AVAILABLE flags from serial and do conditional processing
       based on that or other source flags such as CHN_DISCONNECTED.*/
    process1_flags = chEvtGetAndClearFlags(&el);

    /* Set lower priority for event processing.*/
    tprio_t priority = chThdSetPriority(LOWPRIO);

    /* Process worker events. Note this is a hard loop while any task is
       requesting more processing time.*/
    do {

      /* Get my thread event(s). Note these are independent of the source
         event flags and are local events for this thread.*/
      eventmask_t events = chEvtGetAndClearEvents(events);

      chEvtDispatch(handlers, events);

    } while (chEvtGetEventsX());

    /* Restore priority.*/
    (void) chThdSetPriority(priority);
  }

  /* Unregister listeners from the event source.*/
  chEvtUnregister(esp, &el1);
  chEvtUnregister(esp, &el2);
  chEvtUnregister(esp, &el3);
  chSysLock();
  chThdExitS(MSG_OK);
}


law
Posts: 12
Joined: Tue Jan 12, 2016 5:20 am
Been thanked: 1 time

Re: New event behaviour while busy

Postby law » Thu Oct 03, 2024 2:24 am

Thanks Bob - that is very helpful!


Return to “ChibiOS/RT”

Who is online

Users browsing this forum: No registered users and 1 guest