Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | /* * Copyright (c) 2018 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include <ztest.h> #include <kernel.h> #include <cmsis_os2.h> #include <irq_offload.h> #include <kernel_structs.h> #define TIMEOUT_TICKS (100) #define FLAG1 (0x00000020) #define FLAG2 (0x00000004) #define FLAG (FLAG1 | FLAG2) #define ISR_FLAG 0x50 #define STACKSZ CONFIG_CMSIS_V2_THREAD_MAX_STACK_SIZE osEventFlagsId_t evt_id; static void thread1(void *arg) { int flags = osEventFlagsSet((osEventFlagsId_t)arg, FLAG1); zassert_equal(flags & FLAG1, FLAG1, ""); } 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, ""); } static K_THREAD_STACK_DEFINE(test_stack1, STACKSZ); static osThreadAttr_t thread1_attr = { .name = "Thread1", .stack_mem = &test_stack1, .stack_size = STACKSZ, .priority = osPriorityHigh, }; static K_THREAD_STACK_DEFINE(test_stack2, STACKSZ); static osThreadAttr_t thread2_attr = { .name = "Thread2", .stack_mem = &test_stack2, .stack_size = STACKSZ, .priority = osPriorityHigh, }; static osEventFlagsAttr_t event_flags_attrs = { .name = "MyEvent", .attr_bits = 0, .cb_mem = NULL, .cb_size = 0, }; void test_event_flags_no_wait_timeout(void) { osThreadId_t id1; u32_t flags; const char *name; osEventFlagsId_t dummy_id = NULL; evt_id = osEventFlagsNew(&event_flags_attrs); zassert_true(evt_id != NULL, "Failed creating event flags"); name = osEventFlagsGetName(dummy_id); zassert_true(name == NULL, "Invalid event Flags ID is unexpectedly working!"); name = osEventFlagsGetName(evt_id); zassert_true(strcmp(event_flags_attrs.name, name) == 0, "Error getting event_flags object name"); id1 = osThreadNew(thread1, evt_id, &thread1_attr); zassert_true(id1 != NULL, "Failed creating thread1"); /* Let id1 run to trigger FLAG1 */ osDelay(2); /* wait for FLAG1. It should return immediately as it is * already triggered. */ flags = osEventFlagsWait(evt_id, FLAG1, osFlagsWaitAny | osFlagsNoClear, 0); zassert_equal(flags & FLAG1, FLAG1, ""); /* Since the flags are not cleared automatically in the previous step, * we should be able to get the same flags upon query below. */ flags = osEventFlagsGet(evt_id); zassert_equal(flags & FLAG1, FLAG1, ""); flags = osEventFlagsGet(dummy_id); zassert_true(flags == 0U, "Invalid event Flags ID is unexpectedly working!"); /* Clear the Flag explicitly */ flags = osEventFlagsClear(evt_id, FLAG1); zassert_not_equal(flags, osFlagsErrorParameter, "Event clear failed"); /* wait for FLAG1. It should timeout here as the event * though triggered, gets cleared in the previous step. */ flags = osEventFlagsWait(evt_id, FLAG1, osFlagsWaitAny, TIMEOUT_TICKS); zassert_equal(flags, osFlagsErrorTimeout, "EventFlagsWait failed"); } void test_event_flags_signalled(void) { osThreadId_t id1, id2; u32_t flags; id1 = osThreadNew(thread1, evt_id, &thread1_attr); zassert_true(id1 != NULL, "Failed creating thread1"); id2 = osThreadNew(thread2, evt_id, &thread2_attr); zassert_true(id2 != NULL, "Failed creating thread2"); /* wait for multiple flags. The flags will be cleared automatically * upon being set since "osFlagsNoClear" is not opted for. */ flags = osEventFlagsWait(evt_id, FLAG, osFlagsWaitAll, TIMEOUT_TICKS); zassert_equal(flags & FLAG, FLAG, "osEventFlagsWait failed unexpectedly"); /* set any single flag */ flags = osEventFlagsSet(evt_id, FLAG1); zassert_equal(flags & FLAG1, FLAG1, "set any flag failed"); flags = osEventFlagsWait(evt_id, FLAG1, osFlagsWaitAny, TIMEOUT_TICKS); zassert_equal(flags & FLAG1, FLAG1, "osEventFlagsWait failed unexpectedly"); /* validate by passing invalid parameters */ zassert_equal(osEventFlagsSet(NULL, 0), osFlagsErrorParameter, "Invalid event Flags ID is unexpectedly working!"); zassert_equal(osEventFlagsSet(evt_id, 0x80010000), osFlagsErrorParameter, "Event with MSB set is set unexpectedly"); zassert_equal(osEventFlagsClear(NULL, 0), osFlagsErrorParameter, "Invalid event Flags ID is unexpectedly working!"); zassert_equal(osEventFlagsClear(evt_id, 0x80010000), osFlagsErrorParameter, "Event with MSB set is cleared unexpectedly"); /* cannot wait for Flag mask with MSB set */ zassert_equal(osEventFlagsWait(evt_id, 0x80010000, osFlagsWaitAny, 0), osFlagsErrorParameter, "EventFlagsWait passed unexpectedly"); } /* IRQ offload function handler to set event flag */ static void offload_function(void *param) { int flags; /* Make sure we're in IRQ context */ zassert_true(k_is_in_isr(), "Not in IRQ context!"); flags = osEventFlagsSet((osEventFlagsId_t)param, ISR_FLAG); zassert_equal(flags & ISR_FLAG, ISR_FLAG, "EventFlagsSet failed in ISR"); } void test_event_from_isr(void *event_id) { /**TESTPOINT: Offload to IRQ context*/ irq_offload(offload_function, (void *)event_id); } static K_THREAD_STACK_DEFINE(test_stack3, STACKSZ); static osThreadAttr_t thread3_attr = { .name = "Thread3", .stack_mem = &test_stack3, .stack_size = STACKSZ, .priority = osPriorityHigh, }; void test_event_flags_isr(void) { osThreadId_t id; int flags; osEventFlagsId_t dummy_id = NULL; id = osThreadNew(test_event_from_isr, evt_id, &thread3_attr); zassert_true(id != NULL, "Failed creating thread"); flags = osEventFlagsWait(dummy_id, ISR_FLAG, osFlagsWaitAll, TIMEOUT_TICKS); zassert_true(flags == osFlagsErrorParameter, "Invalid event Flags ID is unexpectedly working!"); flags = osEventFlagsWait(evt_id, ISR_FLAG, osFlagsWaitAll, TIMEOUT_TICKS); zassert_equal((flags & ISR_FLAG), ISR_FLAG, "unexpected event flags value"); zassert_true(osEventFlagsDelete(dummy_id) == osErrorResource, "Invalid event Flags ID is unexpectedly working!"); zassert_true(osEventFlagsDelete(evt_id) == osOK, "EventFlagsDelete failed"); } |