Untitled diff
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