Rtos API example

Committer:
marcozecchini
Date:
Sat Feb 23 12:13:36 2019 +0000
Revision:
0:9fca2b23d0ba
final commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
marcozecchini 0:9fca2b23d0ba 1 /* mbed Microcontroller Library
marcozecchini 0:9fca2b23d0ba 2 * Copyright (c) 2017 ARM Limited
marcozecchini 0:9fca2b23d0ba 3 *
marcozecchini 0:9fca2b23d0ba 4 * Licensed under the Apache License, Version 2.0 (the "License");
marcozecchini 0:9fca2b23d0ba 5 * you may not use this file except in compliance with the License.
marcozecchini 0:9fca2b23d0ba 6 * You may obtain a copy of the License at
marcozecchini 0:9fca2b23d0ba 7 *
marcozecchini 0:9fca2b23d0ba 8 * http://www.apache.org/licenses/LICENSE-2.0
marcozecchini 0:9fca2b23d0ba 9 *
marcozecchini 0:9fca2b23d0ba 10 * Unless required by applicable law or agreed to in writing, software
marcozecchini 0:9fca2b23d0ba 11 * distributed under the License is distributed on an "AS IS" BASIS,
marcozecchini 0:9fca2b23d0ba 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
marcozecchini 0:9fca2b23d0ba 13 * See the License for the specific language governing permissions and
marcozecchini 0:9fca2b23d0ba 14 * limitations under the License.
marcozecchini 0:9fca2b23d0ba 15 */
marcozecchini 0:9fca2b23d0ba 16 #include "mbed.h"
marcozecchini 0:9fca2b23d0ba 17 #include "greentea-client/test_env.h"
marcozecchini 0:9fca2b23d0ba 18 #include "utest/utest.h"
marcozecchini 0:9fca2b23d0ba 19 #include "unity/unity.h"
marcozecchini 0:9fca2b23d0ba 20
marcozecchini 0:9fca2b23d0ba 21 using utest::v1::Case;
marcozecchini 0:9fca2b23d0ba 22
marcozecchini 0:9fca2b23d0ba 23
marcozecchini 0:9fca2b23d0ba 24 #if defined(MBED_RTOS_SINGLE_THREAD)
marcozecchini 0:9fca2b23d0ba 25 #error [NOT_SUPPORTED] test not supported
marcozecchini 0:9fca2b23d0ba 26 #endif
marcozecchini 0:9fca2b23d0ba 27
marcozecchini 0:9fca2b23d0ba 28 #define TEST_STACK_SIZE 512
marcozecchini 0:9fca2b23d0ba 29 #define MAX_FLAG_POS 30
marcozecchini 0:9fca2b23d0ba 30
marcozecchini 0:9fca2b23d0ba 31 #define ALL_SIGNALS 0x7fffffff
marcozecchini 0:9fca2b23d0ba 32 #define NO_SIGNALS 0x0
marcozecchini 0:9fca2b23d0ba 33 #define PROHIBITED_SIGNAL 0x80000000
marcozecchini 0:9fca2b23d0ba 34 #define SIGNAL1 0x1
marcozecchini 0:9fca2b23d0ba 35 #define SIGNAL2 0x2
marcozecchini 0:9fca2b23d0ba 36 #define SIGNAL3 0x4
marcozecchini 0:9fca2b23d0ba 37
marcozecchini 0:9fca2b23d0ba 38 struct Sync {
marcozecchini 0:9fca2b23d0ba 39 Sync(Semaphore &parent, Semaphore &child): sem_parent(parent), sem_child(child)
marcozecchini 0:9fca2b23d0ba 40 {}
marcozecchini 0:9fca2b23d0ba 41
marcozecchini 0:9fca2b23d0ba 42 Semaphore &sem_parent;
marcozecchini 0:9fca2b23d0ba 43 Semaphore &sem_child;
marcozecchini 0:9fca2b23d0ba 44 };
marcozecchini 0:9fca2b23d0ba 45
marcozecchini 0:9fca2b23d0ba 46
marcozecchini 0:9fca2b23d0ba 47 /* In order to successfully run this test suite when compiled with --profile=debug
marcozecchini 0:9fca2b23d0ba 48 * error() has to be redefined as noop.
marcozecchini 0:9fca2b23d0ba 49 *
marcozecchini 0:9fca2b23d0ba 50 * ThreadFlags calls RTX API which uses Event Recorder functionality. When compiled
marcozecchini 0:9fca2b23d0ba 51 * with MBED_TRAP_ERRORS_ENABLED=1 (set in debug profile) EvrRtxEventFlagsError() calls error()
marcozecchini 0:9fca2b23d0ba 52 * which aborts test program.
marcozecchini 0:9fca2b23d0ba 53 */
marcozecchini 0:9fca2b23d0ba 54 #if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED
marcozecchini 0:9fca2b23d0ba 55 void error(const char* format, ...) {
marcozecchini 0:9fca2b23d0ba 56 (void) format;
marcozecchini 0:9fca2b23d0ba 57 }
marcozecchini 0:9fca2b23d0ba 58 #endif
marcozecchini 0:9fca2b23d0ba 59
marcozecchini 0:9fca2b23d0ba 60
marcozecchini 0:9fca2b23d0ba 61 template <int32_t signals, uint32_t timeout, int32_t test_val>
marcozecchini 0:9fca2b23d0ba 62 void run_signal_wait(void)
marcozecchini 0:9fca2b23d0ba 63 {
marcozecchini 0:9fca2b23d0ba 64 osEvent ev = Thread::signal_wait(signals, timeout);
marcozecchini 0:9fca2b23d0ba 65 TEST_ASSERT_EQUAL(test_val, ev.status);
marcozecchini 0:9fca2b23d0ba 66 }
marcozecchini 0:9fca2b23d0ba 67
marcozecchini 0:9fca2b23d0ba 68 template <int32_t signals, uint32_t timeout, int32_t test_val>
marcozecchini 0:9fca2b23d0ba 69 void run_release_signal_wait(Semaphore *sem)
marcozecchini 0:9fca2b23d0ba 70 {
marcozecchini 0:9fca2b23d0ba 71 sem->release();
marcozecchini 0:9fca2b23d0ba 72 osEvent ev = Thread::signal_wait(signals, timeout);
marcozecchini 0:9fca2b23d0ba 73 TEST_ASSERT_EQUAL(test_val, ev.status);
marcozecchini 0:9fca2b23d0ba 74 }
marcozecchini 0:9fca2b23d0ba 75
marcozecchini 0:9fca2b23d0ba 76 template <int32_t signals, uint32_t timeout, int32_t test_val>
marcozecchini 0:9fca2b23d0ba 77 void run_release_wait_signal_wait(Sync *sync)
marcozecchini 0:9fca2b23d0ba 78 {
marcozecchini 0:9fca2b23d0ba 79 sync->sem_parent.release();
marcozecchini 0:9fca2b23d0ba 80 sync->sem_child.wait();
marcozecchini 0:9fca2b23d0ba 81 osEvent ev = Thread::signal_wait(signals, timeout);
marcozecchini 0:9fca2b23d0ba 82 TEST_ASSERT_EQUAL(test_val, ev.status);
marcozecchini 0:9fca2b23d0ba 83 }
marcozecchini 0:9fca2b23d0ba 84
marcozecchini 0:9fca2b23d0ba 85 template <int32_t signals, int32_t test_val>
marcozecchini 0:9fca2b23d0ba 86 void run_clear(void)
marcozecchini 0:9fca2b23d0ba 87 {
marcozecchini 0:9fca2b23d0ba 88 int32_t ret = Thread::signal_clr(signals);
marcozecchini 0:9fca2b23d0ba 89 TEST_ASSERT_EQUAL(test_val, ret);
marcozecchini 0:9fca2b23d0ba 90 }
marcozecchini 0:9fca2b23d0ba 91
marcozecchini 0:9fca2b23d0ba 92 template <int32_t signals, int32_t test_val>
marcozecchini 0:9fca2b23d0ba 93 void run_wait_clear(Sync *sync)
marcozecchini 0:9fca2b23d0ba 94 {
marcozecchini 0:9fca2b23d0ba 95 sync->sem_parent.release();
marcozecchini 0:9fca2b23d0ba 96 sync->sem_child.wait();
marcozecchini 0:9fca2b23d0ba 97 int32_t ret = Thread::signal_clr(signals);
marcozecchini 0:9fca2b23d0ba 98 TEST_ASSERT_EQUAL(test_val, ret);
marcozecchini 0:9fca2b23d0ba 99 }
marcozecchini 0:9fca2b23d0ba 100
marcozecchini 0:9fca2b23d0ba 101 template <int32_t signals1, int32_t signals2, int32_t test_val1, int32_t test_val2>
marcozecchini 0:9fca2b23d0ba 102 void run_double_wait_clear(Sync *sync)
marcozecchini 0:9fca2b23d0ba 103 {
marcozecchini 0:9fca2b23d0ba 104 int32_t ret;
marcozecchini 0:9fca2b23d0ba 105
marcozecchini 0:9fca2b23d0ba 106 sync->sem_parent.release();
marcozecchini 0:9fca2b23d0ba 107 sync->sem_child.wait();
marcozecchini 0:9fca2b23d0ba 108 ret = Thread::signal_clr(signals1);
marcozecchini 0:9fca2b23d0ba 109 TEST_ASSERT_EQUAL(test_val1, ret);
marcozecchini 0:9fca2b23d0ba 110
marcozecchini 0:9fca2b23d0ba 111 ret = Thread::signal_clr(signals2);
marcozecchini 0:9fca2b23d0ba 112 TEST_ASSERT_EQUAL(test_val2, ret);
marcozecchini 0:9fca2b23d0ba 113 }
marcozecchini 0:9fca2b23d0ba 114
marcozecchini 0:9fca2b23d0ba 115 void run_loop_wait_clear(Sync *sync)
marcozecchini 0:9fca2b23d0ba 116 {
marcozecchini 0:9fca2b23d0ba 117 int32_t signals = NO_SIGNALS;
marcozecchini 0:9fca2b23d0ba 118 for (int i = 0; i <= MAX_FLAG_POS; i++) {
marcozecchini 0:9fca2b23d0ba 119 int32_t signal = 1 << i;
marcozecchini 0:9fca2b23d0ba 120 signals |= signal;
marcozecchini 0:9fca2b23d0ba 121 sync->sem_child.wait();
marcozecchini 0:9fca2b23d0ba 122 int32_t ret = Thread::signal_clr(NO_SIGNALS);
marcozecchini 0:9fca2b23d0ba 123 TEST_ASSERT_EQUAL(signals, ret);
marcozecchini 0:9fca2b23d0ba 124 sync->sem_parent.release();
marcozecchini 0:9fca2b23d0ba 125 }
marcozecchini 0:9fca2b23d0ba 126 }
marcozecchini 0:9fca2b23d0ba 127
marcozecchini 0:9fca2b23d0ba 128
marcozecchini 0:9fca2b23d0ba 129 /** Validate that call signal_clr(NO_SIGNALS) doesn't change thread signals and return actual signals
marcozecchini 0:9fca2b23d0ba 130
marcozecchini 0:9fca2b23d0ba 131 Given two threads A & B are started, B with all signals already set
marcozecchini 0:9fca2b23d0ba 132 When thread B calls @a signal_clr(NO_SIGNALS)
marcozecchini 0:9fca2b23d0ba 133 Then thread B @a signal_clr status should be ALL_SIGNALS indicating that thread B state is unchanged
marcozecchini 0:9fca2b23d0ba 134 */
marcozecchini 0:9fca2b23d0ba 135 void test_clear_no_signals(void)
marcozecchini 0:9fca2b23d0ba 136 {
marcozecchini 0:9fca2b23d0ba 137 Semaphore sem_parent(0, 1);
marcozecchini 0:9fca2b23d0ba 138 Semaphore sem_child(0, 1);
marcozecchini 0:9fca2b23d0ba 139 Sync sync(sem_parent, sem_child);
marcozecchini 0:9fca2b23d0ba 140
marcozecchini 0:9fca2b23d0ba 141 Thread t(osPriorityNormal, TEST_STACK_SIZE);
marcozecchini 0:9fca2b23d0ba 142 t.start(callback(run_double_wait_clear<NO_SIGNALS, NO_SIGNALS, ALL_SIGNALS, ALL_SIGNALS>, &sync));
marcozecchini 0:9fca2b23d0ba 143 sem_parent.wait();
marcozecchini 0:9fca2b23d0ba 144 t.signal_set(ALL_SIGNALS);
marcozecchini 0:9fca2b23d0ba 145 sem_child.release();
marcozecchini 0:9fca2b23d0ba 146 t.join();
marcozecchini 0:9fca2b23d0ba 147 }
marcozecchini 0:9fca2b23d0ba 148
marcozecchini 0:9fca2b23d0ba 149 /** Validate if any signals are set on just created thread
marcozecchini 0:9fca2b23d0ba 150
marcozecchini 0:9fca2b23d0ba 151 Given the thread is running
marcozecchini 0:9fca2b23d0ba 152 When thread execute @a signal_clr(NO_SIGNALS)
marcozecchini 0:9fca2b23d0ba 153 Then thread @a signal_clr return status should be NO_SIGNALS(0) indicating no signals set
marcozecchini 0:9fca2b23d0ba 154 */
marcozecchini 0:9fca2b23d0ba 155 void test_init_state(void)
marcozecchini 0:9fca2b23d0ba 156 {
marcozecchini 0:9fca2b23d0ba 157 Thread t(osPriorityNormal, TEST_STACK_SIZE);
marcozecchini 0:9fca2b23d0ba 158 t.start(callback(run_clear<NO_SIGNALS, NO_SIGNALS>));
marcozecchini 0:9fca2b23d0ba 159 t.join();
marcozecchini 0:9fca2b23d0ba 160 }
marcozecchini 0:9fca2b23d0ba 161
marcozecchini 0:9fca2b23d0ba 162 /** Validate all signals set in one shot
marcozecchini 0:9fca2b23d0ba 163
marcozecchini 0:9fca2b23d0ba 164 Given two threads A & B are started
marcozecchini 0:9fca2b23d0ba 165 When thread A call @a signal_set(ALL_SIGNALS) with all possible signals
marcozecchini 0:9fca2b23d0ba 166 Then thread B @a signal_clr(NO_SIGNALS) status should be ALL_SIGNALS indicating all signals set correctly
marcozecchini 0:9fca2b23d0ba 167 */
marcozecchini 0:9fca2b23d0ba 168 void test_set_all(void)
marcozecchini 0:9fca2b23d0ba 169 {
marcozecchini 0:9fca2b23d0ba 170 int32_t ret;
marcozecchini 0:9fca2b23d0ba 171 Semaphore sem_parent(0, 1);
marcozecchini 0:9fca2b23d0ba 172 Semaphore sem_child(0, 1);
marcozecchini 0:9fca2b23d0ba 173 Sync sync(sem_parent, sem_child);
marcozecchini 0:9fca2b23d0ba 174
marcozecchini 0:9fca2b23d0ba 175 Thread t(osPriorityNormal, TEST_STACK_SIZE);
marcozecchini 0:9fca2b23d0ba 176 t.start(callback(run_wait_clear<NO_SIGNALS, ALL_SIGNALS>, &sync));
marcozecchini 0:9fca2b23d0ba 177
marcozecchini 0:9fca2b23d0ba 178 sem_parent.wait();
marcozecchini 0:9fca2b23d0ba 179 ret = t.signal_set(ALL_SIGNALS);
marcozecchini 0:9fca2b23d0ba 180 TEST_ASSERT_EQUAL(ALL_SIGNALS, ret);
marcozecchini 0:9fca2b23d0ba 181
marcozecchini 0:9fca2b23d0ba 182 sem_child.release();
marcozecchini 0:9fca2b23d0ba 183 t.join();
marcozecchini 0:9fca2b23d0ba 184 }
marcozecchini 0:9fca2b23d0ba 185
marcozecchini 0:9fca2b23d0ba 186 /** Validate that call signal_set with prohibited signal doesn't change thread signals
marcozecchini 0:9fca2b23d0ba 187
marcozecchini 0:9fca2b23d0ba 188 Given two threads A & B are started, B with all signals set
marcozecchini 0:9fca2b23d0ba 189 When thread A executes @a signal_set(PROHIBITED_SIGNAL) with prohibited signal
marcozecchini 0:9fca2b23d0ba 190 Then thread B @a signal_clr(NO_SIGNALS) status should be ALL_SIGNALS indicating that thread B signals are unchanged
marcozecchini 0:9fca2b23d0ba 191
marcozecchini 0:9fca2b23d0ba 192 @note Each signal has up to 31 event flags 0x1, 0x2, 0x4, 0x8, ..., 0x40000000
marcozecchini 0:9fca2b23d0ba 193 Most significant bit is reserved and thereby flag 0x80000000 is prohibited
marcozecchini 0:9fca2b23d0ba 194 */
marcozecchini 0:9fca2b23d0ba 195 void test_set_prohibited(void)
marcozecchini 0:9fca2b23d0ba 196 {
marcozecchini 0:9fca2b23d0ba 197 int32_t ret;
marcozecchini 0:9fca2b23d0ba 198 Semaphore sem_parent(0, 1);
marcozecchini 0:9fca2b23d0ba 199 Semaphore sem_child(0, 1);
marcozecchini 0:9fca2b23d0ba 200 Sync sync(sem_parent, sem_child);
marcozecchini 0:9fca2b23d0ba 201
marcozecchini 0:9fca2b23d0ba 202 Thread t(osPriorityNormal, TEST_STACK_SIZE);
marcozecchini 0:9fca2b23d0ba 203 t.start(callback(run_wait_clear<NO_SIGNALS, ALL_SIGNALS>, &sync));
marcozecchini 0:9fca2b23d0ba 204
marcozecchini 0:9fca2b23d0ba 205 sem_parent.wait();
marcozecchini 0:9fca2b23d0ba 206 t.signal_set(ALL_SIGNALS);
marcozecchini 0:9fca2b23d0ba 207
marcozecchini 0:9fca2b23d0ba 208 ret = t.signal_set(PROHIBITED_SIGNAL);
marcozecchini 0:9fca2b23d0ba 209 TEST_ASSERT_EQUAL(osErrorParameter, ret);
marcozecchini 0:9fca2b23d0ba 210
marcozecchini 0:9fca2b23d0ba 211 sem_child.release();
marcozecchini 0:9fca2b23d0ba 212 t.join();
marcozecchini 0:9fca2b23d0ba 213 }
marcozecchini 0:9fca2b23d0ba 214
marcozecchini 0:9fca2b23d0ba 215 /** Validate all signals clear in one shot
marcozecchini 0:9fca2b23d0ba 216
marcozecchini 0:9fca2b23d0ba 217 Given two threads A & B are started, B with all signals set
marcozecchini 0:9fca2b23d0ba 218 When thread B execute @a signal_clr(ALL_SIGNALS) with all possible signals
marcozecchini 0:9fca2b23d0ba 219 Then thread B @a signal_clr(NO_SIGNALS) status should be NO_SIGNALS(0) indicating all signals cleared correctly
marcozecchini 0:9fca2b23d0ba 220 */
marcozecchini 0:9fca2b23d0ba 221 void test_clear_all(void)
marcozecchini 0:9fca2b23d0ba 222 {
marcozecchini 0:9fca2b23d0ba 223 Semaphore sem_parent(0, 1);
marcozecchini 0:9fca2b23d0ba 224 Semaphore sem_child(0, 1);
marcozecchini 0:9fca2b23d0ba 225 Sync sync(sem_parent, sem_child);
marcozecchini 0:9fca2b23d0ba 226
marcozecchini 0:9fca2b23d0ba 227 Thread t(osPriorityNormal, TEST_STACK_SIZE);
marcozecchini 0:9fca2b23d0ba 228 t.start(callback(run_double_wait_clear<ALL_SIGNALS, NO_SIGNALS, ALL_SIGNALS, NO_SIGNALS>, &sync));
marcozecchini 0:9fca2b23d0ba 229 sem_parent.wait();
marcozecchini 0:9fca2b23d0ba 230 t.signal_set(ALL_SIGNALS);
marcozecchini 0:9fca2b23d0ba 231 sem_child.release();
marcozecchini 0:9fca2b23d0ba 232 t.join();
marcozecchini 0:9fca2b23d0ba 233 }
marcozecchini 0:9fca2b23d0ba 234
marcozecchini 0:9fca2b23d0ba 235 /** Validate all signals set one by one in loop
marcozecchini 0:9fca2b23d0ba 236
marcozecchini 0:9fca2b23d0ba 237 Given two threads A & B are started
marcozecchini 0:9fca2b23d0ba 238 When thread A executes @a signal_set(signal) in loop with all possible signals
marcozecchini 0:9fca2b23d0ba 239 */
marcozecchini 0:9fca2b23d0ba 240 void test_set_all_loop(void)
marcozecchini 0:9fca2b23d0ba 241 {
marcozecchini 0:9fca2b23d0ba 242 int32_t ret;
marcozecchini 0:9fca2b23d0ba 243 Semaphore sem_parent(0, 1);
marcozecchini 0:9fca2b23d0ba 244 Semaphore sem_child(0, 1);
marcozecchini 0:9fca2b23d0ba 245 Sync sync(sem_parent, sem_child);
marcozecchini 0:9fca2b23d0ba 246
marcozecchini 0:9fca2b23d0ba 247 Thread t(osPriorityNormal, TEST_STACK_SIZE);
marcozecchini 0:9fca2b23d0ba 248 t.start(callback(run_loop_wait_clear, &sync));
marcozecchini 0:9fca2b23d0ba 249
marcozecchini 0:9fca2b23d0ba 250 int32_t signals = 0;
marcozecchini 0:9fca2b23d0ba 251 for (int i = 0; i <= MAX_FLAG_POS; i++) {
marcozecchini 0:9fca2b23d0ba 252 int32_t signal = 1 << i;
marcozecchini 0:9fca2b23d0ba 253
marcozecchini 0:9fca2b23d0ba 254 ret = t.signal_set(signal);
marcozecchini 0:9fca2b23d0ba 255 signals |= signal;
marcozecchini 0:9fca2b23d0ba 256 TEST_ASSERT_EQUAL(signals, ret);
marcozecchini 0:9fca2b23d0ba 257 sem_child.release();
marcozecchini 0:9fca2b23d0ba 258 sem_parent.wait();
marcozecchini 0:9fca2b23d0ba 259 }
marcozecchini 0:9fca2b23d0ba 260 t.join();
marcozecchini 0:9fca2b23d0ba 261 }
marcozecchini 0:9fca2b23d0ba 262
marcozecchini 0:9fca2b23d0ba 263 /** Validate signal_wait return status if timeout specified
marcozecchini 0:9fca2b23d0ba 264
marcozecchini 0:9fca2b23d0ba 265 Given the thread is running
marcozecchini 0:9fca2b23d0ba 266 When thread executes @a signal_wait(signals, timeout) with specified signals and timeout
marcozecchini 0:9fca2b23d0ba 267 Then thread @a signal_wait status should be osEventTimeout indicating a timeout
marcozecchini 0:9fca2b23d0ba 268 thread @a signal_wait status should be osOK indicating 0[ms] timeout set
marcozecchini 0:9fca2b23d0ba 269 */
marcozecchini 0:9fca2b23d0ba 270 template <int32_t signals, uint32_t timeout, int32_t status>
marcozecchini 0:9fca2b23d0ba 271 void test_wait_timeout(void)
marcozecchini 0:9fca2b23d0ba 272 {
marcozecchini 0:9fca2b23d0ba 273 Thread t(osPriorityNormal, TEST_STACK_SIZE);
marcozecchini 0:9fca2b23d0ba 274 t.start(callback(run_signal_wait<signals, timeout, status>));
marcozecchini 0:9fca2b23d0ba 275 t.join();
marcozecchini 0:9fca2b23d0ba 276 }
marcozecchini 0:9fca2b23d0ba 277
marcozecchini 0:9fca2b23d0ba 278 /** Validate that call of signal_wait return correctly when thread has all signals already set
marcozecchini 0:9fca2b23d0ba 279
marcozecchini 0:9fca2b23d0ba 280 Given two threads A & B are started, B with all signals already set
marcozecchini 0:9fca2b23d0ba 281 When thread B executes @a signal_wait(ALL_SIGNALS, osWaitForever),
marcozecchini 0:9fca2b23d0ba 282 Then thread B @a signal_wait return immediately with status osEventSignal indicating all wait signals was already set
marcozecchini 0:9fca2b23d0ba 283 */
marcozecchini 0:9fca2b23d0ba 284 void test_wait_all_already_set(void)
marcozecchini 0:9fca2b23d0ba 285 {
marcozecchini 0:9fca2b23d0ba 286 Semaphore sem_parent(0, 1);
marcozecchini 0:9fca2b23d0ba 287 Semaphore sem_child(0, 1);
marcozecchini 0:9fca2b23d0ba 288 Sync sync(sem_parent, sem_child);
marcozecchini 0:9fca2b23d0ba 289
marcozecchini 0:9fca2b23d0ba 290 Thread t(osPriorityNormal, TEST_STACK_SIZE);
marcozecchini 0:9fca2b23d0ba 291 t.start(callback(run_release_wait_signal_wait<ALL_SIGNALS, osWaitForever, osEventSignal>, &sync));
marcozecchini 0:9fca2b23d0ba 292
marcozecchini 0:9fca2b23d0ba 293 sem_parent.wait();
marcozecchini 0:9fca2b23d0ba 294 TEST_ASSERT_EQUAL(Thread::WaitingSemaphore, t.get_state());
marcozecchini 0:9fca2b23d0ba 295 t.signal_set(ALL_SIGNALS);
marcozecchini 0:9fca2b23d0ba 296 sem_child.release();
marcozecchini 0:9fca2b23d0ba 297 t.join();
marcozecchini 0:9fca2b23d0ba 298 }
marcozecchini 0:9fca2b23d0ba 299
marcozecchini 0:9fca2b23d0ba 300 /** Validate if signal_wait return correctly when all signals set
marcozecchini 0:9fca2b23d0ba 301
marcozecchini 0:9fca2b23d0ba 302 Given two threads A & B are started and B waiting for a thread flag to be set
marcozecchini 0:9fca2b23d0ba 303 When thread A executes @a signal_set(ALL_SIGNALS) with all possible signals
marcozecchini 0:9fca2b23d0ba 304 Then thread B @a signal_wait status is osEventSignal indicating all wait signals was set
marcozecchini 0:9fca2b23d0ba 305 */
marcozecchini 0:9fca2b23d0ba 306 void test_wait_all(void)
marcozecchini 0:9fca2b23d0ba 307 {
marcozecchini 0:9fca2b23d0ba 308 Semaphore sem(0, 1);
marcozecchini 0:9fca2b23d0ba 309
marcozecchini 0:9fca2b23d0ba 310 Thread t(osPriorityNormal, TEST_STACK_SIZE);
marcozecchini 0:9fca2b23d0ba 311 t.start(callback(run_release_signal_wait<ALL_SIGNALS, osWaitForever, osEventSignal>, &sem));
marcozecchini 0:9fca2b23d0ba 312
marcozecchini 0:9fca2b23d0ba 313 sem.wait();
marcozecchini 0:9fca2b23d0ba 314 TEST_ASSERT_EQUAL(Thread::WaitingThreadFlag, t.get_state());
marcozecchini 0:9fca2b23d0ba 315
marcozecchini 0:9fca2b23d0ba 316 t.signal_set(ALL_SIGNALS);
marcozecchini 0:9fca2b23d0ba 317 t.join();
marcozecchini 0:9fca2b23d0ba 318 }
marcozecchini 0:9fca2b23d0ba 319
marcozecchini 0:9fca2b23d0ba 320 /** Validate if signal_wait accumulate signals and return correctly when all signals set
marcozecchini 0:9fca2b23d0ba 321
marcozecchini 0:9fca2b23d0ba 322 Given two threads A & B are started and B waiting for a thread signals to be set
marcozecchini 0:9fca2b23d0ba 323 When thread A executes @a signal_set setting all signals in loop
marcozecchini 0:9fca2b23d0ba 324 Then thread B @a signal_wait status is osEventSignal indicating that all wait signals was set
marcozecchini 0:9fca2b23d0ba 325 */
marcozecchini 0:9fca2b23d0ba 326 void test_wait_all_loop(void)
marcozecchini 0:9fca2b23d0ba 327 {
marcozecchini 0:9fca2b23d0ba 328 int32_t ret;
marcozecchini 0:9fca2b23d0ba 329 Semaphore sem(0, 1);
marcozecchini 0:9fca2b23d0ba 330
marcozecchini 0:9fca2b23d0ba 331 Thread t(osPriorityNormal, TEST_STACK_SIZE);
marcozecchini 0:9fca2b23d0ba 332 t.start(callback(run_release_signal_wait<ALL_SIGNALS, osWaitForever, osEventSignal>, &sem));
marcozecchini 0:9fca2b23d0ba 333
marcozecchini 0:9fca2b23d0ba 334 sem.wait();
marcozecchini 0:9fca2b23d0ba 335 TEST_ASSERT_EQUAL(Thread::WaitingThreadFlag, t.get_state());
marcozecchini 0:9fca2b23d0ba 336
marcozecchini 0:9fca2b23d0ba 337 for (int i = 0; i < MAX_FLAG_POS; i++) {
marcozecchini 0:9fca2b23d0ba 338 int32_t signal = 1 << i;
marcozecchini 0:9fca2b23d0ba 339 ret = t.signal_set(signal);
marcozecchini 0:9fca2b23d0ba 340 }
marcozecchini 0:9fca2b23d0ba 341 ret = t.signal_set(1 << MAX_FLAG_POS);
marcozecchini 0:9fca2b23d0ba 342 TEST_ASSERT_EQUAL(NO_SIGNALS, ret);
marcozecchini 0:9fca2b23d0ba 343 t.join();
marcozecchini 0:9fca2b23d0ba 344 }
marcozecchini 0:9fca2b23d0ba 345
marcozecchini 0:9fca2b23d0ba 346 /** Validate if setting same signal twice cause any unwanted behaviour
marcozecchini 0:9fca2b23d0ba 347
marcozecchini 0:9fca2b23d0ba 348 Given two threads A & B are started and B waiting for a thread signals to be set
marcozecchini 0:9fca2b23d0ba 349 When thread A executes @a signal_set twice for the same signal
marcozecchini 0:9fca2b23d0ba 350 Then thread A @a signal_set status is current signal set
marcozecchini 0:9fca2b23d0ba 351 thread B @a signal_wait status is osEventSignal indicating that all wait signals was set
marcozecchini 0:9fca2b23d0ba 352 */
marcozecchini 0:9fca2b23d0ba 353 void test_set_double(void)
marcozecchini 0:9fca2b23d0ba 354 {
marcozecchini 0:9fca2b23d0ba 355 int32_t ret;
marcozecchini 0:9fca2b23d0ba 356 Semaphore sem(0, 1);
marcozecchini 0:9fca2b23d0ba 357
marcozecchini 0:9fca2b23d0ba 358 Thread t(osPriorityNormal, TEST_STACK_SIZE);
marcozecchini 0:9fca2b23d0ba 359 t.start(callback(run_release_signal_wait<SIGNAL1|SIGNAL2|SIGNAL3, osWaitForever, osEventSignal>, &sem));
marcozecchini 0:9fca2b23d0ba 360
marcozecchini 0:9fca2b23d0ba 361 sem.wait();
marcozecchini 0:9fca2b23d0ba 362 TEST_ASSERT_EQUAL(Thread::WaitingThreadFlag, t.get_state());
marcozecchini 0:9fca2b23d0ba 363
marcozecchini 0:9fca2b23d0ba 364 ret = t.signal_set(SIGNAL1);
marcozecchini 0:9fca2b23d0ba 365 TEST_ASSERT_EQUAL(SIGNAL1, ret);
marcozecchini 0:9fca2b23d0ba 366
marcozecchini 0:9fca2b23d0ba 367 ret = t.signal_set(SIGNAL2);
marcozecchini 0:9fca2b23d0ba 368 TEST_ASSERT_EQUAL(SIGNAL1 | SIGNAL2, ret);
marcozecchini 0:9fca2b23d0ba 369
marcozecchini 0:9fca2b23d0ba 370 ret = t.signal_set(SIGNAL2);
marcozecchini 0:9fca2b23d0ba 371 TEST_ASSERT_EQUAL(SIGNAL1 | SIGNAL2, ret);
marcozecchini 0:9fca2b23d0ba 372 TEST_ASSERT_EQUAL(Thread::WaitingThreadFlag, t.get_state());
marcozecchini 0:9fca2b23d0ba 373
marcozecchini 0:9fca2b23d0ba 374 ret = t.signal_set(SIGNAL3);
marcozecchini 0:9fca2b23d0ba 375 TEST_ASSERT_EQUAL(NO_SIGNALS, ret);
marcozecchini 0:9fca2b23d0ba 376 t.join();
marcozecchini 0:9fca2b23d0ba 377 }
marcozecchini 0:9fca2b23d0ba 378
marcozecchini 0:9fca2b23d0ba 379
marcozecchini 0:9fca2b23d0ba 380 utest::v1::status_t test_setup(const size_t number_of_cases)
marcozecchini 0:9fca2b23d0ba 381 {
marcozecchini 0:9fca2b23d0ba 382 GREENTEA_SETUP(10, "default_auto");
marcozecchini 0:9fca2b23d0ba 383 return utest::v1::verbose_test_setup_handler(number_of_cases);
marcozecchini 0:9fca2b23d0ba 384 }
marcozecchini 0:9fca2b23d0ba 385
marcozecchini 0:9fca2b23d0ba 386 Case cases[] = {
marcozecchini 0:9fca2b23d0ba 387 Case("Validate that call signal_clr(NO_SIGNALS) doesn't change thread signals and return actual signals", test_clear_no_signals),
marcozecchini 0:9fca2b23d0ba 388 Case("Validate if any signals are set on just created thread", test_init_state),
marcozecchini 0:9fca2b23d0ba 389 Case("Validate all signals set in one shot", test_set_all),
marcozecchini 0:9fca2b23d0ba 390 Case("Validate that call signal_set with prohibited signal doesn't change thread signals", test_set_prohibited),
marcozecchini 0:9fca2b23d0ba 391 Case("Validate all signals clear in one shot", test_clear_all),
marcozecchini 0:9fca2b23d0ba 392 Case("Validate all signals set one by one in loop", test_set_all_loop),
marcozecchini 0:9fca2b23d0ba 393 Case("Validate signal_wait return status if timeout specified: 0[ms] no signals", test_wait_timeout<0, 0, osOK>),
marcozecchini 0:9fca2b23d0ba 394 Case("Validate signal_wait return status if timeout specified: 0[ms] all signals", test_wait_timeout<ALL_SIGNALS, 0, osOK>),
marcozecchini 0:9fca2b23d0ba 395 Case("Validate signal_wait return status if timeout specified: 1[ms] no signals", test_wait_timeout<0, 1, osEventTimeout>),
marcozecchini 0:9fca2b23d0ba 396 Case("Validate signal_wait return status if timeout specified: 1[ms] all signals", test_wait_timeout<ALL_SIGNALS, 1, osEventTimeout>),
marcozecchini 0:9fca2b23d0ba 397 Case("Validate that call of signal_wait return correctly when thread has all signals already set", test_wait_all_already_set),
marcozecchini 0:9fca2b23d0ba 398 Case("Validate if signal_wait return correctly when all signals set", test_wait_all),
marcozecchini 0:9fca2b23d0ba 399 Case("Validate if signal_wait accumulate signals and return correctly when all signals set", test_wait_all_loop),
marcozecchini 0:9fca2b23d0ba 400 Case("Validate if setting same signal twice cause any unwanted behaviour", test_set_double)
marcozecchini 0:9fca2b23d0ba 401 };
marcozecchini 0:9fca2b23d0ba 402
marcozecchini 0:9fca2b23d0ba 403 utest::v1::Specification specification(test_setup, cases);
marcozecchini 0:9fca2b23d0ba 404
marcozecchini 0:9fca2b23d0ba 405 int main()
marcozecchini 0:9fca2b23d0ba 406 {
marcozecchini 0:9fca2b23d0ba 407 return !utest::v1::Harness::run(specification);
marcozecchini 0:9fca2b23d0ba 408 }