diff --git a/sys/include/timex.h b/sys/include/timex.h index 66bd2f925e..fdfe37c794 100644 --- a/sys/include/timex.h +++ b/sys/include/timex.h @@ -55,6 +55,13 @@ int timex_isnormalized(timex_t *time); */ uint64_t timex_uint64(const timex_t a); +/** + * @brief Converts a uint64_t of microseconds to a timex_t + * + * @return a timex representation of an uint64 timestamp. + */ +timex_t timex_from_uint64(const uint64_t timestamp); + /** * @brief Prints a timex_t */ diff --git a/sys/timex/timex.c b/sys/timex/timex.c index b481c492f5..dce1edda41 100644 --- a/sys/timex/timex.c +++ b/sys/timex/timex.c @@ -14,6 +14,7 @@ * @author Kaspar Schleiser * @author Oliver Hahm * @author Christian Mehlis + * @author Daniel Jentsch * */ @@ -39,15 +40,11 @@ timex_t timex_add(const timex_t a, const timex_t b) result.seconds = a.seconds + b.seconds; result.microseconds = a.microseconds + b.microseconds; - if (result.microseconds < a.microseconds) { + if (result.microseconds > SEC_IN_USEC) { + result.microseconds -= SEC_IN_USEC; result.seconds++; } - /* if (result.microseconds > SEC_IN_USEC) { - result.microseconds -= SEC_IN_USEC; - result.seconds++; - } - */ return result; } @@ -86,8 +83,15 @@ timex_t timex_sub(const timex_t a, const timex_t b) #endif timex_t result; - result.seconds = a.seconds - b.seconds; - result.microseconds = a.microseconds - b.microseconds; + + if (a.microseconds >= b.microseconds) { + result.seconds = a.seconds - b.seconds; + result.microseconds = a.microseconds - b.microseconds; + } + else { + result.seconds = a.seconds - b.seconds - 1; + result.microseconds = a.microseconds + SEC_IN_USEC - b.microseconds; + } return result; } @@ -122,6 +126,11 @@ uint64_t timex_uint64(const timex_t a) return (uint64_t) a.seconds * SEC_IN_USEC + a.microseconds; } +timex_t timex_from_uint64(const uint64_t timestamp) +{ + return timex_set(timestamp / SEC_IN_USEC, timestamp % SEC_IN_USEC); +} + void timex_print(const timex_t t) { printf("Seconds: %" PRIu32 " - Microseconds: %" PRIu32 "\n", t.seconds, t.microseconds); diff --git a/tests/unittests/tests-timex/Makefile b/tests/unittests/tests-timex/Makefile new file mode 100644 index 0000000000..7eb455cc3c --- /dev/null +++ b/tests/unittests/tests-timex/Makefile @@ -0,0 +1,3 @@ +MODULE = tests-timex + +include $(RIOTBASE)/Makefile.base diff --git a/tests/unittests/tests-timex/Makefile.include b/tests/unittests/tests-timex/Makefile.include new file mode 100644 index 0000000000..fde719b471 --- /dev/null +++ b/tests/unittests/tests-timex/Makefile.include @@ -0,0 +1,2 @@ +USEMODULE += timex + diff --git a/tests/unittests/tests-timex/tests-timex.c b/tests/unittests/tests-timex/tests-timex.c new file mode 100644 index 0000000000..ca0b624387 --- /dev/null +++ b/tests/unittests/tests-timex/tests-timex.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2014 Philipp Rosenkranz, Daniel Jentsch + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +#include "tests-timex.h" + +#include "timex.h" + +static void test_timex_set(void) +{ + timex_t time; + time = timex_set(1, 0); + TEST_ASSERT_EQUAL_INT(1, time.seconds); + TEST_ASSERT_EQUAL_INT(0, time.microseconds); +} + +static void test_timex_add(void) +{ + timex_t time; + time = timex_add(timex_set(100, 100), timex_set(40, 10)); + TEST_ASSERT_EQUAL_INT(0, timex_cmp(time, timex_set(140, 110))); + time = timex_add(timex_set(100, 700000), timex_set(40, 800000)); + TEST_ASSERT_EQUAL_INT(0, timex_cmp(time, timex_set(141, 500000))); +} + +static void test_timex_sub(void) +{ + timex_t time; + time = timex_sub(timex_set(100, 100), timex_set(40, 10)); + TEST_ASSERT_EQUAL_INT(0, timex_cmp(time, timex_set(60, 90))); + time = timex_sub(timex_set(100, 100), timex_set(40, 200)); + TEST_ASSERT_EQUAL_INT(0, timex_cmp(time, timex_set(59, 999900))); +} + +static void test_timex_from_uint64(void) +{ + timex_t time; + time = timex_from_uint64(1001000); + TEST_ASSERT(time.seconds == 1); + TEST_ASSERT(time.microseconds == 1000); +} + +Test *tests_timex_tests(void) +{ + EMB_UNIT_TESTFIXTURES(fixtures) { + new_TestFixture(test_timex_set), + new_TestFixture(test_timex_add), + new_TestFixture(test_timex_sub), + new_TestFixture(test_timex_from_uint64), + }; + + EMB_UNIT_TESTCALLER(timex_tests, NULL, NULL, fixtures); + + return (Test *)&timex_tests; +} + +void tests_timex(void) +{ + TESTS_RUN(tests_timex_tests()); +} diff --git a/tests/unittests/tests-timex/tests-timex.h b/tests/unittests/tests-timex/tests-timex.h new file mode 100644 index 0000000000..d65a33ca36 --- /dev/null +++ b/tests/unittests/tests-timex/tests-timex.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2014 Philipp Rosenkranz, Daniel Jentsch + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @addtogroup unittests + * @{ + * + * @file tests-timex.h + * @brief Unittests for the ``timex`` module + * + * @author Philipp Rosenkranz + * @author Daniel Jentsch + */ +#ifndef __TESTS_TIMEX_H_ +#define __TESTS_TIMEX_H_ + +#include "../unittests.h" + +/** + * @brief The entry point of this test suite. + */ +void tests_timex(void); + +/** + * @brief Generates tests for timex + * + * @return embUnit tests if successful, NULL if not. + */ +Test *tests_timex_tests(void); + +#endif /* __TESTS_TIMEX_H_ */ +/** @} */