Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002  * Copyright (c) 2017, ARM Limited, All Rights Reserved
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00006  * not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  * http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00013  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include "mbed.h"
00019 #include "greentea-client/test_env.h"
00020 #include "unity.h"
00021 #include "utest.h"
00022 #include "rtos.h"
00023 #include "hal/us_ticker_api.h"
00024 
00025 using namespace utest::v1;
00026 
00027 extern uint32_t SystemCoreClock;
00028 
00029 /* Macro to define delta based on CPU clock frequency.
00030  *
00031  * Note that some extra time is counted by the timer.
00032  * Additional time is caused by the function calls and
00033  * additional operations performed by wait and
00034  * stop functions before in fact timer is stopped. This may
00035  * add additional time to the counted result.
00036  *
00037  * To take in to account this extra time we introduce DELTA
00038  * value based on CPU clock (speed):
00039  *   DELTA = TOLERANCE_FACTOR / SystemCoreClock * US_FACTOR
00040  *
00041  *   e.g.
00042  *   For K64F          DELTA = (30000 / 120000000) * 1000000 = 250[us]
00043  *   For NUCLEO_F070RB DELTA = (30000 /  48000000) * 1000000 = 625[us]
00044  *   For NRF51_DK      DELTA = (30000 /  16000000) * 1000000 = 1875[us]
00045  */
00046 #define US_PER_SEC       1000000
00047 #define US_PER_MSEC      1000
00048 #define TOLERANCE_FACTOR 30000.0f
00049 #define US_FACTOR        1000000.0f
00050 
00051 static const int delta_sys_clk_us = ((int) (TOLERANCE_FACTOR / (float)SystemCoreClock * US_FACTOR));
00052 
00053 /* When test performs time measurement using Timer in sequence, then measurement error accumulates
00054  * in the successive attempts. */
00055  #define DELTA_US(i) (delta_sys_clk_us * i)
00056  #define DELTA_S(i)  ((float)delta_sys_clk_us * i / US_PER_SEC)
00057  #define DELTA_MS(i) (1 + ( (i * delta_sys_clk_us) / US_PER_MSEC))
00058 
00059 #define TICKER_FREQ_1MHZ 1000000
00060 #define TICKER_BITS 32
00061 
00062 static Timer *p_timer = NULL;
00063 
00064 /* Global variable used to simulate passage of time
00065  * in case when timer which uses user ticker is tested.
00066  */
00067 static uint32_t curr_ticker_ticks_val;
00068 
00069 /* User ticker interface function. */
00070 static void stub_interface_init()
00071 {
00072     /* do nothing. */
00073 }
00074 
00075 /* User ticker interface function - only this
00076  * ticker interface function is used by Timer API. */
00077 static uint32_t stub_ticker_read(void)
00078 {
00079     /* Simulate elapsed time. */
00080     return curr_ticker_ticks_val;
00081 }
00082 
00083 /* User ticker interface function. */
00084 static void stub_disable_interrupt(void)
00085 {
00086     /* do nothing. */
00087 }
00088 
00089 /* User ticker interface function. */
00090 static void stub_clear_interrupt(void)
00091 {
00092     /* do nothing. */
00093 }
00094 
00095 /* User ticker interface function. */
00096 static void stub_set_interrupt(timestamp_t timestamp)
00097 {
00098     /* do nothing. */
00099 }
00100 
00101 /* User ticker interface function. */
00102 static void stub_fire_interrupt(void)
00103 {
00104     /* do nothing. */
00105 }
00106 
00107 ticker_info_t info =
00108 { TICKER_FREQ_1MHZ, TICKER_BITS };
00109 
00110 const ticker_info_t * stub_get_info(void)
00111 {
00112     return &info;
00113 }
00114 
00115 /* User ticker event queue. */
00116 static ticker_event_queue_t my_events = { 0 };
00117 
00118 /* User ticker interface data. */
00119 static const ticker_interface_t us_interface = {
00120     .init = stub_interface_init,
00121     .read = stub_ticker_read, /* Only this function is used by the Timer. */
00122     .disable_interrupt = stub_disable_interrupt,
00123     .clear_interrupt = stub_clear_interrupt,
00124     .set_interrupt = stub_set_interrupt,
00125     .fire_interrupt = stub_fire_interrupt,
00126     .get_info = stub_get_info,
00127 };
00128 
00129 /* User ticker data structure. */
00130 static const ticker_data_t us_data = {
00131     .interface = &us_interface,
00132     .queue = &my_events
00133 };
00134 
00135 /* Function which returns user ticker data. */
00136 const ticker_data_t* get_user_ticker_data(void)
00137 {
00138     return &us_data;
00139 }
00140 
00141 /* Initialisation of the Timer object which uses
00142  * ticker data provided by the user.
00143  *
00144  * */
00145 utest::v1::status_t timer_user_ticker_setup_handler(const Case *const source, const size_t index_of_case)
00146 {
00147     p_timer = new Timer(get_user_ticker_data());
00148 
00149     /* Check if Timer object has been created. */
00150     TEST_ASSERT_NOT_NULL(p_timer);
00151 
00152     return greentea_case_setup_handler(source, index_of_case);
00153 }
00154 
00155 /* Initialisation of the Timer object which uses
00156  * default os ticker data.
00157  *
00158  * */
00159 utest::v1::status_t timer_os_ticker_setup_handler(const Case *const source, const size_t index_of_case)
00160 {
00161     p_timer = new Timer();
00162 
00163     /* Check if Timer object has been created. */
00164     TEST_ASSERT_NOT_NULL(p_timer);
00165 
00166     return greentea_case_setup_handler(source, index_of_case);
00167 }
00168 
00169 /* Test finalisation.
00170  *
00171  * */
00172 utest::v1::status_t cleanup_handler(const Case *const source, const size_t passed, const size_t failed, const failure_t reason)
00173 {
00174     delete p_timer;
00175 
00176     p_timer = NULL;
00177 
00178     return greentea_case_teardown_handler(source, passed, failed, reason);
00179 }
00180 
00181 /* This test verifies if timer is stopped after
00182  * creation.
00183  *
00184  * Note: this function assumes that Timer uses os ticker.
00185  *
00186  * Given Timer has been successfully created.
00187  * When read of timer elapsed time is requested.
00188  * Then result is always 0.
00189  */
00190 void test_timer_creation_os_ticker()
00191 {
00192     /* Check results. */
00193     TEST_ASSERT_EQUAL_FLOAT(0, p_timer->read());
00194     TEST_ASSERT_EQUAL_INT32(0, p_timer->read_ms());
00195     TEST_ASSERT_EQUAL_INT32(0, p_timer->read_us());
00196     TEST_ASSERT_EQUAL_UINT64(0, p_timer->read_high_resolution_us());
00197 
00198     /* Wait 10 ms.
00199      * After that operation timer read routines should still return 0. */
00200     wait_ms(10);
00201 
00202     /* Check results. */
00203     TEST_ASSERT_EQUAL_FLOAT(0, p_timer->read());
00204     TEST_ASSERT_EQUAL_INT32(0, p_timer->read_ms());
00205     TEST_ASSERT_EQUAL_INT32(0, p_timer->read_us());
00206     TEST_ASSERT_EQUAL_UINT64(0, p_timer->read_high_resolution_us());
00207 }
00208 
00209 /* This test verifies if timer is stopped after
00210  * creation.
00211  *
00212  * Note: this function assumes that Timer uses user/fake ticker
00213  * which returns time value provided in curr_ticker_ticks_val
00214  * global variable.
00215  *
00216  * Given Timer has been successfully created.
00217  * When read of timer elapsed time is requested.
00218  * Then result is always 0.
00219  */
00220 void test_timer_creation_user_ticker()
00221 {
00222     /* For timer which is using user ticker simulate timer
00223      * creation time (irrelevant in case of os ticker). */
00224     curr_ticker_ticks_val = 10000;
00225 
00226     /* Check results. */
00227     TEST_ASSERT_EQUAL_FLOAT(0, p_timer->read());
00228     TEST_ASSERT_EQUAL_INT32(0, p_timer->read_ms());
00229     TEST_ASSERT_EQUAL_INT32(0, p_timer->read_us());
00230     TEST_ASSERT_EQUAL_UINT64(0, p_timer->read_high_resolution_us());
00231 
00232     /* Simulate that 10 ms has elapsed.
00233      * After that operation timer read routines should still return 0. */
00234     curr_ticker_ticks_val += 10000;
00235 
00236     /* Check results. */
00237     TEST_ASSERT_EQUAL_FLOAT(0, p_timer->read());
00238     TEST_ASSERT_EQUAL_INT32(0, p_timer->read_ms());
00239     TEST_ASSERT_EQUAL_INT32(0, p_timer->read_us());
00240     TEST_ASSERT_EQUAL_UINT64(0, p_timer->read_high_resolution_us());
00241 }
00242 
00243 /* This test verifies verifies if read(), read_us(), read_ms(),
00244  * read_high_resolution_us() functions returns valid values.
00245  *
00246  * Note: this function assumes that Timer uses user/fake ticker
00247  * which returns time value provided in curr_ticker_ticks_val
00248  * global variable.
00249  *
00250  * Given Timer has been successfully created and
00251  * few times started and stopped after a specified period of time.
00252  * When timer read request is performed.
00253  * Then read functions return accumulated time elapsed between starts
00254  * and stops.
00255  */
00256 void test_timer_time_accumulation_user_ticker()
00257 {
00258     /* Simulate that current time is equal to 0 us. */
00259     curr_ticker_ticks_val = 0;
00260 
00261     /* Start the timer. */
00262     p_timer->start();
00263 
00264     /* -- Simulate that current time is equal to 1 us -- */
00265     curr_ticker_ticks_val = 1;
00266 
00267     /* Stop the timer. */
00268     p_timer->stop();
00269 
00270     /* Check results - 1 us has elapsed. */
00271     TEST_ASSERT_EQUAL_FLOAT(0.000001f, p_timer->read());
00272     TEST_ASSERT_EQUAL_INT32(0, p_timer->read_ms());
00273     TEST_ASSERT_EQUAL_INT32(1, p_timer->read_us());
00274     TEST_ASSERT_EQUAL_UINT64(1, p_timer->read_high_resolution_us());
00275 
00276     /* Simulate that 100 us has elapsed between stop and start. */
00277     curr_ticker_ticks_val = 101;
00278 
00279     /* Start the timer. */
00280     p_timer->start();
00281 
00282     /* -- Simulate that current time is equal to 225 us -- */
00283     curr_ticker_ticks_val = 225;
00284 
00285     /* Stop the timer. */
00286     p_timer->stop();
00287 
00288     /* Check results - 125 us have elapsed. */
00289     TEST_ASSERT_EQUAL_FLOAT(0.000125f, p_timer->read());
00290     TEST_ASSERT_EQUAL_INT32(0, p_timer->read_ms());
00291     TEST_ASSERT_EQUAL_INT32(125, p_timer->read_us());
00292     TEST_ASSERT_EQUAL_UINT64(125, p_timer->read_high_resolution_us());
00293 
00294     /* Simulate that 100 us has elapsed between stop and start. */
00295     curr_ticker_ticks_val = 325;
00296 
00297     /* Start the timer. */
00298     p_timer->start();
00299 
00300     /* -- Simulate that current time is equal to 1200 us -- */
00301     curr_ticker_ticks_val = 1200;
00302 
00303     /* Stop the timer. */
00304     p_timer->stop();
00305 
00306     /* Check results - 1 ms has elapsed. */
00307     TEST_ASSERT_EQUAL_FLOAT(0.001000f, p_timer->read());
00308     TEST_ASSERT_EQUAL_INT32(1, p_timer->read_ms());
00309     TEST_ASSERT_EQUAL_INT32(1000, p_timer->read_us());
00310     TEST_ASSERT_EQUAL_UINT64(1000, p_timer->read_high_resolution_us());
00311 
00312     /* Simulate that 100 us has elapsed between stop and start. */
00313     curr_ticker_ticks_val = 1300;
00314 
00315     /* Start the timer. */
00316     p_timer->start();
00317 
00318     /* -- Simulate that current time is equal to 125300 us -- */
00319     curr_ticker_ticks_val = 125300;
00320 
00321     /* Stop the timer. */
00322     p_timer->stop();
00323 
00324     /* Check results - 125 ms have elapsed. */
00325     TEST_ASSERT_EQUAL_FLOAT(0.125000f, p_timer->read());
00326     TEST_ASSERT_EQUAL_INT32(125, p_timer->read_ms());
00327     TEST_ASSERT_EQUAL_INT32(125000, p_timer->read_us());
00328     TEST_ASSERT_EQUAL_UINT64(125000, p_timer->read_high_resolution_us());
00329 
00330     /* Simulate that 100 us has elapsed between stop and start. */
00331     curr_ticker_ticks_val = 125400;
00332 
00333     /* Start the timer. */
00334     p_timer->start();
00335 
00336     /* -- Simulate that current time is equal to 1000400 us -- */
00337     curr_ticker_ticks_val = 1000400;
00338 
00339     /* Stop the timer. */
00340     p_timer->stop();
00341 
00342     /* Check results - 1 s has elapsed. */
00343     TEST_ASSERT_EQUAL_FLOAT(1.000000f, p_timer->read());
00344     TEST_ASSERT_EQUAL_INT32(1000, p_timer->read_ms());
00345     TEST_ASSERT_EQUAL_INT32(1000000, p_timer->read_us());
00346     TEST_ASSERT_EQUAL_UINT64(1000000, p_timer->read_high_resolution_us());
00347 
00348     /* Simulate that 100 us has elapsed between stop and start. */
00349     curr_ticker_ticks_val = 1000500;
00350 
00351     /* Start the timer. */
00352     p_timer->start();
00353 
00354     /* -- Simulate that current time is equal to 125000500 us -- */
00355     curr_ticker_ticks_val = 125000500;
00356 
00357     /* Stop the timer. */
00358     p_timer->stop();
00359 
00360     /* Check results - 125 s have elapsed. */
00361     TEST_ASSERT_EQUAL_FLOAT(125.000000f, p_timer->read());
00362     TEST_ASSERT_EQUAL_INT32(125000, p_timer->read_ms());
00363     TEST_ASSERT_EQUAL_INT32(125000000, p_timer->read_us());
00364     TEST_ASSERT_EQUAL_UINT64(125000000, p_timer->read_high_resolution_us());
00365 
00366     /* Simulate that 100 us has elapsed between stop and start. */
00367     curr_ticker_ticks_val = 125000600;
00368 
00369     /* Start the timer. */
00370     p_timer->start();
00371 
00372     /* -- Simulate that current time is equal to MAX_INT_32 us + 600 us (delays
00373      *    between stops and starts) -- */
00374 
00375     /* Note that ticker is based on unsigned 32-bit int microsecond counters
00376      * while timers are based on 32-bit signed int microsecond counters,
00377      * so timers can only count up to a maximum of 2^31-1 microseconds i.e.
00378      * 2147483647 us (about 35 minutes). */
00379     curr_ticker_ticks_val = 2147484247;
00380 
00381     /* Stop the timer. */
00382     p_timer->stop();
00383 
00384     /* Check results - 2147483647 (MAX_INT_32) us have elapsed. */
00385     TEST_ASSERT_EQUAL_FLOAT(2147.483647f, p_timer->read());
00386     TEST_ASSERT_EQUAL_INT32(2147483, p_timer->read_ms());
00387     TEST_ASSERT_EQUAL_INT32(2147483647, p_timer->read_us());
00388     TEST_ASSERT_EQUAL_UINT64(2147483647, p_timer->read_high_resolution_us());
00389 }
00390 
00391 /* This test verifies if read(), read_us(), read_ms(),
00392  * read_high_resolution_us()
00393  * functions return time accumulated between
00394  * timer starts and stops.
00395  *
00396  * Note this function assumes that Timer uses os ticker.
00397  *
00398  * Given Timer has been successfully created and
00399  * few times started and stopped after a specified period of time.
00400  * When timer read request is performed.
00401  * Then read functions return accumulated time elapsed between starts
00402  * and stops.
00403  */
00404 void test_timer_time_accumulation_os_ticker()
00405 {
00406     /* Start the timer. */
00407     p_timer->start();
00408 
00409     /* Wait 10 ms. */
00410     wait_ms(10);
00411 
00412     /* Stop the timer. */
00413     p_timer->stop();
00414 
00415     /* Check results - totally 10 ms have elapsed. */
00416     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(1), 0.010f, p_timer->read());
00417     TEST_ASSERT_INT32_WITHIN(DELTA_MS(1), 10, p_timer->read_ms());
00418     TEST_ASSERT_INT32_WITHIN(DELTA_US(1), 10000, p_timer->read_us());
00419     TEST_ASSERT_UINT64_WITHIN(DELTA_US(1), 10000, p_timer->read_high_resolution_us());
00420 
00421     /* Wait 50 ms - this is done to show that time elapsed when
00422      * the timer is stopped does not have influence on the
00423      * timer counted time. */
00424     wait_ms(50);
00425 
00426     /* ------ */
00427 
00428     /* Start the timer. */
00429     p_timer->start();
00430 
00431     /* Wait 20 ms. */
00432     wait_ms(20);
00433 
00434     /* Stop the timer. */
00435     p_timer->stop();
00436 
00437     /* Check results - totally 30 ms have elapsed. */
00438     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(2), 0.030f, p_timer->read());
00439     TEST_ASSERT_INT32_WITHIN(DELTA_MS(2), 30, p_timer->read_ms());
00440     TEST_ASSERT_INT32_WITHIN(DELTA_US(2), 30000, p_timer->read_us());
00441     TEST_ASSERT_UINT64_WITHIN(DELTA_US(2), 30000, p_timer->read_high_resolution_us());
00442 
00443     /* Wait 50 ms - this is done to show that time elapsed when
00444      * the timer is stopped does not have influence on the
00445      * timer counted time. */
00446 
00447     /* ------ */
00448 
00449     /* Start the timer. */
00450     p_timer->start();
00451 
00452     /* Wait 30 ms. */
00453     wait_ms(30);
00454 
00455     /* Stop the timer. */
00456     p_timer->stop();
00457 
00458     /* Check results - totally 60 ms have elapsed. */
00459     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(3), 0.060f, p_timer->read());
00460     TEST_ASSERT_INT32_WITHIN(DELTA_MS(3), 60, p_timer->read_ms());
00461     TEST_ASSERT_INT32_WITHIN(DELTA_US(3), 60000, p_timer->read_us());
00462     TEST_ASSERT_UINT64_WITHIN(DELTA_US(3), 60000, p_timer->read_high_resolution_us());
00463 
00464     /* Wait 50 ms - this is done to show that time elapsed when
00465      * the timer is stopped does not have influence on the
00466      * timer time. */
00467     wait_ms(50);
00468 
00469     /* ------ */
00470 
00471     /* Start the timer. */
00472     p_timer->start();
00473 
00474     /* Wait 1 sec. */
00475     wait_ms(1000);
00476 
00477     /* Stop the timer. */
00478     p_timer->stop();
00479 
00480     /* Check results - totally 1060 ms have elapsed. */
00481     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(4), 1.060f, p_timer->read());
00482     TEST_ASSERT_INT32_WITHIN(DELTA_MS(4), 1060, p_timer->read_ms());
00483     TEST_ASSERT_INT32_WITHIN(DELTA_US(4), 1060000, p_timer->read_us());
00484     TEST_ASSERT_UINT64_WITHIN(DELTA_US(4), 1060000, p_timer->read_high_resolution_us());
00485 }
00486 
00487 /* This test verifies if reset() function resets the timer
00488  * counted time.
00489  *
00490  * Note this function assumes that Timer uses os ticker.
00491  *
00492  * Given timer has been started and stopped once, then reset
00493  * operation was performed.
00494  * When timer is started and stopped next time.
00495  * Then timer read functions returns only the the second
00496  * measured time.
00497  */
00498 void test_timer_reset_os_ticker()
00499 {
00500     /* First measure 10 ms delay. */
00501     p_timer->start();
00502 
00503     /* Wait 10 ms. */
00504     wait_ms(10);
00505 
00506     /* Stop the timer. */
00507     p_timer->stop();
00508 
00509     /* Check results - totally 10 ms elapsed. */
00510     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(1), 0.010f, p_timer->read());
00511     TEST_ASSERT_INT32_WITHIN(DELTA_MS(1), 10, p_timer->read_ms());
00512     TEST_ASSERT_INT32_WITHIN(DELTA_US(1), 10000, p_timer->read_us());
00513     TEST_ASSERT_UINT64_WITHIN(DELTA_US(1), 10000, p_timer->read_high_resolution_us());
00514 
00515     /* Reset the timer - previous measured time should be lost now. */
00516     p_timer->reset();
00517 
00518     /* Now measure 20 ms delay. */
00519     p_timer->start();
00520 
00521     /* Wait 20 ms. */
00522     wait_ms(20);
00523 
00524     /* Stop the timer. */
00525     p_timer->stop();
00526 
00527     /* Check results - 20 ms elapsed since the reset. */
00528     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(1), 0.020f, p_timer->read());
00529     TEST_ASSERT_INT32_WITHIN(DELTA_MS(1), 20, p_timer->read_ms());
00530     TEST_ASSERT_INT32_WITHIN(DELTA_US(1), 20000, p_timer->read_us());
00531     TEST_ASSERT_UINT64_WITHIN(DELTA_US(1), 20000, p_timer->read_high_resolution_us());
00532 }
00533 
00534 /* This test verifies if reset() function resets the timer
00535  * counted time.
00536  *
00537  * Note this function assumes that Timer uses user ticker.
00538  *
00539  * Given timer has been started and stopped once, then reset
00540  * operation was performed.
00541  * When timer is started and stopped next time.
00542  * Then timer read functions returns only the the second
00543  * measured time.
00544  */
00545 void test_timer_reset_user_ticker()
00546 {
00547     /* For timer which is using user ticker simulate set current
00548      * time (irrelevant in case of os ticker). */
00549     curr_ticker_ticks_val = 0;
00550 
00551     /* First measure 10 ms delay. */
00552     p_timer->start();
00553 
00554     /* Simulate that 10 ms have elapsed. */
00555     curr_ticker_ticks_val = 10000;
00556 
00557     /* Stop the timer. */
00558     p_timer->stop();
00559 
00560     /* Check results - totally 10 ms elapsed. */
00561     TEST_ASSERT_EQUAL_FLOAT(0.010f, p_timer->read());
00562     TEST_ASSERT_EQUAL_INT32(10, p_timer->read_ms());
00563     TEST_ASSERT_EQUAL_INT32(10000, p_timer->read_us());
00564     TEST_ASSERT_EQUAL_UINT64(10000, p_timer->read_high_resolution_us());
00565 
00566     /* Reset the timer - previous measured time should be lost now. */
00567     p_timer->reset();
00568 
00569     /* Now measure 20 ms delay. */
00570     p_timer->start();
00571 
00572     /* Simulate that 20 ms have elapsed. */
00573     curr_ticker_ticks_val = 30000;
00574 
00575     /* Stop the timer. */
00576     p_timer->stop();
00577 
00578     /* Check results - 20 ms elapsed since the reset. */
00579     TEST_ASSERT_EQUAL_FLOAT(0.020f, p_timer->read());
00580     TEST_ASSERT_EQUAL_INT32(20, p_timer->read_ms());
00581     TEST_ASSERT_EQUAL_INT32(20000, p_timer->read_us());
00582     TEST_ASSERT_EQUAL_UINT64(20000, p_timer->read_high_resolution_us());
00583 }
00584 
00585 /* This test verifies if calling start() for already
00586  * started timer does nothing.
00587  *
00588  * Note this function assumes that Timer uses os ticker.
00589  *
00590  * Given timer is already started.
00591  * When timer is started again.
00592  * Then second start operation is ignored.
00593  */
00594 void test_timer_start_started_timer_os_ticker()
00595 {
00596     /* Start the timer. */
00597     p_timer->start();
00598 
00599     /* Wait 10 ms. */
00600     wait_ms(10);
00601 
00602     /* Now start timer again. */
00603     p_timer->start();
00604 
00605     /* Wait 20 ms. */
00606     wait_ms(20);
00607 
00608     /* Stop the timer. */
00609     p_timer->stop();
00610 
00611     /* Check results - 30 ms have elapsed since the first start. */
00612     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(2), 0.030f, p_timer->read());
00613     TEST_ASSERT_INT32_WITHIN(DELTA_MS(2), 30, p_timer->read_ms());
00614     TEST_ASSERT_INT32_WITHIN(DELTA_US(2), 30000, p_timer->read_us());
00615     TEST_ASSERT_UINT64_WITHIN(DELTA_US(2), 30000, p_timer->read_high_resolution_us());
00616 }
00617 
00618 /* This test verifies if calling start() for already
00619  * started timer does nothing.
00620  *
00621  * Note this function assumes that Timer uses user ticker.
00622  *
00623  * Given timer is already started.
00624  * When timer is started again.
00625  * Then second start operation is ignored.
00626  */
00627 void test_timer_start_started_timer_user_ticker()
00628 {
00629     /* For timer which is using user ticker set current
00630      * time (irrelevant in case of os ticker). */
00631     curr_ticker_ticks_val = 0;
00632 
00633     /* Start the timer. */
00634     p_timer->start();
00635 
00636     /* Simulate that 10 ms have elapsed. */
00637     curr_ticker_ticks_val = 10000;
00638 
00639     /* Now start timer again. */
00640     p_timer->start();
00641 
00642     /* Simulate that 20 ms have elapsed. */
00643     curr_ticker_ticks_val = 30000;
00644 
00645     /* Stop the timer. */
00646     p_timer->stop();
00647 
00648     /* Check results - 30 ms have elapsed since the first start. */
00649     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(2), 0.030f, p_timer->read());
00650     TEST_ASSERT_INT32_WITHIN(DELTA_MS(2), 30, p_timer->read_ms());
00651     TEST_ASSERT_INT32_WITHIN(DELTA_US(2), 30000, p_timer->read_us());
00652     TEST_ASSERT_UINT64_WITHIN(DELTA_US(2), 30000, p_timer->read_high_resolution_us());
00653 }
00654 
00655 /* This test verifies Timer float operator.
00656  *
00657  * Note this function assumes that Timer uses os ticker.
00658  *
00659  * Given timer is created and a time period time is counted.
00660  * When timer object is casted on float type.
00661  * Then counted type in seconds is returned by means of
00662  * read() function.
00663  */
00664 void test_timer_float_operator_os_ticker()
00665 {
00666     /* Start the timer. */
00667     p_timer->start();
00668 
00669     /* Wait 10 ms. */
00670     wait_ms(10);
00671 
00672     /* Stop the timer. */
00673     p_timer->stop();
00674 
00675     /* Check result - 10 ms elapsed. */
00676     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(1), 0.010f, (float)(*p_timer));
00677 }
00678 
00679 /* This test verifies Timer float operator.
00680  *
00681  * Note this function assumes that Timer uses user ticker.
00682  *
00683  * Given timer is created and a time period time is counted.
00684  * When timer object is casted on float type.
00685  * Then counted type in seconds is returned by means of
00686  * read() function.
00687  */
00688 void test_timer_float_operator_user_ticker()
00689 {
00690     /* For timer which is using user ticker set current
00691      * time (irrelevant in case of os ticker). */
00692     curr_ticker_ticks_val = 0;
00693 
00694     /* Start the timer. */
00695     p_timer->start();
00696 
00697     /* Simulate that 10 ms have elapsed. */
00698     curr_ticker_ticks_val = 10000;
00699 
00700     /* Stop the timer. */
00701     p_timer->stop();
00702 
00703     /* Check result - 10 ms elapsed. */
00704     TEST_ASSERT_EQUAL_FLOAT(0.010f, (float)(*p_timer));
00705 }
00706 
00707 /* This test verifies if time counted by the timer is
00708  * valid.
00709  *
00710  * For this test Timer which uses os ticker
00711  * must be used.
00712  *
00713  * Given timer is created.
00714  * When timer is used to measure 1ms/10ms/100ms/1s
00715  * delays.
00716  * Then the results are valid (within acceptable range).
00717  */
00718 template<int wait_val_us>
00719 void test_timer_time_measurement()
00720 {
00721     /* Start the timer. */
00722     p_timer->start();
00723 
00724     /* Wait <wait_val_us> us. */
00725     wait_us(wait_val_us);
00726 
00727     /* Stop the timer. */
00728     p_timer->stop();
00729 
00730     /* Check results. */
00731     TEST_ASSERT_FLOAT_WITHIN(DELTA_S(1), (float)wait_val_us / 1000000, p_timer->read());
00732     TEST_ASSERT_INT32_WITHIN(DELTA_MS(1), wait_val_us / 1000, p_timer->read_ms());
00733     TEST_ASSERT_INT32_WITHIN(DELTA_US(1), wait_val_us, p_timer->read_us());
00734     TEST_ASSERT_UINT64_WITHIN(DELTA_US(1), wait_val_us, p_timer->read_high_resolution_us());
00735 }
00736 
00737 utest::v1::status_t test_setup(const size_t number_of_cases) {
00738     GREENTEA_SETUP(15, "default_auto");
00739     return verbose_test_setup_handler(number_of_cases);
00740 }
00741 
00742 Case cases[] = {
00743     Case("Test: Timer (based on os ticker) is stopped after creation.", timer_os_ticker_setup_handler, test_timer_creation_os_ticker, cleanup_handler),
00744     Case("Test: Timer (based on user ticker) is stopped after creation.", timer_user_ticker_setup_handler, test_timer_creation_user_ticker, cleanup_handler),
00745 
00746     Case("Test: Timer (based on os ticker) - measured time accumulation.", timer_os_ticker_setup_handler, test_timer_time_accumulation_os_ticker, cleanup_handler),
00747     Case("Test: Timer (based on user ticker) measured time accumulation.", timer_user_ticker_setup_handler, test_timer_time_accumulation_user_ticker, cleanup_handler),
00748 
00749     Case("Test: Timer (based on os ticker) - reset.", timer_os_ticker_setup_handler, test_timer_reset_os_ticker, cleanup_handler),
00750     Case("Test: Timer (based on user ticker) - reset.", timer_user_ticker_setup_handler, test_timer_reset_user_ticker, cleanup_handler),
00751 
00752     Case("Test: Timer (based on os ticker) - start started timer.", timer_os_ticker_setup_handler, test_timer_start_started_timer_os_ticker, cleanup_handler),
00753     Case("Test: Timer (based on user ticker) - start started timer.", timer_user_ticker_setup_handler, test_timer_start_started_timer_user_ticker, cleanup_handler),
00754 
00755     Case("Test: Timer (based on os ticker) - float operator.", timer_os_ticker_setup_handler, test_timer_float_operator_os_ticker, cleanup_handler),
00756     Case("Test: Timer (based on user ticker) - float operator.", timer_user_ticker_setup_handler, test_timer_float_operator_user_ticker, cleanup_handler),
00757 
00758     Case("Test: Timer - time measurement 1 ms.", timer_os_ticker_setup_handler, test_timer_time_measurement<1000>, cleanup_handler),
00759     Case("Test: Timer - time measurement 10 ms.", timer_os_ticker_setup_handler, test_timer_time_measurement<10000>, cleanup_handler),
00760     Case("Test: Timer - time measurement 100 ms.", timer_os_ticker_setup_handler, test_timer_time_measurement<100000>, cleanup_handler),
00761     Case("Test: Timer - time measurement 1 s.", timer_os_ticker_setup_handler, test_timer_time_measurement<1000000>, cleanup_handler),
00762 };
00763 
00764 Specification specification(test_setup, cases);
00765 
00766 int main() {
00767     return !Harness::run(specification);
00768 }
00769