Skip to content

Commit bce720d

Browse files
authored
Merge pull request #3786 from bulislaw/feature_rework_rtos_tests
Rework RTOS mutex tests
2 parents 6f6e5c4 + 9377fa9 commit bce720d

File tree

1 file changed

+171
-49
lines changed

1 file changed

+171
-49
lines changed
Lines changed: 171 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,31 @@
11
#include "mbed.h"
22
#include "greentea-client/test_env.h"
3+
#include "unity.h"
4+
#include "utest.h"
35
#include "rtos.h"
46

57
#if defined(MBED_RTOS_SINGLE_THREAD)
68
#error [NOT_SUPPORTED] test not supported
79
#endif
810

9-
#define THREAD_DELAY 50
10-
#define SIGNALS_TO_EMIT 100
11+
using namespace utest::v1;
1112

1213
/*
1314
* The stack size is defined in cmsis_os.h mainly dependent on the underlying toolchain and
1415
* the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes
1516
* and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize.
1617
*/
17-
#if defined(TARGET_STM32F334R8) && defined(TOOLCHAIN_IAR)
18-
#define STACK_SIZE DEFAULT_STACK_SIZE/4
19-
#elif defined(TARGET_STM32F070RB)
20-
#define STACK_SIZE DEFAULT_STACK_SIZE/2
21-
#elif defined(TARGET_STM32F072RB)
22-
#define STACK_SIZE DEFAULT_STACK_SIZE/2
23-
#elif defined(TARGET_STM32F302R8) && defined(TOOLCHAIN_IAR)
24-
#define STACK_SIZE DEFAULT_STACK_SIZE/2
25-
#elif defined(TARGET_STM32F303K8) && defined(TOOLCHAIN_IAR)
26-
#define STACK_SIZE DEFAULT_STACK_SIZE/2
27-
#elif defined(TARGET_STM32L073RZ)
28-
#define STACK_SIZE DEFAULT_STACK_SIZE/2
29-
#elif (defined(TARGET_EFM32HG_STK3400)) && !defined(TOOLCHAIN_ARM_MICRO)
30-
#define STACK_SIZE 512
31-
#elif (defined(TARGET_EFM32LG_STK3600) || defined(TARGET_EFM32WG_STK3800) || defined(TARGET_EFM32PG_STK3401)) && !defined(TOOLCHAIN_ARM_MICRO)
32-
#define STACK_SIZE 768
33-
#elif (defined(TARGET_EFM32GG_STK3700)) && !defined(TOOLCHAIN_ARM_MICRO)
34-
#define STACK_SIZE 1536
35-
#elif (defined(TARGET_EFR32)) && !defined(TOOLCHAIN_ARM_MICRO)
36-
#define STACK_SIZE 768
37-
#elif defined(TARGET_MCU_NRF51822) || defined(TARGET_MCU_NRF52832)
38-
#define STACK_SIZE 1024
39-
#elif defined(TARGET_XDOT_L151CC)
40-
#define STACK_SIZE 1024
41-
#else
42-
#define STACK_SIZE DEFAULT_STACK_SIZE
43-
#endif
18+
#define TEST_STACK_SIZE 512
4419

45-
void print_char(char c = '*') {
46-
printf("%c", c);
47-
fflush(stdout);
48-
}
20+
#define TEST_ONE_SEC_MS (1000)
21+
#define TEST_HALF_SEC_MS (500)
22+
#define TEST_HALF_SEC_US (500000)
23+
#define TEST_ONE_MS_US (1000)
24+
25+
#define THREAD_DELAY 50
26+
#define SIGNALS_TO_EMIT 100
4927

5028
Mutex stdio_mutex;
51-
DigitalOut led(LED1);
5229

5330
volatile int change_counter = 0;
5431
volatile bool changing_counter = false;
@@ -57,23 +34,20 @@ volatile bool mutex_defect = false;
5734
bool manipulate_protected_zone(const int thread_delay) {
5835
bool result = true;
5936

60-
stdio_mutex.lock(); // LOCK
37+
osStatus stat = stdio_mutex.lock();
38+
TEST_ASSERT_EQUAL(stat, osOK);
6139
if (changing_counter == true) {
62-
// 'e' stands for error. If changing_counter is true access is not exclusively
63-
print_char('e');
6440
result = false;
6541
mutex_defect = true;
6642
}
6743
changing_counter = true;
6844

69-
// Some action on protected
70-
led = !led;
7145
change_counter++;
72-
print_char('.');
7346
Thread::wait(thread_delay);
7447

7548
changing_counter = false;
76-
stdio_mutex.unlock(); // UNLOCK
49+
stat = stdio_mutex.unlock();
50+
TEST_ASSERT_EQUAL(stat, osOK);
7751
return result;
7852
}
7953

@@ -83,14 +57,14 @@ void test_thread(int const *thread_delay) {
8357
}
8458
}
8559

86-
int main() {
87-
GREENTEA_SETUP(20, "default_auto");
88-
60+
void test_multiple_threads(void)
61+
{
8962
const int t1_delay = THREAD_DELAY * 1;
9063
const int t2_delay = THREAD_DELAY * 2;
9164
const int t3_delay = THREAD_DELAY * 3;
92-
Thread t2(osPriorityNormal, STACK_SIZE);
93-
Thread t3(osPriorityNormal, STACK_SIZE);
65+
66+
Thread t2(osPriorityNormal, TEST_STACK_SIZE);
67+
Thread t3(osPriorityNormal, TEST_STACK_SIZE);
9468

9569
t2.start(callback(test_thread, &t2_delay));
9670
t3.start(callback(test_thread, &t3_delay));
@@ -99,14 +73,162 @@ int main() {
9973
// Thread 1 action
10074
Thread::wait(t1_delay);
10175
manipulate_protected_zone(t1_delay);
76+
10277
if (change_counter >= SIGNALS_TO_EMIT or mutex_defect == true) {
10378
t2.terminate();
10479
t3.terminate();
10580
break;
10681
}
10782
}
10883

109-
fflush(stdout);
110-
GREENTEA_TESTSUITE_RESULT(!mutex_defect);
111-
return 0;
84+
TEST_ASSERT_EQUAL(mutex_defect, false);
85+
}
86+
87+
void test_dual_thread_nolock_lock_thread(Mutex *mutex)
88+
{
89+
bool stat_b = mutex->trylock();
90+
TEST_ASSERT_EQUAL(stat_b, true);
91+
92+
osStatus stat = mutex->unlock();
93+
TEST_ASSERT_EQUAL(stat, osOK);
94+
}
95+
96+
void test_dual_thread_nolock_trylock_thread(Mutex *mutex)
97+
{
98+
bool stat_b = mutex->trylock();
99+
TEST_ASSERT_EQUAL(stat_b, true);
100+
101+
osStatus stat = mutex->unlock();
102+
TEST_ASSERT_EQUAL(stat, osOK);
103+
}
104+
105+
template <void (*F)(Mutex *)>
106+
void test_dual_thread_nolock(void)
107+
{
108+
Mutex mutex;
109+
Thread thread;
110+
111+
thread.start(callback(F, &mutex));
112+
113+
wait_us(TEST_HALF_SEC_MS);
114+
}
115+
116+
void test_dual_thread_lock_unlock_thread(Mutex *mutex)
117+
{
118+
osStatus stat = mutex->lock(osWaitForever);
119+
TEST_ASSERT_EQUAL(stat, osOK);
120+
}
121+
122+
void test_dual_thread_lock_unlock(void)
123+
{
124+
Mutex mutex;
125+
osStatus stat;
126+
Thread thread(osPriorityNormal, TEST_STACK_SIZE);
127+
128+
stat = mutex.lock();
129+
TEST_ASSERT_EQUAL(stat, osOK);
130+
131+
thread.start(callback(test_dual_thread_lock_unlock_thread, &mutex));
132+
133+
stat = mutex.unlock();
134+
TEST_ASSERT_EQUAL(stat, osOK);
135+
136+
wait_us(TEST_HALF_SEC_MS);
137+
}
138+
139+
void test_dual_thread_lock_trylock_thread(Mutex *mutex)
140+
{
141+
bool stat = mutex->trylock();
142+
TEST_ASSERT_EQUAL(stat, false);
143+
}
144+
145+
void test_dual_thread_lock_lock_thread(Mutex *mutex)
146+
{
147+
uint32_t start = us_ticker_read();
148+
149+
osStatus stat = mutex->lock(TEST_HALF_SEC_MS);
150+
TEST_ASSERT_EQUAL(stat, osEventTimeout);
151+
TEST_ASSERT_UINT32_WITHIN(TEST_ONE_MS_US, TEST_HALF_SEC_US, us_ticker_read() - start);
152+
}
153+
154+
template <void (*F)(Mutex *)>
155+
void test_dual_thread_lock(void)
156+
{
157+
Mutex mutex;
158+
osStatus stat;
159+
Thread thread(osPriorityNormal, TEST_STACK_SIZE);
160+
161+
stat = mutex.lock();
162+
TEST_ASSERT_EQUAL(stat, osOK);
163+
164+
thread.start(callback(F, &mutex));
165+
166+
wait_us(TEST_ONE_SEC_MS);
167+
168+
stat = mutex.unlock();
169+
TEST_ASSERT_EQUAL(stat, osOK);
170+
}
171+
172+
void test_single_thread_lock_recursive(void)
173+
{
174+
Mutex mutex;
175+
osStatus stat;
176+
177+
stat = mutex.lock();
178+
TEST_ASSERT_EQUAL(stat, osOK);
179+
180+
stat = mutex.lock();
181+
TEST_ASSERT_EQUAL(stat, osOK);
182+
183+
stat = mutex.unlock();
184+
TEST_ASSERT_EQUAL(stat, osOK);
185+
186+
stat = mutex.unlock();
187+
TEST_ASSERT_EQUAL(stat, osOK);
188+
}
189+
190+
void test_single_thread_trylock(void)
191+
{
192+
Mutex mutex;
193+
194+
bool stat_b = mutex.trylock();
195+
TEST_ASSERT_EQUAL(stat_b, true);
196+
197+
osStatus stat = mutex.unlock();
198+
TEST_ASSERT_EQUAL(stat, osOK);
199+
}
200+
201+
void test_single_thread_lock(void)
202+
{
203+
Mutex mutex;
204+
osStatus stat;
205+
206+
stat = mutex.lock();
207+
TEST_ASSERT_EQUAL(stat, osOK);
208+
209+
stat = mutex.unlock();
210+
TEST_ASSERT_EQUAL(stat, osOK);
211+
}
212+
213+
utest::v1::status_t test_setup(const size_t number_of_cases) {
214+
GREENTEA_SETUP(15, "default_auto");
215+
return verbose_test_setup_handler(number_of_cases);
216+
}
217+
218+
Case cases[] = {
219+
Case("Test single thread lock", test_single_thread_lock),
220+
Case("Test single thread trylock", test_single_thread_trylock),
221+
Case("Test single thread lock recursive", test_single_thread_lock_recursive),
222+
Case("Test dual thread lock locked", test_dual_thread_lock<test_dual_thread_lock_lock_thread>),
223+
Case("Test dual thread trylock locked", test_dual_thread_lock<test_dual_thread_lock_trylock_thread>),
224+
Case("Test dual thread lock unlock", test_dual_thread_lock_unlock),
225+
Case("Test dual thread second thread lock", test_dual_thread_nolock<test_dual_thread_nolock_lock_thread>),
226+
Case("Test dual thread second thread trylock", test_dual_thread_nolock<test_dual_thread_nolock_trylock_thread>),
227+
Case("Test multiple thread", test_multiple_threads),
228+
};
229+
230+
Specification specification(test_setup, cases);
231+
232+
int main() {
233+
return !Harness::run(specification);
112234
}

0 commit comments

Comments
 (0)