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 00017 #define __STDC_LIMIT_MACROS 00018 #include <stdint.h> 00019 #include <algorithm> 00020 00021 #include "utest/utest.h" 00022 #include "unity/unity.h" 00023 #include "greentea-client/test_env.h" 00024 00025 #include "mbed.h" 00026 #include "ticker_api.h" 00027 00028 using namespace utest::v1; 00029 00030 #define MBED_ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0])) 00031 00032 #define TIMESTAMP_MAX_DELTA_BITS(bits) ((uint64_t)(0x7 << ((bits) - 4))) 00033 #define TIMESTAMP_MAX_DELTA TIMESTAMP_MAX_DELTA_BITS(32) 00034 00035 struct ticker_interface_stub_t { 00036 ticker_interface_t interface; 00037 bool initialized; 00038 bool interrupt_flag; 00039 timestamp_t timestamp ; 00040 timestamp_t interrupt_timestamp; 00041 unsigned int init_call; 00042 unsigned int read_call; 00043 unsigned int disable_interrupt_call; 00044 unsigned int clear_interrupt_call; 00045 unsigned int set_interrupt_call; 00046 unsigned int fire_interrupt_call; 00047 unsigned int get_info_call; 00048 }; 00049 00050 static ticker_interface_stub_t interface_stub = { 0 }; 00051 static ticker_info_t interface_info_stub = { 0 }; 00052 00053 static void ticker_interface_stub_init() 00054 { 00055 ++interface_stub.init_call; 00056 interface_stub.initialized = true; 00057 } 00058 00059 static uint32_t ticker_interface_stub_read() 00060 { 00061 ++interface_stub.read_call; 00062 return interface_stub.timestamp; 00063 } 00064 00065 static void ticker_interface_stub_disable_interrupt() 00066 { 00067 ++interface_stub.disable_interrupt_call; 00068 } 00069 00070 static void ticker_interface_stub_clear_interrupt() 00071 { 00072 ++interface_stub.clear_interrupt_call; 00073 interface_stub.interrupt_flag = false; 00074 } 00075 00076 static void ticker_interface_stub_set_interrupt(timestamp_t timestamp) 00077 { 00078 ++interface_stub.set_interrupt_call; 00079 interface_stub.interrupt_timestamp = timestamp; 00080 } 00081 00082 static void ticker_interface_stub_fire_interrupt() 00083 { 00084 ++interface_stub.fire_interrupt_call; 00085 } 00086 00087 static const ticker_info_t *ticker_interface_stub_get_info() 00088 { 00089 ++interface_stub.get_info_call; 00090 return &interface_info_stub; 00091 } 00092 00093 static void reset_ticker_interface_stub() 00094 { 00095 interface_stub.interface.init = ticker_interface_stub_init; 00096 interface_stub.interface.read = ticker_interface_stub_read; 00097 interface_stub.interface.disable_interrupt = 00098 ticker_interface_stub_disable_interrupt; 00099 interface_stub.interface.clear_interrupt = 00100 ticker_interface_stub_clear_interrupt; 00101 interface_stub.interface.set_interrupt =ticker_interface_stub_set_interrupt; 00102 interface_stub.interface.fire_interrupt = ticker_interface_stub_fire_interrupt; 00103 interface_stub.interface.get_info = ticker_interface_stub_get_info; 00104 interface_stub.initialized = false; 00105 interface_stub.interrupt_flag = false; 00106 interface_stub.timestamp = 0; 00107 interface_stub.interrupt_timestamp = 0; 00108 interface_stub.init_call = 0; 00109 interface_stub.read_call = 0; 00110 interface_stub.disable_interrupt_call = 0; 00111 interface_stub.clear_interrupt_call = 0; 00112 interface_stub.set_interrupt_call = 0; 00113 interface_stub.fire_interrupt_call = 0; 00114 00115 interface_info_stub.frequency = 1000000; 00116 interface_info_stub.bits = 32; 00117 } 00118 00119 // stub of the event queue 00120 static ticker_event_queue_t queue_stub = { 00121 /* event handler */ NULL, 00122 /* head */ NULL, 00123 /* timestamp */ 0, 00124 /* initialized */ false 00125 }; 00126 00127 static void reset_queue_stub() 00128 { 00129 queue_stub.event_handler = NULL; 00130 queue_stub.head = NULL, 00131 queue_stub.tick_last_read = 0; 00132 queue_stub.tick_remainder = 0; 00133 queue_stub.frequency = 0; 00134 queue_stub.bitmask = 0; 00135 queue_stub.max_delta = 0; 00136 queue_stub.max_delta_us = 0; 00137 queue_stub.present_time = 0; 00138 queue_stub.initialized = false; 00139 } 00140 00141 // stub of the ticker 00142 static ticker_data_t ticker_stub = { 00143 /* interface */ &interface_stub.interface, 00144 /* queue */ &queue_stub 00145 }; 00146 00147 static void reset_ticker_stub() 00148 { 00149 reset_queue_stub(); 00150 reset_ticker_interface_stub(); 00151 } 00152 00153 const uint32_t test_frequencies[] = { 00154 1, 00155 32768, // 2^15 00156 1000000, 00157 0xFFFFFFFF // 2^32 - 1 00158 }; 00159 00160 const uint32_t test_bitwidths[] = { 00161 32, 00162 31, 00163 16, 00164 8 00165 }; 00166 00167 template < void (F)(uint32_t a, uint32_t b)> 00168 static void test_over_frequency_and_width(void) 00169 { 00170 for (unsigned int i = 0; i < MBED_ARRAY_SIZE(test_frequencies); i++) { 00171 for (unsigned int j = 0; j < MBED_ARRAY_SIZE(test_bitwidths); j++) { 00172 reset_ticker_stub(); 00173 interface_info_stub.frequency = test_frequencies[i]; 00174 interface_info_stub.bits = test_bitwidths[j]; 00175 00176 F(test_frequencies[i], test_bitwidths[j]); 00177 } 00178 } 00179 } 00180 00181 static utest::v1::status_t case_setup_handler( 00182 const Case *const source, const size_t index_of_case 00183 ) { 00184 utest::v1::status_t status = greentea_case_setup_handler(source, index_of_case); 00185 reset_ticker_stub(); 00186 return status; 00187 } 00188 00189 static utest::v1::status_t case_teardown_handler( 00190 const Case *const source, const size_t passed, const size_t failed, const failure_t reason 00191 ) { 00192 reset_ticker_stub(); 00193 utest::v1::status_t status = greentea_case_teardown_handler( 00194 source, passed, failed, reason 00195 ); 00196 return status; 00197 } 00198 00199 static utest::v1::status_t greentea_failure_handler( 00200 const Case *const source, const failure_t reason 00201 ) { 00202 utest::v1::status_t status = greentea_case_failure_abort_handler( 00203 source, reason 00204 ); 00205 return status; 00206 } 00207 00208 #define MAKE_TEST_CASE(description, handler) \ 00209 { \ 00210 description, \ 00211 handler, \ 00212 NULL, \ 00213 NULL, \ 00214 case_setup_handler, \ 00215 case_teardown_handler, \ 00216 greentea_failure_handler \ 00217 } 00218 00219 /** 00220 * Given an unitialized ticker_data instance. 00221 * When the ticker is initialized 00222 * Then: 00223 * - The ticker interface should be initialized 00224 * - The queue handler should be set to the handler provided in parameter 00225 * - The internal ticker timestamp should be zero 00226 * - interrupt should be scheduled in current timestamp + 00227 * TIMESTAMP_MAX_DELTA 00228 * - The queue should not contains any event 00229 */ 00230 static void test_ticker_initialization() 00231 { 00232 ticker_event_handler dummy_handler = (ticker_event_handler)0xDEADBEEF; 00233 00234 // setup of the stub 00235 interface_stub.timestamp = 0xFEEDBABE; 00236 00237 ticker_set_handler(&ticker_stub, dummy_handler); 00238 00239 TEST_ASSERT_TRUE(interface_stub.initialized); 00240 TEST_ASSERT_EQUAL_PTR(dummy_handler, queue_stub.event_handler); 00241 TEST_ASSERT_EQUAL_UINT64(0, queue_stub.present_time); 00242 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); 00243 TEST_ASSERT_EQUAL_UINT32( 00244 interface_stub.timestamp + TIMESTAMP_MAX_DELTA, 00245 interface_stub.interrupt_timestamp 00246 ); 00247 TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head); 00248 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 00249 } 00250 00251 /** 00252 * Given an initialized ticker_data instance. 00253 * When the ticker handler is set to a new value 00254 * Then: 00255 * - The ticker interface initialization function should not be called. 00256 * - The queue handler should be set to the new handler. 00257 * - The events in the queue should remains the same. 00258 */ 00259 static void test_ticker_re_initialization() 00260 { 00261 ticker_event_handler dummy_handler = (ticker_event_handler) 0xDEADBEEF; 00262 ticker_event_handler expected_handler = (ticker_event_handler) 0xFEEDDEAF; 00263 00264 ticker_event_t first_event = { 0 }; 00265 ticker_event_t second_event = { 0 }; 00266 ticker_event_t third_event = { 0 }; 00267 00268 first_event.next = &second_event; 00269 second_event.next = &third_event; 00270 00271 // initialize the ticker and put few events in the queue. 00272 ticker_set_handler(&ticker_stub, dummy_handler); 00273 // simulate insertion, it shouldn't affect the queue behaviour for this test 00274 queue_stub.head = &first_event; 00275 interface_stub.init_call = 0; 00276 00277 ticker_set_handler(&ticker_stub, expected_handler); 00278 00279 TEST_ASSERT_TRUE(interface_stub.initialized); 00280 TEST_ASSERT_EQUAL(0, interface_stub.init_call); 00281 TEST_ASSERT_EQUAL(expected_handler, queue_stub.event_handler); 00282 TEST_ASSERT_EQUAL(&first_event, queue_stub.head); 00283 TEST_ASSERT_EQUAL(&second_event, queue_stub.head->next); 00284 TEST_ASSERT_EQUAL(&third_event, queue_stub.head->next->next); 00285 TEST_ASSERT_EQUAL(NULL, queue_stub.head->next->next->next); 00286 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 00287 } 00288 00289 /** 00290 * Given an initialized ticker_data instance. 00291 * When the ticker is read 00292 * Then it should return the value present in the ticker interface 00293 */ 00294 static void test_ticker_read() 00295 { 00296 ticker_set_handler(&ticker_stub, NULL); 00297 00298 timestamp_t timestamps[] = { 00299 0xA, 00300 0xAA, 00301 0xAAA, 00302 0xAAAA, 00303 0xAAAAA, 00304 0xAAAAAA, 00305 0xAAAAAAA, 00306 0xAAAAAAAA 00307 }; 00308 00309 for (size_t i = 0; i < MBED_ARRAY_SIZE(timestamps); ++i) { 00310 interface_stub.timestamp = timestamps[i]; 00311 TEST_ASSERT_EQUAL_UINT32(timestamps[i], ticker_read(&ticker_stub)); 00312 TEST_ASSERT_EQUAL_UINT64(timestamps[i], ticker_read_us(&ticker_stub)); 00313 } 00314 00315 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 00316 } 00317 00318 /** 00319 * Given an initialized ticker_data instance. 00320 * When the ticker is read and the value read is less than the previous 00321 * value read. 00322 * Then: 00323 * - ticker_read should return the value read in the ticker interface 00324 * - ticker_read_us should return a value where: 00325 * + lower 8 bytes should be equal to the value in the ticker interface 00326 * + upper 8 bytes should be equal to the previous value of upper 8 bytes 00327 * plus one. 00328 */ 00329 static void test_ticker_read_overflow() 00330 { 00331 const timestamp_t timestamps[] = { 00332 0xAAAAAAAA, 00333 0xAAAAAAA, 00334 0xAAAAAA, 00335 0xAAAAA, 00336 0xAAAA, 00337 0xAAA, 00338 0xAA, 00339 0xA 00340 }; 00341 00342 ticker_set_handler(&ticker_stub, NULL); 00343 00344 uint32_t upper_bytes_begin = ticker_read_us(&ticker_stub) >> 32; 00345 00346 for (size_t i = 0; i < MBED_ARRAY_SIZE(timestamps); ++i) { 00347 interface_stub.timestamp = timestamps[i]; 00348 TEST_ASSERT_EQUAL_UINT32(timestamps[i], ticker_read(&ticker_stub)); 00349 TEST_ASSERT_EQUAL_UINT32(timestamps[i], ticker_read_us(&ticker_stub)); 00350 TEST_ASSERT_EQUAL_UINT64( 00351 upper_bytes_begin + i, ticker_read_us(&ticker_stub) >> 32 00352 ); 00353 } 00354 00355 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 00356 } 00357 00358 /** 00359 * Given an initialized ticker without user registered events. 00360 * When an event is inserted with ticker_insert_event and the timestamp passed 00361 * in parameter is in range [ticker_timestamp : ticker_timestamp + 00362 * TIMESTAMP_MAX_DELTA[. 00363 * Then 00364 * - The event should be in the queue 00365 * - The interrupt timestamp should be equal to the timestamp of the event 00366 * - The timestamp of the event should reflect the timestamp requested. 00367 * - The id of the event should be equal to the id passed in parameter. 00368 */ 00369 static void test_legacy_insert_event_outside_overflow_range() 00370 { 00371 ticker_set_handler(&ticker_stub, NULL); 00372 interface_stub.set_interrupt_call = 0; 00373 00374 // test the end of the range 00375 ticker_event_t last_event = { 0 }; 00376 const timestamp_t timestamp_last_event = 00377 interface_stub.timestamp + TIMESTAMP_MAX_DELTA; 00378 const uint32_t id_last_event = 0xDEADDEAF; 00379 00380 ticker_insert_event( 00381 &ticker_stub, 00382 &last_event, timestamp_last_event, id_last_event 00383 ); 00384 00385 TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head); 00386 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); 00387 TEST_ASSERT_EQUAL_UINT32( 00388 timestamp_last_event, interface_stub.interrupt_timestamp 00389 ); 00390 TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next); 00391 TEST_ASSERT_EQUAL_UINT32(timestamp_last_event, last_event.timestamp); 00392 TEST_ASSERT_EQUAL_UINT32(id_last_event, last_event.id); 00393 00394 // test the beginning of the range 00395 ticker_event_t first_event = { 0 }; 00396 const timestamp_t timestamp_first_event = interface_stub.timestamp + 1; 00397 const uint32_t id_first_event = 0xAAAAAAAA; 00398 00399 ticker_insert_event( 00400 &ticker_stub, 00401 &first_event, timestamp_first_event, id_first_event 00402 ); 00403 00404 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head); 00405 TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call); 00406 TEST_ASSERT_EQUAL_UINT32( 00407 timestamp_first_event, interface_stub.interrupt_timestamp 00408 ); 00409 TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head->next); 00410 TEST_ASSERT_EQUAL_UINT32( 00411 timestamp_first_event, first_event.timestamp 00412 ); 00413 TEST_ASSERT_EQUAL_UINT32(id_first_event, first_event.id); 00414 00415 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 00416 } 00417 00418 /** 00419 * Given an initialized ticker without user registered events. 00420 * When an event is inserted with ticker_insert_event and a timestamp in the 00421 * range [ticker_timestamp + TIMESTAMP_MAX_DELTA + 1 : 00422 * ticker_timestamp + UINT32MAX [ 00423 * Then 00424 * - The event should be in the queue 00425 * - The interrupt timestamp should be equal to 00426 * TIMESTAMP_MAX_DELTA 00427 * - The timestamp of the event should reflect the timestamp requested. 00428 * - The id of the event should be equal to the id passed in parameter. 00429 */ 00430 static void test_legacy_insert_event_in_overflow_range() 00431 { 00432 ticker_set_handler(&ticker_stub, NULL); 00433 interface_stub.set_interrupt_call = 0; 00434 00435 // test the end of the range 00436 ticker_event_t last_event = { 0 }; 00437 const timestamp_t timestamp_last_event = 00438 interface_stub.timestamp + UINT32_MAX; 00439 const uint32_t id_last_event = 0xDEADDEAF; 00440 00441 ticker_insert_event( 00442 &ticker_stub, 00443 &last_event, timestamp_last_event, id_last_event 00444 ); 00445 00446 TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head); 00447 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); 00448 TEST_ASSERT_EQUAL_UINT32( 00449 interface_stub.timestamp + TIMESTAMP_MAX_DELTA, 00450 interface_stub.interrupt_timestamp 00451 ); 00452 TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next); 00453 TEST_ASSERT_EQUAL_UINT32(timestamp_last_event, last_event.timestamp); 00454 TEST_ASSERT_EQUAL_UINT32(id_last_event, last_event.id); 00455 00456 // test the beginning of the range 00457 ++interface_stub.timestamp; 00458 00459 ticker_event_t first_event = { 0 }; 00460 const timestamp_t timestamp_first_event = 00461 interface_stub.timestamp + TIMESTAMP_MAX_DELTA + 1; 00462 const uint32_t id_first_event = 0xAAAAAAAA; 00463 00464 ticker_insert_event( 00465 &ticker_stub, 00466 &first_event, timestamp_first_event, id_first_event 00467 ); 00468 00469 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head); 00470 TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call); 00471 TEST_ASSERT_EQUAL_UINT32( 00472 interface_stub.timestamp + TIMESTAMP_MAX_DELTA, 00473 interface_stub.interrupt_timestamp 00474 ); 00475 TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head->next); 00476 TEST_ASSERT_EQUAL_UINT32( 00477 timestamp_first_event, first_event.timestamp 00478 ); 00479 TEST_ASSERT_EQUAL_UINT32(id_first_event, first_event.id); 00480 00481 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 00482 } 00483 00484 /** 00485 * Given an initialized ticker without user registered events. 00486 * When an event is inserted with ticker_insert_event and the timestamp in 00487 * parameter is less than the current timestamp value. 00488 * Then 00489 * - The event should be in the queue 00490 * - The timestamp of the event should reflect the timestamp requested: 00491 * + lower 8 bytes should be equal to the timestamp in input. 00492 * + upper 8 bytes should be equal to the upper of the upper 8 bytes of the 00493 * timestamp state stored in the queue plus one. 00494 * - The id of the event should be equal to the id passed in parameter. 00495 */ 00496 static void test_legacy_insert_event_overflow(){ 00497 ticker_set_handler(&ticker_stub, NULL); 00498 interface_stub.set_interrupt_call = 0; 00499 00500 interface_stub.timestamp = 0x20000000; 00501 ticker_read(&ticker_stub); 00502 00503 ticker_event_t event = { 0 }; 00504 const timestamp_t expected_timestamp = 00505 interface_stub.timestamp + 00506 TIMESTAMP_MAX_DELTA + 00507 1; 00508 const us_timestamp_t expected_us_timestamp = 00509 (((queue_stub.present_time >> 32) + 1) << 32) | expected_timestamp; 00510 const uint32_t expected_id = 0xDEADDEAF; 00511 00512 ticker_insert_event( 00513 &ticker_stub, 00514 &event, expected_timestamp, expected_id 00515 ); 00516 00517 TEST_ASSERT_EQUAL_PTR(&event, queue_stub.head); 00518 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); 00519 TEST_ASSERT_EQUAL_UINT32( 00520 interface_stub.timestamp + TIMESTAMP_MAX_DELTA, 00521 interface_stub.interrupt_timestamp 00522 ); 00523 TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next); 00524 TEST_ASSERT_EQUAL_UINT32(expected_us_timestamp, event.timestamp); 00525 TEST_ASSERT_EQUAL_UINT32(expected_id, event.id); 00526 00527 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 00528 } 00529 00530 /** 00531 * Given an initialized ticker. 00532 * When an event is inserted with ticker_insert_event and a timestamp less than 00533 * the one for the next scheduled timestamp. 00534 * Then 00535 * - The event inserted should be the first in the queue 00536 * - The interrupt timestamp should be equal to the timestamp of the event or 00537 * TIMESTAMP_MAX_DELTA if in the overflow range. 00538 * - The timestamp of the event should reflect the timestamp requested. 00539 * - The id of the event should be equal to the id passed in parameter. 00540 * - Events in the queue should remained ordered by timestamp. 00541 */ 00542 static void test_legacy_insert_event_head() 00543 { 00544 ticker_set_handler(&ticker_stub, NULL); 00545 interface_stub.set_interrupt_call = 0; 00546 00547 const timestamp_t timestamps[] = { 00548 UINT32_MAX, 00549 TIMESTAMP_MAX_DELTA + 1, 00550 TIMESTAMP_MAX_DELTA, 00551 TIMESTAMP_MAX_DELTA / 2, 00552 TIMESTAMP_MAX_DELTA / 4, 00553 TIMESTAMP_MAX_DELTA / 8, 00554 TIMESTAMP_MAX_DELTA / 16, 00555 }; 00556 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; 00557 00558 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { 00559 ticker_insert_event( 00560 &ticker_stub, 00561 &events[i], timestamps[i], i 00562 ); 00563 00564 TEST_ASSERT_EQUAL_PTR(&events[i], queue_stub.head); 00565 TEST_ASSERT_EQUAL(i + 1, interface_stub.set_interrupt_call); 00566 if (timestamps[i] < TIMESTAMP_MAX_DELTA) { 00567 TEST_ASSERT_EQUAL_UINT32( 00568 timestamps[i], 00569 interface_stub.interrupt_timestamp 00570 ); 00571 } else { 00572 TEST_ASSERT_EQUAL_UINT32( 00573 TIMESTAMP_MAX_DELTA, 00574 interface_stub.interrupt_timestamp 00575 ); 00576 } 00577 00578 TEST_ASSERT_EQUAL_UINT32( 00579 timestamps[i], events[i].timestamp 00580 ); 00581 TEST_ASSERT_EQUAL_UINT32(i, events[i].id); 00582 00583 ticker_event_t* e = &events[i]; 00584 while (e) { 00585 TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp); 00586 if (e->next) { 00587 TEST_ASSERT_TRUE(e->id > e->next->id); 00588 TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp); 00589 } else { 00590 TEST_ASSERT_EQUAL_UINT32(0, e->id); 00591 } 00592 e = e->next; 00593 } 00594 } 00595 00596 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 00597 } 00598 00599 /** 00600 * Given an initialized ticker. 00601 * When an event is inserted with ticker_insert_event and its timestamp is bigger 00602 * than the one of the last event in the queue. 00603 * Then 00604 * - The event inserted should be the last in the queue 00605 * - The interrupt timestamp should remains equal to the interrupt timestamp 00606 * of the head event . 00607 * - The timestamp of the event should reflect the timestamp requested. 00608 * - The id of the event should be equal to the id passed in parameter. 00609 * - Events in the queue should remained ordered by timestamp. 00610 */ 00611 static void test_legacy_insert_event_tail() 00612 { 00613 ticker_set_handler(&ticker_stub, NULL); 00614 interface_stub.set_interrupt_call = 0; 00615 00616 const timestamp_t timestamps[] = { 00617 0xA, 00618 0xAA, 00619 0xAAA, 00620 0xAAAA, 00621 0xAAAAA, 00622 0xAAAAAA, 00623 0xAAAAAAA, 00624 0xAAAAAAAA, 00625 }; 00626 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; 00627 00628 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { 00629 ticker_insert_event( 00630 &ticker_stub, 00631 &events[i], timestamps[i], i 00632 ); 00633 00634 TEST_ASSERT_EQUAL_PTR(&events[0], queue_stub.head); 00635 TEST_ASSERT_EQUAL_UINT32( 00636 timestamps[0], interface_stub.interrupt_timestamp 00637 ); 00638 00639 TEST_ASSERT_EQUAL_UINT32(timestamps[i], events[i].timestamp); 00640 TEST_ASSERT_EQUAL_UINT32(i, events[i].id); 00641 00642 ticker_event_t* e = queue_stub.head; 00643 while (e) { 00644 TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp); 00645 if (e->next) { 00646 TEST_ASSERT_TRUE(e->id < e->next->id); 00647 TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp); 00648 } else { 00649 TEST_ASSERT_EQUAL_UINT32(&events[i], e); 00650 } 00651 e = e->next; 00652 } 00653 } 00654 00655 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 00656 } 00657 00658 /** 00659 * Given an initialized ticker. 00660 * When an event is inserted with ticker_insert_event and a timestamp less 00661 * than the current timestamp in the interface and less than the relative 00662 * timestamp of the next event to execute. 00663 * Then 00664 * - The event inserted should be after the head 00665 * - The interrupt timestamp should remains equal to the interrupt timestamp 00666 * of the head event . 00667 * - The timestamp of the event should reflect the timestamp requested (overflow) 00668 * - The id of the event should be equal to the id passed in parameter. 00669 * - Events in the queue should remained ordered by timestamp. 00670 */ 00671 static void test_legacy_insert_event_multiple_overflow() 00672 { 00673 ticker_set_handler(&ticker_stub, NULL); 00674 interface_stub.set_interrupt_call = 0; 00675 00676 const timestamp_t timestamps[] = { 00677 0xA, 00678 0xAA, 00679 0xAAA, 00680 0xAAAA, 00681 0xAAAAA, 00682 0xAAAAAA, 00683 0xAAAAAAA, 00684 0xAAAAAAAA 00685 }; 00686 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; 00687 00688 ticker_event_t ref_event; 00689 timestamp_t ref_event_timestamp = 0xCCCCCCCC; 00690 ticker_insert_event( 00691 &ticker_stub, 00692 &ref_event, ref_event_timestamp, 0xDEADBEEF 00693 ); 00694 00695 timestamp_t last_timestamp_to_insert = 00696 timestamps[MBED_ARRAY_SIZE(timestamps) - 1]; 00697 interface_stub.timestamp = 00698 last_timestamp_to_insert + 00699 ((ref_event_timestamp - last_timestamp_to_insert) / 2); 00700 00701 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { 00702 ticker_insert_event( 00703 &ticker_stub, 00704 &events[i], timestamps[i], i 00705 ); 00706 00707 TEST_ASSERT_EQUAL_PTR(&ref_event, queue_stub.head); 00708 TEST_ASSERT_EQUAL_PTR(&events[0], queue_stub.head->next); 00709 TEST_ASSERT_EQUAL_UINT32( 00710 ref_event_timestamp, interface_stub.interrupt_timestamp 00711 ); 00712 00713 TEST_ASSERT_EQUAL_UINT32(timestamps[i], events[i].timestamp); 00714 TEST_ASSERT_EQUAL_UINT32(i, events[i].id); 00715 00716 ticker_event_t* e = queue_stub.head->next; 00717 while (e) { 00718 TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp); 00719 if (e->next) { 00720 TEST_ASSERT_TRUE(e->id < e->next->id); 00721 TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp); 00722 } else { 00723 TEST_ASSERT_EQUAL_UINT32(&events[i], e); 00724 } 00725 e = e->next; 00726 } 00727 } 00728 00729 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 00730 } 00731 00732 /** 00733 * Given an initialized ticker. 00734 * When an event is inserted with ticker_insert_event. 00735 * Then 00736 * - The event inserted should be at the correct position in the queue 00737 * - The event queue should remain ordered by timestamp 00738 * - The interrupt timestamp should be equal to the interrupt timestamp 00739 * of the head event or TIMESTAMP_MAX_DELTA if the 00740 * timestamp is in the overflow range. 00741 * - The timestamp of the event should reflect the timestamp requested (overflow) 00742 * - The id of the event should be equal to the id passed in parameter. 00743 * - Events in the queue should remained ordered by timestamp. 00744 */ 00745 static void test_legacy_insert_event_multiple_random() 00746 { 00747 ticker_set_handler(&ticker_stub, NULL); 00748 interface_stub.set_interrupt_call = 0; 00749 00750 const timestamp_t ref_timestamp = UINT32_MAX / 2; 00751 interface_stub.timestamp = ref_timestamp; 00752 00753 // insert first event at the head of the queue 00754 ticker_event_t first_event; 00755 const timestamp_t first_event_timestamp = 00756 ref_timestamp + TIMESTAMP_MAX_DELTA + 100; 00757 00758 ticker_insert_event( 00759 &ticker_stub, 00760 &first_event, first_event_timestamp, (uint32_t) &first_event 00761 ); 00762 00763 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head); 00764 TEST_ASSERT_EQUAL_PTR(NULL, first_event.next); 00765 TEST_ASSERT_EQUAL_UINT32( 00766 ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp 00767 ); 00768 TEST_ASSERT_EQUAL_UINT32(first_event_timestamp, first_event.timestamp); 00769 TEST_ASSERT_EQUAL_UINT64( 00770 first_event.timestamp, 00771 first_event_timestamp + 00772 ((first_event_timestamp < ref_timestamp) ? (1ULL << 32) : 0) 00773 ); 00774 TEST_ASSERT_EQUAL_UINT32((uint32_t) &first_event, first_event.id); 00775 00776 // insert second event at the tail of the queue 00777 ticker_event_t second_event; 00778 const timestamp_t second_event_timestamp = first_event_timestamp + 1; 00779 00780 ticker_insert_event( 00781 &ticker_stub, 00782 &second_event, second_event_timestamp, (uint32_t) &second_event 00783 ); 00784 00785 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head); 00786 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next); 00787 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next); 00788 TEST_ASSERT_EQUAL_UINT32( 00789 ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp 00790 ); 00791 TEST_ASSERT_EQUAL_UINT32(second_event_timestamp, second_event.timestamp); 00792 TEST_ASSERT_EQUAL_UINT64( 00793 second_event.timestamp, 00794 second_event_timestamp + 00795 ((second_event_timestamp < ref_timestamp) ? (1ULL << 32) : 0) 00796 ); 00797 TEST_ASSERT_EQUAL_UINT32((uint32_t) &second_event, second_event.id); 00798 00799 00800 // insert third event at the head of the queue out the overflow zone 00801 ticker_event_t third_event; 00802 const timestamp_t third_event_timestamp = 00803 ref_timestamp + TIMESTAMP_MAX_DELTA - 100; 00804 00805 ticker_insert_event( 00806 &ticker_stub, 00807 &third_event, third_event_timestamp, (uint32_t) &third_event 00808 ); 00809 00810 TEST_ASSERT_EQUAL_PTR(&third_event, queue_stub.head); 00811 TEST_ASSERT_EQUAL_PTR(&first_event, third_event.next); 00812 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next); 00813 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next); 00814 TEST_ASSERT_EQUAL_UINT32( 00815 third_event_timestamp, interface_stub.interrupt_timestamp 00816 ); 00817 TEST_ASSERT_EQUAL_UINT32(third_event_timestamp, third_event.timestamp); 00818 TEST_ASSERT_EQUAL_UINT64( 00819 third_event.timestamp, 00820 third_event_timestamp + 00821 ((third_event_timestamp < ref_timestamp) ? (1ULL << 32) : 0) 00822 ); 00823 TEST_ASSERT_EQUAL_UINT32((uint32_t) &third_event, third_event.id); 00824 00825 // insert fourth event right after the third event 00826 ticker_event_t fourth_event; 00827 const timestamp_t fourth_event_timestamp = third_event_timestamp + 50; 00828 00829 ticker_insert_event( 00830 &ticker_stub, 00831 &fourth_event, fourth_event_timestamp, (uint32_t) &fourth_event 00832 ); 00833 00834 TEST_ASSERT_EQUAL_PTR(&third_event, queue_stub.head); 00835 TEST_ASSERT_EQUAL_PTR(&fourth_event, third_event.next); 00836 TEST_ASSERT_EQUAL_PTR(&first_event, fourth_event.next); 00837 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next); 00838 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next); 00839 TEST_ASSERT_EQUAL_UINT32( 00840 third_event_timestamp, interface_stub.interrupt_timestamp 00841 ); 00842 TEST_ASSERT_EQUAL_UINT32(fourth_event_timestamp, fourth_event.timestamp); 00843 TEST_ASSERT_EQUAL_UINT64( 00844 fourth_event.timestamp, 00845 fourth_event_timestamp + 00846 ((fourth_event_timestamp < ref_timestamp) ? (1ULL << 32) : 0) 00847 ); 00848 TEST_ASSERT_EQUAL_UINT32((uint32_t) &fourth_event, fourth_event.id); 00849 00850 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 00851 } 00852 00853 /** 00854 * Given an initialized ticker without user registered events. 00855 * When an event is inserted with ticker_insert_event_us and the timestamp passed 00856 * in parameter is in range [ticker_timestamp : ticker_timestamp + 00857 * TIMESTAMP_MAX_DELTA[. 00858 * Then 00859 * - The event should be in the queue 00860 * - The interrupt timestamp should be equal to the lower 8 bytes of the event. 00861 * - The timestamp of the event should be equal to the timestamp requested. 00862 * - The id of the event should be equal to the id passed in parameter. 00863 */ 00864 static void test_insert_event_us_outside_overflow_range() 00865 { 00866 ticker_set_handler(&ticker_stub, NULL); 00867 interface_stub.set_interrupt_call = 0; 00868 interface_stub.timestamp = 0xAAAAAAAA; 00869 queue_stub.tick_last_read = interface_stub.timestamp; 00870 queue_stub.present_time = 10ULL << 32 | interface_stub.timestamp; 00871 00872 // test the end of the range 00873 ticker_event_t last_event = { 0 }; 00874 const us_timestamp_t timestamp_last_event = 00875 queue_stub.present_time + TIMESTAMP_MAX_DELTA; 00876 const uint32_t id_last_event = 0xDEADDEAF; 00877 00878 ticker_insert_event_us( 00879 &ticker_stub, 00880 &last_event, timestamp_last_event, id_last_event 00881 ); 00882 00883 TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head); 00884 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); 00885 TEST_ASSERT_EQUAL_UINT32( 00886 timestamp_last_event, interface_stub.interrupt_timestamp 00887 ); 00888 TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next); 00889 TEST_ASSERT_EQUAL_UINT64(timestamp_last_event, last_event.timestamp); 00890 TEST_ASSERT_EQUAL_UINT32(id_last_event, last_event.id); 00891 00892 // test the beginning of the range 00893 ticker_event_t first_event = { 0 }; 00894 const us_timestamp_t timestamp_first_event = queue_stub.present_time + 1; 00895 const uint32_t id_first_event = 0xAAAAAAAA; 00896 00897 ticker_insert_event_us( 00898 &ticker_stub, 00899 &first_event, timestamp_first_event, id_first_event 00900 ); 00901 00902 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head); 00903 TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call); 00904 TEST_ASSERT_EQUAL_UINT32( 00905 timestamp_first_event, interface_stub.interrupt_timestamp 00906 ); 00907 TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head->next); 00908 TEST_ASSERT_EQUAL_UINT64( 00909 timestamp_first_event, first_event.timestamp 00910 ); 00911 TEST_ASSERT_EQUAL_UINT32(id_first_event, first_event.id); 00912 00913 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 00914 } 00915 00916 /** 00917 * Given an initialized ticker without user registered events. 00918 * When an event is inserted with ticker_insert_event_us and a timestamp in the 00919 * range [ticker_timestamp + TIMESTAMP_MAX_DELTA + 1 : UINT64_MAX [ 00920 * Then 00921 * - The event should be in the queue 00922 * - The interrupt timestamp should be equal to TIMESTAMP_MAX_DELTA 00923 * - The timestamp of the event should be equal to the timestamp in parameter. 00924 * - The id of the event should be equal to the id passed in parameter. 00925 */ 00926 static void test_insert_event_us_in_overflow_range() 00927 { 00928 ticker_set_handler(&ticker_stub, NULL); 00929 interface_stub.set_interrupt_call = 0; 00930 interface_stub.timestamp = 0xAAAAAAAA; 00931 queue_stub.tick_last_read = interface_stub.timestamp; 00932 queue_stub.present_time = 10ULL << 32 | interface_stub.timestamp; 00933 00934 // test the end of the range 00935 ticker_event_t last_event = { 0 }; 00936 const us_timestamp_t timestamp_last_event = UINT64_MAX; 00937 const uint32_t id_last_event = 0xDEADDEAF; 00938 00939 ticker_insert_event_us( 00940 &ticker_stub, 00941 &last_event, timestamp_last_event, id_last_event 00942 ); 00943 00944 TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head); 00945 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); 00946 TEST_ASSERT_EQUAL_UINT32( 00947 interface_stub.timestamp + TIMESTAMP_MAX_DELTA, 00948 interface_stub.interrupt_timestamp 00949 ); 00950 TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next); 00951 TEST_ASSERT_EQUAL_UINT64(timestamp_last_event, last_event.timestamp); 00952 TEST_ASSERT_EQUAL_UINT32(id_last_event, last_event.id); 00953 00954 // test the beginning of the range 00955 ++interface_stub.timestamp; 00956 ++queue_stub.present_time; 00957 00958 ticker_event_t first_event = { 0 }; 00959 const us_timestamp_t timestamp_first_event = 00960 queue_stub.present_time + TIMESTAMP_MAX_DELTA + 1; 00961 uint32_t id_first_event = 0xAAAAAAAA; 00962 00963 ticker_insert_event_us(&ticker_stub, 00964 &first_event, timestamp_first_event, id_first_event 00965 ); 00966 00967 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head); 00968 TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call); 00969 TEST_ASSERT_EQUAL_UINT32( 00970 interface_stub.timestamp + TIMESTAMP_MAX_DELTA, 00971 interface_stub.interrupt_timestamp 00972 ); 00973 TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head->next); 00974 TEST_ASSERT_EQUAL_UINT64(timestamp_first_event, first_event.timestamp); 00975 TEST_ASSERT_EQUAL_UINT32(id_first_event, first_event.id); 00976 00977 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 00978 } 00979 00980 /** 00981 * Given an initialized ticker without user registered events. 00982 * When an event is inserted with ticker_insert_event_us and a timestamp less 00983 * than timestamp value in the ticker interface. 00984 * Then 00985 * - The event should be in the queue 00986 * - The interrupt timestamp should be set to interface_stub.timestamp so it 00987 * is scheduled immediately. 00988 */ 00989 static void test_insert_event_us_underflow() 00990 { 00991 ticker_set_handler(&ticker_stub, NULL); 00992 interface_stub.set_interrupt_call = 0; 00993 00994 interface_stub.timestamp = 0xAAAAAAAA; 00995 queue_stub.tick_last_read = interface_stub.timestamp; 00996 queue_stub.present_time = 10ULL << 32 | interface_stub.timestamp; 00997 00998 // test the end of the range 00999 ticker_event_t event = { 0 }; 01000 const timestamp_t expected_timestamp = queue_stub.present_time - 1; 01001 const uint32_t expected_id = 0xDEADDEAF; 01002 01003 ticker_insert_event_us( 01004 &ticker_stub, 01005 &event, expected_timestamp, expected_id 01006 ); 01007 01008 TEST_ASSERT_EQUAL_PTR(&event, queue_stub.head); 01009 TEST_ASSERT_EQUAL(1, interface_stub.fire_interrupt_call); 01010 01011 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 01012 } 01013 01014 /** 01015 * Given an initialized ticker. 01016 * When an event is inserted with ticker_insert_event_us and a timestamp less 01017 * than the one for the next scheduled timestamp. 01018 * Then 01019 * - The event inserted should be the first in the queue 01020 * - The interrupt timestamp should be equal to the timestamp of the event or 01021 * TIMESTAMP_MAX_DELTA if in the overflow range. 01022 * - The timestamp of the event should be equal to the timestamp in parameter. 01023 * - The id of the event should be equal to the id passed in parameter. 01024 * - Events in the queue should remained ordered by timestamp. 01025 */ 01026 static void test_insert_event_us_head() 01027 { 01028 ticker_set_handler(&ticker_stub, NULL); 01029 interface_stub.set_interrupt_call = 0; 01030 interface_stub.timestamp = 0xAAAAAAAA; 01031 queue_stub.tick_last_read = interface_stub.timestamp; 01032 queue_stub.present_time = 10ULL << 32 | interface_stub.timestamp; 01033 01034 const us_timestamp_t timestamps[] = { 01035 UINT64_MAX, 01036 queue_stub.present_time + TIMESTAMP_MAX_DELTA + 1, 01037 queue_stub.present_time + TIMESTAMP_MAX_DELTA, 01038 queue_stub.present_time + (TIMESTAMP_MAX_DELTA / 2), 01039 queue_stub.present_time + (TIMESTAMP_MAX_DELTA / 4), 01040 queue_stub.present_time + (TIMESTAMP_MAX_DELTA / 8), 01041 queue_stub.present_time + (TIMESTAMP_MAX_DELTA / 16), 01042 }; 01043 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; 01044 01045 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { 01046 ticker_insert_event_us( 01047 &ticker_stub, 01048 &events[i], timestamps[i], i 01049 ); 01050 01051 TEST_ASSERT_EQUAL_PTR(&events[i], queue_stub.head); 01052 if ((timestamps[i] - queue_stub.present_time) < TIMESTAMP_MAX_DELTA) { 01053 TEST_ASSERT_EQUAL_UINT32( 01054 timestamps[i], 01055 interface_stub.interrupt_timestamp 01056 ); 01057 } else { 01058 TEST_ASSERT_EQUAL_UINT32( 01059 queue_stub.present_time + TIMESTAMP_MAX_DELTA, 01060 interface_stub.interrupt_timestamp 01061 ); 01062 } 01063 01064 TEST_ASSERT_EQUAL_UINT64(timestamps[i], events[i].timestamp); 01065 TEST_ASSERT_EQUAL_UINT32(i, events[i].id); 01066 01067 ticker_event_t* e = &events[i]; 01068 while (e) { 01069 TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp); 01070 if (e->next) { 01071 TEST_ASSERT_TRUE(e->id > e->next->id); 01072 TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp); 01073 } else { 01074 TEST_ASSERT_EQUAL_UINT32(0, e->id); 01075 } 01076 e = e->next; 01077 } 01078 } 01079 01080 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 01081 } 01082 01083 /** 01084 * Given an initialized ticker. 01085 * When an event is inserted with ticker_insert_event_us and its timestamp is 01086 * bigger than the one of the last event in the queue. 01087 * Then 01088 * - The event inserted should be the last in the queue 01089 * - The interrupt timestamp should remains equal to the interrupt timestamp 01090 * of the head event . 01091 * - The timestamp of the event should reflect the timestamp requested. 01092 * - The id of the event should be equal to the id passed in parameter. 01093 * - Events in the queue should remained ordered by timestamp. 01094 */ 01095 static void test_insert_event_us_tail() 01096 { 01097 ticker_set_handler(&ticker_stub, NULL); 01098 interface_stub.set_interrupt_call = 0; 01099 01100 const us_timestamp_t timestamps[] = { 01101 0xA, 01102 (1ULL << 32), 01103 (2ULL << 32), 01104 (4ULL << 32), 01105 (8ULL << 32), 01106 (16ULL << 32), 01107 (32ULL << 32), 01108 (64ULL << 32), 01109 }; 01110 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; 01111 01112 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { 01113 ticker_insert_event_us( 01114 &ticker_stub, 01115 &events[i], timestamps[i], i 01116 ); 01117 01118 TEST_ASSERT_EQUAL_PTR(&events[0], queue_stub.head); 01119 TEST_ASSERT_EQUAL_UINT32( 01120 timestamps[0], interface_stub.interrupt_timestamp 01121 ); 01122 TEST_ASSERT_EQUAL_UINT64(timestamps[i], events[i].timestamp); 01123 TEST_ASSERT_EQUAL_UINT32(i, events[i].id); 01124 01125 ticker_event_t* e = queue_stub.head; 01126 while (e) { 01127 TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp); 01128 if (e->next) { 01129 TEST_ASSERT_TRUE(e->id < e->next->id); 01130 TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp); 01131 } else { 01132 TEST_ASSERT_EQUAL_UINT32(&events[i], e); 01133 } 01134 e = e->next; 01135 } 01136 } 01137 01138 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 01139 } 01140 01141 /** 01142 * Given an initialized ticker. 01143 * When an event is inserted with ticker_insert_event_us. 01144 * Then 01145 * - The event inserted should be at the correct position in the queue 01146 * - The event queue should remain ordered by timestamp 01147 * - The interrupt timestamp should be equal to the interrupt timestamp 01148 * of the head event or TIMESTAMP_MAX_DELTA if the 01149 * timestamp is in the overflow range. 01150 * - The timestamp of the event should be equal to the timestamp parameter. 01151 * - The id of the event should be equal to the id passed in parameter. 01152 * - Events in the queue should remained ordered by timestamp. 01153 */ 01154 static void test_insert_event_us_multiple_random() 01155 { 01156 ticker_set_handler(&ticker_stub, NULL); 01157 interface_stub.set_interrupt_call = 0; 01158 01159 const timestamp_t ref_timestamp = UINT32_MAX / 2; 01160 interface_stub.timestamp = ref_timestamp; 01161 01162 // insert first event at the head of the queue 01163 ticker_event_t first_event; 01164 const us_timestamp_t first_event_timestamp = 01165 ref_timestamp + TIMESTAMP_MAX_DELTA + 100; 01166 01167 ticker_insert_event_us( 01168 &ticker_stub, 01169 &first_event, first_event_timestamp, (uint32_t) &first_event 01170 ); 01171 01172 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head); 01173 TEST_ASSERT_EQUAL_PTR(NULL, first_event.next); 01174 TEST_ASSERT_EQUAL_UINT32( 01175 ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp 01176 ); 01177 TEST_ASSERT_EQUAL_UINT64(first_event.timestamp, first_event_timestamp); 01178 TEST_ASSERT_EQUAL_UINT32((uint32_t) &first_event, first_event.id); 01179 01180 // insert second event at the tail of the queue 01181 ticker_event_t second_event; 01182 const us_timestamp_t second_event_timestamp = first_event_timestamp + 1; 01183 01184 ticker_insert_event_us( 01185 &ticker_stub, 01186 &second_event, second_event_timestamp, (uint32_t) &second_event 01187 ); 01188 01189 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head); 01190 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next); 01191 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next); 01192 TEST_ASSERT_EQUAL_UINT32( 01193 ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp 01194 ); 01195 TEST_ASSERT_EQUAL_UINT64(second_event_timestamp, second_event.timestamp); 01196 TEST_ASSERT_EQUAL_UINT32((uint32_t) &second_event, second_event.id); 01197 01198 01199 // insert third event at the head of the queue out the overflow zone 01200 ticker_event_t third_event; 01201 const us_timestamp_t third_event_timestamp = 01202 ref_timestamp + TIMESTAMP_MAX_DELTA - 100; 01203 01204 ticker_insert_event_us( 01205 &ticker_stub, 01206 &third_event, third_event_timestamp, (uint32_t) &third_event 01207 ); 01208 01209 TEST_ASSERT_EQUAL_PTR(&third_event, queue_stub.head); 01210 TEST_ASSERT_EQUAL_PTR(&first_event, third_event.next); 01211 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next); 01212 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next); 01213 TEST_ASSERT_EQUAL_UINT32( 01214 third_event_timestamp, interface_stub.interrupt_timestamp 01215 ); 01216 TEST_ASSERT_EQUAL_UINT64(third_event_timestamp, third_event.timestamp); 01217 TEST_ASSERT_EQUAL_UINT32((uint32_t) &third_event, third_event.id); 01218 01219 // insert fourth event right after the third event 01220 ticker_event_t fourth_event; 01221 const us_timestamp_t fourth_event_timestamp = third_event_timestamp + 50; 01222 01223 ticker_insert_event_us( 01224 &ticker_stub, 01225 &fourth_event, fourth_event_timestamp, (uint32_t) &fourth_event 01226 ); 01227 01228 TEST_ASSERT_EQUAL_PTR(&third_event, queue_stub.head); 01229 TEST_ASSERT_EQUAL_PTR(&fourth_event, third_event.next); 01230 TEST_ASSERT_EQUAL_PTR(&first_event, fourth_event.next); 01231 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next); 01232 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next); 01233 TEST_ASSERT_EQUAL_UINT32( 01234 third_event_timestamp, interface_stub.interrupt_timestamp 01235 ); 01236 TEST_ASSERT_EQUAL_UINT64(fourth_event_timestamp, fourth_event.timestamp); 01237 TEST_ASSERT_EQUAL_UINT32((uint32_t) &fourth_event, fourth_event.id); 01238 01239 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 01240 } 01241 01242 /** 01243 * Given an initialized ticker with multiple events registered. 01244 * When the event at the tail of the queue is removed from the queue. 01245 * Then: 01246 * - The event should not be in the queue. 01247 * - The events in the queue should remain ordered 01248 * - The interrupt timestamp should be unchanged. 01249 */ 01250 static void test_remove_event_tail() 01251 { 01252 ticker_set_handler(&ticker_stub, NULL); 01253 const us_timestamp_t timestamps[] = { 01254 0xA, 01255 (1ULL << 32), 01256 (2ULL << 32), 01257 (4ULL << 32), 01258 (8ULL << 32), 01259 (16ULL << 32), 01260 (32ULL << 32), 01261 (64ULL << 32), 01262 }; 01263 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; 01264 01265 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { 01266 ticker_insert_event_us( 01267 &ticker_stub, 01268 &events[i], timestamps[i], i 01269 ); 01270 } 01271 01272 for (ssize_t i = MBED_ARRAY_SIZE(events) - 1; i >= 0; --i) { 01273 ticker_remove_event(&ticker_stub, &events[i]); 01274 01275 ticker_event_t* e = queue_stub.head; 01276 size_t event_count = 0; 01277 while (e) { 01278 TEST_ASSERT_NOT_EQUAL(e, &events[i]); 01279 if (e->next) { 01280 TEST_ASSERT_TRUE(e->timestamp <= e->next->timestamp); 01281 } 01282 e = e->next; 01283 ++event_count; 01284 } 01285 01286 TEST_ASSERT_EQUAL(i, event_count); 01287 01288 if (i != 0 ) { 01289 TEST_ASSERT_EQUAL( 01290 timestamps[0], 01291 interface_stub.interrupt_timestamp 01292 ); 01293 } else { 01294 TEST_ASSERT_EQUAL( 01295 interface_stub.timestamp + TIMESTAMP_MAX_DELTA, 01296 interface_stub.interrupt_timestamp 01297 ); 01298 } 01299 } 01300 01301 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 01302 } 01303 01304 /** 01305 * Given an initialized ticker with multiple events registered. 01306 * When the event at the head of the queue is removed from the queue. 01307 * Then: 01308 * - The event should not be in the queue. 01309 * - The event at the head of the queue should be the equal to the one 01310 * after the event removed. 01311 * - The interrupt timestamp should be equal to the interrupt timestamp 01312 * of the head event or TIMESTAMP_MAX_DELTA if the 01313 * timestamp is in the overflow range. 01314 */ 01315 static void test_remove_event_head() 01316 { 01317 ticker_set_handler(&ticker_stub, NULL); 01318 const us_timestamp_t timestamps[] = { 01319 TIMESTAMP_MAX_DELTA / 8, 01320 TIMESTAMP_MAX_DELTA / 4, 01321 TIMESTAMP_MAX_DELTA / 2, 01322 TIMESTAMP_MAX_DELTA - 1, 01323 TIMESTAMP_MAX_DELTA, 01324 TIMESTAMP_MAX_DELTA + 1, 01325 (1ULL << 32) | TIMESTAMP_MAX_DELTA, 01326 UINT64_MAX 01327 }; 01328 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; 01329 01330 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { 01331 ticker_insert_event_us(&ticker_stub, 01332 &events[i], timestamps[i], i 01333 ); 01334 } 01335 01336 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { 01337 ticker_remove_event(&ticker_stub, &events[i]); 01338 01339 ticker_event_t* e = queue_stub.head; 01340 size_t event_count = 0; 01341 while (e) { 01342 TEST_ASSERT_NOT_EQUAL(e, &events[i]); 01343 if (e->next) { 01344 TEST_ASSERT_TRUE(e->timestamp <= e->next->timestamp); 01345 } 01346 e = e->next; 01347 ++event_count; 01348 } 01349 01350 TEST_ASSERT_EQUAL(MBED_ARRAY_SIZE(events) - i - 1, event_count); 01351 01352 if (event_count) { 01353 TEST_ASSERT_EQUAL( 01354 std::min( 01355 timestamps[i + 1], 01356 interface_stub.timestamp + TIMESTAMP_MAX_DELTA 01357 ), 01358 interface_stub.interrupt_timestamp 01359 ); 01360 } else { 01361 TEST_ASSERT_EQUAL( 01362 interface_stub.timestamp + TIMESTAMP_MAX_DELTA, 01363 interface_stub.interrupt_timestamp 01364 ); 01365 } 01366 01367 } 01368 01369 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 01370 } 01371 01372 /** 01373 * Given an initialized ticker with multiple events registered. 01374 * When an event not in the queue is attempted to be removed. 01375 * Then the queue should remains identical as before. 01376 */ 01377 static void test_remove_event_invalid() 01378 { 01379 ticker_set_handler(&ticker_stub, NULL); 01380 const us_timestamp_t timestamps[] = { 01381 TIMESTAMP_MAX_DELTA / 8, 01382 TIMESTAMP_MAX_DELTA / 4, 01383 TIMESTAMP_MAX_DELTA / 2, 01384 TIMESTAMP_MAX_DELTA - 1, 01385 TIMESTAMP_MAX_DELTA, 01386 TIMESTAMP_MAX_DELTA + 1, 01387 (1ULL << 32) | TIMESTAMP_MAX_DELTA, 01388 UINT64_MAX 01389 }; 01390 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; 01391 01392 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { 01393 ticker_insert_event_us( 01394 &ticker_stub, 01395 &events[i], timestamps[i], i 01396 ); 01397 } 01398 01399 ticker_event_t invalid_event; 01400 ticker_remove_event(&ticker_stub, &invalid_event); 01401 01402 TEST_ASSERT_EQUAL(&events[0], queue_stub.head); 01403 01404 ticker_event_t* e = queue_stub.head; 01405 size_t event_count = 0; 01406 while (e) { 01407 TEST_ASSERT_EQUAL(e, &events[event_count]); 01408 e = e->next; 01409 ++event_count; 01410 } 01411 TEST_ASSERT_EQUAL(MBED_ARRAY_SIZE(events), event_count); 01412 } 01413 01414 /** 01415 * Given an initialized ticker with multiple events inserted. 01416 * When an event is remoced 01417 * Then: 01418 * - the event should not be in the queue 01419 * - the queue should remain ordered 01420 * - the interrupt timestamp should be set to either head->timestamp or 01421 * TIMESTAMP_MAX_DELTA depending on the distance between the current time 01422 * ans the timestamp of the event at the head of the queue. 01423 */ 01424 static void test_remove_random() 01425 { 01426 ticker_set_handler(&ticker_stub, NULL); 01427 interface_stub.set_interrupt_call = 0; 01428 01429 const timestamp_t ref_timestamp = UINT32_MAX / 2; 01430 interface_stub.timestamp = ref_timestamp; 01431 01432 // insert all events 01433 ticker_event_t first_event; 01434 const us_timestamp_t first_event_timestamp = 01435 ref_timestamp + TIMESTAMP_MAX_DELTA + 100; 01436 01437 ticker_insert_event_us( 01438 &ticker_stub, 01439 &first_event, first_event_timestamp, (uint32_t) &first_event 01440 ); 01441 01442 01443 ticker_event_t second_event; 01444 const us_timestamp_t second_event_timestamp = first_event_timestamp + 1; 01445 01446 ticker_insert_event_us( 01447 &ticker_stub, 01448 &second_event, second_event_timestamp, (uint32_t) &second_event 01449 ); 01450 01451 ticker_event_t third_event; 01452 const us_timestamp_t third_event_timestamp = 01453 ref_timestamp + TIMESTAMP_MAX_DELTA - 100; 01454 01455 ticker_insert_event_us( 01456 &ticker_stub, 01457 &third_event, third_event_timestamp, (uint32_t) &third_event 01458 ); 01459 01460 ticker_event_t fourth_event; 01461 const us_timestamp_t fourth_event_timestamp = third_event_timestamp + 50; 01462 01463 ticker_insert_event_us( 01464 &ticker_stub, 01465 &fourth_event, fourth_event_timestamp, (uint32_t) &fourth_event 01466 ); 01467 01468 // test that the queue is in the correct state 01469 TEST_ASSERT_EQUAL_PTR(&third_event, queue_stub.head); 01470 TEST_ASSERT_EQUAL_PTR(&fourth_event, third_event.next); 01471 TEST_ASSERT_EQUAL_PTR(&first_event, fourth_event.next); 01472 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next); 01473 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next); 01474 TEST_ASSERT_EQUAL_UINT32( 01475 third_event_timestamp, interface_stub.interrupt_timestamp 01476 ); 01477 TEST_ASSERT_EQUAL_UINT64(fourth_event_timestamp, fourth_event.timestamp); 01478 TEST_ASSERT_EQUAL_UINT32((uint32_t) &fourth_event, fourth_event.id); 01479 01480 // remove fourth event 01481 ticker_remove_event(&ticker_stub, &fourth_event); 01482 01483 TEST_ASSERT_EQUAL_PTR(&third_event, queue_stub.head); 01484 TEST_ASSERT_EQUAL_PTR(&first_event, third_event.next); 01485 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next); 01486 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next); 01487 TEST_ASSERT_EQUAL_UINT32( 01488 third_event_timestamp, interface_stub.interrupt_timestamp 01489 ); 01490 TEST_ASSERT_EQUAL_UINT64(third_event_timestamp, third_event.timestamp); 01491 TEST_ASSERT_EQUAL_UINT32((uint32_t) &third_event, third_event.id); 01492 01493 // remove third event 01494 ticker_remove_event(&ticker_stub, &third_event); 01495 01496 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head); 01497 TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next); 01498 TEST_ASSERT_EQUAL_PTR(NULL, second_event.next); 01499 TEST_ASSERT_EQUAL_UINT32( 01500 ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp 01501 ); 01502 TEST_ASSERT_EQUAL_UINT64(second_event_timestamp, second_event.timestamp); 01503 TEST_ASSERT_EQUAL_UINT32((uint32_t) &second_event, second_event.id); 01504 01505 // remove second event 01506 ticker_remove_event(&ticker_stub, &second_event); 01507 01508 TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head); 01509 TEST_ASSERT_EQUAL_PTR(NULL, first_event.next); 01510 TEST_ASSERT_EQUAL_UINT32( 01511 ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp 01512 ); 01513 TEST_ASSERT_EQUAL_UINT64(first_event.timestamp, first_event_timestamp); 01514 TEST_ASSERT_EQUAL_UINT32((uint32_t) &first_event, first_event.id); 01515 01516 // remove first event 01517 ticker_remove_event(&ticker_stub, &first_event); 01518 01519 TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head); 01520 TEST_ASSERT_EQUAL_PTR(NULL, first_event.next); 01521 TEST_ASSERT_EQUAL_UINT32( 01522 ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp 01523 ); 01524 01525 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 01526 } 01527 01528 /** 01529 * Given an initialized ticker without user registered events and a ticker 01530 * interface timestamp equal or bigger than the one registered by the overflow 01531 * event. 01532 * When the interrupt handler is called. 01533 * Then: 01534 * - The interrupt timestamp should be updated to the timestamp of the ticker 01535 * interface plus TIMESTAMP_MAX_DELTA. 01536 * - The irq handler registered should not be called. 01537 */ 01538 static void test_overflow_event_update() 01539 { 01540 static uint32_t handler_call = 0; 01541 struct irq_handler_stub_t { 01542 static void event_handler(uint32_t id) { 01543 ++handler_call; 01544 } 01545 }; 01546 handler_call = 0; 01547 01548 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler); 01549 interface_stub.set_interrupt_call = 0; 01550 01551 for (size_t i = 0; i < 8; ++i) { 01552 us_timestamp_t previous_timestamp = queue_stub.present_time; 01553 timestamp_t interface_timestamp = 01554 previous_timestamp + (TIMESTAMP_MAX_DELTA + i * 100); 01555 interface_stub.timestamp = interface_timestamp; 01556 01557 ticker_irq_handler(&ticker_stub); 01558 TEST_ASSERT_EQUAL(i + 1, interface_stub.clear_interrupt_call); 01559 01560 TEST_ASSERT_EQUAL(i + 1, interface_stub.set_interrupt_call); 01561 TEST_ASSERT_EQUAL_UINT32( 01562 interface_timestamp + TIMESTAMP_MAX_DELTA, 01563 interface_stub.interrupt_timestamp 01564 ); 01565 TEST_ASSERT_EQUAL(0, handler_call); 01566 } 01567 01568 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 01569 } 01570 01571 /** 01572 * Given an initialized ticker without user registered events and a ticker 01573 * interface timestamp less than the one registered to handle overflow. 01574 * When the interrupt handler is called. 01575 * Then: 01576 * - The interrupt timestamp should be updated to the timestamp of the ticker 01577 * interface plus TIMESTAMP_MAX_DELTA. 01578 * - The irq handler registered should not be called. 01579 */ 01580 static void test_overflow_event_update_when_spurious_interrupt() 01581 { 01582 static uint32_t handler_call = 0; 01583 struct irq_handler_stub_t { 01584 static void event_handler(uint32_t id) { 01585 ++handler_call; 01586 } 01587 }; 01588 handler_call = 0; 01589 01590 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler); 01591 interface_stub.set_interrupt_call = 0; 01592 01593 for (size_t i = 0; i < 8; ++i) { 01594 us_timestamp_t previous_timestamp = queue_stub.present_time; 01595 timestamp_t interface_timestamp = 01596 previous_timestamp + (TIMESTAMP_MAX_DELTA / (2 + i)); 01597 interface_stub.timestamp = interface_timestamp; 01598 01599 ticker_irq_handler(&ticker_stub); 01600 01601 TEST_ASSERT_EQUAL(i + 1, interface_stub.clear_interrupt_call); 01602 TEST_ASSERT_EQUAL(i + 1, interface_stub.set_interrupt_call); 01603 TEST_ASSERT_EQUAL_UINT32( 01604 interface_timestamp + TIMESTAMP_MAX_DELTA, 01605 interface_stub.interrupt_timestamp 01606 ); 01607 TEST_ASSERT_EQUAL(0, handler_call); 01608 } 01609 01610 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 01611 } 01612 01613 /** 01614 * Given an initialized ticker with a single ticker event inserted and a ticker 01615 * interface timestamp bigger than the one set for interrupt. 01616 * When ticker_irq_handler is called. 01617 * Then: 01618 * - The IRQ handler should be called with the id of the event at the head of 01619 * the queue. 01620 * - The event at the head of the queue should be replaced by the next event. 01621 * - The interrupt timestamp in the ticker interface should be set to the 01622 * value of the interface timestamp + TIMESTAMP_MAX_DELTA 01623 */ 01624 static void test_irq_handler_single_event() 01625 { 01626 static const timestamp_t event_timestamp = 0xAAAAAAAA; 01627 static const timestamp_t interface_timestamp_after_irq = event_timestamp + 100; 01628 01629 uint32_t handler_call = 0; 01630 struct irq_handler_stub_t { 01631 static void event_handler(uint32_t id) { 01632 ++ (*((uint32_t*) id)); 01633 interface_stub.timestamp = interface_timestamp_after_irq; 01634 } 01635 }; 01636 01637 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler); 01638 interface_stub.set_interrupt_call = 0; 01639 01640 ticker_event_t e; 01641 ticker_insert_event(&ticker_stub, &e, event_timestamp, (uint32_t) &handler_call); 01642 01643 interface_stub.timestamp = event_timestamp; 01644 interface_stub.set_interrupt_call = 0; 01645 01646 ticker_irq_handler(&ticker_stub); 01647 01648 TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call); 01649 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); 01650 TEST_ASSERT_EQUAL(1, handler_call); 01651 TEST_ASSERT_EQUAL_UINT32( 01652 interface_timestamp_after_irq + TIMESTAMP_MAX_DELTA, 01653 interface_stub.interrupt_timestamp 01654 ); 01655 01656 TEST_ASSERT_NULL(queue_stub.head); 01657 01658 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 01659 } 01660 01661 /** 01662 * Given an initialized ticker with at least a ticker event inserted and a ticker 01663 * interface timestamp less than the one set for interrupt. 01664 * When ticker_irq_handler is called. 01665 * Then: 01666 * - The IRQ handler should not be called. 01667 * - The event at the head of the queue should remains the same. 01668 * - The interrupt timestamp in the ticker interface should be set to the 01669 * value of the event timestamp 01670 */ 01671 static void test_irq_handler_single_event_spurious() 01672 { 01673 struct irq_handler_stub_t { 01674 static void event_handler(uint32_t id) { 01675 TEST_FAIL(); 01676 } 01677 }; 01678 01679 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler); 01680 interface_stub.set_interrupt_call = 0; 01681 01682 const us_timestamp_t timestamps [] = { 01683 UINT32_MAX, 01684 TIMESTAMP_MAX_DELTA + 1, 01685 TIMESTAMP_MAX_DELTA, 01686 TIMESTAMP_MAX_DELTA - 1 01687 }; 01688 01689 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; 01690 01691 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { 01692 ticker_insert_event_us( 01693 &ticker_stub, 01694 &events[i], timestamps[i], timestamps[i] 01695 ); 01696 interface_stub.set_interrupt_call = 0; 01697 interface_stub.clear_interrupt_call = 0; 01698 01699 ticker_irq_handler(&ticker_stub); 01700 01701 TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call); 01702 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); 01703 TEST_ASSERT_EQUAL_UINT32( 01704 std::min(timestamps[i], TIMESTAMP_MAX_DELTA), 01705 interface_stub.interrupt_timestamp 01706 ); 01707 } 01708 01709 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 01710 } 01711 01712 /** 01713 * Given an initialized ticker with multiple ticker event inserted, its 01714 * interface timestamp at greater than the timestamp of the next schedule event 01715 * and all event execution time taking at least the time befor ethe next event. 01716 * When ticker_irq_handler is called. 01717 * Then: 01718 * - The IRQ handler should have been called for every event. 01719 * - The head of the queue should be set to NULL. 01720 * - The interrupt timestamp in the ticker interface should be scheduled in 01721 * TIMESTAMP_MAX_DELTAs 01722 */ 01723 static void test_irq_handler_multiple_event_multiple_dequeue() 01724 { 01725 const us_timestamp_t timestamps [] = { 01726 10, 01727 10 + TIMESTAMP_MAX_DELTA - 1, 01728 10 + TIMESTAMP_MAX_DELTA, 01729 10 + TIMESTAMP_MAX_DELTA + 1, 01730 UINT32_MAX 01731 }; 01732 01733 static size_t handler_called = 0; 01734 struct irq_handler_stub_t { 01735 static void event_handler(uint32_t id) { 01736 ++handler_called; 01737 ticker_event_t* e = (ticker_event_t*) id; 01738 if (e->next) { 01739 interface_stub.timestamp = e->next->timestamp; 01740 } 01741 } 01742 }; 01743 handler_called = 0; 01744 01745 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler); 01746 interface_stub.set_interrupt_call = 0; 01747 01748 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; 01749 01750 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { 01751 ticker_insert_event_us( 01752 &ticker_stub, 01753 &events[i], timestamps[i], (uint32_t) &events[i] 01754 ); 01755 } 01756 01757 interface_stub.set_interrupt_call = 0; 01758 interface_stub.clear_interrupt_call = 0; 01759 interface_stub.timestamp = timestamps[0]; 01760 01761 ticker_irq_handler(&ticker_stub); 01762 01763 TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call); 01764 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); 01765 TEST_ASSERT_EQUAL_UINT32(MBED_ARRAY_SIZE(timestamps), handler_called); 01766 TEST_ASSERT_EQUAL_UINT32( 01767 timestamps[MBED_ARRAY_SIZE(timestamps) - 1] + TIMESTAMP_MAX_DELTA, 01768 interface_stub.interrupt_timestamp 01769 ); 01770 TEST_ASSERT_NULL(queue_stub.head); 01771 01772 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 01773 } 01774 01775 /** 01776 * Given an initialized ticker with two ticker event inserted scheduled from more 01777 * than TIMESTAMP_MAX_DELTA from one another. The interface 01778 * timestamp is equal to the timestamp of the first event. 01779 * When ticker_irq_handler is called. 01780 * Then: 01781 * - The IRQ handler should have been called for the first event. 01782 * - The head of the queue should be set to the event after the first event. 01783 * - The interrupt timestamp in the ticker interface should be scheduled in 01784 * TIMESTAMP_MAX_DELTA. 01785 */ 01786 static void test_irq_handler_multiple_event_single_dequeue_overflow() 01787 { 01788 const us_timestamp_t timestamps [] = { 01789 10, 01790 10 + TIMESTAMP_MAX_DELTA + 1 01791 }; 01792 01793 size_t handler_called = 0; 01794 struct irq_handler_stub_t { 01795 static void event_handler(uint32_t id) { 01796 ++ (*((size_t*) id)); 01797 } 01798 }; 01799 01800 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler); 01801 interface_stub.set_interrupt_call = 0; 01802 01803 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; 01804 01805 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { 01806 ticker_insert_event_us( 01807 &ticker_stub, 01808 &events[i], timestamps[i], (uint32_t) &handler_called 01809 ); 01810 } 01811 01812 interface_stub.set_interrupt_call = 0; 01813 interface_stub.clear_interrupt_call = 0; 01814 interface_stub.timestamp = timestamps[0]; 01815 01816 ticker_irq_handler(&ticker_stub); 01817 01818 TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call); 01819 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); 01820 TEST_ASSERT_EQUAL_UINT32(1, handler_called); 01821 TEST_ASSERT_EQUAL_UINT32( 01822 timestamps[0] + TIMESTAMP_MAX_DELTA, 01823 interface_stub.interrupt_timestamp 01824 ); 01825 TEST_ASSERT_EQUAL_PTR(&events[1], queue_stub.head); 01826 01827 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 01828 } 01829 01830 /** 01831 * Given an initialized ticker with two ticker event inserted scheduled from less 01832 * than TIMESTAMP_MAX_DELTA from one another. The interface 01833 * timestamp is equal to the timestamp of the first event. 01834 * When ticker_irq_handler is called. 01835 * Then: 01836 * - The IRQ handler should have been called for the first event. 01837 * - The head of the queue should be set to second event. 01838 * - The interrupt timestamp in the ticker interface should be equal to the 01839 * timestamp of the second event. 01840 */ 01841 static void test_irq_handler_multiple_event_single_dequeue() 01842 { 01843 const us_timestamp_t timestamps [] = { 01844 10, 01845 10 + TIMESTAMP_MAX_DELTA - 1 01846 }; 01847 01848 size_t handler_called = 0; 01849 struct irq_handler_stub_t { 01850 static void event_handler(uint32_t id) { 01851 ++ (*((size_t*) id)); 01852 } 01853 }; 01854 01855 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler); 01856 interface_stub.set_interrupt_call = 0; 01857 01858 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; 01859 01860 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { 01861 ticker_insert_event_us( 01862 &ticker_stub, 01863 &events[i], timestamps[i], (uint32_t) &handler_called 01864 ); 01865 } 01866 01867 interface_stub.set_interrupt_call = 0; 01868 interface_stub.clear_interrupt_call = 0; 01869 interface_stub.timestamp = timestamps[0]; 01870 01871 ticker_irq_handler(&ticker_stub); 01872 01873 TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call); 01874 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); 01875 TEST_ASSERT_EQUAL_UINT32(1, handler_called); 01876 TEST_ASSERT_EQUAL_UINT32( 01877 timestamps[1], 01878 interface_stub.interrupt_timestamp 01879 ); 01880 TEST_ASSERT_EQUAL_PTR(&events[1], queue_stub.head); 01881 01882 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 01883 } 01884 01885 /** 01886 * Given an initialized ticker with multiple ticker event inserted and the 01887 * interface timestamp is equal to the timestamp of the first event. The first 01888 * event to execute will insert an events in the ticker which have to be executed 01889 * immediately. 01890 * When ticker_irq_handler is called. 01891 * Then: 01892 * - The IRQ handler should have been called for the first event and the event 01893 * inserted during irq. 01894 * - The head of the queue should be set correctly. 01895 * - The interrupt timestamp in the ticker interface should be equal to 01896 * timestamp of the head event. 01897 */ 01898 static void test_irq_handler_insert_immediate_in_irq() 01899 { 01900 static const us_timestamp_t timestamps [] = { 01901 10, 01902 10 + TIMESTAMP_MAX_DELTA - 1 01903 }; 01904 01905 static const us_timestamp_t expected_timestamp = 01906 ((timestamps[1] - timestamps[0]) / 2) + timestamps[0]; 01907 01908 struct ctrl_block_t { 01909 bool irq_event_called; 01910 ticker_event_t immediate_event; 01911 size_t handler_called; 01912 }; 01913 01914 ctrl_block_t ctrl_block = { 0 }; 01915 01916 struct irq_handler_stub_t { 01917 static void event_handler(uint32_t id) { 01918 ctrl_block_t* ctrl_block = (ctrl_block_t*) id; 01919 01920 if (ctrl_block->handler_called == 0) { 01921 ticker_insert_event( 01922 &ticker_stub, 01923 &ctrl_block->immediate_event, expected_timestamp, id 01924 ); 01925 interface_stub.timestamp = expected_timestamp; 01926 } else if (ctrl_block->handler_called > 1) { 01927 TEST_FAIL(); 01928 } 01929 ++ctrl_block->handler_called; 01930 } 01931 }; 01932 01933 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler); 01934 interface_stub.set_interrupt_call = 0; 01935 01936 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; 01937 01938 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { 01939 ticker_insert_event_us( 01940 &ticker_stub, 01941 &events[i], timestamps[i], (uint32_t) &ctrl_block 01942 ); 01943 } 01944 01945 interface_stub.set_interrupt_call = 0; 01946 interface_stub.clear_interrupt_call = 0; 01947 interface_stub.timestamp = timestamps[0]; 01948 01949 ticker_irq_handler(&ticker_stub); 01950 01951 TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call); 01952 TEST_ASSERT_EQUAL_UINT32(2, ctrl_block.handler_called); 01953 TEST_ASSERT_EQUAL_UINT32( 01954 timestamps[1], 01955 interface_stub.interrupt_timestamp 01956 ); 01957 TEST_ASSERT_EQUAL_PTR(&events[1], queue_stub.head); 01958 01959 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 01960 } 01961 01962 /** 01963 * Given an initialized ticker with multiple ticker event inserted and the 01964 * interface timestamp is equal to the timestamp of the first event. The first 01965 * event to execute will insert an events in the ticker which does not have to 01966 * be executed immediately. 01967 * When ticker_irq_handler is called. 01968 * Then: 01969 * - The IRQ handler should have been called for the first event. 01970 * - The head of the queue should be set to the event inserted in IRQ. 01971 * - The interrupt timestamp in the ticker interface should be equal to 01972 * timestamp of the head event. 01973 */ 01974 static void test_irq_handler_insert_non_immediate_in_irq() 01975 { 01976 static const us_timestamp_t timestamps [] = { 01977 10, 01978 10 + TIMESTAMP_MAX_DELTA - 1 01979 }; 01980 01981 static const us_timestamp_t expected_timestamp = 01982 ((timestamps[1] - timestamps[0]) / 2) + timestamps[0]; 01983 01984 struct ctrl_block_t { 01985 bool irq_event_called; 01986 ticker_event_t non_immediate_event; 01987 size_t handler_called; 01988 }; 01989 01990 ctrl_block_t ctrl_block = { 0 }; 01991 01992 struct irq_handler_stub_t { 01993 static void event_handler(uint32_t id) { 01994 ctrl_block_t* ctrl_block = (ctrl_block_t*) id; 01995 01996 if (ctrl_block->handler_called == 0) { 01997 ticker_insert_event( 01998 &ticker_stub, 01999 &ctrl_block->non_immediate_event, expected_timestamp, id 02000 ); 02001 } else { 02002 TEST_FAIL(); 02003 } 02004 ++ctrl_block->handler_called; 02005 } 02006 }; 02007 02008 02009 ticker_set_handler(&ticker_stub, irq_handler_stub_t::event_handler); 02010 interface_stub.set_interrupt_call = 0; 02011 02012 ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 }; 02013 02014 for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) { 02015 ticker_insert_event_us( 02016 &ticker_stub, 02017 &events[i], timestamps[i], (uint32_t) &ctrl_block 02018 ); 02019 } 02020 02021 interface_stub.set_interrupt_call = 0; 02022 interface_stub.clear_interrupt_call = 0; 02023 interface_stub.timestamp = timestamps[0]; 02024 02025 ticker_irq_handler(&ticker_stub); 02026 02027 TEST_ASSERT_EQUAL(1, interface_stub.clear_interrupt_call); 02028 TEST_ASSERT_EQUAL_UINT32(1, ctrl_block.handler_called); 02029 TEST_ASSERT_EQUAL_UINT32( 02030 expected_timestamp, 02031 interface_stub.interrupt_timestamp 02032 ); 02033 TEST_ASSERT_EQUAL_PTR(&ctrl_block.non_immediate_event, queue_stub.head); 02034 TEST_ASSERT_EQUAL_PTR(&events[1], queue_stub.head->next); 02035 02036 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 02037 } 02038 02039 static uint32_t ticker_interface_stub_read_interrupt_time() 02040 { 02041 ++interface_stub.read_call; 02042 // only if set interrupt call, to test the condition afterwards 02043 if (interface_stub.set_interrupt_call) { 02044 return interface_stub.interrupt_timestamp; 02045 } else { 02046 return interface_stub.timestamp; 02047 } 02048 } 02049 02050 /** 02051 * Test to insert an event that is already in the past, the fire_interrupt should 02052 * be invoked, instead of set_interrupt 02053 */ 02054 static void test_set_interrupt_past_time() 02055 { 02056 ticker_set_handler(&ticker_stub, NULL); 02057 02058 interface_stub.set_interrupt_call = 0; 02059 interface_stub.fire_interrupt_call = 0; 02060 interface_stub.timestamp = 0xFF; 02061 02062 02063 // This tests fire now functinality when next_event_timestamp <= present 02064 ticker_event_t event = { 0 }; 02065 const timestamp_t event_timestamp = interface_stub.timestamp; 02066 const uint32_t id_last_event = 0xDEADDEAF; 02067 02068 ticker_insert_event(&ticker_stub, &event, event_timestamp, id_last_event); 02069 TEST_ASSERT_EQUAL(0, interface_stub.set_interrupt_call); 02070 TEST_ASSERT_EQUAL(1, interface_stub.fire_interrupt_call); 02071 } 02072 /** 02073 * Test to insert an event that is being delayed, set_interrupt is set 02074 * but then event is already in the past, thus fire_interrupt should be invoked right-away 02075 */ 02076 static void test_set_interrupt_past_time_with_delay() 02077 { 02078 ticker_set_handler(&ticker_stub, NULL); 02079 02080 interface_stub.set_interrupt_call = 0; 02081 interface_stub.fire_interrupt_call = 0; 02082 interface_stub.timestamp = 0xFF; 02083 02084 // This tests fire now functionality when present time >= new_match_time 02085 interface_stub.interface.read = ticker_interface_stub_read_interrupt_time; 02086 ticker_event_t event = { 0 }; 02087 const timestamp_t event_timestamp = interface_stub.timestamp + 5; 02088 const uint32_t id_last_event = 0xDEADDEAF; 02089 02090 ticker_insert_event(&ticker_stub, &event, event_timestamp, id_last_event); 02091 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); 02092 TEST_ASSERT_EQUAL(1, interface_stub.fire_interrupt_call); 02093 } 02094 02095 /** 02096 * Convert ticks at a given frequency to time in microseconds 02097 * 02098 * Assert if there is a 64-bit overflow 02099 */ 02100 static uint64_t convert_to_us(uint64_t ticks, uint32_t frequency) 02101 { 02102 uint64_t scaled_ticks = ticks * 1000000; 02103 // Assert that there was not an overflow 02104 TEST_ASSERT_EQUAL(ticks, scaled_ticks / 1000000); 02105 return scaled_ticks / frequency; 02106 } 02107 02108 /** 02109 * Given an uninitialized ticker instance and an interface of a 02110 * certain frequency and bit width. 02111 * Then the time returned the ticker should match the cumulative time. 02112 */ 02113 void test_frequencies_and_masks(uint32_t frequency, uint32_t bits) 02114 { 02115 const uint32_t bitmask = ((uint64_t)1 << bits) - 1; 02116 02117 ticker_set_handler(&ticker_stub, NULL); 02118 uint64_t ticks = 0; 02119 02120 // Single tick 02121 ticks += 1; 02122 interface_stub.timestamp = ticks & bitmask; 02123 TEST_ASSERT_EQUAL_UINT32(convert_to_us(ticks, frequency), ticker_read(&ticker_stub)); 02124 TEST_ASSERT_EQUAL_UINT64(convert_to_us(ticks, frequency), ticker_read_us(&ticker_stub)); 02125 02126 // Run until the loop before 64-bit overflow (worst case with frequency=1hz, bits=32) 02127 for (unsigned int k = 0; k < 4294; k++) { 02128 02129 // Largest value possible tick 02130 ticks += ((uint64_t)1 << bits) - 1; 02131 interface_stub.timestamp = ticks & bitmask; 02132 TEST_ASSERT_EQUAL_UINT32(convert_to_us(ticks, frequency), ticker_read(&ticker_stub)); 02133 TEST_ASSERT_EQUAL_UINT64(convert_to_us(ticks, frequency), ticker_read_us(&ticker_stub)); 02134 } 02135 } 02136 02137 /** 02138 * Given an uninitialized ticker_data instance. 02139 * When the ticker is initialized 02140 * Then: 02141 * - The internal ticker timestamp should be zero 02142 * - interrupt should be scheduled in current (timestamp + 02143 * TIMESTAMP_MAX_DELTA_BITS(bitwidth)) % modval 02144 * - The queue should not contains any event 02145 */ 02146 static void test_ticker_max_value() 02147 { 02148 for (int bitwidth = 8; bitwidth <= 32; bitwidth++) { 02149 const uint64_t modval = 1ULL << bitwidth; 02150 02151 // setup of the stub 02152 reset_ticker_stub(); 02153 interface_info_stub.bits = bitwidth; 02154 interface_stub.timestamp = 0xBA; 02155 02156 ticker_set_handler(&ticker_stub, NULL); 02157 02158 TEST_ASSERT_EQUAL_UINT64(0, queue_stub.present_time); 02159 TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call); 02160 TEST_ASSERT_EQUAL_UINT32( 02161 (interface_stub.timestamp + TIMESTAMP_MAX_DELTA_BITS(bitwidth)) % modval, 02162 interface_stub.interrupt_timestamp 02163 ); 02164 TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head); 02165 TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call); 02166 } 02167 } 02168 02169 /** 02170 * Check that _ticker_match_interval_passed correctly detects matches 02171 * 02172 * Brute force test that _ticker_match_interval_passed returns the correct match value 02173 * for all cominations of values within a small range. 02174 */ 02175 static void test_match_interval_passed() 02176 { 02177 02178 for (int modval = 1; modval <= 5; modval++) { 02179 for (int prev = 0; prev < modval; prev++) { 02180 for (int cur = 0; cur < modval; cur++) { 02181 for (int match = 0; match < modval; match++) { 02182 uint32_t delta = (cur - prev) % modval; 02183 uint32_t delta_to_match = (match - prev) % modval; 02184 bool match_expected = false; 02185 if (delta_to_match) { 02186 match_expected = delta >= delta_to_match; 02187 } 02188 02189 // Sanity checks 02190 if (prev == cur) { 02191 // No time has passed 02192 TEST_ASSERT_EQUAL(false, match_expected); 02193 } else if (match == prev) { 02194 // Match can't occur without an overflow occurring 02195 TEST_ASSERT_EQUAL(false, match_expected); 02196 } else if (cur == match) { 02197 // All other cases where cur == match a match should be expected 02198 TEST_ASSERT_EQUAL(true, match_expected); 02199 } 02200 02201 // Actual test 02202 TEST_ASSERT_EQUAL(match_expected, _ticker_match_interval_passed(prev, cur, match)); 02203 } 02204 } 02205 } 02206 } 02207 } 02208 02209 typedef struct { 02210 timestamp_t prev; 02211 timestamp_t cur; 02212 timestamp_t match; 02213 bool result; 02214 } match_interval_entry_t; 02215 02216 /** 02217 * Check that _ticker_match_interval_passed correctly detects matches 02218 * 02219 * Use a table of pre-computed values to check that _ticker_match_interval_passed 02220 * returns the correct match value. 02221 */ 02222 static void test_match_interval_passed_table() 02223 { 02224 static const match_interval_entry_t test_values[] = { 02225 /* prev, cur, match, result */ 02226 {0x00000000, 0x00000000, 0x00000000, false}, 02227 {0x00000000, 0x00000000, 0xffffffff, false}, 02228 {0x00000000, 0x00000000, 0x00000001, false}, 02229 {0x00000000, 0xffffffff, 0x00000000, false}, 02230 {0x00000000, 0x00000001, 0x00000000, false}, 02231 {0xffffffff, 0x00000000, 0x00000000, true}, 02232 {0x00000001, 0x00000000, 0x00000000, true}, 02233 {0x00005555, 0x00005555, 0x00005555, false}, 02234 {0x00005555, 0x00005555, 0x00005554, false}, 02235 {0x00005555, 0x00005555, 0x00005556, false}, 02236 {0x00005555, 0x00005554, 0x00005555, false}, 02237 {0x00005555, 0x00005556, 0x00005555, false}, 02238 {0x00005554, 0x00005555, 0x00005555, true}, 02239 {0x00005556, 0x00005555, 0x00005555, true}, 02240 {0xffffffff, 0xffffffff, 0xffffffff, false}, 02241 {0xffffffff, 0xffffffff, 0xfffffffe, false}, 02242 {0xffffffff, 0xffffffff, 0x00000000, false}, 02243 {0xffffffff, 0xfffffffe, 0xffffffff, false}, 02244 {0xffffffff, 0x00000000, 0xffffffff, false}, 02245 {0xfffffffe, 0xffffffff, 0xffffffff, true}, 02246 {0x00000000, 0xffffffff, 0xffffffff, true}, 02247 }; 02248 for (int i = 0; i < MBED_ARRAY_SIZE(test_values); i++) { 02249 const uint32_t prev = test_values[i].prev; 02250 const uint32_t cur = test_values[i].cur; 02251 const uint32_t match = test_values[i].match; 02252 const uint32_t result = test_values[i].result; 02253 TEST_ASSERT_EQUAL(result, _ticker_match_interval_passed(prev, cur, match)); 02254 } 02255 } 02256 02257 static const case_t cases[] = { 02258 MAKE_TEST_CASE("ticker initialization", test_ticker_initialization), 02259 MAKE_TEST_CASE( 02260 "ticker multiple initialization", test_ticker_re_initialization 02261 ), 02262 MAKE_TEST_CASE("ticker read", test_ticker_read), 02263 MAKE_TEST_CASE("ticker read overflow", test_ticker_read_overflow), 02264 MAKE_TEST_CASE( 02265 "legacy insert event outside overflow range", 02266 test_legacy_insert_event_outside_overflow_range 02267 ), 02268 MAKE_TEST_CASE( 02269 "legacy insert event in overflow range", 02270 test_legacy_insert_event_in_overflow_range 02271 ), 02272 MAKE_TEST_CASE( 02273 "legacy insert event overflow", test_legacy_insert_event_overflow 02274 ), 02275 MAKE_TEST_CASE( 02276 "legacy insert event head", test_legacy_insert_event_head 02277 ), 02278 MAKE_TEST_CASE( 02279 "legacy insert event tail", test_legacy_insert_event_tail 02280 ), 02281 MAKE_TEST_CASE( 02282 "legacy insert event multiple overflow", 02283 test_legacy_insert_event_multiple_overflow 02284 ), 02285 MAKE_TEST_CASE( 02286 "test_legacy_insert_event_multiple_random", 02287 test_legacy_insert_event_multiple_random 02288 ), 02289 MAKE_TEST_CASE( 02290 "test_insert_event_us_outside_overflow_range", 02291 test_insert_event_us_outside_overflow_range 02292 ), 02293 MAKE_TEST_CASE( 02294 "test_insert_event_us_in_overflow_range", 02295 test_insert_event_us_in_overflow_range 02296 ), 02297 MAKE_TEST_CASE( 02298 "test_insert_event_us_underflow", test_insert_event_us_underflow 02299 ), 02300 MAKE_TEST_CASE("test_insert_event_us_head", test_insert_event_us_head), 02301 MAKE_TEST_CASE("test_insert_event_us_tail", test_insert_event_us_tail), 02302 MAKE_TEST_CASE( 02303 "test_insert_event_us_multiple_random", 02304 test_insert_event_us_multiple_random 02305 ), 02306 MAKE_TEST_CASE("test_remove_event_tail", test_remove_event_tail), 02307 MAKE_TEST_CASE("test_remove_event_head", test_remove_event_head), 02308 MAKE_TEST_CASE("test_remove_event_invalid", test_remove_event_invalid), 02309 MAKE_TEST_CASE("test_remove_random", test_remove_random), 02310 MAKE_TEST_CASE("update overflow guard", test_overflow_event_update), 02311 MAKE_TEST_CASE( 02312 "update overflow guard in case of spurious interrupt", 02313 test_overflow_event_update_when_spurious_interrupt 02314 ), 02315 MAKE_TEST_CASE( 02316 "test_irq_handler_single_event", test_irq_handler_single_event 02317 ), 02318 MAKE_TEST_CASE( 02319 "test_irq_handler_single_event_spurious", 02320 test_irq_handler_single_event_spurious 02321 ), 02322 MAKE_TEST_CASE( 02323 "test_irq_handler_multiple_event_multiple_dequeue", 02324 test_irq_handler_multiple_event_multiple_dequeue 02325 ), 02326 MAKE_TEST_CASE( 02327 "test_irq_handler_multiple_event_single_dequeue_overflow", 02328 test_irq_handler_multiple_event_single_dequeue_overflow 02329 ), 02330 MAKE_TEST_CASE( 02331 "test_irq_handler_multiple_event_single_dequeue", 02332 test_irq_handler_multiple_event_single_dequeue 02333 ), 02334 MAKE_TEST_CASE( 02335 "test_irq_handler_insert_immediate_in_irq", 02336 test_irq_handler_insert_immediate_in_irq 02337 ), 02338 MAKE_TEST_CASE( 02339 "test_irq_handler_insert_non_immediate_in_irq", 02340 test_irq_handler_insert_non_immediate_in_irq 02341 ), 02342 MAKE_TEST_CASE( 02343 "test_set_interrupt_past_time", 02344 test_set_interrupt_past_time 02345 ), 02346 MAKE_TEST_CASE( 02347 "test_set_interrupt_past_time_with_delay", 02348 test_set_interrupt_past_time_with_delay 02349 ), 02350 MAKE_TEST_CASE( 02351 "test_frequencies_and_masks", 02352 test_over_frequency_and_width<test_frequencies_and_masks> 02353 ), 02354 MAKE_TEST_CASE( 02355 "test_ticker_max_value", 02356 test_ticker_max_value 02357 ), 02358 MAKE_TEST_CASE( 02359 "test_match_interval_passed", 02360 test_match_interval_passed 02361 ), 02362 MAKE_TEST_CASE( 02363 "test_match_interval_passed_table", 02364 test_match_interval_passed_table 02365 ) 02366 }; 02367 02368 static utest::v1::status_t greentea_test_setup(const size_t number_of_cases) 02369 { 02370 GREENTEA_SETUP(60, "default_auto"); 02371 return verbose_test_setup_handler(number_of_cases); 02372 } 02373 02374 int main() 02375 { 02376 Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); 02377 return !Harness::run(specification); 02378 }
Generated on Tue Jul 12 2022 13:03:02 by
