Merge branch 'development' into mueller/tm-stack-robustness

This commit is contained in:
Robin Müller 2021-10-04 14:45:37 +02:00
commit 6e57581a1e
11 changed files with 145 additions and 135 deletions

View File

@ -165,11 +165,9 @@ ReturnValue_t DleEncoder::decodeStreamEscaped(const uint8_t *sourceStream, size_
if (sourceStream[encodedIndex++] != STX_CHAR) {
return DECODING_ERROR;
}
while ((encodedIndex < sourceStreamLen)
and (decodedIndex < maxDestStreamlen)
and (sourceStream[encodedIndex] != ETX_CHAR)
and (sourceStream[encodedIndex] != STX_CHAR)) {
if (sourceStream[encodedIndex] == DLE_CHAR) {
while ((encodedIndex < sourceStreamLen) and (decodedIndex < maxDestStreamlen)) {
switch(sourceStream[encodedIndex]) {
case(DLE_CHAR): {
if(encodedIndex + 1 >= sourceStreamLen) {
//reached the end of the sourceStream
*readLen = sourceStreamLen;
@ -197,29 +195,33 @@ ReturnValue_t DleEncoder::decodeStreamEscaped(const uint8_t *sourceStream, size_
}
}
++encodedIndex;
break;
}
else {
case(STX_CHAR): {
*readLen = encodedIndex;
return DECODING_ERROR;
}
case(ETX_CHAR): {
*readLen = ++encodedIndex;
*decodedLen = decodedIndex;
return RETURN_OK;
}
default: {
destStream[decodedIndex] = sourceStream[encodedIndex];
break;
}
}
++encodedIndex;
++decodedIndex;
}
if (sourceStream[encodedIndex] != ETX_CHAR) {
if(decodedIndex == maxDestStreamlen) {
//so far we did not find anything wrong here, so let user try again
*readLen = 0;
return STREAM_TOO_SHORT;
}
else {
*readLen = ++encodedIndex;
return DECODING_ERROR;
}
}
else {
*readLen = ++encodedIndex;
*decodedLen = decodedIndex;
return RETURN_OK;
if(decodedIndex == maxDestStreamlen) {
//so far we did not find anything wrong here, so let user try again
*readLen = 0;
return STREAM_TOO_SHORT;
} else {
*readLen = encodedIndex;
return DECODING_ERROR;
}
}

View File

@ -13,7 +13,6 @@ target_sources(${LIB_FSFW_NAME}
QueueFactory.cpp
SemaphoreFactory.cpp
TaskFactory.cpp
Timer.cpp
tcpipHelpers.cpp
unixUtility.cpp
)

View File

@ -1,45 +0,0 @@
#include "fsfw/osal/linux/Timer.h"
#include "fsfw/serviceinterface/ServiceInterfaceStream.h"
#include <errno.h>
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;
}

View File

@ -1,45 +0,0 @@
#ifndef FRAMEWORK_OSAL_LINUX_TIMER_H_
#define FRAMEWORK_OSAL_LINUX_TIMER_H_
#include <signal.h>
#include <time.h>
#include <stdint.h>
/**
* 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_ */

View File

@ -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( &current_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( &current_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( &currentTime );
return currentTime;
}

View File

@ -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_ */

View File

@ -19,7 +19,7 @@ class TmTcBridge : public AcceptsTelemetryIF,
public:
static constexpr uint8_t TMTC_RECEPTION_QUEUE_DEPTH = 20;
static constexpr uint8_t LIMIT_STORED_DATA_SENT_PER_CYCLE = 15;
static constexpr uint8_t LIMIT_DOWNLINK_PACKETS_STORED = 20;
static constexpr uint8_t LIMIT_DOWNLINK_PACKETS_STORED = 200;
static constexpr uint8_t DEFAULT_STORED_DATA_SENT_PER_CYCLE = 5;
static constexpr uint8_t DEFAULT_DOWNLINK_PACKETS_STORED = 10;

View File

@ -18,4 +18,5 @@ add_subdirectory(serialize)
add_subdirectory(datapoollocal)
add_subdirectory(storagemanager)
add_subdirectory(globalfunctions)
add_subdirectory(timemanager)
add_subdirectory(tmtcpacket)

View File

@ -218,5 +218,10 @@ TEST_CASE("DleEncoder" , "[DleEncoder]") {
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
dleEncoder.setEscapeMode(true);
testArray1EncodedFaulty = TEST_ARRAY_1_ENCODED_ESCAPED;
testArray1EncodedFaulty[5] = 0;
result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(),
&readLen, buffer.data(), buffer.size(), &encodedLen);
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
}
}

View File

@ -0,0 +1,3 @@
target_sources(${TARGET_NAME} PRIVATE
TestCountdown.cpp
)

View File

@ -0,0 +1,27 @@
#include "fsfw_tests/unit/CatchDefinitions.h"
#include <fsfw/timemanager/Countdown.h>
#include <catch2/catch_test_macros.hpp>
TEST_CASE( "Countdown Tests", "[TestCountdown]") {
INFO("Countdown Tests");
Countdown count(20);
REQUIRE(count.timeout == 20);
REQUIRE(count.setTimeout(100) == static_cast<uint16_t>(HasReturnvaluesIF::RETURN_OK));
REQUIRE(count.timeout == 100);
REQUIRE(count.setTimeout(150) == static_cast<uint16_t>(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());
}