To add a new zbus event, complete the following procedure:
-
Create a header for the new channel and message type at
app/src/modules/uart_power_control/uart_power_control.h.#ifndef UART_POWER_CONTROL_H_ #define UART_POWER_CONTROL_H_ #include <zephyr/zbus/zbus.h> enum vbus_msg_type { /* VBUS power supply is connected. */ VBUS_CONNECTED, /* VBUS power supply is disconnected. */ VBUS_DISCONNECTED, }; struct vbus_msg { enum vbus_msg_type type; }; ZBUS_CHAN_DECLARE(vbus_chan); #endif /* UART_POWER_CONTROL_H_ */ -
Define the channel and publish events from the existing
event_callback()function inapp/src/modules/uart_power_control/uart_power_control.c. Add the include and channel definition near the top of the file:#include "uart_power_control.h" #include "app_common.h" ZBUS_CHAN_DEFINE(vbus_chan, struct vbus_msg, NULL, NULL, ZBUS_OBSERVERS_EMPTY, ZBUS_MSG_INIT(0));Then publish the events from inside
event_callback():if (pins & BIT(NPM13XX_EVENT_VBUS_DETECTED)) { LOG_DBG("VBUS detected"); vbus_present = true; struct vbus_msg msg = { .type = VBUS_CONNECTED }; int pub_err = zbus_chan_pub(&vbus_chan, &msg, PUB_TIMEOUT); if (pub_err) { LOG_ERR("zbus_chan_pub, error: %d", pub_err); SEND_FATAL_ERROR(); } // ... existing code ... } if (pins & BIT(NPM13XX_EVENT_VBUS_REMOVED)) { LOG_DBG("VBUS removed"); vbus_present = false; struct vbus_msg msg = { .type = VBUS_DISCONNECTED }; int pub_err = zbus_chan_pub(&vbus_chan, &msg, PUB_TIMEOUT); if (pub_err) { LOG_ERR("zbus_chan_pub, error: %d", pub_err); SEND_FATAL_ERROR(); } // ... existing code ... } -
Make sure the channel is observed by the subscriber module. In
app/src/main.c, addvbus_chanto theCHANNEL_LISTso it is gated byCONFIG_APP_UART_POWER_CONTROL:#include "uart_power_control.h" #define CHANNEL_LIST(X) \ X(cloud_chan, struct cloud_msg) \ X(fota_chan, struct fota_msg) \ X(network_chan, struct network_msg) \ X(location_chan, struct location_msg) \ X(storage_chan, struct storage_msg) \ X(timer_chan, struct timer_msg) \ X(priv_main_chan, struct priv_main_msg) \ IF_ENABLED(CONFIG_APP_BUTTON, (X(button_chan, struct button_msg))) \ IF_ENABLED(CONFIG_APP_POWER, (X(power_chan, struct power_msg))) \ IF_ENABLED(CONFIG_APP_UART_POWER_CONTROL, (X(vbus_chan, struct vbus_msg)))If you are subscribing from a different module, add the channel to that module's
CHANNEL_LISTinstead. -
Implement a handler for the new events in the subscriber module. For example, add the following block to the
running_run()state handler inapp/src/main.c:if (state_object->chan == &vbus_chan) { const struct vbus_msg *msg = (const struct vbus_msg *)state_object->msg_buf; if (msg->type == VBUS_CONNECTED) { LOG_DBG("VBUS connected, request white LED blinking rapidly for 10 seconds"); struct led_msg led_msg = { .type = LED_RGB_SET, .red = 255, .green = 255, .blue = 255, .duration_on_msec = 300, .duration_off_msec = 300, .repetitions = 10, }; int err = zbus_chan_pub(&led_chan, &led_msg, PUB_TIMEOUT); if (err) { LOG_ERR("zbus_chan_pub, error: %d", err); SEND_FATAL_ERROR(); } return SMF_EVENT_HANDLED; } else if (msg->type == VBUS_DISCONNECTED) { LOG_DBG("VBUS disconnected, request purple LED blinking slowly for 10 seconds"); struct led_msg led_msg = { .type = LED_RGB_SET, .red = 255, .green = 0, .blue = 255, .duration_on_msec = 1000, .duration_off_msec = 700, .repetitions = 10, }; int err = zbus_chan_pub(&led_chan, &led_msg, PUB_TIMEOUT); if (err) { LOG_ERR("zbus_chan_pub, error: %d", err); SEND_FATAL_ERROR(); } return SMF_EVENT_HANDLED; } } -
Test the implementation by connecting and disconnecting VBUS to verify the LED patterns change as expected.