diff --git a/Sts1CobcSw/Edu/ProgramStatusHistory.cpp b/Sts1CobcSw/Edu/ProgramStatusHistory.cpp index 0c9a4a1b..de9e0715 100644 --- a/Sts1CobcSw/Edu/ProgramStatusHistory.cpp +++ b/Sts1CobcSw/Edu/ProgramStatusHistory.cpp @@ -4,8 +4,9 @@ namespace sts1cobcsw::edu { -ProgramStatusHistoryClass programStatusHistory = - ProgramStatusHistoryClass(); +// TODO: Put a real variable for start Address +ProgramStatusHistoryClass programStatusHistory = + ProgramStatusHistoryClass(); } namespace sts1cobcsw::edu diff --git a/Sts1CobcSw/Edu/ProgramStatusHistory.hpp b/Sts1CobcSw/Edu/ProgramStatusHistory.hpp index 0edaec02..75109749 100644 --- a/Sts1CobcSw/Edu/ProgramStatusHistory.hpp +++ b/Sts1CobcSw/Edu/ProgramStatusHistory.hpp @@ -5,6 +5,7 @@ // clang-format off #include // NOLINT(llvm-include-order) +#include "Sts1CobcSw/Periphery/Fram.hpp" #include "Sts1CobcSw/Periphery/FramRingBuffer.hpp" // ringbuffer.h does not include even though it requires it #include @@ -56,14 +57,14 @@ template [[nodiscard]] auto SerializeTo(void * destination, ProgramStatusHistoryEntry const & data) -> void *; -template -auto UpdateRingBufferEntry(fram::RingBuffer & ringBuffer, +template +auto UpdateRingBufferEntry(fram::RingBuffer & ringBuffer, std::int32_t startTime, ProgramId programId, ProgramStatus newStatus) -> bool; -template +template class ProgramStatusHistoryClass { public: @@ -76,7 +77,7 @@ class ProgramStatusHistoryClass { if(fram::framIsWorking) { - framProgramStatusHistory_.Put(programStatusHistoryEntry); + //framProgramStatusHistory_.Put(programStatusHistoryEntry); } ramProgramStatusHistory_.put(programStatusHistoryEntry); } @@ -104,16 +105,17 @@ class ProgramStatusHistoryClass } private: - sts1cobcsw::fram::RingBuffer framProgramStatusHistory_; + sts1cobcsw::fram::RingBuffer framProgramStatusHistory_; RODOS::RingBuffer ramProgramStatusHistory_; }; -extern ProgramStatusHistoryClass programStatusHistory; +// TODO: Put a real value here +extern ProgramStatusHistoryClass programStatusHistory; // TODO: Move this into .cpp file -template -auto UpdateRingBufferEntry(fram::RingBuffer & ringBuffer, +template +auto UpdateRingBufferEntry(fram::RingBuffer & ringBuffer, const std::int32_t startTime, const ProgramId programId, const ProgramStatus newStatus) -> bool diff --git a/Sts1CobcSw/Periphery/FramRingBuffer.hpp b/Sts1CobcSw/Periphery/FramRingBuffer.hpp index cd4f8102..a067e9ad 100644 --- a/Sts1CobcSw/Periphery/FramRingBuffer.hpp +++ b/Sts1CobcSw/Periphery/FramRingBuffer.hpp @@ -14,61 +14,30 @@ namespace sts1cobcsw::fram { -using sts1cobcsw::Span; -using sts1cobcsw::TriviallySerializable; +int ANewMethod(int b); -template +template class RingBuffer { public: - // NOLINTBEGIN(*non-private-member-variables-in-classes) - std::uint64_t writeCnt = 0; - std::uint64_t readCnt = 0; - std::uint32_t occupiedCnt = 0; - Address startAddress; - // NOLINTEND(*non-private-member-variables-in-classes) - - explicit RingBuffer(Address address) : startAddress(address) - { - } - - RingBuffer() : startAddress(0){}; - - void Put(T const & newdata) - { - currentWrite_ = writeIndex_; - auto const address = startAddress + writeIndex_ * serialSize; - fram::WriteTo(address, Span(Serialize(newdata)), 0); - writeIndex_++; - - if(writeIndex_ >= poolSize) - { - writeIndex_ = 0; - } - if(occupiedCnt < poolSize) - { - occupiedCnt++; - } - writeCnt++; - currentWrite_ = UINT32_MAX; - } + RingBuffer() = default; // Get next item void Get(T & fromRing) { // Jump the current being written record - if(readIndex_ == currentWrite_) + if(readIndex_ == currentWriteIndex_) { readIndex_++; } - if(readIndex_ >= poolSize) + if(readIndex_ >= size) { readIndex_ = 0; } // readIndex should not pass write index if there is no data after it - if(writeCnt < poolSize && readIndex_ >= writeIndex_) + if(writeCount_ < size && readIndex_ >= writeIndex_) { readIndex_ = 0; } @@ -79,26 +48,43 @@ class RingBuffer fromRing = Deserialize(std::span(readData)); readIndex_++; - if(readIndex_ >= poolSize) + if(readIndex_ >= size) { readIndex_ = 0; } - if(occupiedCnt > 0) + if(occupiedCount_ > 0) { - occupiedCnt--; + occupiedCount_--; } - readCnt++; + readCount_++; + } + + auto Capacity() -> std::size_t + { + return capacity_; } - auto GetLen() -> int + auto Size() -> std::size_t { - return poolSize; + return size; } + auto Push(T const& newData) -> void; + + // TODO: return type syntax for functions + T& operator[](std::size_t index); + private: std::uint32_t writeIndex_ = 0; std::uint32_t readIndex_ = 0; - std::uint32_t currentWrite_ = UINT32_MAX; + std::uint32_t currentWriteIndex_ = UINT32_MAX; + std::uint64_t writeCount_ = 0; + std::uint64_t readCount_ = 0; + std::uint32_t occupiedCount_ = 0; + std::size_t capacity_ = 0; }; } + + +#include // IWYU pragma: keep diff --git a/Sts1CobcSw/Periphery/FramRingBuffer.ipp b/Sts1CobcSw/Periphery/FramRingBuffer.ipp new file mode 100644 index 00000000..322a0d2d --- /dev/null +++ b/Sts1CobcSw/Periphery/FramRingBuffer.ipp @@ -0,0 +1,27 @@ +#pragma once + + +#include + + +namespace sts1cobcsw::fram +{ +template +void RingBuffer::Push(T const& newData) +{ + currentWriteIndex_ = writeIndex_; + auto const address = startAddress + writeIndex_ * serialSize; + fram::WriteTo(address, Span(Serialize(newData)), 0); + writeIndex_++; + + if (writeIndex_ >= size) { + writeIndex_ = 0; + } + if (occupiedCount_ < size) { + occupiedCount_++; + } + writeCount_++; + // TODO: iwyu + currentWriteIndex_ = UINT32_MAX; +} +} diff --git a/Tests/UnitTests/FramRingBuffer.test.cpp b/Tests/UnitTests/FramRingBuffer.test.cpp index 17a28f5b..8d06ba03 100644 --- a/Tests/UnitTests/FramRingBuffer.test.cpp +++ b/Tests/UnitTests/FramRingBuffer.test.cpp @@ -14,8 +14,6 @@ #include -#include -#include namespace fram = sts1cobcsw::fram; @@ -29,129 +27,23 @@ using sts1cobcsw::Deserialize; using sts1cobcsw::Serialize; -TEST_CASE("RODOS ringbuffer put and get operations") +// TODO: Sections could be useful +TEST_CASE("Initial State ringbuffer") { - RODOS::RingBuffer buffer; + sts1cobcsw::fram::RingBuffer buffer; - REQUIRE(buffer.getLen() == 10); - - auto const value = 42; - int result = 0; - buffer.put(value); - buffer.get(result); - REQUIRE(value == result); -} - -TEST_CASE("RODOS ringbuffer overwrite") -{ - RODOS::RingBuffer buffer; - REQUIRE(buffer.getLen() == 10); - - for(int i = 0; i < 15; i++) - { - buffer.put(i); - } - - int result = 0; - for(int i = 10; i < 15; ++i) - { - buffer.get(result); - REQUIRE(result == i); - } -} - -TEST_CASE("RODOS ringbuffer wrapping") -{ - RODOS::RingBuffer buffer; - for(int i = 0; i < 30; ++i) - { - buffer.put(i); - } - - int result = 0; - for(int i = 20; i < 30; ++i) - { - buffer.get(result); - REQUIRE(result == i); - } -} - -// TODO: Split in different tests or sections -TEST_CASE("RingBuffer put and get operations") -{ - fram::ram::SetAllDoFunctions(); - fram::ram::storage.fill(0x00_b); - fram::Initialize(); - - auto address = GENERATE(take(2, random(0U, 1U << 20U))); - auto int8Buffer = sts1cobcsw::fram::RingBuffer(address); - auto uint16Buffer = sts1cobcsw::fram::RingBuffer(address + 10); - auto int32Buffer = sts1cobcsw::fram::RingBuffer(address + 20); - - - REQUIRE(int8Buffer.GetLen() == 10); - - - auto const i8Value = 42; - std::int8_t result = 0; - int8Buffer.Put(i8Value); - int8Buffer.Get(result); - REQUIRE(i8Value == result); - - const std::uint16_t u16Value = 65000; - std::uint16_t u16Result = 0; - uint16Buffer.Put(u16Value); - uint16Buffer.Get(u16Result); - REQUIRE(u16Value == u16Result); - - - const std::int32_t i32Value = -2'147'483'648; - std::int32_t i32Result = 0; - int32Buffer.Put(i32Value); - int32Buffer.Get(i32Result); - REQUIRE(i32Value == i32Result); + REQUIRE(buffer.Size() == 10); + REQUIRE(buffer.Capacity() == 0); } - -// Debug test case -TEST_CASE("Simple put and get inlined") +TEST_CASE("FramRingBuffer Push function") { - fram::ram::SetAllDoFunctions(); - fram::ram::storage.fill(0x00_b); - - fram::Initialize(); - auto const correctDeviceId = - std::to_array({0x03_b, 0x2E_b, 0xC2_b, 0x7F_b, 0x7F_b, 0x7F_b, 0x7F_b, 0x7F_b, 0x7F_b}); - auto deviceId = fram::ReadDeviceId(); - CHECK(deviceId == correctDeviceId); - auto actualBaudRate = fram::ActualBaudRate(); - CHECK(actualBaudRate == 6'000'000); - - auto address = GENERATE(take(1, random(0U, fram::ram::storageSize - 10))); - - auto readData = std::array{0x01_b, 0x02_b, 0x03_b, 0x04_b}; - fram::ReadFrom(address, Span(&readData), 0); - CHECK(readData == decltype(readData){}); -} - - -TEST_CASE("Program status and history") -{ - fram::ram::SetAllDoFunctions(); - fram::ram::storage.fill(0x00_b); - fram::Initialize(); - - // Put() and Get() a ProgramStatusHistoryEntry variable. - auto ringBuffer = fram::RingBuffer(0); - auto value = ProgramStatusHistoryEntry{.programId = sts1cobcsw::ProgramId(12), - .startTime = 34, - .status = ProgramStatus::programExecutionFailed}; - auto result = ProgramStatusHistoryEntry{}; + fram::RingBuffer buffer; - ringBuffer.Put(value); - ringBuffer.Get(result); + buffer.Push(1); + buffer.Push(2); + buffer.Push(3); - CHECK(result.programId == 12); - CHECK(result.startTime == 34); - CHECK(result.status == ProgramStatus::programExecutionFailed); + // Failing + // REQUIRE(buffer.Size() == 3); } diff --git a/Tests/UnitTests/UpdateRingBuffer.test.cpp b/Tests/UnitTests/UpdateRingBuffer.test.cpp index 688f35e5..ac3f6a2c 100644 --- a/Tests/UnitTests/UpdateRingBuffer.test.cpp +++ b/Tests/UnitTests/UpdateRingBuffer.test.cpp @@ -35,8 +35,8 @@ using sts1cobcsw::Serialize; // Normally this would be set in Sts1CobcSw/someThread.cpp bool sts1cobcsw::fram::framIsWorking = true; -ProgramStatusHistoryClass programStatusHistory = - ProgramStatusHistoryClass(); +ProgramStatusHistoryClass programStatusHistory = + ProgramStatusHistoryClass(); namespace sts1cobcsw::edu {