Skip to content

Commit

Permalink
Move EDU program queue to FRAM (#336)
Browse files Browse the repository at this point in the history
  • Loading branch information
PatrickKa authored Jan 5, 2025
2 parents e80f2c5 + 3342296 commit c1ffc6b
Show file tree
Hide file tree
Showing 20 changed files with 961 additions and 371 deletions.
18 changes: 10 additions & 8 deletions Sts1CobcSw/CobcSoftware/CommandParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@
#include <Sts1CobcSw/CobcSoftware/EduProgramQueueThread.hpp>
#include <Sts1CobcSw/Edu/Edu.hpp>
#include <Sts1CobcSw/Edu/ProgramQueue.hpp>
#include <Sts1CobcSw/FramSections/FramLayout.hpp>
#include <Sts1CobcSw/FramSections/FramVector.hpp>
#include <Sts1CobcSw/FramSections/PersistentVariables.hpp>
#include <Sts1CobcSw/Serial/Serial.hpp>
#include <Sts1CobcSw/Utility/DebugPrint.hpp>

#include <strong_type/type.hpp>

#include <cinttypes> // IWYU pragma: keep


Expand Down Expand Up @@ -59,14 +64,11 @@ auto DispatchCommand(etl::vector<Byte, commandSize> const & command) -> void
auto BuildEduQueue(std::span<Byte const> commandData) -> void
{
DEBUG_PRINT("Entering build queue command parsing\n");

edu::programQueue.clear();
edu::programQueue.Clear();
persistentVariables.Store<"eduProgramQueueIndex">(0);
ParseAndAddQueueEntries(commandData);
edu::queueIndex = 0;

DEBUG_PRINT("Queue index reset. Current size of EDU program queue is %d.\n",
static_cast<int>(edu::programQueue.size()));

static_cast<int>(edu::programQueue.Size()));
ResumeEduProgramQueueThread();
}

Expand All @@ -80,7 +82,7 @@ auto ParseAndAddQueueEntries(std::span<Byte const> queueEntries) -> void
DEBUG_PRINT("Printing and parsing\n");

while(queueEntries.size() >= totalSerialSize<edu::ProgramQueueEntry>
and (not edu::programQueue.full()))
and (not edu::programQueue.IsFull()))
{
auto entry = Deserialize<edu::ProgramQueueEntry>(
queueEntries.first<totalSerialSize<edu::ProgramQueueEntry>>());
Expand All @@ -89,7 +91,7 @@ auto ParseAndAddQueueEntries(std::span<Byte const> queueEntries) -> void
DEBUG_PRINT("Start Time : %" PRIi32 "\n", value_of(entry.startTime));
DEBUG_PRINT("Timeout : %" PRIi16 "\n", entry.timeout);

edu::programQueue.push_back(entry);
edu::programQueue.PushBack(entry);
queueEntries = queueEntries.subspan<totalSerialSize<edu::ProgramQueueEntry>>();
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sts1CobcSw/CobcSoftware/EduCommunicationErrorThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class EduCommunicationErrorThread : public RODOS::StaticThread<stackSize>
{
SuspendUntil(endOfTime);

persistentVariables.template Increment<"eduCommunicationErrorCounter">();
persistentVariables.template Increment<"nEduCommunicationErrors">();

DEBUG_PRINT("[EduCommunicationErrorThread] Resetting the Edu\n");
// Reset EDU
Expand Down
2 changes: 1 addition & 1 deletion Sts1CobcSw/CobcSoftware/EduHeartbeatThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ auto EduIsAlive() -> bool
}
}

auto executionTime = CurrentRodosTime() - begin;
[[maybe_unused]] auto executionTime = CurrentRodosTime() - begin;
DEBUG_PRINT("Execution Time of EduIsAlive: %" PRIi64 " ns\n", executionTime / ns);
DEBUG_PRINT("Execution Time of EduIsAlive: %" PRIi64 " ms\n", executionTime / ms);
return false;
Expand Down
61 changes: 30 additions & 31 deletions Sts1CobcSw/CobcSoftware/EduProgramQueueThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
#include <Sts1CobcSw/Edu/Edu.hpp>
#include <Sts1CobcSw/Edu/ProgramQueue.hpp>
#include <Sts1CobcSw/Edu/ProgramStatusHistory.hpp>
#include <Sts1CobcSw/Edu/Types.hpp>
#include <Sts1CobcSw/FramSections/RingArray.hpp>
#include <Sts1CobcSw/FramSections/FramLayout.hpp>
#include <Sts1CobcSw/FramSections/FramRingArray.hpp>
#include <Sts1CobcSw/FramSections/FramVector.hpp>
#include <Sts1CobcSw/FramSections/PersistentVariables.hpp>
#include <Sts1CobcSw/ProgramId/ProgramId.hpp> // IWYU pragma: keep
#include <Sts1CobcSw/Utility/DebugPrint.hpp>
#include <Sts1CobcSw/Utility/RealTime.hpp>
Expand All @@ -19,14 +21,12 @@

#include <rodos_no_using_namespace.h>

#include <etl/vector.h>

#include <cinttypes> // IWYU pragma: keep


namespace sts1cobcsw
{
[[nodiscard]] auto ComputeStartDelay() -> Duration;
[[nodiscard]] auto ComputeStartDelay(RealTime startTime) -> Duration;


// TODO: Get a better estimation for the required stack size. We only have 128 kB of RAM.
Expand Down Expand Up @@ -56,32 +56,33 @@ class EduProgramQueueThread : public RODOS::StaticThread<stackSize>
// eduProgramQueue.push_back(queueEntry1);
// eduProgramQueue.push_back(queueEntry2);

DEBUG_PRINT("Size of EduProgramQueue : %zu\n", edu::programQueue.size());
DEBUG_PRINT("Size of EDU program queue = %" PRIu32 "\n", edu::programQueue.Size());
}

void run() override
{
// TODO: Define some DebugPrint() or something in a separate file that can be turned on/off
DEBUG_PRINT("Entering EduProgramQueueThread\n");
DEBUG_PRINT_REAL_TIME();
while(true)
{
if(edu::programQueue.empty())
if(edu::programQueue.IsEmpty())
{
DEBUG_PRINT("Edu Program Queue is empty, thread set to sleep until end of time\n");
SuspendUntil(endOfTime);
}
else if(edu::queueIndex >= edu::programQueue.size())
else if(persistentVariables.Load<"eduProgramQueueIndex">() >= edu::programQueue.Size())
{
DEBUG_PRINT("End of queue is reached, thread set to sleep until end of time\n");
SuspendUntil(endOfTime);
}

auto startDelay = ComputeStartDelay();
auto queueIndex = persistentVariables.Load<"eduProgramQueueIndex">();
auto queueEntry = edu::programQueue.Get(queueIndex);
auto startDelay = ComputeStartDelay(queueEntry.startTime);
nextProgramStartDelayTopic.publish(startDelay);

DEBUG_PRINT("Program at queue index %d will start in : %" PRIi64 " s\n",
edu::queueIndex,
queueIndex,
startDelay / s);

// Suspend until delay time - 2 seconds
Expand All @@ -92,8 +93,7 @@ class EduProgramQueueThread : public RODOS::StaticThread<stackSize>
DEBUG_PRINT("Resuming here after first wait.\n");
DEBUG_PRINT_REAL_TIME();

auto updateTimeResult =
edu::UpdateTime(edu::UpdateTimeData{.currentTime = CurrentRealTime()});
auto updateTimeResult = edu::UpdateTime({CurrentRealTime()});
if(updateTimeResult.has_error())
{
DEBUG_PRINT("UpdateTime error code : %d\n",
Expand All @@ -103,11 +103,15 @@ class EduProgramQueueThread : public RODOS::StaticThread<stackSize>
ResumeEduCommunicationErrorThread();
}

auto startDelay2 = ComputeStartDelay();
// Reload queue index and entry because the start delay might be very long and the
// variables might have been corrupted in the meantime
queueIndex = persistentVariables.Load<"eduProgramQueueIndex">();
queueEntry = edu::programQueue.Get(queueIndex);
auto startDelay2 = ComputeStartDelay(queueEntry.startTime);
nextProgramStartDelayTopic.publish(startDelay2);

DEBUG_PRINT("Program at queue index %d will start in : %" PRIi64 " s\n",
edu::queueIndex,
queueIndex,
startDelay2 / s);

// Suspend for delay a second time
Expand All @@ -118,14 +122,10 @@ class EduProgramQueueThread : public RODOS::StaticThread<stackSize>
// Never reached
DEBUG_PRINT("Done suspending for the second time\n");

auto startTime = edu::programQueue[edu::queueIndex].startTime;
auto programId = edu::programQueue[edu::queueIndex].programId;
auto timeout = edu::programQueue[edu::queueIndex].timeout;

DEBUG_PRINT("Executing program %" PRIu16 "\n", value_of(programId));
DEBUG_PRINT("Executing EDU program %" PRIu16 "\n", value_of(queueEntry.programId));
// Start Process
auto executeProgramResult = edu::ExecuteProgram(edu::ExecuteProgramData{
.programId = programId, .startTime = startTime, .timeout = timeout});
auto executeProgramResult = edu::ExecuteProgram(
{queueEntry.programId, queueEntry.startTime, queueEntry.timeout});
// errorCode = edu::ErrorCode::success;

if(executeProgramResult.has_error())
Expand All @@ -137,20 +137,19 @@ class EduProgramQueueThread : public RODOS::StaticThread<stackSize>
}
else
{
edu::programStatusHistory.PushBack(
edu::ProgramStatusHistoryEntry{.programId = programId,
.startTime = startTime,
.status = edu::ProgramStatus::programRunning});
edu::programStatusHistory.PushBack({queueEntry.programId,
queueEntry.startTime,
edu::ProgramStatus::programRunning});

// Suspend Self for execution time
auto const executionTime = timeout * s + eduCommunicationDelay;
auto const executionTime = queueEntry.timeout * s + eduCommunicationDelay;
DEBUG_PRINT("Suspending for execution time\n");
SuspendFor(executionTime);
DEBUG_PRINT("Resuming from execution time\n");
DEBUG_PRINT_REAL_TIME();

// Set current Queue ID to next
edu::queueIndex++;
// Set current queue ID to next
persistentVariables.Increment<"eduProgramQueueIndex">();
}
}
}
Expand All @@ -160,9 +159,9 @@ class EduProgramQueueThread : public RODOS::StaticThread<stackSize>
// TODO: We should just use time points instead of delays in the thread. Then we won't need this
// function.
//! Compute the delay in nanoseconds before the start of program at current queue index
auto ComputeStartDelay() -> Duration
auto ComputeStartDelay(RealTime startTime) -> Duration
{
auto delay = ToRodosTime(edu::programQueue[edu::queueIndex].startTime) - CurrentRodosTime();
auto delay = ToRodosTime(startTime) - CurrentRodosTime();
return delay < Duration(0) ? Duration(0) : delay;
}

Expand Down
2 changes: 2 additions & 0 deletions Sts1CobcSw/Edu/EduMock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <Sts1CobcSw/Edu/Types.hpp>
#include <Sts1CobcSw/Utility/DebugPrint.hpp>

#include <strong_type/type.hpp>

#include <cinttypes> // IWYU pragma: keep


Expand Down
8 changes: 5 additions & 3 deletions Sts1CobcSw/Edu/ProgramQueue.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#include <Sts1CobcSw/Edu/ProgramQueue.hpp>


// TODO: Change namespace here too, or move it back to Sts1CobSw/
namespace sts1cobcsw::edu
{
using sts1cobcsw::DeserializeFrom;
using sts1cobcsw::SerializeTo;


etl::vector<ProgramQueueEntry, nProgramQueueEntries> programQueue{};
std::uint16_t queueIndex = 0;
sts1cobcsw::
FramVector<ProgramQueueEntry, framSections.Get<"eduProgramQueue">(), nCachedProgramQueueEntries>
programQueue;


template<std::endian endianness>
Expand All @@ -21,6 +21,7 @@ auto DeserializeFrom(void const * source, ProgramQueueEntry * data) -> void cons
return source;
}


// Explicit template specializations to keep everything in .cpp file
template auto DeserializeFrom<std::endian::big>(void const *, ProgramQueueEntry *) -> void const *;
template auto DeserializeFrom<std::endian::little>(void const *, ProgramQueueEntry *)
Expand All @@ -36,6 +37,7 @@ auto SerializeTo(void * destination, ProgramQueueEntry const & data) -> void *
return destination;
}


// Explicit template specializations to keep everything in .cpp file
template auto SerializeTo<std::endian::big>(void *, ProgramQueueEntry const &) -> void *;
template auto SerializeTo<std::endian::little>(void *, ProgramQueueEntry const &) -> void *;
Expand Down
18 changes: 6 additions & 12 deletions Sts1CobcSw/Edu/ProgramQueue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@


#include <Sts1CobcSw/FramSections/FramLayout.hpp>
#include <Sts1CobcSw/FramSections/Section.hpp>
#include <Sts1CobcSw/FramSections/FramVector.hpp>
#include <Sts1CobcSw/FramSections/Subsections.hpp>
#include <Sts1CobcSw/ProgramId/ProgramId.hpp>
#include <Sts1CobcSw/Serial/Serial.hpp>
#include <Sts1CobcSw/Utility/TimeTypes.hpp>

#include <strong_type/type.hpp>

#include <etl/vector.h>

#include <bit>
#include <cstddef>
#include <cstdint>
Expand Down Expand Up @@ -39,13 +35,11 @@ inline constexpr std::size_t serialSize<edu::ProgramQueueEntry> =

namespace edu
{
inline constexpr auto nProgramQueueEntries =
value_of(framSections.template Get<"eduProgramQueue">().size)
/ totalSerialSize<ProgramQueueEntry>;


extern std::uint16_t queueIndex;
extern etl::vector<ProgramQueueEntry, nProgramQueueEntries> programQueue;
inline constexpr auto nCachedProgramQueueEntries = 10;
extern FramVector<ProgramQueueEntry,
framSections.template Get<"eduProgramQueue">(),
nCachedProgramQueueEntries>
programQueue;


template<std::endian endianness>
Expand Down
18 changes: 9 additions & 9 deletions Sts1CobcSw/Edu/ProgramStatusHistory.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
#include <Sts1CobcSw/Edu/ProgramStatusHistory.hpp>
#include <Sts1CobcSw/FramSections/FramLayout.hpp>
#include <Sts1CobcSw/FramSections/RingArray.hpp>

#include <strong_type/equality.hpp>

#include <etl/circular_buffer.h>


namespace sts1cobcsw::edu
{
sts1cobcsw::RingArray<ProgramStatusHistoryEntry,
framSections.Get<"eduProgramStatusHistory">(),
nCachedProgramStatusHistoryEntries>
using sts1cobcsw::DeserializeFrom;
using sts1cobcsw::SerializeTo;


sts1cobcsw::FramRingArray<ProgramStatusHistoryEntry,
framSections.Get<"eduProgramStatusHistory">(),
nCachedProgramStatusHistoryEntries>
programStatusHistory;


Expand All @@ -23,10 +27,6 @@ auto UpdateProgramStatusHistory(ProgramId programId, RealTime startTime, Program
}


using sts1cobcsw::DeserializeFrom;
using sts1cobcsw::SerializeTo;


template<std::endian endianness>
auto DeserializeFrom(void const * source, ProgramStatusHistoryEntry * data) -> void const *
{
Expand Down
10 changes: 5 additions & 5 deletions Sts1CobcSw/Edu/ProgramStatusHistory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


#include <Sts1CobcSw/FramSections/FramLayout.hpp>
#include <Sts1CobcSw/FramSections/RingArray.hpp>
#include <Sts1CobcSw/FramSections/FramRingArray.hpp>
#include <Sts1CobcSw/FramSections/Subsections.hpp>
#include <Sts1CobcSw/ProgramId/ProgramId.hpp>
#include <Sts1CobcSw/Serial/Serial.hpp>
Expand Down Expand Up @@ -49,12 +49,12 @@ inline constexpr std::size_t serialSize<edu::ProgramStatusHistoryEntry> =
namespace edu
{
inline constexpr auto nCachedProgramStatusHistoryEntries = 10;

extern RingArray<ProgramStatusHistoryEntry,
framSections.template Get<"eduProgramStatusHistory">(),
nCachedProgramStatusHistoryEntries>
extern FramRingArray<ProgramStatusHistoryEntry,
framSections.template Get<"eduProgramStatusHistory">(),
nCachedProgramStatusHistoryEntries>
programStatusHistory;


auto UpdateProgramStatusHistory(ProgramId programId, RealTime startTime, ProgramStatus newStatus)
-> void;

Expand Down
10 changes: 7 additions & 3 deletions Sts1CobcSw/FramSections/FramLayout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,22 @@ namespace sts1cobcsw
inline constexpr auto framMemory = Section<fram::Address(0), fram::memorySize>{};
inline constexpr auto framSections =
Subsections<framMemory,
SubsectionInfo<"persistentVariables0", fram::Size(300)>,
SubsectionInfo<"persistentVariables", fram::Size(300)>,
SubsectionInfo<"eduProgramQueue", fram::Size(20 * 8)>,
SubsectionInfo<"eduProgramStatusHistory", fram::Size(50 * 7)>,
SubsectionInfo<"testMemory", fram::Size(1000)>,
SubsectionInfo<"telemetry", fram::Size(26'168 * 40)>>{};
inline constexpr auto persistentVariables =
PersistentVariables<framSections.Get<"persistentVariables0">(),
PersistentVariables<framSections.Get<"persistentVariables">(),
// Bootloader
PersistentVariableInfo<"nResetsSinceRf", std::uint16_t>,
PersistentVariableInfo<"activeSecondaryFwPartition", std::int8_t>,
PersistentVariableInfo<"backupSecondaryFwPartition", std::int8_t>,
// COBC state
PersistentVariableInfo<"txIsOn", bool>,
PersistentVariableInfo<"antennasShouldBeDeployed", bool>,
PersistentVariableInfo<"eduProgramQueueIndex", std::uint8_t>,
// Housekeeping
PersistentVariableInfo<"nTotalResets", std::uint32_t>,
PersistentVariableInfo<"realTime", RealTime>,
PersistentVariableInfo<"realTimeOffset", Duration>,
Expand All @@ -37,5 +41,5 @@ inline constexpr auto persistentVariables =
PersistentVariableInfo<"nRfErrors", std::uint16_t>,
PersistentVariableInfo<"nFileSystemErrors", std::uint16_t>,
PersistentVariableInfo<"eduShouldBePowered", bool>,
PersistentVariableInfo<"eduCommunicationErrorCounter", std::uint16_t>>{};
PersistentVariableInfo<"nEduCommunicationErrors", std::uint16_t>>{};
}
Loading

0 comments on commit c1ffc6b

Please sign in to comment.