Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2017 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 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 Thu Jul 14 2022 14:36:19 by
