1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #14023 from benpicco/core/msg_bus-bus_flag

core/msg_bus: allow to differ between messages form bus and from thread
This commit is contained in:
benpicco 2020-11-03 13:51:19 +01:00 committed by GitHub
commit ee7a52db2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 7 deletions

View File

@ -50,6 +50,12 @@ typedef struct {
kernel_pid_t pid; /**< Subscriber PID */
} msg_bus_entry_t;
/**
* @brief Flag set on `sender_pid` of `msg_t` that indicates that
* the message was sent over a bus.
*/
#define MSB_BUS_PID_FLAG (1U << ((8 * sizeof(kernel_pid_t)) - 1))
/**
* @brief Initialize a message bus.
*
@ -68,30 +74,60 @@ void msg_bus_init(msg_bus_t *bus);
* The `type` field of the`msg_t` also encodes the message bus ID,
* so use this function to get the real 5 bit message type.
*
* If the message was not sent over a bus, this will return the
* original message ID.
*
* @param[in] msg A message that was received over a bus
*
* @return The message type
*/
static inline uint8_t msg_bus_get_type(const msg_t *msg)
static inline uint16_t msg_bus_get_type(const msg_t *msg)
{
return msg->type & 0x1F;
if (msg->sender_pid & MSB_BUS_PID_FLAG) {
return msg->type & 0x1F;
} else {
return msg->type;
}
}
/**
* @brief Check if a message originates from a certain bus
* @brief Get the sender PID of a message bus message.
*
* The `sender_pid` field of the`msg_t` has a flag bit set
* to indicate the message was sent over a bus, thus it should
* not be used directly.
*
* @param[in] msg A message that was received over a bus
*
* @return The sender pid
*/
static inline kernel_pid_t msg_bus_get_sender_pid(const msg_t *msg)
{
return msg->sender_pid & ~MSB_BUS_PID_FLAG;
}
/**
* @brief Check if a message originates from a bus
*
* If a thread is attached to multiple buses, this function can be used
* to determine if a message originated from a certain bus.
*
* @param[in] bus The bus to check for
* @param[in] bus The bus to check for, may be NULL
* @param[in] msg The received message
*
* @return True if the messages @p m was sent over @p bus
* False otherwise.
* If @p bus is NULL, this function returns true
* if the message was sent over *any* bus.
* False if the messages @p m was a direct message
* or from a different bus.
*/
static inline bool msg_is_from_bus(const msg_bus_t *bus, const msg_t *msg)
{
return bus->id == (msg->type >> 5);
if (bus != NULL && (bus->id != (msg->type >> 5))) {
return false;
}
return msg->sender_pid & MSB_BUS_PID_FLAG;
}
/**

View File

@ -241,7 +241,8 @@ int msg_send_bus(msg_t *m, msg_bus_t *bus)
const uint32_t event_mask = (1UL << (m->type & 0x1F));
int count = 0;
m->sender_pid = in_irq ? KERNEL_PID_ISR : thread_getpid();
m->sender_pid = (in_irq ? KERNEL_PID_ISR : thread_getpid())
| MSB_BUS_PID_FLAG;
unsigned state = irq_disable();

View File

@ -47,6 +47,7 @@ void *thread1(void *arg)
/* check if the message came from the right bus */
assert(msg_is_from_bus(arg, &msg));
assert(msg_bus_get_sender_pid(&msg) == p_main);
printf("T1 recv: %s (type=%d)\n",
(char*) msg.content.ptr, msg_bus_get_type(&msg));
@ -70,6 +71,7 @@ void *thread2(void *arg)
/* check if the message came from the right bus */
assert(msg_is_from_bus(arg, &msg));
assert(msg_bus_get_sender_pid(&msg) == p_main);
printf("T2 recv: %s (type=%d)\n",
(char*) msg.content.ptr, msg_bus_get_type(&msg));
@ -93,6 +95,7 @@ void *thread3(void *arg)
/* check if the message came from the right bus */
assert(msg_is_from_bus(arg, &msg));
assert(msg_bus_get_sender_pid(&msg) == p_main);
printf("T3 recv: %s (type=%d)\n",
(char*) msg.content.ptr, msg_bus_get_type(&msg));