1
1
#include " mbed.h"
2
2
#include " greentea-client/test_env.h"
3
+ #include " unity.h"
4
+ #include " utest.h"
3
5
#include " rtos.h"
4
6
5
7
#if defined(MBED_RTOS_SINGLE_THREAD)
6
8
#error [NOT_SUPPORTED] test not supported
7
9
#endif
8
10
9
- #define THREAD_DELAY 50
10
- #define SIGNALS_TO_EMIT 100
11
+ using namespace utest ::v1;
11
12
12
13
/*
13
14
* The stack size is defined in cmsis_os.h mainly dependent on the underlying toolchain and
14
15
* the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes
15
16
* and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize.
16
17
*/
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
44
19
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
49
27
50
28
Mutex stdio_mutex;
51
- DigitalOut led (LED1);
52
29
53
30
volatile int change_counter = 0 ;
54
31
volatile bool changing_counter = false ;
@@ -57,23 +34,20 @@ volatile bool mutex_defect = false;
57
34
bool manipulate_protected_zone (const int thread_delay) {
58
35
bool result = true ;
59
36
60
- stdio_mutex.lock (); // LOCK
37
+ osStatus stat = stdio_mutex.lock ();
38
+ TEST_ASSERT_EQUAL (stat, osOK);
61
39
if (changing_counter == true ) {
62
- // 'e' stands for error. If changing_counter is true access is not exclusively
63
- print_char (' e' );
64
40
result = false ;
65
41
mutex_defect = true ;
66
42
}
67
43
changing_counter = true ;
68
44
69
- // Some action on protected
70
- led = !led;
71
45
change_counter++;
72
- print_char (' .' );
73
46
Thread::wait (thread_delay);
74
47
75
48
changing_counter = false ;
76
- stdio_mutex.unlock (); // UNLOCK
49
+ stat = stdio_mutex.unlock ();
50
+ TEST_ASSERT_EQUAL (stat, osOK);
77
51
return result;
78
52
}
79
53
@@ -83,14 +57,14 @@ void test_thread(int const *thread_delay) {
83
57
}
84
58
}
85
59
86
- int main () {
87
- GREENTEA_SETUP (20 , " default_auto" );
88
-
60
+ void test_multiple_threads (void )
61
+ {
89
62
const int t1_delay = THREAD_DELAY * 1 ;
90
63
const int t2_delay = THREAD_DELAY * 2 ;
91
64
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);
94
68
95
69
t2.start (callback (test_thread, &t2_delay));
96
70
t3.start (callback (test_thread, &t3_delay));
@@ -99,14 +73,162 @@ int main() {
99
73
// Thread 1 action
100
74
Thread::wait (t1_delay);
101
75
manipulate_protected_zone (t1_delay);
76
+
102
77
if (change_counter >= SIGNALS_TO_EMIT or mutex_defect == true ) {
103
78
t2.terminate ();
104
79
t3.terminate ();
105
80
break ;
106
81
}
107
82
}
108
83
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);
112
234
}
0 commit comments