Untitled diff

Created Diff never expires
8 removals
Lines
Total
Removed
Words
Total
Removed
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
747 lines
10 additions
Lines
Total
Added
Words
Total
Added
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
747 lines
/* mbed Microcontroller Library
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
* Copyright (c) 2017 ARM Limited
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* See the License for the specific language governing permissions and
* limitations under the License.
* limitations under the License.
*/
*/


#define __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#include <stdint.h>
#include <algorithm>
#include <algorithm>


#include "utest/utest.h"
#include "utest/utest.h"
#include "unity/unity.h"
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#include "greentea-client/test_env.h"


#include "mbed.h"
#include "mbed.h"
#include "ticker_api.h"
#include "ticker_api.h"


using namespace utest::v1;
using namespace utest::v1;


#define MBED_ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
#define MBED_ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))


#define TIMESTAMP_MAX_DELTA MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA
#define TIMESTAMP_MAX_DELTA MBED_TICKER_INTERRUPT_TIMESTAMP_MAX_DELTA


struct ticker_interface_stub_t {
struct ticker_interface_stub_t {
ticker_interface_t interface;
ticker_interface_t interface;
bool initialized;
bool initialized;
bool interrupt_flag;
bool interrupt_flag;
timestamp_t timestamp ;
timestamp_t timestamp ;
timestamp_t interrupt_timestamp;
timestamp_t interrupt_timestamp;
unsigned int init_call;
unsigned int init_call;
unsigned int read_call;
unsigned int read_call;
unsigned int disable_interrupt_call;
unsigned int disable_interrupt_call;
unsigned int clear_interrupt_call;
unsigned int clear_interrupt_call;
unsigned int set_interrupt_call;
unsigned int set_interrupt_call;
};
};


static ticker_interface_stub_t interface_stub = { 0 };
static ticker_interface_stub_t interface_stub = { 0 };


static void ticker_interface_stub_init()
static void ticker_interface_stub_init()
{
{
++interface_stub.init_call;
++interface_stub.init_call;
interface_stub.initialized = true;
interface_stub.initialized = true;
}
}


static uint32_t ticker_interface_stub_read()
static uint32_t ticker_interface_stub_read()
{
{
++interface_stub.read_call;
++interface_stub.read_call;
return interface_stub.timestamp;
return interface_stub.timestamp;
}
}


static void ticker_interface_stub_disable_interrupt()
static void ticker_interface_stub_disable_interrupt()
{
{
++interface_stub.disable_interrupt_call;
++interface_stub.disable_interrupt_call;
}
}


static void ticker_interface_stub_clear_interrupt()
static void ticker_interface_stub_clear_interrupt()
{
{
++interface_stub.clear_interrupt_call;
++interface_stub.clear_interrupt_call;
interface_stub.interrupt_flag = false;
interface_stub.interrupt_flag = false;
}
}


static void ticker_interface_stub_set_interrupt(timestamp_t timestamp)
static void ticker_interface_stub_set_interrupt(timestamp_t timestamp)
{
{
++interface_stub.set_interrupt_call;
++interface_stub.set_interrupt_call;
interface_stub.interrupt_timestamp = timestamp;
interface_stub.interrupt_timestamp = timestamp;
}
}


static void reset_ticker_interface_stub()
static void reset_ticker_interface_stub()
{
{
interface_stub.interface.init = ticker_interface_stub_init;
interface_stub.interface.init = ticker_interface_stub_init;
interface_stub.interface.read = ticker_interface_stub_read;
interface_stub.interface.read = ticker_interface_stub_read;
interface_stub.interface.disable_interrupt =
interface_stub.interface.disable_interrupt =
ticker_interface_stub_disable_interrupt;
ticker_interface_stub_disable_interrupt;
interface_stub.interface.clear_interrupt =
interface_stub.interface.clear_interrupt =
ticker_interface_stub_clear_interrupt;
ticker_interface_stub_clear_interrupt;
interface_stub.interface.set_interrupt =ticker_interface_stub_set_interrupt;
interface_stub.interface.set_interrupt =ticker_interface_stub_set_interrupt;
interface_stub.initialized = false;
interface_stub.initialized = false;
interface_stub.interrupt_flag = false;
interface_stub.interrupt_flag = false;
interface_stub.timestamp = 0;
interface_stub.timestamp = 0;
interface_stub.interrupt_timestamp = 0;
interface_stub.interrupt_timestamp = 0;
interface_stub.init_call = 0;
interface_stub.init_call = 0;
interface_stub.read_call = 0;
interface_stub.read_call = 0;
interface_stub.disable_interrupt_call = 0;
interface_stub.disable_interrupt_call = 0;
interface_stub.clear_interrupt_call = 0;
interface_stub.clear_interrupt_call = 0;
interface_stub.set_interrupt_call = 0;
interface_stub.set_interrupt_call = 0;
}
}


// stub of the event queue
// stub of the event queue
static ticker_event_queue_t queue_stub = {
static ticker_event_queue_t queue_stub = {
/* event handler */ NULL,
/* event handler */ NULL,
/* head */ NULL,
/* head */ NULL,
/* timestamp */ 0,
/* timestamp */ 0,
/* initialized */ false
/* initialized */ false
};
};


static void reset_queue_stub()
static void reset_queue_stub()
{
{
queue_stub.event_handler = NULL;
queue_stub.event_handler = NULL;
queue_stub.head = NULL,
queue_stub.head = NULL,
queue_stub.present_time = 0;
queue_stub.present_time = 0;
queue_stub.initialized = false;
queue_stub.initialized = false;
}
}


// stub of the ticker
// stub of the ticker
static ticker_data_t ticker_stub = {
static ticker_data_t ticker_stub = {
/* interface */ &interface_stub.interface,
/* interface */ &interface_stub.interface,
/* queue */ &queue_stub
/* queue */ &queue_stub
};
};


static void reset_ticker_stub()
static void reset_ticker_stub()
{
{
reset_queue_stub();
reset_queue_stub();
reset_ticker_interface_stub();
reset_ticker_interface_stub();
}
}


static utest::v1::status_t case_setup_handler(
static utest::v1::status_t case_setup_handler(
const Case *const source, const size_t index_of_case
const Case *const source, const size_t index_of_case
) {
) {
utest::v1::status_t status = greentea_case_setup_handler(source, index_of_case);
utest::v1::status_t status = greentea_case_setup_handler(source, index_of_case);
reset_ticker_stub();
reset_ticker_stub();
return status;
return status;
}
}


static utest::v1::status_t case_teardown_handler(
static utest::v1::status_t case_teardown_handler(
const Case *const source, const size_t passed, const size_t failed, const failure_t reason
const Case *const source, const size_t passed, const size_t failed, const failure_t reason
) {
) {
reset_ticker_stub();
reset_ticker_stub();
utest::v1::status_t status = greentea_case_teardown_handler(
utest::v1::status_t status = greentea_case_teardown_handler(
source, passed, failed, reason
source, passed, failed, reason
);
);
return status;
return status;
}
}


static utest::v1::status_t greentea_failure_handler(
static utest::v1::status_t greentea_failure_handler(
const Case *const source, const failure_t reason
const Case *const source, const failure_t reason
) {
) {
utest::v1::status_t status = greentea_case_failure_abort_handler(
utest::v1::status_t status = greentea_case_failure_abort_handler(
source, reason
source, reason
);
);
return status;
return status;
}
}


static Case make_test_case(const char *description, const case_handler_t handler)
#define MAKE_TEST_CASE(description, handler) \
{
{ \
return Case(
description, \
description,
handler, \
case_setup_handler,
NULL, \
handler,
NULL, \
case_teardown_handler,
case_setup_handler, \
greentea_failure_handler
case_teardown_handler, \
);
greentea_failure_handler \
}
}


/**
/**
* Given an unitialized ticker_data instance.
* Given an unitialized ticker_data instance.
* When the ticker is initialized
* When the ticker is initialized
* Then:
* Then:
* - The ticker interface should be initialized
* - The ticker interface should be initialized
* - The queue handler should be set to the handler provided in parameter
* - The queue handler should be set to the handler provided in parameter
* - The internal ticker timestamp should be synced with the counter in the
* - The internal ticker timestamp should be synced with the counter in the
* interface counter.
* interface counter.
* - interrupt should be scheduled in current timestamp +
* - interrupt should be scheduled in current timestamp +
* TIMESTAMP_MAX_DELTA
* TIMESTAMP_MAX_DELTA
* - The queue should not contains any event
* - The queue should not contains any event
*/
*/
static void test_ticker_initialization()
static void test_ticker_initialization()
{
{
ticker_event_handler dummy_handler = (ticker_event_handler)0xDEADBEEF;
ticker_event_handler dummy_handler = (ticker_event_handler)0xDEADBEEF;


// setup of the stub
// setup of the stub
interface_stub.timestamp = 0xFEEDBABE;
interface_stub.timestamp = 0xFEEDBABE;


ticker_set_handler(&ticker_stub, dummy_handler);
ticker_set_handler(&ticker_stub, dummy_handler);


TEST_ASSERT_TRUE(interface_stub.initialized);
TEST_ASSERT_TRUE(interface_stub.initialized);
TEST_ASSERT_EQUAL_PTR(dummy_handler, queue_stub.event_handler);
TEST_ASSERT_EQUAL_PTR(dummy_handler, queue_stub.event_handler);
TEST_ASSERT_EQUAL_UINT64(interface_stub.timestamp, queue_stub.present_time);
TEST_ASSERT_EQUAL_UINT64(interface_stub.timestamp, queue_stub.present_time);
TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
TEST_ASSERT_EQUAL_UINT32(
TEST_ASSERT_EQUAL_UINT32(
interface_stub.timestamp + TIMESTAMP_MAX_DELTA,
interface_stub.timestamp + TIMESTAMP_MAX_DELTA,
interface_stub.interrupt_timestamp
interface_stub.interrupt_timestamp
);
);
TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head);
TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head);
TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
}
}


/**
/**
* Given an initialized ticker_data instance.
* Given an initialized ticker_data instance.
* When the ticker handler is set to a new value
* When the ticker handler is set to a new value
* Then:
* Then:
* - The ticker interface initialization function should not be called.
* - The ticker interface initialization function should not be called.
* - The queue handler should be set to the new handler.
* - The queue handler should be set to the new handler.
* - The events in the queue should remains the same.
* - The events in the queue should remains the same.
*/
*/
static void test_ticker_re_initialization()
static void test_ticker_re_initialization()
{
{
ticker_event_handler dummy_handler = (ticker_event_handler) 0xDEADBEEF;
ticker_event_handler dummy_handler = (ticker_event_handler) 0xDEADBEEF;
ticker_event_handler expected_handler = (ticker_event_handler) 0xFEEDDEAF;
ticker_event_handler expected_handler = (ticker_event_handler) 0xFEEDDEAF;
ticker_event_t first_event = { 0 };
ticker_event_t first_event = { 0 };
ticker_event_t second_event = { 0 };
ticker_event_t second_event = { 0 };
ticker_event_t third_event = { 0 };
ticker_event_t third_event = { 0 };


first_event.next = &second_event;
first_event.next = &second_event;
second_event.next = &third_event;
second_event.next = &third_event;


// initialize the ticker and put few events in the queue.
// initialize the ticker and put few events in the queue.
ticker_set_handler(&ticker_stub, dummy_handler);
ticker_set_handler(&ticker_stub, dummy_handler);
// simulate insertion, it shouldn't affect the queue behaviour for this test
// simulate insertion, it shouldn't affect the queue behaviour for this test
queue_stub.head = &first_event;
queue_stub.head = &first_event;
interface_stub.init_call = 0;
interface_stub.init_call = 0;


ticker_set_handler(&ticker_stub, expected_handler);
ticker_set_handler(&ticker_stub, expected_handler);


TEST_ASSERT_TRUE(interface_stub.initialized);
TEST_ASSERT_TRUE(interface_stub.initialized);
TEST_ASSERT_EQUAL(0, interface_stub.init_call);
TEST_ASSERT_EQUAL(0, interface_stub.init_call);
TEST_ASSERT_EQUAL(expected_handler, queue_stub.event_handler);
TEST_ASSERT_EQUAL(expected_handler, queue_stub.event_handler);
TEST_ASSERT_EQUAL(&first_event, queue_stub.head);
TEST_ASSERT_EQUAL(&first_event, queue_stub.head);
TEST_ASSERT_EQUAL(&second_event, queue_stub.head->next);
TEST_ASSERT_EQUAL(&second_event, queue_stub.head->next);
TEST_ASSERT_EQUAL(&third_event, queue_stub.head->next->next);
TEST_ASSERT_EQUAL(&third_event, queue_stub.head->next->next);
TEST_ASSERT_EQUAL(NULL, queue_stub.head->next->next->next);
TEST_ASSERT_EQUAL(NULL, queue_stub.head->next->next->next);
TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
}
}


/**
/**
* Given an initialized ticker_data instance.
* Given an initialized ticker_data instance.
* When the ticker is read
* When the ticker is read
* Then it should return the value present in the ticker interface
* Then it should return the value present in the ticker interface
*/
*/
static void test_ticker_read()
static void test_ticker_read()
{
{
ticker_set_handler(&ticker_stub, NULL);
ticker_set_handler(&ticker_stub, NULL);


timestamp_t timestamps[] = {
timestamp_t timestamps[] = {
0xA,
0xA,
0xAA,
0xAA,
0xAAA,
0xAAA,
0xAAAA,
0xAAAA,
0xAAAAA,
0xAAAAA,
0xAAAAAA,
0xAAAAAA,
0xAAAAAAA,
0xAAAAAAA,
0xAAAAAAAA
0xAAAAAAAA
};
};


for (size_t i = 0; i < MBED_ARRAY_SIZE(timestamps); ++i) {
for (size_t i = 0; i < MBED_ARRAY_SIZE(timestamps); ++i) {
interface_stub.timestamp = timestamps[i];
interface_stub.timestamp = timestamps[i];
TEST_ASSERT_EQUAL_UINT32(timestamps[i], ticker_read(&ticker_stub));
TEST_ASSERT_EQUAL_UINT32(timestamps[i], ticker_read(&ticker_stub));
TEST_ASSERT_EQUAL_UINT64(timestamps[i], ticker_read_us(&ticker_stub));
TEST_ASSERT_EQUAL_UINT64(timestamps[i], ticker_read_us(&ticker_stub));
}
}


TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
}
}


/**
/**
* Given an initialized ticker_data instance.
* Given an initialized ticker_data instance.
* When the ticker is read and the value read is less than the previous
* When the ticker is read and the value read is less than the previous
* value read.
* value read.
* Then:
* Then:
* - ticker_read should return the value read in the ticker interface
* - ticker_read should return the value read in the ticker interface
* - ticker_read_us should return a value where:
* - ticker_read_us should return a value where:
* + lower 8 bytes should be equal to the value in the ticker interface
* + lower 8 bytes should be equal to the value in the ticker interface
* + upper 8 bytes should be equal to the previous value of upper 8 bytes
* + upper 8 bytes should be equal to the previous value of upper 8 bytes
* plus one.
* plus one.
*/
*/
static void test_ticker_read_overflow()
static void test_ticker_read_overflow()
{
{
const timestamp_t timestamps[] = {
const timestamp_t timestamps[] = {
0xAAAAAAAA,
0xAAAAAAAA,
0xAAAAAAA,
0xAAAAAAA,
0xAAAAAA,
0xAAAAAA,
0xAAAAA,
0xAAAAA,
0xAAAA,
0xAAAA,
0xAAA,
0xAAA,
0xAA,
0xAA,
0xA
0xA
};
};


ticker_set_handler(&ticker_stub, NULL);
ticker_set_handler(&ticker_stub, NULL);


uint32_t upper_bytes_begin = ticker_read_us(&ticker_stub) >> 32;
uint32_t upper_bytes_begin = ticker_read_us(&ticker_stub) >> 32;


for (size_t i = 0; i < MBED_ARRAY_SIZE(timestamps); ++i) {
for (size_t i = 0; i < MBED_ARRAY_SIZE(timestamps); ++i) {
interface_stub.timestamp = timestamps[i];
interface_stub.timestamp = timestamps[i];
TEST_ASSERT_EQUAL_UINT32(timestamps[i], ticker_read(&ticker_stub));
TEST_ASSERT_EQUAL_UINT32(timestamps[i], ticker_read(&ticker_stub));
TEST_ASSERT_EQUAL_UINT32(timestamps[i], ticker_read_us(&ticker_stub));
TEST_ASSERT_EQUAL_UINT32(timestamps[i], ticker_read_us(&ticker_stub));
TEST_ASSERT_EQUAL_UINT64(
TEST_ASSERT_EQUAL_UINT64(
upper_bytes_begin + i, ticker_read_us(&ticker_stub) >> 32
upper_bytes_begin + i, ticker_read_us(&ticker_stub) >> 32
);
);
}
}


TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
}
}


/**
/**
* Given an initialized ticker without user registered events.
* Given an initialized ticker without user registered events.
* When an event is inserted with ticker_insert_event and the timestamp passed
* When an event is inserted with ticker_insert_event and the timestamp passed
* in parameter is in range [ticker_timestamp : ticker_timestamp +
* in parameter is in range [ticker_timestamp : ticker_timestamp +
* TIMESTAMP_MAX_DELTA[.
* TIMESTAMP_MAX_DELTA[.
* Then
* Then
* - The event should be in the queue
* - The event should be in the queue
* - The interrupt timestamp should be equal to the timestamp of the event
* - The interrupt timestamp should be equal to the timestamp of the event
* - The timestamp of the event should reflect the timestamp requested.
* - The timestamp of the event should reflect the timestamp requested.
* - The id of the event should be equal to the id passed in parameter.
* - The id of the event should be equal to the id passed in parameter.
*/
*/
static void test_legacy_insert_event_outside_overflow_range()
static void test_legacy_insert_event_outside_overflow_range()
{
{
ticker_set_handler(&ticker_stub, NULL);
ticker_set_handler(&ticker_stub, NULL);
interface_stub.set_interrupt_call = 0;
interface_stub.set_interrupt_call = 0;


// test the end of the range
// test the end of the range
ticker_event_t last_event = { 0 };
ticker_event_t last_event = { 0 };
const timestamp_t timestamp_last_event =
const timestamp_t timestamp_last_event =
interface_stub.timestamp + TIMESTAMP_MAX_DELTA;
interface_stub.timestamp + TIMESTAMP_MAX_DELTA;
const uint32_t id_last_event = 0xDEADDEAF;
const uint32_t id_last_event = 0xDEADDEAF;


ticker_insert_event(
ticker_insert_event(
&ticker_stub,
&ticker_stub,
&last_event, timestamp_last_event, id_last_event
&last_event, timestamp_last_event, id_last_event
);
);


TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head);
TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head);
TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
TEST_ASSERT_EQUAL_UINT32(
TEST_ASSERT_EQUAL_UINT32(
timestamp_last_event, interface_stub.interrupt_timestamp
timestamp_last_event, interface_stub.interrupt_timestamp
);
);
TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next);
TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next);
TEST_ASSERT_EQUAL_UINT32(timestamp_last_event, last_event.timestamp);
TEST_ASSERT_EQUAL_UINT32(timestamp_last_event, last_event.timestamp);
TEST_ASSERT_EQUAL_UINT32(id_last_event, last_event.id);
TEST_ASSERT_EQUAL_UINT32(id_last_event, last_event.id);


// test the beginning of the range
// test the beginning of the range
ticker_event_t first_event = { 0 };
ticker_event_t first_event = { 0 };
const timestamp_t timestamp_first_event = interface_stub.timestamp + 1;
const timestamp_t timestamp_first_event = interface_stub.timestamp + 1;
const uint32_t id_first_event = 0xAAAAAAAA;
const uint32_t id_first_event = 0xAAAAAAAA;


ticker_insert_event(
ticker_insert_event(
&ticker_stub,
&ticker_stub,
&first_event, timestamp_first_event, id_first_event
&first_event, timestamp_first_event, id_first_event
);
);


TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call);
TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call);
TEST_ASSERT_EQUAL_UINT32(
TEST_ASSERT_EQUAL_UINT32(
timestamp_first_event, interface_stub.interrupt_timestamp
timestamp_first_event, interface_stub.interrupt_timestamp
);
);
TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head->next);
TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head->next);
TEST_ASSERT_EQUAL_UINT32(
TEST_ASSERT_EQUAL_UINT32(
timestamp_first_event, first_event.timestamp
timestamp_first_event, first_event.timestamp
);
);
TEST_ASSERT_EQUAL_UINT32(id_first_event, first_event.id);
TEST_ASSERT_EQUAL_UINT32(id_first_event, first_event.id);


TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
}
}


/**
/**
* Given an initialized ticker without user registered events.
* Given an initialized ticker without user registered events.
* When an event is inserted with ticker_insert_event and a timestamp in the
* When an event is inserted with ticker_insert_event and a timestamp in the
* range [ticker_timestamp + TIMESTAMP_MAX_DELTA + 1 :
* range [ticker_timestamp + TIMESTAMP_MAX_DELTA + 1 :
* ticker_timestamp + UINT32MAX [
* ticker_timestamp + UINT32MAX [
* Then
* Then
* - The event should be in the queue
* - The event should be in the queue
* - The interrupt timestamp should be equal to
* - The interrupt timestamp should be equal to
* TIMESTAMP_MAX_DELTA
* TIMESTAMP_MAX_DELTA
* - The timestamp of the event should reflect the timestamp requested.
* - The timestamp of the event should reflect the timestamp requested.
* - The id of the event should be equal to the id passed in parameter.
* - The id of the event should be equal to the id passed in parameter.
*/
*/
static void test_legacy_insert_event_in_overflow_range()
static void test_legacy_insert_event_in_overflow_range()
{
{
ticker_set_handler(&ticker_stub, NULL);
ticker_set_handler(&ticker_stub, NULL);
interface_stub.set_interrupt_call = 0;
interface_stub.set_interrupt_call = 0;


// test the end of the range
// test the end of the range
ticker_event_t last_event = { 0 };
ticker_event_t last_event = { 0 };
const timestamp_t timestamp_last_event =
const timestamp_t timestamp_last_event =
interface_stub.timestamp + UINT32_MAX;
interface_stub.timestamp + UINT32_MAX;
const uint32_t id_last_event = 0xDEADDEAF;
const uint32_t id_last_event = 0xDEADDEAF;


ticker_insert_event(
ticker_insert_event(
&ticker_stub,
&ticker_stub,
&last_event, timestamp_last_event, id_last_event
&last_event, timestamp_last_event, id_last_event
);
);


TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head);
TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head);
TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
TEST_ASSERT_EQUAL_UINT32(
TEST_ASSERT_EQUAL_UINT32(
interface_stub.timestamp + TIMESTAMP_MAX_DELTA,
interface_stub.timestamp + TIMESTAMP_MAX_DELTA,
interface_stub.interrupt_timestamp
interface_stub.interrupt_timestamp
);
);
TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next);
TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next);
TEST_ASSERT_EQUAL_UINT32(timestamp_last_event, last_event.timestamp);
TEST_ASSERT_EQUAL_UINT32(timestamp_last_event, last_event.timestamp);
TEST_ASSERT_EQUAL_UINT32(id_last_event, last_event.id);
TEST_ASSERT_EQUAL_UINT32(id_last_event, last_event.id);


// test the beginning of the range
// test the beginning of the range
++interface_stub.timestamp;
++interface_stub.timestamp;


ticker_event_t first_event = { 0 };
ticker_event_t first_event = { 0 };
const timestamp_t timestamp_first_event =
const timestamp_t timestamp_first_event =
interface_stub.timestamp + TIMESTAMP_MAX_DELTA + 1;
interface_stub.timestamp + TIMESTAMP_MAX_DELTA + 1;
const uint32_t id_first_event = 0xAAAAAAAA;
const uint32_t id_first_event = 0xAAAAAAAA;


ticker_insert_event(
ticker_insert_event(
&ticker_stub,
&ticker_stub,
&first_event, timestamp_first_event, id_first_event
&first_event, timestamp_first_event, id_first_event
);
);


TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call);
TEST_ASSERT_EQUAL(2, interface_stub.set_interrupt_call);
TEST_ASSERT_EQUAL_UINT32(
TEST_ASSERT_EQUAL_UINT32(
interface_stub.timestamp + TIMESTAMP_MAX_DELTA,
interface_stub.timestamp + TIMESTAMP_MAX_DELTA,
interface_stub.interrupt_timestamp
interface_stub.interrupt_timestamp
);
);
TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head->next);
TEST_ASSERT_EQUAL_PTR(&last_event, queue_stub.head->next);
TEST_ASSERT_EQUAL_UINT32(
TEST_ASSERT_EQUAL_UINT32(
timestamp_first_event, first_event.timestamp
timestamp_first_event, first_event.timestamp
);
);
TEST_ASSERT_EQUAL_UINT32(id_first_event, first_event.id);
TEST_ASSERT_EQUAL_UINT32(id_first_event, first_event.id);


TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
}
}


/**
/**
* Given an initialized ticker without user registered events.
* Given an initialized ticker without user registered events.
* When an event is inserted with ticker_insert_event and the timestamp in
* When an event is inserted with ticker_insert_event and the timestamp in
* parameter is less than the current timestamp value.
* parameter is less than the current timestamp value.
* Then
* Then
* - The event should be in the queue
* - The event should be in the queue
* - The timestamp of the event should reflect the timestamp requested:
* - The timestamp of the event should reflect the timestamp requested:
* + lower 8 bytes should be equal to the timestamp in input.
* + lower 8 bytes should be equal to the timestamp in input.
* + upper 8 bytes should be equal to the upper of the upper 8 bytes of the
* + upper 8 bytes should be equal to the upper of the upper 8 bytes of the
* timestamp state stored in the queue plus one.
* timestamp state stored in the queue plus one.
* - The id of the event should be equal to the id passed in parameter.
* - The id of the event should be equal to the id passed in parameter.
*/
*/
static void test_legacy_insert_event_overflow(){
static void test_legacy_insert_event_overflow(){
ticker_set_handler(&ticker_stub, NULL);
ticker_set_handler(&ticker_stub, NULL);
interface_stub.set_interrupt_call = 0;
interface_stub.set_interrupt_call = 0;


interface_stub.timestamp = 0x20000000;
interface_stub.timestamp = 0x20000000;
ticker_read(&ticker_stub);
ticker_read(&ticker_stub);


ticker_event_t event = { 0 };
ticker_event_t event = { 0 };
const timestamp_t expected_timestamp =
const timestamp_t expected_timestamp =
interface_stub.timestamp +
interface_stub.timestamp +
TIMESTAMP_MAX_DELTA +
TIMESTAMP_MAX_DELTA +
1;
1;
const us_timestamp_t expected_us_timestamp =
const us_timestamp_t expected_us_timestamp =
(((queue_stub.present_time >> 32) + 1) << 32) | expected_timestamp;
(((queue_stub.present_time >> 32) + 1) << 32) | expected_timestamp;
const uint32_t expected_id = 0xDEADDEAF;
const uint32_t expected_id = 0xDEADDEAF;


ticker_insert_event(
ticker_insert_event(
&ticker_stub,
&ticker_stub,
&event, expected_timestamp, expected_id
&event, expected_timestamp, expected_id
);
);


TEST_ASSERT_EQUAL_PTR(&event, queue_stub.head);
TEST_ASSERT_EQUAL_PTR(&event, queue_stub.head);
TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
TEST_ASSERT_EQUAL(1, interface_stub.set_interrupt_call);
TEST_ASSERT_EQUAL_UINT32(
TEST_ASSERT_EQUAL_UINT32(
interface_stub.timestamp + TIMESTAMP_MAX_DELTA,
interface_stub.timestamp + TIMESTAMP_MAX_DELTA,
interface_stub.interrupt_timestamp
interface_stub.interrupt_timestamp
);
);
TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next);
TEST_ASSERT_EQUAL_PTR(NULL, queue_stub.head->next);
TEST_ASSERT_EQUAL_UINT32(expected_us_timestamp, event.timestamp);
TEST_ASSERT_EQUAL_UINT32(expected_us_timestamp, event.timestamp);
TEST_ASSERT_EQUAL_UINT32(expected_id, event.id);
TEST_ASSERT_EQUAL_UINT32(expected_id, event.id);


TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
}
}


/**
/**
* Given an initialized ticker.
* Given an initialized ticker.
* When an event is inserted with ticker_insert_event and a timestamp less than
* When an event is inserted with ticker_insert_event and a timestamp less than
* the one for the next scheduled timestamp.
* the one for the next scheduled timestamp.
* Then
* Then
* - The event inserted should be the first in the queue
* - The event inserted should be the first in the queue
* - The interrupt timestamp should be equal to the timestamp of the event or
* - The interrupt timestamp should be equal to the timestamp of the event or
* TIMESTAMP_MAX_DELTA if in the overflow range.
* TIMESTAMP_MAX_DELTA if in the overflow range.
* - The timestamp of the event should reflect the timestamp requested.
* - The timestamp of the event should reflect the timestamp requested.
* - The id of the event should be equal to the id passed in parameter.
* - The id of the event should be equal to the id passed in parameter.
* - Events in the queue should remained ordered by timestamp.
* - Events in the queue should remained ordered by timestamp.
*/
*/
static void test_legacy_insert_event_head()
static void test_legacy_insert_event_head()
{
{
ticker_set_handler(&ticker_stub, NULL);
ticker_set_handler(&ticker_stub, NULL);
interface_stub.set_interrupt_call = 0;
interface_stub.set_interrupt_call = 0;


const timestamp_t timestamps[] = {
const timestamp_t timestamps[] = {
UINT32_MAX,
UINT32_MAX,
TIMESTAMP_MAX_DELTA + 1,
TIMESTAMP_MAX_DELTA + 1,
TIMESTAMP_MAX_DELTA,
TIMESTAMP_MAX_DELTA,
TIMESTAMP_MAX_DELTA / 2,
TIMESTAMP_MAX_DELTA / 2,
TIMESTAMP_MAX_DELTA / 4,
TIMESTAMP_MAX_DELTA / 4,
TIMESTAMP_MAX_DELTA / 8,
TIMESTAMP_MAX_DELTA / 8,
TIMESTAMP_MAX_DELTA / 16,
TIMESTAMP_MAX_DELTA / 16,
};
};
ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };
ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };


for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
ticker_insert_event(
ticker_insert_event(
&ticker_stub,
&ticker_stub,
&events[i], timestamps[i], i
&events[i], timestamps[i], i
);
);


TEST_ASSERT_EQUAL_PTR(&events[i], queue_stub.head);
TEST_ASSERT_EQUAL_PTR(&events[i], queue_stub.head);
TEST_ASSERT_EQUAL(i + 1, interface_stub.set_interrupt_call);
TEST_ASSERT_EQUAL(i + 1, interface_stub.set_interrupt_call);
if (timestamps[i] < TIMESTAMP_MAX_DELTA) {
if (timestamps[i] < TIMESTAMP_MAX_DELTA) {
TEST_ASSERT_EQUAL_UINT32(
TEST_ASSERT_EQUAL_UINT32(
timestamps[i],
timestamps[i],
interface_stub.interrupt_timestamp
interface_stub.interrupt_timestamp
);
);
} else {
} else {
TEST_ASSERT_EQUAL_UINT32(
TEST_ASSERT_EQUAL_UINT32(
TIMESTAMP_MAX_DELTA,
TIMESTAMP_MAX_DELTA,
interface_stub.interrupt_timestamp
interface_stub.interrupt_timestamp
);
);
}
}


TEST_ASSERT_EQUAL_UINT32(
TEST_ASSERT_EQUAL_UINT32(
timestamps[i], events[i].timestamp
timestamps[i], events[i].timestamp
);
);
TEST_ASSERT_EQUAL_UINT32(i, events[i].id);
TEST_ASSERT_EQUAL_UINT32(i, events[i].id);


ticker_event_t* e = &events[i];
ticker_event_t* e = &events[i];
while (e) {
while (e) {
TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp);
TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp);
if (e->next) {
if (e->next) {
TEST_ASSERT_TRUE(e->id > e->next->id);
TEST_ASSERT_TRUE(e->id > e->next->id);
TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp);
TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp);
} else {
} else {
TEST_ASSERT_EQUAL_UINT32(0, e->id);
TEST_ASSERT_EQUAL_UINT32(0, e->id);
}
}
e = e->next;
e = e->next;
}
}
}
}


TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
}
}


/**
/**
* Given an initialized ticker.
* Given an initialized ticker.
* When an event is inserted with ticker_insert_event and its timestamp is bigger
* When an event is inserted with ticker_insert_event and its timestamp is bigger
* than the one of the last event in the queue.
* than the one of the last event in the queue.
* Then
* Then
* - The event inserted should be the last in the queue
* - The event inserted should be the last in the queue
* - The interrupt timestamp should remains equal to the interrupt timestamp
* - The interrupt timestamp should remains equal to the interrupt timestamp
* of the head event .
* of the head event .
* - The timestamp of the event should reflect the timestamp requested.
* - The timestamp of the event should reflect the timestamp requested.
* - The id of the event should be equal to the id passed in parameter.
* - The id of the event should be equal to the id passed in parameter.
* - Events in the queue should remained ordered by timestamp.
* - Events in the queue should remained ordered by timestamp.
*/
*/
static void test_legacy_insert_event_tail()
static void test_legacy_insert_event_tail()
{
{
ticker_set_handler(&ticker_stub, NULL);
ticker_set_handler(&ticker_stub, NULL);
interface_stub.set_interrupt_call = 0;
interface_stub.set_interrupt_call = 0;


const timestamp_t timestamps[] = {
const timestamp_t timestamps[] = {
0xA,
0xA,
0xAA,
0xAA,
0xAAA,
0xAAA,
0xAAAA,
0xAAAA,
0xAAAAA,
0xAAAAA,
0xAAAAAA,
0xAAAAAA,
0xAAAAAAA,
0xAAAAAAA,
0xAAAAAAAA,
0xAAAAAAAA,
};
};
ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };
ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };


for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
ticker_insert_event(
ticker_insert_event(
&ticker_stub,
&ticker_stub,
&events[i], timestamps[i], i
&events[i], timestamps[i], i
);
);


TEST_ASSERT_EQUAL_PTR(&events[0], queue_stub.head);
TEST_ASSERT_EQUAL_PTR(&events[0], queue_stub.head);
TEST_ASSERT_EQUAL_UINT32(
TEST_ASSERT_EQUAL_UINT32(
timestamps[0], interface_stub.interrupt_timestamp
timestamps[0], interface_stub.interrupt_timestamp
);
);


TEST_ASSERT_EQUAL_UINT32(timestamps[i], events[i].timestamp);
TEST_ASSERT_EQUAL_UINT32(timestamps[i], events[i].timestamp);
TEST_ASSERT_EQUAL_UINT32(i, events[i].id);
TEST_ASSERT_EQUAL_UINT32(i, events[i].id);


ticker_event_t* e = queue_stub.head;
ticker_event_t* e = queue_stub.head;
while (e) {
while (e) {
TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp);
TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp);
if (e->next) {
if (e->next) {
TEST_ASSERT_TRUE(e->id < e->next->id);
TEST_ASSERT_TRUE(e->id < e->next->id);
TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp);
TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp);
} else {
} else {
TEST_ASSERT_EQUAL_UINT32(&events[i], e);
TEST_ASSERT_EQUAL_UINT32(&events[i], e);
}
}
e = e->next;
e = e->next;
}
}
}
}


TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
}
}


/**
/**
* Given an initialized ticker.
* Given an initialized ticker.
* When an event is inserted with ticker_insert_event and a timestamp less
* When an event is inserted with ticker_insert_event and a timestamp less
* than the current timestamp in the interface and less than the relative
* than the current timestamp in the interface and less than the relative
* timestamp of the next event to execute.
* timestamp of the next event to execute.
* Then
* Then
* - The event inserted should be after the head
* - The event inserted should be after the head
* - The interrupt timestamp should remains equal to the interrupt timestamp
* - The interrupt timestamp should remains equal to the interrupt timestamp
* of the head event .
* of the head event .
* - The timestamp of the event should reflect the timestamp requested (overflow)
* - The timestamp of the event should reflect the timestamp requested (overflow)
* - The id of the event should be equal to the id passed in parameter.
* - The id of the event should be equal to the id passed in parameter.
* - Events in the queue should remained ordered by timestamp.
* - Events in the queue should remained ordered by timestamp.
*/
*/
static void test_legacy_insert_event_multiple_overflow()
static void test_legacy_insert_event_multiple_overflow()
{
{
ticker_set_handler(&ticker_stub, NULL);
ticker_set_handler(&ticker_stub, NULL);
interface_stub.set_interrupt_call = 0;
interface_stub.set_interrupt_call = 0;


const timestamp_t timestamps[] = {
const timestamp_t timestamps[] = {
0xA,
0xA,
0xAA,
0xAA,
0xAAA,
0xAAA,
0xAAAA,
0xAAAA,
0xAAAAA,
0xAAAAA,
0xAAAAAA,
0xAAAAAA,
0xAAAAAAA,
0xAAAAAAA,
0xAAAAAAAA
0xAAAAAAAA
};
};
ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };
ticker_event_t events[MBED_ARRAY_SIZE(timestamps)] = { 0 };


ticker_event_t ref_event;
ticker_event_t ref_event;
timestamp_t ref_event_timestamp = 0xCCCCCCCC;
timestamp_t ref_event_timestamp = 0xCCCCCCCC;
ticker_insert_event(
ticker_insert_event(
&ticker_stub,
&ticker_stub,
&ref_event, ref_event_timestamp, 0xDEADBEEF
&ref_event, ref_event_timestamp, 0xDEADBEEF
);
);


timestamp_t last_timestamp_to_insert =
timestamp_t last_timestamp_to_insert =
timestamps[MBED_ARRAY_SIZE(timestamps) - 1];
timestamps[MBED_ARRAY_SIZE(timestamps) - 1];
interface_stub.timestamp =
interface_stub.timestamp =
last_timestamp_to_insert +
last_timestamp_to_insert +
((ref_event_timestamp - last_timestamp_to_insert) / 2);
((ref_event_timestamp - last_timestamp_to_insert) / 2);


for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
for (size_t i = 0; i < MBED_ARRAY_SIZE(events); ++i) {
ticker_insert_event(
ticker_insert_event(
&ticker_stub,
&ticker_stub,
&events[i], timestamps[i], i
&events[i], timestamps[i], i
);
);


TEST_ASSERT_EQUAL_PTR(&ref_event, queue_stub.head);
TEST_ASSERT_EQUAL_PTR(&ref_event, queue_stub.head);
TEST_ASSERT_EQUAL_PTR(&events[0], queue_stub.head->next);
TEST_ASSERT_EQUAL_PTR(&events[0], queue_stub.head->next);
TEST_ASSERT_EQUAL_UINT32(
TEST_ASSERT_EQUAL_UINT32(
ref_event_timestamp, interface_stub.interrupt_timestamp
ref_event_timestamp, interface_stub.interrupt_timestamp
);
);


TEST_ASSERT_EQUAL_UINT32(timestamps[i], events[i].timestamp);
TEST_ASSERT_EQUAL_UINT32(timestamps[i], events[i].timestamp);
TEST_ASSERT_EQUAL_UINT32(i, events[i].id);
TEST_ASSERT_EQUAL_UINT32(i, events[i].id);


ticker_event_t* e = queue_stub.head->next;
ticker_event_t* e = queue_stub.head->next;
while (e) {
while (e) {
TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp);
TEST_ASSERT_EQUAL_UINT32(timestamps[e->id], e->timestamp);
if (e->next) {
if (e->next) {
TEST_ASSERT_TRUE(e->id < e->next->id);
TEST_ASSERT_TRUE(e->id < e->next->id);
TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp);
TEST_ASSERT_TRUE(e->timestamp < e->next->timestamp);
} else {
} else {
TEST_ASSERT_EQUAL_UINT32(&events[i], e);
TEST_ASSERT_EQUAL_UINT32(&events[i], e);
}
}
e = e->next;
e = e->next;
}
}
}
}


TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
TEST_ASSERT_EQUAL(0, interface_stub.disable_interrupt_call);
}
}


/**
/**
* Given an initialized ticker.
* Given an initialized ticker.
* When an event is inserted with ticker_insert_event.
* When an event is inserted with ticker_insert_event.
* Then
* Then
* - The event inserted should be at the correct position in the queue
* - The event inserted should be at the correct position in the queue
* - The event queue should remain ordered by timestamp
* - The event queue should remain ordered by timestamp
* - The interrupt timestamp should be equal to the interrupt timestamp
* - The interrupt timestamp should be equal to the interrupt timestamp
* of the head event or TIMESTAMP_MAX_DELTA if the
* of the head event or TIMESTAMP_MAX_DELTA if the
* timestamp is in the overflow range.
* timestamp is in the overflow range.
* - The timestamp of the event should reflect the timestamp requested (overflow)
* - The timestamp of the event should reflect the timestamp requested (overflow)
* - The id of the event should be equal to the id passed in parameter.
* - The id of the event should be equal to the id passed in parameter.
* - Events in the queue should remained ordered by timestamp.
* - Events in the queue should remained ordered by timestamp.
*/
*/
static void test_legacy_insert_event_multiple_random()
static void test_legacy_insert_event_multiple_random()
{
{
ticker_set_handler(&ticker_stub, NULL);
ticker_set_handler(&ticker_stub, NULL);
interface_stub.set_interrupt_call = 0;
interface_stub.set_interrupt_call = 0;


const timestamp_t ref_timestamp = UINT32_MAX / 2;
const timestamp_t ref_timestamp = UINT32_MAX / 2;
interface_stub.timestamp = ref_timestamp;
interface_stub.timestamp = ref_timestamp;


// insert first event at the head of the queue
// insert first event at the head of the queue
ticker_event_t first_event;
ticker_event_t first_event;
const timestamp_t first_event_timestamp =
const timestamp_t first_event_timestamp =
ref_timestamp + TIMESTAMP_MAX_DELTA + 100;
ref_timestamp + TIMESTAMP_MAX_DELTA + 100;


ticker_insert_event(
ticker_insert_event(
&ticker_stub,
&ticker_stub,
&first_event, first_event_timestamp, (uint32_t) &first_event
&first_event, first_event_timestamp, (uint32_t) &first_event
);
);


TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
TEST_ASSERT_EQUAL_PTR(NULL, first_event.next);
TEST_ASSERT_EQUAL_PTR(NULL, first_event.next);
TEST_ASSERT_EQUAL_UINT32(
TEST_ASSERT_EQUAL_UINT32(
ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp
ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp
);
);
TEST_ASSERT_EQUAL_UINT32(first_event_timestamp, first_event.timestamp);
TEST_ASSERT_EQUAL_UINT32(first_event_timestamp, first_event.timestamp);
TEST_ASSERT_EQUAL_UINT64(
TEST_ASSERT_EQUAL_UINT64(
first_event.timestamp,
first_event.timestamp,
first_event_timestamp +
first_event_timestamp +
((first_event_timestamp < ref_timestamp) ? (1ULL << 32) : 0)
((first_event_timestamp < ref_timestamp) ? (1ULL << 32) : 0)
);
);
TEST_ASSERT_EQUAL_UINT32((uint32_t) &first_event, first_event.id);
TEST_ASSERT_EQUAL_UINT32((uint32_t) &first_event, first_event.id);


// insert second event at the tail of the queue
// insert second event at the tail of the queue
ticker_event_t second_event;
ticker_event_t second_event;
const timestamp_t second_event_timestamp = first_event_timestamp + 1;
const timestamp_t second_event_timestamp = first_event_timestamp + 1;


ticker_insert_event(
ticker_insert_event(
&ticker_stub,
&ticker_stub,
&second_event, second_event_timestamp, (uint32_t) &second_event
&second_event, second_event_timestamp, (uint32_t) &second_event
);
);


TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
TEST_ASSERT_EQUAL_PTR(&first_event, queue_stub.head);
TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next);
TEST_ASSERT_EQUAL_PTR(&second_event, first_event.next);
TEST_ASSERT_EQUAL_PTR(NULL, second_event.next);
TEST_ASSERT_EQUAL_PTR(NULL, second_event.next);
TEST_ASSERT_EQUAL_UINT32(
TEST_ASSERT_EQUAL_UINT32(
ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp
ref_timestamp + TIMESTAMP_MAX_DELTA, interface_stub.interrupt_timestamp
);
);
TEST_ASSERT_EQUAL_UINT32(second_event_timestamp, second_event.timestamp);
TEST_ASSERT_EQUAL_UINT32(second_event_timestamp, second_event.timestamp);
TEST_ASSERT_EQUAL_UINT64(
TEST_ASSERT_EQUAL_UINT64(
second_event.timestamp,
second_event.timestamp,
second_event_timestamp +
second_event_timestamp +
((second_event_timestamp < ref_timestamp) ? (1ULL << 32) : 0)
((second_event_timestamp < ref_timestamp) ? (1ULL << 32) : 0)
);
);
TEST_ASSERT_EQUAL_UINT32((uint32_t) &second_event, second_event.id);
TEST_ASSERT_EQUAL_UINT32((uint32_t) &second_event, second_event.id);




// insert third event at the head of the queue out the overflow zone
// insert third event at the head of the queue out the overflow zone
ticker
ticker_event_t