diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index be47f0aff8a..b65902ebe4f 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -2129,6 +2129,21 @@ __syscall void k_event_post(struct k_event *event, uint32_t events); */ __syscall void k_event_set(struct k_event *event, uint32_t events); +/** + * @brief Set or clear the events in an event object + * + * This routine sets the events stored in event object to the specified value. + * All tasks waiting on the event object @a event whose waiting conditions + * become met by this immediately unpend. Unlike @ref k_event_set, this routine + * allows specific event bits to be set and cleared as determined by the mask. + * + * @param event Address of the event object + * @param events Set of events to post to @a event + * @param events_mask Mask to be applied to @a events + */ +__syscall void k_event_set_masked(struct k_event *event, uint32_t events, + uint32_t events_mask); + /** * @brief Wait for any of the specified events * diff --git a/kernel/events.c b/kernel/events.c index 259d1b8ada8..a95d3485c14 100644 --- a/kernel/events.c +++ b/kernel/events.c @@ -174,6 +174,22 @@ void z_vrfy_k_event_set(struct k_event *event, uint32_t events) #include #endif +void z_impl_k_event_set_masked(struct k_event *event, uint32_t events, + uint32_t events_mask) +{ + k_event_post_internal(event, events, events_mask); +} + +#ifdef CONFIG_USERSPACE +void z_vrfy_k_event_set_masked(struct k_event *event, uint32_t events, + uint32_t events_mask) +{ + Z_OOPS(Z_SYSCALL_OBJ(event, K_OBJ_EVENT)); + z_impl_k_event_set_masked(event, events, events_mask); +} +#include +#endif + static uint32_t k_event_wait_internal(struct k_event *event, uint32_t events, unsigned int options, k_timeout_t timeout) { diff --git a/tests/kernel/events/event_api/src/test_event_apis.c b/tests/kernel/events/event_api/src/test_event_apis.c index 42997483735..11e48ba4de3 100644 --- a/tests/kernel/events/event_api/src/test_event_apis.c +++ b/tests/kernel/events/event_api/src/test_event_apis.c @@ -340,6 +340,7 @@ ZTEST(events_api, test_event_deliver) { static struct k_event event; uint32_t events; + uint32_t events_mask; k_event_init(&event); @@ -361,6 +362,33 @@ ZTEST(events_api, test_event_deliver) events = 0xAAAA0000; k_event_set(&event, events); zassert_true(event.events == events, NULL); + + /* + * Verify k_event_set_masked() update the events + * stored in the event object as expected + */ + events = 0x33333333; + k_event_set(&event, events); + zassert_true(event.events == events, NULL); + + events_mask = 0x11111111; + k_event_set_masked(&event, 0, events_mask); + zassert_true(event.events == 0x22222222, NULL); + + events_mask = 0x22222222; + k_event_set_masked(&event, 0, events_mask); + zassert_true(event.events == 0, NULL); + + events = 0x22222222; + events_mask = 0x22222222; + k_event_set_masked(&event, events, events_mask); + zassert_true(event.events == events, NULL); + + events = 0x11111111; + events_mask = 0x33333333; + k_event_set_masked(&event, events, events_mask); + zassert_true(event.events == events, NULL); + } /**