diff --git a/src/fsfw/osal/rtems/Clock.cpp b/src/fsfw/osal/rtems/Clock.cpp index cb7bd0429..1ffed9871 100644 --- a/src/fsfw/osal/rtems/Clock.cpp +++ b/src/fsfw/osal/rtems/Clock.cpp @@ -107,9 +107,6 @@ ReturnValue_t Clock::getDateAndTime(TimeOfDay_t* time) { rtems_status_code status = rtems_clock_get_tod(&timeRtems); switch (status) { case RTEMS_SUCCESSFUL: { - /* The last field now contains the RTEMS ticks of the seconds from 0 - to rtems_clock_get_ticks_per_second() minus one. - We calculate the microseconds accordingly */ time->day = timeRtems.day; time->hour = timeRtems.hour; time->minute = timeRtems.minute; @@ -140,7 +137,7 @@ ReturnValue_t Clock::convertTimeOfDayToTimeval(const TimeOfDay_t* from, timeval* timeRtems.hour = from->hour; timeRtems.minute = from->minute; timeRtems.second = from->second; - timeRtems.ticks = from->usecond * getTicksPerSecond() / 1e6; + timeRtems.ticks = from->usecond * rtems_clock_get_ticks_per_second() / 1e6; to->tv_sec = _TOD_To_seconds(&timeRtems); to->tv_usec = from->usecond; return returnvalue::OK; diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index ad26e3923..e02e76494 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -20,7 +20,9 @@ add_subdirectory(globalfunctions) add_subdirectory(timemanager) add_subdirectory(tmtcpacket) add_subdirectory(cfdp) +IF(NOT FSFW_OSAL MATCHES "rtems") add_subdirectory(hal) +ENDIF() add_subdirectory(internalerror) add_subdirectory(devicehandler) add_subdirectory(tmtcservices) diff --git a/unittests/CatchRunner.cpp b/unittests/CatchRunner.cpp index b6017b430..59dde71ec 100644 --- a/unittests/CatchRunner.cpp +++ b/unittests/CatchRunner.cpp @@ -46,38 +46,53 @@ void unittestTaskFunction(void* pvParameters) { #ifdef FSFW_OSAL_RTEMS #include -int sigaltstack(const stack_t * ss, stack_t * old_ss){ - return 0; -} +int sigaltstack(const stack_t* ss, stack_t* old_ss) { return 0; } extern "C" { -#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER -#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +void exit_qemu_failing(int error) { + asm(/* 0x20026 == ADP_Stopped_ApplicationExit */ + "mov x1, #0x26\n\t" + "movk x1, #2, lsl #16\n\t" + "str x1, [sp,#0]\n\t"); -#define CONFIGURE_UNLIMITED_OBJECTS -#define CONFIGURE_UNIFIED_WORK_AREAS + /* Exit status code. Host QEMU process exits with that status. */ + asm("mov x0, %[error]\n\t" : : [error] "r" (error)); + asm( + "str x0, [sp,#8]\n\t" -#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + /* x1 contains the address of parameter block. + * Any memory address could be used. */ + "mov x1, sp\n\t" -#define CONFIGURE_INIT + /* SYS_EXIT */ + "mov w0, #0x18\n\t" -#include - - -#include -#include -#include - -rtems_task Init( - rtems_task_argument ignored -) -{ - printf( "\nHello World\n" ); - char* argv[] = {"fsfw-test"}; - int result = Catch::Session().run(1, argv); - exit( result ); + /* Do the semihosting call on A64. */ + "hlt 0xf000\n\t" +); } +#include "testcfg/rtems/rtemsConfig.h" + +rtems_task Init(rtems_task_argument ignored) { + rtems_time_of_day now; + now.year = 2023; + now.month = 1; + now.day = 15; + now.hour = 0; + now.minute = 0; + now.second = 0; + now.ticks = 0; + rtems_clock_set(&now); + customSetup(); + const char* argv[] = {"fsfw-test", ""}; + int result = Catch::Session().run(1, argv); + customTeardown(); + if (result != 0) { + exit_qemu_failing(result); + } + exit(result); +} } #endif diff --git a/unittests/osal/TestClock.cpp b/unittests/osal/TestClock.cpp index bdfefde63..5e381e8bf 100644 --- a/unittests/osal/TestClock.cpp +++ b/unittests/osal/TestClock.cpp @@ -8,6 +8,8 @@ #include "CatchDefinitions.h" +//TODO setClock() + TEST_CASE("OSAL::Clock Test", "[OSAL::Clock Test]") { SECTION("Test getClock") { timeval time; @@ -22,7 +24,14 @@ TEST_CASE("OSAL::Clock Test", "[OSAL::Clock Test]") { // We require timeOfDayAsTimeval to be larger than time as it // was request a few ns later double difference = timevalOperations::toDouble(timeOfDayAsTimeval - time); - CHECK(difference >= 0.0); + uint32_t ticksPerSecond =Clock:: getTicksPerSecond(); + float secondPerTick = 0; + if (ticksPerSecond != 0){ + secondPerTick = 1.0 / ticksPerSecond; + } + // In rtems, timevals have microsecond resolution, while TOD has only tick resolution, leading to + // negative differences when comparing "equal" times + CHECK(difference >= -secondPerTick); CHECK(difference <= 0.005); // Conversion in the other direction diff --git a/unittests/testcfg/rtems/rtemsConfig.h b/unittests/testcfg/rtems/rtemsConfig.h new file mode 100644 index 000000000..e9af11079 --- /dev/null +++ b/unittests/testcfg/rtems/rtemsConfig.h @@ -0,0 +1,25 @@ +#pragma once + +#define RTEMS_USE_UNLIMITED_OBJECTS_ALLOCATION 0 + +#define CONFIGURE_MICROSECONDS_PER_TICK 1000 + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_MAXIMUM_TASKS 20 +#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 30 +#define CONFIGURE_MAXIMUM_SEMAPHORES 20 +#define CONFIGURE_MAXIMUM_TIMERS 10 +//! Required for Rate-Monotonic Scheduling (RMS) +#define CONFIGURE_MAXIMUM_PERIODS 15 +#define CONFIGURE_INIT_TASK_STACK_SIZE (RTEMS_MINIMUM_STACK_SIZE * 6) +//! Around 41 kB extra task stack for now. +#define CONFIGURE_EXTRA_TASK_STACKS (10 * RTEMS_MINIMUM_STACK_SIZE) + +#define CONFIGURE_INIT + +#include +#include