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.
Dependents: cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more
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 class Stopwatch: public Timer { 00034 private: 00035 Semaphore _sem; 00036 00037 public: 00038 Stopwatch() : 00039 Timer(), _sem(1) 00040 { 00041 } 00042 00043 ~Stopwatch() 00044 { 00045 } 00046 00047 void start(void) 00048 { 00049 _sem.wait(0); 00050 Timer::start(); 00051 } 00052 00053 void stop(void) 00054 { 00055 Timer::stop(); 00056 _sem.release(); 00057 } 00058 00059 int32_t wait_until_stopped(uint32_t millisec = osWaitForever) 00060 { 00061 core_util_critical_section_enter(); 00062 int running = _running; 00063 core_util_critical_section_exit(); 00064 if (!running) { 00065 return 1; 00066 } 00067 return _sem.wait(millisec); 00068 } 00069 }; 00070 00071 void sem_callback(Semaphore *sem) 00072 { 00073 sem->release(); 00074 } 00075 00076 /* In order to successfully run this test suite when compiled with --profile=debug 00077 * error() has to be redefined as noop. 00078 * 00079 * RtosTimer calls RTX API which uses Event Recorder functionality. When compiled 00080 * with MBED_TRAP_ERRORS_ENABLED=1 (set in debug profile) EvrRtxTimerError() calls error() 00081 * which aborts test program. 00082 */ 00083 #if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED 00084 void error(const char* format, ...) 00085 { 00086 (void) format; 00087 } 00088 #endif 00089 00090 /** Test one-shot not restarted when elapsed 00091 * 00092 * Given a one-shot RtosTimer 00093 * When the timer is started 00094 * and given time elapses 00095 * Then timer stops 00096 * and elapsed time matches given delay 00097 * and timer stays stopped 00098 */ 00099 void test_oneshot_not_restarted() 00100 { 00101 Stopwatch stopwatch; 00102 RtosTimer rtostimer(mbed::callback(&stopwatch, &Stopwatch::stop), osTimerOnce); 00103 00104 stopwatch.start(); 00105 osStatus status = rtostimer.start(DELAY_MS); 00106 TEST_ASSERT_EQUAL(osOK, status); 00107 00108 int32_t slots = stopwatch.wait_until_stopped(); 00109 TEST_ASSERT_EQUAL(1, slots); 00110 TEST_ASSERT_INT_WITHIN(DELTA_MS, DELAY_MS, stopwatch.read_ms()); 00111 stopwatch.start(); 00112 00113 slots = stopwatch.wait_until_stopped(DELAY_MS + DELTA_MS); 00114 TEST_ASSERT_EQUAL(0, slots); 00115 status = rtostimer.stop(); 00116 TEST_ASSERT_EQUAL(osErrorResource, status); 00117 } 00118 00119 /** Test periodic repeats continuously 00120 * 00121 * Given a periodic RtosTimer 00122 * When timer is started 00123 * and given time elapses 00124 * Then timer repeats its operation 00125 * When timer is stopped 00126 * Then timer stops operation 00127 */ 00128 void test_periodic_repeats() 00129 { 00130 Stopwatch stopwatch; 00131 RtosTimer rtostimer(mbed::callback(&stopwatch, &Stopwatch::stop), osTimerPeriodic); 00132 00133 stopwatch.start(); 00134 osStatus status = rtostimer.start(DELAY_MS); 00135 TEST_ASSERT_EQUAL(osOK, status); 00136 00137 int32_t slots = stopwatch.wait_until_stopped(); 00138 int t1 = stopwatch.read_ms(); 00139 stopwatch.reset(); 00140 stopwatch.start(); 00141 TEST_ASSERT_EQUAL(1, slots); 00142 TEST_ASSERT_INT_WITHIN(DELTA_MS, DELAY_MS, t1); 00143 00144 slots = stopwatch.wait_until_stopped(); 00145 TEST_ASSERT_EQUAL(1, slots); 00146 TEST_ASSERT_INT_WITHIN(DELTA_MS, DELAY_MS, stopwatch.read_ms()); 00147 stopwatch.start(); 00148 00149 status = rtostimer.stop(); 00150 TEST_ASSERT_EQUAL(osOK, status); 00151 00152 slots = stopwatch.wait_until_stopped(DELAY_MS + DELTA_MS); 00153 TEST_ASSERT_EQUAL(0, slots); 00154 status = rtostimer.stop(); 00155 TEST_ASSERT_EQUAL(osErrorResource, status); 00156 } 00157 00158 /** Test timer can be started again 00159 * 00160 * Given a one-shot Rtosimer 00161 * When the timer is started 00162 * and given time elapses 00163 * Then timer stops 00164 * When the timer is started again 00165 * and given time elapses 00166 * Then timer stops again 00167 */ 00168 void test_start_again() 00169 { 00170 Semaphore sem(0, 1); 00171 RtosTimer rtostimer(mbed::callback(sem_callback, &sem), osTimerOnce); 00172 00173 osStatus status = rtostimer.start(DELAY_MS); 00174 TEST_ASSERT_EQUAL(osOK, status); 00175 00176 int32_t slots = sem.wait(DELAY_MS + DELTA_MS); 00177 TEST_ASSERT_EQUAL(1, slots); 00178 00179 status = rtostimer.stop(); 00180 TEST_ASSERT_EQUAL(osErrorResource, status); 00181 00182 status = rtostimer.start(DELAY_MS); 00183 TEST_ASSERT_EQUAL(osOK, status); 00184 00185 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 00192 /** Test timer restart updates delay 00193 * 00194 * Given a one-shot RtosTimer 00195 * When the timer is started 00196 * and @a start is called again with a different delay before given time elapses 00197 * and updated delay elapses 00198 * Then timer stops 00199 * and time elapsed since the second @a start call matches updated delay 00200 */ 00201 void test_restart_updates_delay() 00202 { 00203 Stopwatch stopwatch; 00204 RtosTimer rtostimer(mbed::callback(&stopwatch, &Stopwatch::stop), osTimerOnce); 00205 00206 stopwatch.start(); 00207 osStatus status = rtostimer.start(DELAY_MS); 00208 TEST_ASSERT_EQUAL(osOK, status); 00209 00210 int32_t slots = stopwatch.wait_until_stopped(RESTART_DELAY_MS); 00211 TEST_ASSERT_EQUAL(0, slots); 00212 00213 stopwatch.reset(); 00214 stopwatch.start(); 00215 status = rtostimer.start(DELAY2_MS); 00216 TEST_ASSERT_EQUAL(osOK, status); 00217 00218 slots = stopwatch.wait_until_stopped(); 00219 TEST_ASSERT_EQUAL(1, slots); 00220 TEST_ASSERT_INT_WITHIN(DELTA_MS, DELAY2_MS, stopwatch.read_ms()); 00221 00222 status = rtostimer.stop(); 00223 TEST_ASSERT_EQUAL(osErrorResource, status); 00224 } 00225 00226 /** Test timer is created in stopped state 00227 * 00228 * Given a one-shot RtosTimer 00229 * When the timer has not been started 00230 * Then the timer is stopped 00231 */ 00232 void test_created_stopped() 00233 { 00234 RtosTimer rtostimer(mbed::callback(sem_callback, (Semaphore *) NULL), osTimerOnce); 00235 osStatus status = rtostimer.stop(); 00236 TEST_ASSERT_EQUAL(osErrorResource, status); 00237 } 00238 00239 /** Test one-shot can be stopped 00240 * 00241 * Given a one-shot RtosTimer 00242 * When the timer is started 00243 * and timer is stopped while still running 00244 * Then timer stops operation 00245 */ 00246 void test_stop() 00247 { 00248 Semaphore sem(0, 1); 00249 RtosTimer rtostimer(mbed::callback(sem_callback, &sem), osTimerOnce); 00250 00251 osStatus status = rtostimer.start(DELAY_MS); 00252 TEST_ASSERT_EQUAL(osOK, status); 00253 00254 int32_t slots = sem.wait(RESTART_DELAY_MS); 00255 TEST_ASSERT_EQUAL(0, slots); 00256 00257 status = rtostimer.stop(); 00258 TEST_ASSERT_EQUAL(osOK, status); 00259 00260 slots = sem.wait(DELAY_MS + DELTA_MS); 00261 TEST_ASSERT_EQUAL(0, slots); 00262 00263 status = rtostimer.stop(); 00264 TEST_ASSERT_EQUAL(osErrorResource, status); 00265 } 00266 00267 /** Test timer started with infinite delay 00268 * 00269 * Given a one-shot RtosTimer 00270 * When the timer is started with @a osWaitForever delay 00271 * Then @a start return status is @a osOK 00272 */ 00273 void test_wait_forever() 00274 { 00275 RtosTimer rtostimer(mbed::callback(sem_callback, (Semaphore *) NULL), osTimerOnce); 00276 00277 osStatus status = rtostimer.start(osWaitForever); 00278 TEST_ASSERT_EQUAL(osOK, status); 00279 00280 status = rtostimer.stop(); 00281 TEST_ASSERT_EQUAL(osOK, status); 00282 } 00283 00284 /** Test timer started with zero delay 00285 * 00286 * Given a one-shot RtosTimer 00287 * When the timer is started with 0 delay 00288 * Then @a start return status is @a osErrorParameter 00289 */ 00290 void test_no_wait() 00291 { 00292 RtosTimer rtostimer(mbed::callback(sem_callback, (Semaphore *) NULL), osTimerOnce); 00293 00294 osStatus status = rtostimer.start(0); 00295 TEST_ASSERT_EQUAL(osErrorParameter, status); 00296 00297 status = rtostimer.stop(); 00298 TEST_ASSERT_EQUAL(osErrorResource, status); 00299 } 00300 00301 void rtostimer_isr_call(RtosTimer *rtostimer) 00302 { 00303 osStatus status = rtostimer->start(DELAY_MS); 00304 TEST_ASSERT_EQUAL(osErrorISR, status); 00305 00306 status = rtostimer->stop(); 00307 TEST_ASSERT_EQUAL(osErrorISR, status); 00308 } 00309 00310 /** Test timer method calls from an ISR fail 00311 * 00312 * Given a one-shot RtosTimer 00313 * When a timer method is called from an ISR 00314 * Then method return status is @a osErrorISR 00315 */ 00316 void test_isr_calls_fail() 00317 { 00318 RtosTimer rtostimer(mbed::callback(sem_callback, (Semaphore *) NULL), osTimerOnce); 00319 00320 Ticker ticker; 00321 ticker.attach(mbed::callback(rtostimer_isr_call, &rtostimer), (float) DELAY_MS / 1000.0); 00322 00323 wait_ms(DELAY_MS + DELTA_MS); 00324 } 00325 00326 utest::v1::status_t test_setup(const size_t number_of_cases) 00327 { 00328 GREENTEA_SETUP(5, "default_auto"); 00329 return verbose_test_setup_handler(number_of_cases); 00330 } 00331 00332 Case cases[] = { 00333 Case("One-shot not restarted when elapsed", test_oneshot_not_restarted), 00334 Case("Periodic repeats continuously", test_periodic_repeats), 00335 Case("Stopped timer can be started again", test_start_again), 00336 Case("Restart changes timeout", test_restart_updates_delay), 00337 Case("Timer can be stopped", test_stop), 00338 Case("Timer is created in stopped state", test_created_stopped), 00339 Case("Timer started with infinite delay", test_wait_forever), 00340 Case("Timer started with zero delay", test_no_wait), 00341 Case("Calls from ISR fail", test_isr_calls_fail) 00342 }; 00343 00344 Specification specification(test_setup, cases); 00345 00346 int main() 00347 { 00348 return !Harness::run(specification); 00349 }
Generated on Tue Jul 12 2022 13:03:03 by
