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

core/msg_bus: allow to differ between messages form bus and from thread

Currently it is not possible to check if a message was sent over a bus
or if it was send the usual way using `msg_send()`.

This adds a flag to the `sender_pid` if the message was sent over a bus.
`MAXTHREADS` is currently set to 32, so there is still plenty of room in
the PID space. (`kernel_pid_t` is `int16_t`)

The message type for bus message type is already accessed through a getter
function, so it's just consistent to do the same for sender_pid.
This commit is contained in:
Benjamin Valentin 2020-05-05 13:39:48 +02:00 committed by Benjamin Valentin
parent 6c3a0eba59
commit d6a6c218a3
2 changed files with 44 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();