Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions subsys/portability/cmsis_rtos_v2/event_flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/**
Expand All @@ -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;
}
Expand All @@ -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;

Expand All @@ -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) {
Expand Down
11 changes: 1 addition & 10 deletions tests/subsys/portability/cmsis_rtos_v2/src/event_flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down