moved TCScheduling Service to use timeval internally #735

Open
mohr wants to merge 7 commits from mohr/timetag_fix into development
3 changed files with 45 additions and 18 deletions

View File

@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/745
- Small tweak for version getter
https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/744
- PUS Scheduling Service: Use timeval internally
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/735
## Added

View File

@ -91,7 +91,6 @@ class Service11TelecommandScheduling final : public PusServiceBase {
private:
struct TelecommandStruct {
uint64_t requestId{};
uint32_t seconds{};
store_address_t storeAddr; // uint16
};
@ -114,7 +113,7 @@ class Service11TelecommandScheduling final : public PusServiceBase {
* The telecommand map uses the exectution time as a Unix time stamp as
* the key. This is mapped to a generic telecommand struct.
*/
using TelecommandMap = etl::multimap<uint32_t, TelecommandStruct, MAX_NUM_TCS>;
using TelecommandMap = etl::multimap<timeval, TelecommandStruct, MAX_NUM_TCS>;
using TcMapIter = typename TelecommandMap::iterator;
TelecommandMap telecommandMap;

View File

@ -3,6 +3,7 @@
#include <cstddef>
#include "fsfw/globalfunctions/CRC.h"
#include "fsfw/globalfunctions/timevalOperations.h"
#include "fsfw/objectmanager/ObjectManager.h"
#include "fsfw/serialize/SerializeAdapter.h"
#include "fsfw/serviceinterface.h"
@ -79,7 +80,7 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::performService
// NOTE: The iterator is increased in the loop here. Increasing the iterator as for-loop arg
// does not work in this case as we are deleting the current element here.
for (auto it = telecommandMap.begin(); it != telecommandMap.end();) {
if (it->first <= tNow.tv_sec) {
if (it->first <= tNow) {
if (schedulingEnabled) {
// release tc
TmTcMessage releaseMsg(it->second.storeAddr);
@ -150,17 +151,25 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::handleResetCom
template <size_t MAX_NUM_TCS>
inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doInsertActivity(
const uint8_t *data, size_t size) {
uint32_t timestamp = 0;
ReturnValue_t result = SerializeAdapter::deSerialize(&timestamp, &data, &size, DEF_END);
uint32_t seconds = 0;
ReturnValue_t result = SerializeAdapter::deSerialize(&seconds, &data, &size, DEF_END);
if (result != returnvalue::OK) {
return result;
}
timeval scheduledTime;
scheduledTime.tv_sec = seconds;
scheduledTime.tv_usec = 0;
// Insert possible if sched. time is above margin
// (See requirement for Time margin)
timeval tNow = {};
Clock::getClock_timeval(&tNow);
if (timestamp - tNow.tv_sec <= RELEASE_TIME_MARGIN_SECONDS) {
timeval timeDifference = scheduledTime - tNow;
// round subseconds up
if (timeDifference.tv_usec != 0) {
timeDifference.tv_sec++;

Is timeval guaranteed to be signed?
This also rounds up when subsecond micros are 0, is this intended?

Is timeval guaranteed to be signed? This also rounds up when subsecond micros are 0, is this intended?
Outdated
Review
  1. Yes, timeval is using time_t in unixoides and long in windows.
  2. Admittedly I was lazy, I will change it so that 0 does not round up.
1) Yes, timeval is using time_t in unixoides and long in windows. 2) Admittedly I was lazy, I will change it so that 0 does not round up.

Can we use timestamp <= tNow.tv_sec + RELEASE_TIME_MARGIN_SECONDS compare logic instead?

That is a bit more readable in my opinion.

Can we use `timestamp <= tNow.tv_sec + RELEASE_TIME_MARGIN_SECONDS` compare logic instead? That is a bit more readable in my opinion.
Outdated
Review

Changed rounding to be correct.
The unreadable comparison is removed with this PR.

Changed rounding to be correct. The unreadable comparison is removed with this PR.
}
if (timeDifference.tv_sec <= RELEASE_TIME_MARGIN_SECONDS) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "Service11TelecommandScheduling::doInsertActivity: Release time too close to "
"current time"
@ -197,11 +206,10 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doInsertActivi
// insert into multimap with new store address
TelecommandStruct tc;
tc.seconds = timestamp;
tc.storeAddr = addr;
tc.requestId = getRequestIdFromTc(); // TODO: Missing sanity check of the returned request id
auto it = telecommandMap.insert(std::pair<uint32_t, TelecommandStruct>(timestamp, tc));
auto it = telecommandMap.insert(std::pair<timeval, TelecommandStruct>(scheduledTime, tc));
if (it == telecommandMap.end()) {
return returnvalue::FAILED;
}
@ -391,7 +399,8 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doTimeshiftAct
// temporarily hold the item
TelecommandStruct tempTc(tcToTimeshiftIt->second);
uint32_t tempKey = tcToTimeshiftIt->first + relativeTime;
timeval tempKey = tcToTimeshiftIt->first;
tempKey.tv_sec += relativeTime;
// delete old entry from the mm
telecommandMap.erase(tcToTimeshiftIt);
@ -436,7 +445,8 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::doFilterTimesh
for (auto it = itBegin; it != itEnd;) {
// temporarily hold the item
TelecommandStruct tempTc(it->second);
uint32_t tempKey = it->first + relativeTime;
timeval tempKey = it->first;
tempKey.tv_sec += relativeTime;
// delete the old entry from the mm
telecommandMap.erase(it++);
@ -533,12 +543,16 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::getMapFilterFr
}
case TypeOfTimeWindow::FROM_TIMETAG: {
uint32_t fromTimestamp = 0;
result = SerializeAdapter::deSerialize(&fromTimestamp, &data, &dataSize, DEF_END);
uint32_t fromSeconds = 0;
result = SerializeAdapter::deSerialize(&fromSeconds, &data, &dataSize, DEF_END);
if (result != returnvalue::OK) {
return result;
}
timeval fromTimestamp;
fromTimestamp.tv_sec = fromSeconds;
fromTimestamp.tv_usec = 0;
itBegin = telecommandMap.begin();
while (itBegin->first < fromTimestamp && itBegin != telecommandMap.end()) {
itBegin++;
@ -549,11 +563,15 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::getMapFilterFr
}
case TypeOfTimeWindow::TO_TIMETAG: {
uint32_t toTimestamp;
result = SerializeAdapter::deSerialize(&toTimestamp, &data, &dataSize, DEF_END);
uint32_t toSeconds = 0;
result = SerializeAdapter::deSerialize(&toSeconds, &data, &dataSize, DEF_END);
if (result != returnvalue::OK) {
return result;
}
timeval toTimestamp;
toTimestamp.tv_sec = toSeconds;
toTimestamp.tv_usec = 0;
itBegin = telecommandMap.begin();
itEnd = telecommandMap.begin();
while (itEnd->first <= toTimestamp && itEnd != telecommandMap.end()) {
@ -563,19 +581,27 @@ inline ReturnValue_t Service11TelecommandScheduling<MAX_NUM_TCS>::getMapFilterFr
}
case TypeOfTimeWindow::FROM_TIMETAG_TO_TIMETAG: {
uint32_t fromTimestamp;
uint32_t toTimestamp;
uint32_t fromSeconds = 0;
uint32_t toSeconds = 0;
result = SerializeAdapter::deSerialize(&fromTimestamp, &data, &dataSize,
result = SerializeAdapter::deSerialize(&fromSeconds, &data, &dataSize,
SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) {
return result;
}
result = SerializeAdapter::deSerialize(&toTimestamp, &data, &dataSize,
result = SerializeAdapter::deSerialize(&toSeconds, &data, &dataSize,
SerializeIF::Endianness::BIG);
if (result != returnvalue::OK) {
return result;
}
timeval fromTimestamp;
fromTimestamp.tv_sec = fromSeconds;
fromTimestamp.tv_usec = 0;
timeval toTimestamp;
toTimestamp.tv_sec = toSeconds;
toTimestamp.tv_usec = 0;
if (fromTimestamp > toTimestamp) {
return INVALID_TIME_WINDOW;
}