Skip to content

zbus: add zbus_publisher for scheduling messages #88533

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

brandon-exact
Copy link
Contributor

@brandon-exact brandon-exact commented Apr 12, 2025

this PR introduces the concept of zbus publishers, a async method of calling zbus_chan_pub() from a work queue at a scheduled time. under the hood, it is very simple and leverages the k_work api. an example of how it could be used:

int event1 = SAMPLE_SENSOR_A;
int event2 = SAMPLE_SENSOR_B;
int event3 = SAMPLE_SENSOR_c;

ZBUS_CHANNEL_PUBLISHER_DEFINE(pub1, &simple_chan, &event1);
ZBUS_CHANNEL_PUBLISHER_DEFINE(pub2, &simple_chan, &event2);
ZBUS_CHANNEL_PUBLISHER_DEFINE(pub2, &simple_chan, &event3);

void my_thread() {
    int msg;

   /* zbus_chan_publisher_start(struct zbus_publisher *publisher, k_timeout_t delay, k_timeout_t period) */
	zbus_chan_publisher_start(&pub1, K_NO_WAIT, K_MSEC(10));
	zbus_chan_publisher_start(&pub2, K_NO_WAIT, K_MINUTES(2));
	zbus_chan_publisher_start(&pub3, K_NO_WAIT, K_HOURS(1));

	while (1) {

		zbus_sub_wait_msg(zbus_obs, &chan, &msg, K_FOREVER);

		if (msg == SAMPLE_SENSOR_A) {
			/* take sensor A sample */
		} 
		if (msg == SAMPLE_SENSOR_B) {
			/* take sensor B sample */
		} 
		if (msg == SAMPLE_SENSOR_C) {
			/* take sensor C sample */
		} 	
	}
}

another way this can be leveraged is directly from a ISR...

int isr_msg = DATA_READY_MSG;
ZBUS_CHANNEL_PUBLISHER_DEFINE(isr_pub, &simple_chan, &isr_msg);

void my_isr( ... )
{
   /* process ISR */
   
   /* alert application */
   zbus_chan_publisher_reschedule(&isr_pub, K_NO_WAIT);
}

adds the concept of publishers to async publish messages
to zbus channels. the new API is really just wrappers
around the work queue API.

a static variable of the publishers message must be provided
when delcaring the struct zbus_plubhser with
ZBUS_CHANNEL_PUBLISHER_DEFINE

Signed-off-by: Brandon Allen <[email protected]>
@brandon-exact
Copy link
Contributor Author

brandon-exact commented Apr 12, 2025

@rodrigopex hi I decided to push to see if twister is happy. any early feedback with this?

@rodrigopex
Copy link
Collaborator

rodrigopex commented Apr 12, 2025

@brandon-exact

@rodrigopex hi I decided to push to see if twister is happy. any early feedback with this?

It's great! There are minor changes, but we will discuss them in the review phase. I suggest putting this feature in separate files (header and implementation) as it is entirely independent. The ZBUS_WQ should be in the zbus itself. I am going to use that in the async listeners. Okay? Thanks for contributing.

@brandon-exact
Copy link
Contributor Author

it is probably best to close this PR and add a async API apart of the async work you plan to do: e.g....

struct zbus_asyc_msg {
  struct k_work_delayable work;
  void *msg
};

int zbus_chan_pub_async(const struct zbus_channel *chan, struct zbus_asyc_msg *msg, k_timeout_t delay, k_timeout_t timeout);
int zbus_chan_pub_async_cancel(lstruct zbus_asyc_msg *msg);

i think this better aligns with zephyr in general. i.e. alot of subsys/drivers have a sync/async options apart of their APIs . @rodrigopex what do you think?

@rodrigopex
Copy link
Collaborator

The publisher is still interesting. The asynchronous listeners are related to reacting asynchronously. The publisher is about acting (pub) asynchronously and periodically.

I usually use timers to publish to channels in a timely manner. I guess a publisher would be more suitable since that does not run in an ISR context.

Maybe we need to think more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants