Maybe this would be useful for reference...
https://www.chibios.org/dokuwiki/doku.p ... nel_events
New event behaviour while busy
Re: New event behaviour while busy
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.
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.
- 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
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)...
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);
}
- 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
Here is an expanded (and tidied - typos fixed) version which shows how multiple listeners can subscribe to a source.
Hope this helps...
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);
}
Who is online
Users browsing this forum: No registered users and 1 guest