diff --git a/Sts1CobcSw/Edu/ProgramStatusHistory.cpp b/Sts1CobcSw/Edu/ProgramStatusHistory.cpp index 9d5345f3..0c9a4a1b 100644 --- a/Sts1CobcSw/Edu/ProgramStatusHistory.cpp +++ b/Sts1CobcSw/Edu/ProgramStatusHistory.cpp @@ -4,12 +4,7 @@ namespace sts1cobcsw::edu { - -sts1cobcsw::fram::RingBuffer - programStatusHistory = - sts1cobcsw::fram::RingBuffer(0); - -ProgramStatusHistoryClass pObject = +ProgramStatusHistoryClass programStatusHistory = ProgramStatusHistoryClass(); } diff --git a/Sts1CobcSw/Edu/ProgramStatusHistory.hpp b/Sts1CobcSw/Edu/ProgramStatusHistory.hpp index 628f5e23..ae31f17e 100644 --- a/Sts1CobcSw/Edu/ProgramStatusHistory.hpp +++ b/Sts1CobcSw/Edu/ProgramStatusHistory.hpp @@ -1,11 +1,10 @@ #pragma once - #include #include // clang-format off -#include +#include // NOLINT(llvm-include-order) #include "Sts1CobcSw/Periphery/FramRingBuffer.hpp" // ringbuffer.h does not include even though it requires it #include @@ -13,10 +12,9 @@ #include + namespace sts1cobcsw { -using fram::RingBuffer; - namespace edu { enum class ProgramStatus : std::uint8_t @@ -38,10 +36,18 @@ struct ProgramStatusHistoryEntry std::int32_t startTime = 0; ProgramStatus status = ProgramStatus::programRunning; }; +} + +template<> +inline constexpr std::size_t serialSize = + totalSerialSize; + +namespace edu +{ inline constexpr auto programStatusHistorySize = 20; -// TODO: Use a class that handle the dual storage (or cache) thing -extern RingBuffer programStatusHistory; template [[nodiscard]] auto DeserializeFrom(void const * source, ProgramStatusHistoryEntry * data) @@ -50,6 +56,12 @@ template [[nodiscard]] auto SerializeTo(void * destination, ProgramStatusHistoryEntry const & data) -> void *; +template +auto UpdateRingBufferEntry(fram::RingBuffer & ringBuffer, + std::int32_t startTime, + ProgramId programId, + ProgramStatus newStatus) -> bool; + template class ProgramStatusHistoryClass @@ -57,6 +69,9 @@ class ProgramStatusHistoryClass public: ProgramStatusHistoryClass() = default; + // EDU program status history should have an internal "cache" that is always used to store the + // data written to the FRAM. If the FRAM fails, the values are then also read from this "cache" + // instead. auto Put(ProgramStatusHistoryEntry const & programStatusHistoryEntry) -> void { if(fram::framIsWorking) @@ -69,16 +84,8 @@ class ProgramStatusHistoryClass auto Update(ProgramId programId, std::int32_t startTime, ProgramStatus newStatus) -> void { // Update FRAM ringbuffer - // TODO: Make it work, there is no vals_ array in a fram ringbuffer so we need something - // else. - // for(std::uint32_t i = 0; i < framProgramStatusHistory_.occupiedCnt; ++i) - //{ - // if(framProgramStatusHistory_.vals[i].startTime == startTime - // and framProgramStatusHistory_.vals[i].programId == programId) - // { - // framProgramStatusHistory_.vals[i].status = newStatus; - // } - //} + // TODO: Test + UpdateRingBufferEntry(framProgramStatusHistory_, startTime, programId, newStatus); // Update RAM ringbuffer for(std::uint32_t i = 0; i < ramProgramStatusHistory_.occupiedCnt; ++i) @@ -96,15 +103,33 @@ class ProgramStatusHistoryClass RODOS::RingBuffer ramProgramStatusHistory_; }; -extern ProgramStatusHistoryClass pObject; -} -} +extern ProgramStatusHistoryClass programStatusHistory; -namespace sts1cobcsw + +// TODO: Move this into .cpp file +template +auto UpdateRingBufferEntry(fram::RingBuffer & ringBuffer, + const std::int32_t startTime, + const ProgramId programId, + const ProgramStatus newStatus) -> bool { -template<> -inline constexpr std::size_t serialSize = - totalSerialSize; + for(std::uint32_t i = 0; i < poolSize; ++i) + { + auto const address = ringBuffer.startAddress + i * serialSize; + auto readData = fram::ReadFrom>(address, 0); + ProgramStatusHistoryEntry data = + Deserialize(std::span(readData)); + + if(data.startTime == startTime and data.programId == programId) + { + fram::WriteTo(address, + Span(Serialize(ProgramStatusHistoryEntry{.programId = data.programId, + .startTime = data.startTime, + .status = newStatus})), + 0); + return true; + } + } +} +} } diff --git a/Sts1CobcSw/EduListenerThread.cpp b/Sts1CobcSw/EduListenerThread.cpp index 2669ee5a..b930cb35 100644 --- a/Sts1CobcSw/EduListenerThread.cpp +++ b/Sts1CobcSw/EduListenerThread.cpp @@ -79,9 +79,10 @@ class EduListenerThread : public RODOS::StaticThread<> // queue thread if(status.exitCode == 0) { - edu::pObject.Update(status.programId, - status.startTime, - edu::ProgramStatus::programExecutionSucceeded); + edu::programStatusHistory.Update( + status.programId, + status.startTime, + edu::ProgramStatus::programExecutionSucceeded); // FIXME: Update // edu::UpdateProgramStatusHistory( // status.programId, @@ -90,9 +91,10 @@ class EduListenerThread : public RODOS::StaticThread<> } else { - edu::pObject.Update(status.programId, - status.startTime, - edu::ProgramStatus::programExecutionFailed); + edu::programStatusHistory.Update( + status.programId, + status.startTime, + edu::ProgramStatus::programExecutionFailed); // FIXME: Update // edu::UpdateProgramStatusHistory( // status.programId, @@ -129,9 +131,10 @@ class EduListenerThread : public RODOS::StaticThread<> } // break; - edu::pObject.Update(status.programId, - status.startTime, - edu::ProgramStatus::resultFileTransfered); + edu::programStatusHistory.Update( + status.programId, + status.startTime, + edu::ProgramStatus::resultFileTransfered); break; } case edu::StatusType::invalid: diff --git a/Sts1CobcSw/EduProgramQueueThread.cpp b/Sts1CobcSw/EduProgramQueueThread.cpp index 18b872b8..6fb86d6a 100644 --- a/Sts1CobcSw/EduProgramQueueThread.cpp +++ b/Sts1CobcSw/EduProgramQueueThread.cpp @@ -142,7 +142,7 @@ class EduProgramQueueThread : public RODOS::StaticThread } else { - edu::pObject.Put( + edu::programStatusHistory.Put( edu::ProgramStatusHistoryEntry{.programId = programId, .startTime = startTime, .status = edu::ProgramStatus::programRunning}); diff --git a/Sts1CobcSw/Periphery/FramRingBuffer.hpp b/Sts1CobcSw/Periphery/FramRingBuffer.hpp index 4840bbd9..cd4f8102 100644 --- a/Sts1CobcSw/Periphery/FramRingBuffer.hpp +++ b/Sts1CobcSw/Periphery/FramRingBuffer.hpp @@ -22,23 +22,23 @@ template class RingBuffer { public: - // NOLINTNEXTLINE(*non-private-member-variables-in-classes) + // NOLINTBEGIN(*non-private-member-variables-in-classes) std::uint64_t writeCnt = 0; - // NOLINTNEXTLINE(*non-private-member-variables-in-classes) std::uint64_t readCnt = 0; - // NOLINTNEXTLINE(*non-private-member-variables-in-classes) std::uint32_t occupiedCnt = 0; + Address startAddress; + // NOLINTEND(*non-private-member-variables-in-classes) - explicit RingBuffer(Address address) : startAddress_(address) + explicit RingBuffer(Address address) : startAddress(address) { } - RingBuffer() : startAddress_(0){}; + RingBuffer() : startAddress(0){}; void Put(T const & newdata) { currentWrite_ = writeIndex_; - auto const address = startAddress_ + writeIndex_ * serialSize; + auto const address = startAddress + writeIndex_ * serialSize; fram::WriteTo(address, Span(Serialize(newdata)), 0); writeIndex_++; @@ -73,7 +73,7 @@ class RingBuffer readIndex_ = 0; } - auto const address = startAddress_ + readIndex_ * serialSize; + auto const address = startAddress + readIndex_ * serialSize; // TODO: Add a real timeout value (spiTimeout in hw tests is 30ms, but for much more data) auto readData = fram::ReadFrom>(address, 0); fromRing = Deserialize(std::span(readData)); @@ -97,7 +97,6 @@ class RingBuffer } private: - Address startAddress_; std::uint32_t writeIndex_ = 0; std::uint32_t readIndex_ = 0; std::uint32_t currentWrite_ = UINT32_MAX; diff --git a/Tests/UnitTests/FramRingBuffer.test.cpp b/Tests/UnitTests/FramRingBuffer.test.cpp index 1a024f45..285a1bf9 100644 --- a/Tests/UnitTests/FramRingBuffer.test.cpp +++ b/Tests/UnitTests/FramRingBuffer.test.cpp @@ -136,16 +136,6 @@ TEST_CASE("Simple put and get inlined") } -namespace sts1cobcsw -{ -template<> -constexpr std::size_t serialSize = - totalSerialSize; -} - - namespace sts1cobcsw::edu { template