diff --git a/subsys/portability/cmsis_rtos_v2/event_flags.c b/subsys/portability/cmsis_rtos_v2/event_flags.c index fc3d50f067dcd..a9eb3dfb0ef2b 100644 --- a/subsys/portability/cmsis_rtos_v2/event_flags.c +++ b/subsys/portability/cmsis_rtos_v2/event_flags.c @@ -57,13 +57,16 @@ osEventFlagsId_t osEventFlagsNew(const osEventFlagsAttr_t *attr) uint32_t osEventFlagsSet(osEventFlagsId_t ef_id, uint32_t flags) { struct cmsis_rtos_event_cb *events = (struct cmsis_rtos_event_cb *)ef_id; + uint32_t rv; + if ((ef_id == NULL) || (flags & osFlagsError)) { return osFlagsErrorParameter; } - k_event_post(&events->z_event, flags); + rv = k_event_test(&events->z_event, 0xFFFFFFFF); + k_event_post(&events->z_event, flags & ~rv); - return k_event_test(&events->z_event, 0xFFFFFFFF); + return flags & ~rv; } /** @@ -79,7 +82,7 @@ uint32_t osEventFlagsClear(osEventFlagsId_t ef_id, uint32_t flags) } rv = k_event_test(&events->z_event, 0xFFFFFFFF); - k_event_clear(&events->z_event, flags); + k_event_clear(&events->z_event, flags & rv); return rv; } @@ -91,6 +94,7 @@ uint32_t osEventFlagsWait(osEventFlagsId_t ef_id, uint32_t flags, uint32_t optio uint32_t timeout) { struct cmsis_rtos_event_cb *events = (struct cmsis_rtos_event_cb *)ef_id; + uint32_t sub_opt = options & (osFlagsWaitAll | osFlagsNoClear); uint32_t rv; k_timeout_t event_timeout; @@ -114,14 +118,21 @@ uint32_t osEventFlagsWait(osEventFlagsId_t ef_id, uint32_t flags, uint32_t optio event_timeout = K_TICKS(timeout); } - if ((options & osFlagsWaitAll) != 0) { + switch (sub_opt) { + case osFlagsWaitAll | osFlagsNoClear: rv = k_event_wait_all(&events->z_event, flags, false, event_timeout); - } else { + break; + case osFlagsWaitAll: + rv = k_event_wait_all_safe(&events->z_event, flags, false, event_timeout); + break; + case osFlagsNoClear: rv = k_event_wait(&events->z_event, flags, false, event_timeout); - } - - if ((options & osFlagsNoClear) == 0) { - k_event_clear(&events->z_event, flags); + break; + case 0: + rv = k_event_wait_safe(&events->z_event, flags, false, event_timeout); + break; + default: + __ASSERT_NO_MSG(0); } if (rv != 0U) { diff --git a/tests/subsys/portability/cmsis_rtos_v2/src/event_flags.c b/tests/subsys/portability/cmsis_rtos_v2/src/event_flags.c index faa3b19bae414..a6e3e50ec38e5 100644 --- a/tests/subsys/portability/cmsis_rtos_v2/src/event_flags.c +++ b/tests/subsys/portability/cmsis_rtos_v2/src/event_flags.c @@ -32,16 +32,7 @@ static void thread2(void *arg) { int flags = osEventFlagsSet((osEventFlagsId_t)arg, FLAG2); - /* Please note that as soon as the last flag that a thread is waiting - * on is set, the control shifts to that thread and that thread may - * choose to clear the flags as part of its osEventFlagsWait operation. - * In this test case, the main thread is waiting for FLAG1 and FLAG2. - * FLAG1 gets set first and then FLAG2 gets set. As soon as FLAG2 gets - * set, control shifts to the waiting thread where osEventFlagsWait - * clears FLAG1 and FLAG2 internally. When this thread eventually gets - * scheduled we should hence check if FLAG2 is cleared. - */ - zassert_equal(flags & FLAG2, 0, ""); + zassert_equal(flags & FLAG2, FLAG2, ""); } static K_THREAD_STACK_DEFINE(test_stack1, STACKSZ);