@@ -109,6 +109,16 @@ struct zbus_channel {
109
109
110
110
/** Mutable channel data struct. */
111
111
struct zbus_channel_data * data ;
112
+
113
+ #if defined(CONFIG_ZBUS_MULTIDOMAIN ) || defined(__DOXYGEN__ )
114
+
115
+ /** Indicates if the channel is a shadow channel.
116
+ * A shadow channel is a channel that should not be used directly, but rather
117
+ * shadows another channel, usually one that is defined in another domain.
118
+ */
119
+ bool is_shadow_channel ;
120
+
121
+ #endif /* CONFIG_ZBUS_MULTIDOMAIN */
112
122
};
113
123
114
124
/**
@@ -275,7 +285,7 @@ struct zbus_channel_observation {
275
285
#define _ZBUS_MESSAGE_NAME (_name ) _CONCAT(_zbus_message_, _name)
276
286
277
287
/* clang-format off */
278
- #define _ZBUS_CHAN_DEFINE (_name , _id , _type , _validator , _user_data ) \
288
+ #define _ZBUS_CHAN_DEFINE (_name , _id , _type , _validator , _user_data , _is_shadow ) \
279
289
static struct zbus_channel_data _CONCAT(_zbus_chan_data_, _name) = { \
280
290
.observers_start_idx = -1, \
281
291
.observers_end_idx = -1, \
@@ -295,6 +305,7 @@ struct zbus_channel_observation {
295
305
.user_data = _user_data , \
296
306
.validator = _validator , \
297
307
.data = & _CONCAT (_zbus_chan_data_ , _name ), \
308
+ IF_ENABLED (CONFIG_ZBUS_MULTIDOMAIN , (.is_shadow_channel = _is_shadow ,)) \
298
309
IF_ENABLED (ZBUS_MSG_SUBSCRIBER_NET_BUF_POOL_ISOLATION , \
299
310
(.msg_subscriber_pool = & _zbus_msg_subscribers_pool ,)) \
300
311
}
@@ -388,12 +399,46 @@ struct zbus_channel_observation {
388
399
*/
389
400
#define ZBUS_CHAN_DEFINE (_name , _type , _validator , _user_data , _observers , _init_val ) \
390
401
static _type _ZBUS_MESSAGE_NAME(_name) = _init_val; \
391
- _ZBUS_CHAN_DEFINE(_name, ZBUS_CHAN_ID_INVALID, _type, _validator, _user_data); \
402
+ _ZBUS_CHAN_DEFINE(_name, ZBUS_CHAN_ID_INVALID, _type, _validator, _user_data, false); \
403
+ /* Extern declaration of observers */ \
404
+ ZBUS_OBS_DECLARE (_observers ); \
405
+ /* Create all channel observations from observers list */ \
406
+ FOR_EACH_FIXED_ARG_NONEMPTY_TERM (_ZBUS_CHAN_OBSERVATION , (;), _name , _observers )
407
+
408
+ #if defined(CONFIG_ZBUS_MULTIDOMAIN ) || defined (__DOXYGEN__ )
409
+
410
+ /**
411
+ * @brief Zbus shadow channel definition.
412
+ *
413
+ * This macro defines a shadow channel.
414
+ * Similar to ZBUS_CHAN_DEFINE, but defines the channel with the
415
+ * is_shadow_channel flag set to true, blocking the channel from
416
+ * being published to normally.
417
+ *
418
+ * @param _name The channel's name.
419
+ * @param _type The Message type. It must be a struct or union.
420
+ * @param _validator The validator function.
421
+ * @param _user_data A pointer to the user data.
422
+ *
423
+ * @see struct zbus_channel
424
+ * @param _observers The observers list. The sequence indicates the priority of the observer. The
425
+ * first the highest priority.
426
+ * @param _init_val The message initialization.
427
+ *
428
+ * @note This macro is used to define shadow channels in a multi-domain setup.
429
+ * Shadow channels are used to represent channels that are defined in another domain, allowing
430
+ * the current domain to observe them without directly publishing to them.
431
+ */
432
+ #define ZBUS_SHADOW_CHAN_DEFINE (_name , _type , _validator , _user_data , _observers , _init_val ) \
433
+ static _type _ZBUS_MESSAGE_NAME(_name) = _init_val; \
434
+ _ZBUS_CHAN_DEFINE(_name, ZBUS_CHAN_ID_INVALID, _type, _validator, _user_data, true); \
392
435
/* Extern declaration of observers */ \
393
436
ZBUS_OBS_DECLARE (_observers ); \
394
437
/* Create all channel observations from observers list */ \
395
438
FOR_EACH_FIXED_ARG_NONEMPTY_TERM (_ZBUS_CHAN_OBSERVATION , (;), _name , _observers )
396
439
440
+ #endif /* CONFIG_ZBUS_MULTIDOMAIN */
441
+
397
442
/**
398
443
* @brief Zbus channel definition with numeric identifier.
399
444
*
@@ -412,12 +457,133 @@ struct zbus_channel_observation {
412
457
*/
413
458
#define ZBUS_CHAN_DEFINE_WITH_ID (_name , _id , _type , _validator , _user_data , _observers , _init_val ) \
414
459
static _type _ZBUS_MESSAGE_NAME(_name) = _init_val; \
415
- _ZBUS_CHAN_DEFINE (_name , _id , _type , _validator , _user_data ); \
460
+ _ZBUS_CHAN_DEFINE(_name, _id, _type, _validator, _user_data, false); \
416
461
/* Extern declaration of observers */ \
417
462
ZBUS_OBS_DECLARE (_observers ); \
418
463
/* Create all channel observations from observers list */ \
419
464
FOR_EACH_FIXED_ARG_NONEMPTY_TERM (_ZBUS_CHAN_OBSERVATION , (;), _name , _observers )
420
465
466
+ #if defined(CONFIG_ZBUS_MULTIDOMAIN ) || defined (__DOXYGEN__ )
467
+
468
+ /**
469
+ * @brief Zbus shadow channel definition.
470
+ *
471
+ * This macro defines a shadow channel.
472
+ * Similar to ZBUS_CHAN_DEFINE, but defines the channel with the
473
+ * is_shadow_channel flag set to true, blocking the channel from
474
+ * being published to normally.
475
+ *
476
+ * @param _name The channel's name.
477
+ * @param _id The channel's unique numeric identifier.
478
+ * @param _type The Message type. It must be a struct or union.
479
+ * @param _validator The validator function.
480
+ * @param _user_data A pointer to the user data.
481
+ *
482
+ * @see struct zbus_channel
483
+ * @param _observers The observers list. The sequence indicates the priority of the observer. The
484
+ * first the highest priority.
485
+ * @param _init_val The message initialization.
486
+ *
487
+ * @note This macro is used to define shadow channels in a multi-domain setup.
488
+ * Shadow channels are used to represent channels that are defined in another domain, allowing
489
+ * the current domain to observe them without directly publishing to them.
490
+ */
491
+ #define ZBUS_SHADOW_CHAN_DEFINE_WITH_ID (_name , _id , _type , _validator , _user_data , _observers , \
492
+ _init_val ) \
493
+ static _type _ZBUS_MESSAGE_NAME(_name) = _init_val; \
494
+ _ZBUS_CHAN_DEFINE(_name, _id, _type, _validator, _user_data, true); \
495
+ /* Extern declaration of observers */ \
496
+ ZBUS_OBS_DECLARE (_observers ); \
497
+ /* Create all channel observations from observers list */ \
498
+ FOR_EACH_FIXED_ARG_NONEMPTY_TERM (_ZBUS_CHAN_OBSERVATION , (;), _name , _observers )
499
+
500
+ /**
501
+ * @brief Macro to check if a channel is a shadow channel.
502
+ *
503
+ * @param _chan The channel to check.
504
+ * @return true if the channel is a shadow channel, false otherwise.
505
+ */
506
+ #define ZBUS_CHANNEL_IS_SHADOW (_chan ) ((_chan )-> is_shadow_channel )
507
+
508
+ /**
509
+ * @brief Macro to check if a channel is a master channel.
510
+ *
511
+ * @param _chan The channel to check.
512
+ * @return true if the channel is a master channel, false if it is a shadow channel.
513
+ */
514
+ #define ZBUS_CHANNEL_IS_MASTER (_chan ) (!(_chan)->is_shadow_channel)
515
+
516
+ /**
517
+ * @brief Zbus multi-domain channel definition.
518
+ *
519
+ * This macro defines a channel that can be either a master or a shadow channel based on the
520
+ * is_master and is_included flags. If is_master is true, it defines a normal channel, otherwise
521
+ * it defines a shadow channel. If is_included is false, the channel will not be defined at all.
522
+ * Intended usage is in a shared header in multi-domain setups where the channel is defined in
523
+ * one domain and shadowed in others, using device specific defines to control the inclusion
524
+ * and master status.
525
+ *
526
+ * @param _name The channel's name.
527
+ * @param _type The Message type. It must be a struct or union.
528
+ * @param _validator The validator function.
529
+ * @param _user_data A pointer to the user data.
530
+ * @param _observers The observers list. The sequence indicates the priority of the observer. The
531
+ * first the highest priority.
532
+ * @param _init_val The message initialization.
533
+ * @param _is_master Indicates if this is the master channel (true) or a shadow channel (false).
534
+ * @param _is_included Indicates if the channel should be included in this device (true) or not
535
+ * (false).
536
+ *
537
+ * @note This macro is used to define channels in a multi-domain setup where the channel can be
538
+ * either a master channel or a shadow channel, depending on the device configuration.
539
+ */
540
+ #define ZBUS_MULTIDOMAIN_CHAN_DEFINE (_name , _type , _validator , _user_data , _observers , _init_val , \
541
+ _is_master , _is_included ) \
542
+ COND_CODE_1(_is_included, \
543
+ (COND_CODE_1(_is_master, \
544
+ (ZBUS_CHAN_DEFINE(_name, _type, _validator, _user_data, _observers, \
545
+ _init_val)), \
546
+ (ZBUS_SHADOW_CHAN_DEFINE(_name, _type, _validator, _user_data, _observers, \
547
+ _init_val)))), \
548
+ (/* Channel not included on this device - no definition*/ ))
549
+
550
+ /**
551
+ * @brief Zbus multi-domain channel definition with ID.
552
+ *
553
+ * This macro defines a channel that can be either a master or a shadow channel based on the
554
+ * is_master and is_included flags. If is_master is true, it defines a normal channel with a unique
555
+ * ID, otherwise it defines a shadow channel with the same ID. If is_included is false, the channel
556
+ * will not be defined at all. Intended usage is in a shared header in multi-domain setups where the
557
+ * channel is defined in one domain and shadowed in others, using device specific defines to control
558
+ * the inclusion and master status.
559
+ *
560
+ * @param _name The channel's name.
561
+ * @param _id The channel's unique numeric identifier.
562
+ * @param _type The Message type. It must be a struct or union.
563
+ * @param _validator The validator function.
564
+ * @param _user_data A pointer to the user data.
565
+ * @param _observers The observers list. The sequence indicates the priority of the observer. The
566
+ * first the highest priority.
567
+ * @param _init_val The message initialization.
568
+ * @param _is_master Indicates if this is the master channel (true) or a shadow channel (false).
569
+ * @param _is_included Indicates if the channel should be included in this device (true) or not
570
+ * (false).
571
+ *
572
+ * @note This macro is used to define channels in a multi-domain setup where the channel can be
573
+ * either a master channel or a shadow channel, depending on the device configuration.
574
+ */
575
+ #define ZBUS_MULTIDOMAIN_CHAN_DEFINE_WITH_ID (_name , _id , _type , _validator , _user_data , \
576
+ _observers , _init_val , _is_master , _is_included ) \
577
+ COND_CODE_1(_is_included, \
578
+ (COND_CODE_1(_is_master, \
579
+ (ZBUS_CHAN_DEFINE_WITH_ID(_name, _id, _type, _validator, _user_data, \
580
+ _observers, _init_val)), \
581
+ (ZBUS_SHADOW_CHAN_DEFINE_WITH_ID(_name, _id, _type, _validator, _user_data,\
582
+ _observers, _init_val)))), \
583
+ (/* Channel not included on this device - no definition*/ ))
584
+
585
+ #endif /* CONFIG_ZBUS_MULTIDOMAIN */
586
+
421
587
/**
422
588
* @brief Initialize a message.
423
589
*
@@ -575,9 +741,46 @@ struct zbus_channel_observation {
575
741
* @retval -EFAULT A parameter is incorrect, the notification could not be sent to one or more
576
742
* observer, or the function context is invalid (inside an ISR). The function only returns this
577
743
* value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
744
+ * @retval -EPERM Attempt to publish a shadow channel. Shadow channels can only be published to
745
+ * via the zbus_chan_pub_shadow function. The function only returns this value when the
746
+ * @kconfig{CONFIG_ZBUS_MULTIDOMAIN} is enabled.
578
747
*/
579
748
int zbus_chan_pub (const struct zbus_channel * chan , const void * msg , k_timeout_t timeout );
580
749
750
+ #if defined(CONFIG_ZBUS_MULTIDOMAIN )
751
+
752
+ /** @cond INTERNAL_HIDDEN */
753
+
754
+ /**
755
+ * @brief Publish to a shadow channel
756
+ *
757
+ * This routine publishes a message to a shadow channel.
758
+ *
759
+ * @param chan The channel's reference.
760
+ * @param msg Reference to the message where the publish function copies the channel's
761
+ * message data from.
762
+ * @param timeout Waiting period to publish the channel,
763
+ * or one of the special values K_NO_WAIT and K_FOREVER.
764
+ *
765
+ * @retval 0 Channel published.
766
+ * @retval -ENOMSG The message is invalid based on the validator function or some of the
767
+ * observers could not receive the notification.
768
+ * @retval -EBUSY The channel is busy.
769
+ * @retval -EAGAIN Waiting period timed out.
770
+ * @retval -EFAULT A parameter is incorrect, the notification could not be sent to one or more
771
+ * observer, or the function context is invalid (inside an ISR). The function only returns this
772
+ * value when the @kconfig{CONFIG_ZBUS_ASSERT_MOCK} is enabled.
773
+ *
774
+ * @note This function is used to publish messages to shadow channels in a multi-domain setup,
775
+ * and should not be used by application logic directly. It is intended for internal use to
776
+ * handle shadow channels.
777
+ */
778
+ int zbus_chan_pub_shadow (const struct zbus_channel * chan , const void * msg , k_timeout_t timeout );
779
+
780
+ /** @endcond */
781
+
782
+ #endif /* CONFIG_ZBUS_MULTIDOMAIN */
783
+
581
784
/**
582
785
* @brief Read a channel
583
786
*
0 commit comments