Skip to content

Commit

Permalink
Add a reset mechanism for fram ringbuffer
Browse files Browse the repository at this point in the history
  • Loading branch information
jeromehue committed Aug 24, 2024
1 parent 21cb751 commit be020c1
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 20 deletions.
15 changes: 10 additions & 5 deletions Sts1CobcSw/Periphery/FramRingBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@ template<typename T, std::size_t size, Address startAddress>
class RingBuffer
{
public:
RingBuffer() : bufferSize_(size + 1U)
RingBuffer() : bufferSize_(size + 1U), offset_(sizeof(std::size_t) * 2)
{
nextWriteIndex_.set(0);
nextReadIndex_.set(0);
Initialize();
};

auto Push(T const & newData) -> void;
Expand All @@ -39,11 +38,17 @@ class RingBuffer
//! @brief Returns the capacity of the ringbuffer
auto Capacity() -> std::size_t;

// @brief Initializes the ringbuffer by reading indices from FRAM
auto Initialize() -> void;

private:
std::size_t bufferSize_;
etl::cyclic_value<std::size_t, 0, size> nextWriteIndex_;
etl::cyclic_value<std::size_t, 0, size> nextReadIndex_;
std::size_t offset_;
etl::cyclic_value<std::size_t, 0, size> iEnd_;
etl::cyclic_value<std::size_t, 0, size> iBegin_;

auto WriteIndices() -> void;
auto ReadIndices() -> void;
};
}

Expand Down
62 changes: 47 additions & 15 deletions Sts1CobcSw/Periphery/FramRingBuffer.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,23 @@ namespace sts1cobcsw::fram
template<typename T, std::size_t size, Address startAddress>
void RingBuffer<T, size, startAddress>::Push(T const & newData)
{
// auto const rawaddress = value_of(startAddress) + (nextWriteIndex_ * serialSize<T>);
auto const rawaddress = value_of(startAddress) + (nextWriteIndex_ * serialSize<T>);
fram::WriteTo(fram::Address(rawaddress), Span(Serialize(newData)), 0);
auto const rawAddress = offset_ + value_of(startAddress) + (iEnd_ * serialSize<T>);
fram::WriteTo(fram::Address(rawAddress), Span(Serialize(newData)), 0);

++nextWriteIndex_;
if(nextWriteIndex_ == nextReadIndex_)
++iEnd_;
if(iEnd_ == iBegin_)
{
nextReadIndex_++;
iBegin_++;
}

WriteIndices();
}


template<typename T, std::size_t size, Address startAddress>
auto RingBuffer<T, size, startAddress>::Front() -> T
{
auto const rawAddress = value_of(startAddress) + (nextReadIndex_ * serialSize<T>);
auto const rawAddress = offset_ + value_of(startAddress) + (iBegin_ * serialSize<T>);
auto readData = fram::ReadFrom<serialSize<T>>(fram::Address(rawAddress), 0);
auto fromRing = Deserialize<T>(std::span(readData));

Expand All @@ -36,16 +37,16 @@ template<typename T, std::size_t size, Address startAddress>
auto RingBuffer<T, size, startAddress>::Back() -> T
{
std::uint32_t readIndex = 0;
if(nextWriteIndex_ == 0)
if(iEnd_ == 0)
{
readIndex = bufferSize_ - 1;
}
else
{
readIndex = nextWriteIndex_.get() - 1;
readIndex = iEnd_.get() - 1;
}

auto const rawAddress = value_of(startAddress) + readIndex * serialSize<T>;
auto const rawAddress = offset_ + value_of(startAddress) + readIndex * serialSize<T>;
auto readData = fram::ReadFrom<serialSize<T>>(fram::Address(rawAddress), 0);
auto fromRing = Deserialize<T>(std::span(readData));

Expand All @@ -57,25 +58,56 @@ template<typename T, std::size_t size, Address startAddress>
auto RingBuffer<T, size, startAddress>::operator[](std::size_t index) -> T
{
auto const rawAddress =
value_of(startAddress) + ((nextReadIndex_ + index) % bufferSize_) * serialSize<T>;
offset_ + value_of(startAddress) + ((iBegin_ + index) % bufferSize_) * serialSize<T>;
auto readData = fram::ReadFrom<serialSize<T>>(fram::Address(rawAddress), 0);
return Deserialize<T>(std::span(readData));
auto fromRing = Deserialize<T>(std::span(readData));

return fromRing;
}


template<typename T, std::size_t size, Address startAddress>
auto RingBuffer<T, size, startAddress>::Size() -> std::size_t
{
if(nextWriteIndex_ >= nextReadIndex_)
if(iEnd_ >= iBegin_)
{
return (nextWriteIndex_ - nextReadIndex_);
return (iEnd_ - iBegin_);
}
return (bufferSize_ - (nextReadIndex_ - nextWriteIndex_));
return (bufferSize_ - (iBegin_ - iEnd_));
}

template<typename T, std::size_t size, Address startAddress>
auto RingBuffer<T, size, startAddress>::Capacity() -> std::size_t
{
return (bufferSize_ - 1U);
}

template<typename T, std::size_t size, Address startAddress>
auto RingBuffer<T, size, startAddress>::Initialize() -> void
{
ReadIndices();
}

template<typename T, std::size_t size, Address startAddress>
auto RingBuffer<T, size, startAddress>::WriteIndices() -> void
{
auto beginAddress = value_of(startAddress);
auto endAddress = beginAddress + sizeof(std::size_t);

fram::WriteTo(fram::Address(beginAddress), Span(Serialize(iBegin_.get())), 0);
fram::WriteTo(fram::Address(endAddress), Span(Serialize(iEnd_.get())), 0);
}

template<typename T, std::size_t size, Address startAddress>
auto RingBuffer<T, size, startAddress>::ReadIndices() -> void
{
auto beginAddress = value_of(startAddress);
auto endAddress = beginAddress + sizeof(std::size_t);

auto beginData = fram::ReadFrom<sizeof(std::size_t)>(fram::Address(beginAddress), 0);
auto endData = fram::ReadFrom<sizeof(std::size_t)>(fram::Address(endAddress), 0);

iBegin_.set(Deserialize<std::size_t>(std::span(beginData)));
iEnd_.set(Deserialize<std::size_t>(std::span(endData)));
}
}
21 changes: 21 additions & 0 deletions Tests/UnitTests/FramRingBuffer.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,24 @@ TEST_CASE("Custom Type")
REQUIRE(buffer.Size() == 1);
REQUIRE(buffer.Front().status == sts1cobcsw::edu::ProgramStatus::programRunning);
}

TEST_CASE("Reset mechanism")
{
fram::ram::SetAllDoFunctions();
fram::ram::memory.fill(0x00_b);
fram::Initialize();

{
sts1cobcsw::fram::RingBuffer<int, 10, sts1cobcsw::fram::Address{1234}> buffer;
buffer.Push(1);
buffer.Push(2);
buffer.Push(3);
}

// Simulate a reset by creating a new buffer instance
fram::RingBuffer<int, 10, fram::Address{1234}> buffer;

REQUIRE(buffer.Size() == 3);
REQUIRE(buffer.Front() == 1);
REQUIRE(buffer.Back() == 3);
}

0 comments on commit be020c1

Please sign in to comment.