diff --git a/src/fsfw/osal/linux/CMakeLists.txt b/src/fsfw/osal/linux/CMakeLists.txt index 0fb66b3ed..418007643 100644 --- a/src/fsfw/osal/linux/CMakeLists.txt +++ b/src/fsfw/osal/linux/CMakeLists.txt @@ -13,7 +13,6 @@ target_sources(${LIB_FSFW_NAME} QueueFactory.cpp SemaphoreFactory.cpp TaskFactory.cpp - Timer.cpp tcpipHelpers.cpp unixUtility.cpp ) diff --git a/src/fsfw/osal/linux/Timer.cpp b/src/fsfw/osal/linux/Timer.cpp deleted file mode 100644 index dca3112dc..000000000 --- a/src/fsfw/osal/linux/Timer.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "fsfw/osal/linux/Timer.h" -#include "fsfw/serviceinterface/ServiceInterfaceStream.h" -#include - - -Timer::Timer() { - sigevent sigEvent; - sigEvent.sigev_notify = SIGEV_NONE; - sigEvent.sigev_signo = 0; - sigEvent.sigev_value.sival_ptr = &timerId; - int status = timer_create(CLOCK_MONOTONIC, &sigEvent, &timerId); - if(status!=0){ -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::error << "Timer creation failed with: " << status << - " errno: " << errno << std::endl; -#endif - } -} - -Timer::~Timer() { - timer_delete(timerId); -} - -int Timer::setTimer(uint32_t intervalMs) { - itimerspec timer; - timer.it_value.tv_sec = intervalMs / 1000; - timer.it_value.tv_nsec = (intervalMs * 1000000) % (1000000000); - timer.it_interval.tv_sec = 0; - timer.it_interval.tv_nsec = 0; - return timer_settime(timerId, 0, &timer, NULL); -} - - -int Timer::getTimer(uint32_t* remainingTimeMs){ - itimerspec timer; - timer.it_value.tv_sec = 0; - timer.it_value.tv_nsec = 0; - timer.it_interval.tv_sec = 0; - timer.it_interval.tv_nsec = 0; - int status = timer_gettime(timerId, &timer); - - *remainingTimeMs = timer.it_value.tv_sec * 1000 + timer.it_value.tv_nsec / 1000000; - - return status; -} diff --git a/src/fsfw/osal/linux/Timer.h b/src/fsfw/osal/linux/Timer.h deleted file mode 100644 index f94bca59b..000000000 --- a/src/fsfw/osal/linux/Timer.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef FRAMEWORK_OSAL_LINUX_TIMER_H_ -#define FRAMEWORK_OSAL_LINUX_TIMER_H_ - -#include -#include -#include - -/** - * This class is a helper for the creation of a Clock Monotonic timer which does not trigger a signal - */ -class Timer { -public: - /** - * Creates the Timer sets the timerId Member - */ - Timer(); - /** - * Deletes the timer - * - * Careful! According to POSIX documentation: - * The treatment of any pending signal generated by the deleted timer is unspecified. - */ - virtual ~Timer(); - - /** - * Set the timer given in timerId to the given interval - * - * @param intervalMs Interval in ms to be set - * @return 0 on Success 1 else - */ - int setTimer(uint32_t intervalMs); - - /** - * Get the remaining time of the timer - * - * @param remainingTimeMs Pointer to integer value which is used to return the remaining time - * @return 0 on Success 1 else (see timer_getime documentation of posix function) - */ - int getTimer(uint32_t* remainingTimeMs); - -private: - timer_t timerId; -}; - -#endif /* FRAMEWORK_OSAL_LINUX_TIMER_H_ */ diff --git a/src/fsfw/timemanager/Countdown.cpp b/src/fsfw/timemanager/Countdown.cpp index c3499685f..23d574776 100644 --- a/src/fsfw/timemanager/Countdown.cpp +++ b/src/fsfw/timemanager/Countdown.cpp @@ -6,16 +6,14 @@ Countdown::Countdown(uint32_t initialTimeout): timeout(initialTimeout) { Countdown::~Countdown() { } -ReturnValue_t Countdown::setTimeout(uint32_t miliseconds) { - ReturnValue_t return_value = Clock::getUptime( &startTime ); - timeout = miliseconds; - return return_value; +ReturnValue_t Countdown::setTimeout(uint32_t milliseconds) { + ReturnValue_t returnValue = Clock::getUptime( &startTime ); + timeout = milliseconds; + return returnValue; } bool Countdown::hasTimedOut() const { - uint32_t current_time; - Clock::getUptime( ¤t_time ); - if ( uint32_t(current_time - startTime) >= timeout) { + if ( uint32_t( this->getCurrentTime() - startTime) >= timeout) { return true; } else { return false; @@ -31,7 +29,23 @@ ReturnValue_t Countdown::resetTimer() { } void Countdown::timeOut() { - uint32_t current_time; - Clock::getUptime( ¤t_time ); - startTime= current_time - timeout; + startTime = this->getCurrentTime() - timeout; +} + +uint32_t Countdown::getRemainingMillis() const { + // We fetch the time before the if-statement + // to be sure that the return is in + // range 0 <= number <= timeout + uint32_t currentTime = this->getCurrentTime(); + if (this->hasTimedOut()){ + return 0; + }else{ + return (startTime + timeout) - currentTime; + } +} + +uint32_t Countdown::getCurrentTime() const { + uint32_t currentTime; + Clock::getUptime( ¤tTime ); + return currentTime; } diff --git a/src/fsfw/timemanager/Countdown.h b/src/fsfw/timemanager/Countdown.h index f6a41e73d..c0afdf755 100644 --- a/src/fsfw/timemanager/Countdown.h +++ b/src/fsfw/timemanager/Countdown.h @@ -4,28 +4,77 @@ #include "Clock.h" /** - * @brief This file defines the Countdown class. - * @author baetz + * + * Countdown keeps track of a timespan. + * + * Countdown::resetTimer restarts the timer. + * Countdown::setTimeout sets a new countdown duration and resets. + * + * Can be checked with Countdown::hasTimedOut or + * Countdown::isBusy. + * + * Countdown::timeOut will force the timer to time out. + * */ class Countdown { public: - uint32_t timeout; + /** + * Constructor which sets the countdown duration in milliseconds + * + * It does not start the countdown! + * Call resetTimer or setTimeout before usage! + * Otherwise a call to hasTimedOut might return True. + * + * @param initialTimeout Countdown duration in milliseconds + */ Countdown(uint32_t initialTimeout = 0); ~Countdown(); - ReturnValue_t setTimeout(uint32_t miliseconds); - + /** + * Call to set a new countdown duration. + * + * Resets the countdown! + * + * @param milliseconds new countdown duration in milliseconds + * @return Returnvalue from Clock::getUptime + */ + ReturnValue_t setTimeout(uint32_t milliseconds); + /** + * Returns true if the countdown duration has passed. + * + * @return True if the countdown has passed + * False if it is still running + */ bool hasTimedOut() const; - + /** + * Complementary to hasTimedOut. + * + * @return True if the countdown is till running + * False if it is still running + */ bool isBusy() const; - - //!< Use last set timeout value and restart timer. + /** + * Uses last set timeout value and restarts timer. + */ ReturnValue_t resetTimer(); - - //!< Make hasTimedOut() return true + /** + * Returns the remaining milliseconds (0 if timeout) + */ + uint32_t getRemainingMillis() const; + /** + * Makes hasTimedOut() return true + */ void timeOut(); - + /** + * Internal countdown duration in milliseconds + */ + uint32_t timeout; private: + /** + * Last time the timer was started (uptime) + */ uint32_t startTime = 0; + + uint32_t getCurrentTime() const; }; #endif /* FSFW_TIMEMANAGER_COUNTDOWN_H_ */ diff --git a/tests/src/fsfw_tests/unit/CMakeLists.txt b/tests/src/fsfw_tests/unit/CMakeLists.txt index 01e4d19c3..f30e4b6bf 100644 --- a/tests/src/fsfw_tests/unit/CMakeLists.txt +++ b/tests/src/fsfw_tests/unit/CMakeLists.txt @@ -18,4 +18,5 @@ add_subdirectory(serialize) add_subdirectory(datapoollocal) add_subdirectory(storagemanager) add_subdirectory(globalfunctions) +add_subdirectory(timemanager) add_subdirectory(tmtcpacket) diff --git a/tests/src/fsfw_tests/unit/timemanager/CMakeLists.txt b/tests/src/fsfw_tests/unit/timemanager/CMakeLists.txt new file mode 100644 index 000000000..2c6357114 --- /dev/null +++ b/tests/src/fsfw_tests/unit/timemanager/CMakeLists.txt @@ -0,0 +1,3 @@ +target_sources(${TARGET_NAME} PRIVATE + TestCountdown.cpp +) diff --git a/tests/src/fsfw_tests/unit/timemanager/TestCountdown.cpp b/tests/src/fsfw_tests/unit/timemanager/TestCountdown.cpp new file mode 100644 index 000000000..b1b26679e --- /dev/null +++ b/tests/src/fsfw_tests/unit/timemanager/TestCountdown.cpp @@ -0,0 +1,27 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" +#include +#include + + +TEST_CASE( "Countdown Tests", "[TestCountdown]") { + INFO("Countdown Tests"); + Countdown count(20); + REQUIRE(count.timeout == 20); + REQUIRE(count.setTimeout(100) == static_cast(HasReturnvaluesIF::RETURN_OK)); + REQUIRE(count.timeout == 100); + REQUIRE(count.setTimeout(150) == static_cast(HasReturnvaluesIF::RETURN_OK)); + REQUIRE(count.isBusy()); + REQUIRE(not count.hasTimedOut()); + uint32_t number = count.getRemainingMillis(); + REQUIRE(number > 0); + bool blocked = false; + while(not count.hasTimedOut()){ + blocked = true; + }; + REQUIRE(blocked); + number = count.getRemainingMillis(); + REQUIRE(number==0); + count.resetTimer(); + REQUIRE(not count.hasTimedOut()); + REQUIRE(count.isBusy()); +}