Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2017 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "mbed.h" 00017 #include "greentea-client/test_env.h" 00018 #include "unity.h" 00019 #include "utest.h" 00020 #include "rtos.h" 00021 00022 using namespace utest::v1; 00023 00024 #define DELAY_MS 50 00025 #define DELTA_MS 5 00026 #define RESTART_DELAY_MS 10 00027 #define DELAY2_MS 30 00028 00029 #if RESTART_DELAY_MS >= DELAY_MS 00030 #error invalid RESTART_DELAY_MS value 00031 #endif 00032 00033 #if !DEVICE_USTICKER 00034 #error [NOT_SUPPORTED] test not supported 00035 #endif 00036 00037 class Stopwatch: public Timer { 00038 private: 00039 Semaphore _sem; 00040 00041 public: 00042 Stopwatch() : 00043 Timer(), _sem(1) 00044 { 00045 } 00046 00047 ~Stopwatch() 00048 { 00049 } 00050 00051 void start(void) 00052 { 00053 _sem.wait(0); 00054 Timer::start(); 00055 } 00056 00057 void stop(void) 00058 { 00059 Timer::stop(); 00060 _sem.release(); 00061 } 00062 00063 int32_t wait_until_stopped(uint32_t millisec = osWaitForever) 00064 { 00065 core_util_critical_section_enter(); 00066 int running = _running; 00067 core_util_critical_section_exit(); 00068 if (!running) { 00069 return 1; 00070 } 00071 return _sem.wait(millisec); 00072 } 00073 }; 00074 00075 void sem_callback(Semaphore *sem) 00076 { 00077 sem->release(); 00078 } 00079 00080 /* In order to successfully run this test suite when compiled with --profile=debug 00081 * error() has to be redefined as noop. 00082 * 00083 * RtosTimer calls RTX API which uses Event Recorder functionality. When compiled 00084 * with MBED_TRAP_ERRORS_ENABLED=1 (set in debug profile) EvrRtxTimerError() calls error() 00085 * which aborts test program. 00086 */ 00087 #if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED 00088 void error(const char* format, ...) 00089 { 00090 (void) format; 00091 } 00092 00093 mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number) 00094 { 00095 return MBED_SUCCESS; 00096 } 00097 #endif 00098 00099 /** Test one-shot not restarted when elapsed 00100 * 00101 * Given a one-shot RtosTimer 00102 * When the timer is started 00103 * and given time elapses 00104 * Then timer stops 00105 * and elapsed time matches given delay 00106 * and timer stays stopped 00107 */ 00108 void test_oneshot_not_restarted() 00109 { 00110 Stopwatch stopwatch; 00111 RtosTimer rtostimer(mbed::callback(&stopwatch, &Stopwatch::stop), osTimerOnce); 00112 00113 stopwatch.start(); 00114 osStatus status = rtostimer.start(DELAY_MS); 00115 TEST_ASSERT_EQUAL(osOK, status); 00116 00117 int32_t slots = stopwatch.wait_until_stopped(); 00118 TEST_ASSERT_EQUAL(1, slots); 00119 TEST_ASSERT_INT_WITHIN(DELTA_MS, DELAY_MS, stopwatch.read_ms()); 00120 stopwatch.start(); 00121 00122 slots = stopwatch.wait_until_stopped(DELAY_MS + DELTA_MS); 00123 TEST_ASSERT_EQUAL(0, slots); 00124 status = rtostimer.stop(); 00125 TEST_ASSERT_EQUAL(osErrorResource, status); 00126 } 00127 00128 /** Test periodic repeats continuously 00129 * 00130 * Given a periodic RtosTimer 00131 * When timer is started 00132 * and given time elapses 00133 * Then timer repeats its operation 00134 * When timer is stopped 00135 * Then timer stops operation 00136 */ 00137 void test_periodic_repeats() 00138 { 00139 Stopwatch stopwatch; 00140 RtosTimer rtostimer(mbed::callback(&stopwatch, &Stopwatch::stop), osTimerPeriodic); 00141 00142 stopwatch.start(); 00143 osStatus status = rtostimer.start(DELAY_MS); 00144 TEST_ASSERT_EQUAL(osOK, status); 00145 00146 int32_t slots = stopwatch.wait_until_stopped(); 00147 int t1 = stopwatch.read_ms(); 00148 stopwatch.reset(); 00149 stopwatch.start(); 00150 TEST_ASSERT_EQUAL(1, slots); 00151 TEST_ASSERT_INT_WITHIN(DELTA_MS, DELAY_MS, t1); 00152 00153 slots = stopwatch.wait_until_stopped(); 00154 TEST_ASSERT_EQUAL(1, slots); 00155 TEST_ASSERT_INT_WITHIN(DELTA_MS, DELAY_MS, stopwatch.read_ms()); 00156 stopwatch.start(); 00157 00158 status = rtostimer.stop(); 00159 TEST_ASSERT_EQUAL(osOK, status); 00160 00161 slots = stopwatch.wait_until_stopped(DELAY_MS + DELTA_MS); 00162 TEST_ASSERT_EQUAL(0, slots); 00163 status = rtostimer.stop(); 00164 TEST_ASSERT_EQUAL(osErrorResource, status); 00165 } 00166 00167 /** Test timer can be started again 00168 * 00169 * Given a one-shot Rtosimer 00170 * When the timer is started 00171 * and given time elapses 00172 * Then timer stops 00173 * When the timer is started again 00174 * and given time elapses 00175 * Then timer stops again 00176 */ 00177 void test_start_again() 00178 { 00179 Semaphore sem(0, 1); 00180 RtosTimer rtostimer(mbed::callback(sem_callback, &sem), osTimerOnce); 00181 00182 osStatus status = rtostimer.start(DELAY_MS); 00183 TEST_ASSERT_EQUAL(osOK, status); 00184 00185 int32_t slots = sem.wait(DELAY_MS + DELTA_MS); 00186 TEST_ASSERT_EQUAL(1, slots); 00187 00188 status = rtostimer.stop(); 00189 TEST_ASSERT_EQUAL(osErrorResource, status); 00190 00191 status = rtostimer.start(DELAY_MS); 00192 TEST_ASSERT_EQUAL(osOK, status); 00193 00194 slots = sem.wait(DELAY_MS + DELTA_MS); 00195 TEST_ASSERT_EQUAL(1, slots); 00196 00197 status = rtostimer.stop(); 00198 TEST_ASSERT_EQUAL(osErrorResource, status); 00199 } 00200 00201 /** Test timer restart updates delay 00202 * 00203 * Given a one-shot RtosTimer 00204 * When the timer is started 00205 * and @a start is called again with a different delay before given time elapses 00206 * and updated delay elapses 00207 * Then timer stops 00208 * and time elapsed since the second @a start call matches updated delay 00209 */ 00210 void test_restart_updates_delay() 00211 { 00212 Stopwatch stopwatch; 00213 RtosTimer rtostimer(mbed::callback(&stopwatch, &Stopwatch::stop), osTimerOnce); 00214 00215 stopwatch.start(); 00216 osStatus status = rtostimer.start(DELAY_MS); 00217 TEST_ASSERT_EQUAL(osOK, status); 00218 00219 int32_t slots = stopwatch.wait_until_stopped(RESTART_DELAY_MS); 00220 TEST_ASSERT_EQUAL(0, slots); 00221 00222 stopwatch.reset(); 00223 stopwatch.start(); 00224 status = rtostimer.start(DELAY2_MS); 00225 TEST_ASSERT_EQUAL(osOK, status); 00226 00227 slots = stopwatch.wait_until_stopped(); 00228 TEST_ASSERT_EQUAL(1, slots); 00229 TEST_ASSERT_INT_WITHIN(DELTA_MS, DELAY2_MS, stopwatch.read_ms()); 00230 00231 status = rtostimer.stop(); 00232 TEST_ASSERT_EQUAL(osErrorResource, status); 00233 } 00234 00235 /** Test timer is created in stopped state 00236 * 00237 * Given a one-shot RtosTimer 00238 * When the timer has not been started 00239 * Then the timer is stopped 00240 */ 00241 void test_created_stopped() 00242 { 00243 RtosTimer rtostimer(mbed::callback(sem_callback, (Semaphore *) NULL), osTimerOnce); 00244 osStatus status = rtostimer.stop(); 00245 TEST_ASSERT_EQUAL(osErrorResource, status); 00246 } 00247 00248 /** Test one-shot can be stopped 00249 * 00250 * Given a one-shot RtosTimer 00251 * When the timer is started 00252 * and timer is stopped while still running 00253 * Then timer stops operation 00254 */ 00255 void test_stop() 00256 { 00257 Semaphore sem(0, 1); 00258 RtosTimer rtostimer(mbed::callback(sem_callback, &sem), osTimerOnce); 00259 00260 osStatus status = rtostimer.start(DELAY_MS); 00261 TEST_ASSERT_EQUAL(osOK, status); 00262 00263 int32_t slots = sem.wait(RESTART_DELAY_MS); 00264 TEST_ASSERT_EQUAL(0, slots); 00265 00266 status = rtostimer.stop(); 00267 TEST_ASSERT_EQUAL(osOK, status); 00268 00269 slots = sem.wait(DELAY_MS + DELTA_MS); 00270 TEST_ASSERT_EQUAL(0, slots); 00271 00272 status = rtostimer.stop(); 00273 TEST_ASSERT_EQUAL(osErrorResource, status); 00274 } 00275 00276 /** Test timer started with infinite delay 00277 * 00278 * Given a one-shot RtosTimer 00279 * When the timer is started with @a osWaitForever delay 00280 * Then @a start return status is @a osOK 00281 */ 00282 void test_wait_forever() 00283 { 00284 RtosTimer rtostimer(mbed::callback(sem_callback, (Semaphore *) NULL), osTimerOnce); 00285 00286 osStatus status = rtostimer.start(osWaitForever); 00287 TEST_ASSERT_EQUAL(osOK, status); 00288 00289 status = rtostimer.stop(); 00290 TEST_ASSERT_EQUAL(osOK, status); 00291 } 00292 00293 /** Test timer started with zero delay 00294 * 00295 * Given a one-shot RtosTimer 00296 * When the timer is started with 0 delay 00297 * Then @a start return status is @a osErrorParameter 00298 */ 00299 void test_no_wait() 00300 { 00301 RtosTimer rtostimer(mbed::callback(sem_callback, (Semaphore *) NULL), osTimerOnce); 00302 00303 osStatus status = rtostimer.start(0); 00304 TEST_ASSERT_EQUAL(osErrorParameter, status); 00305 00306 status = rtostimer.stop(); 00307 TEST_ASSERT_EQUAL(osErrorResource, status); 00308 } 00309 00310 void rtostimer_isr_call(RtosTimer *rtostimer) 00311 { 00312 osStatus status = rtostimer->start(DELAY_MS); 00313 TEST_ASSERT_EQUAL(osErrorISR, status); 00314 00315 status = rtostimer->stop(); 00316 TEST_ASSERT_EQUAL(osErrorISR, status); 00317 } 00318 00319 /** Test timer method calls from an ISR fail 00320 * 00321 * Given a one-shot RtosTimer 00322 * When a timer method is called from an ISR 00323 * Then method return status is @a osErrorISR 00324 */ 00325 void test_isr_calls_fail() 00326 { 00327 RtosTimer rtostimer(mbed::callback(sem_callback, (Semaphore *) NULL), osTimerOnce); 00328 00329 Ticker ticker; 00330 ticker.attach(mbed::callback(rtostimer_isr_call, &rtostimer), (float) DELAY_MS / 1000.0); 00331 00332 wait_ms(DELAY_MS + DELTA_MS); 00333 } 00334 00335 utest::v1::status_t test_setup(const size_t number_of_cases) 00336 { 00337 GREENTEA_SETUP(5, "default_auto"); 00338 return verbose_test_setup_handler(number_of_cases); 00339 } 00340 00341 Case cases[] = { 00342 Case("One-shot not restarted when elapsed", test_oneshot_not_restarted), 00343 Case("Periodic repeats continuously", test_periodic_repeats), 00344 Case("Stopped timer can be started again", test_start_again), 00345 Case("Restart changes timeout", test_restart_updates_delay), 00346 Case("Timer can be stopped", test_stop), 00347 Case("Timer is created in stopped state", test_created_stopped), 00348 Case("Timer started with infinite delay", test_wait_forever), 00349 Case("Timer started with zero delay", test_no_wait), 00350 Case("Calls from ISR fail", test_isr_calls_fail) 00351 }; 00352 00353 Specification specification(test_setup, cases); 00354 00355 int main() 00356 { 00357 return !Harness::run(specification); 00358 }
Generated on Tue Jul 12 2022 12:45:24 by
