Skip to content

Commit

Permalink
WIP: Implement some requested changes for ringbuffer
Browse files Browse the repository at this point in the history
  • Loading branch information
jeromehue committed Jul 14, 2024
1 parent 5998e5e commit 5f33388
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 177 deletions.
5 changes: 3 additions & 2 deletions Sts1CobcSw/Edu/ProgramStatusHistory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

namespace sts1cobcsw::edu
{
ProgramStatusHistoryClass<programStatusHistorySize> programStatusHistory =
ProgramStatusHistoryClass<programStatusHistorySize>();
// TODO: Put a real variable for start Address
ProgramStatusHistoryClass<programStatusHistorySize, 0> programStatusHistory =
ProgramStatusHistoryClass<programStatusHistorySize, 0>();
}

namespace sts1cobcsw::edu
Expand Down
33 changes: 19 additions & 14 deletions Sts1CobcSw/Edu/ProgramStatusHistory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

// clang-format off
#include <cstdint> // NOLINT(llvm-include-order)
#include "Sts1CobcSw/Periphery/Fram.hpp"
#include "Sts1CobcSw/Periphery/FramRingBuffer.hpp"
// ringbuffer.h does not include <cstdint> even though it requires it
#include <rodos/support/support-libs/ringbuffer.h>
Expand Down Expand Up @@ -56,14 +57,15 @@ template<std::endian endianness>
[[nodiscard]] auto SerializeTo(void * destination, ProgramStatusHistoryEntry const & data)
-> void *;

template<std::size_t poolSize>
auto UpdateRingBufferEntry(fram::RingBuffer<ProgramStatusHistoryEntry, poolSize> & ringBuffer,
std::int32_t startTime,
ProgramId programId,
ProgramStatus newStatus) -> bool;
template<std::size_t poolSize, fram::Address address>
auto UpdateRingBufferEntry(
fram::RingBuffer<ProgramStatusHistoryEntry, poolSize, address> & ringBuffer,
std::int32_t startTime,
ProgramId programId,
ProgramStatus newStatus) -> bool;


template<std::size_t size>
template<std::size_t size, fram::Address address>
class ProgramStatusHistoryClass
{
public:
Expand All @@ -76,7 +78,7 @@ class ProgramStatusHistoryClass
{
if(fram::framIsWorking)
{
framProgramStatusHistory_.Put(programStatusHistoryEntry);
// framProgramStatusHistory_.Put(programStatusHistoryEntry);
}
ramProgramStatusHistory_.put(programStatusHistoryEntry);
}
Expand Down Expand Up @@ -104,19 +106,22 @@ class ProgramStatusHistoryClass
}

private:
sts1cobcsw::fram::RingBuffer<ProgramStatusHistoryEntry, size> framProgramStatusHistory_;
sts1cobcsw::fram::RingBuffer<ProgramStatusHistoryEntry, size, address>
framProgramStatusHistory_;
RODOS::RingBuffer<ProgramStatusHistoryEntry, size> ramProgramStatusHistory_;
};

extern ProgramStatusHistoryClass<programStatusHistorySize> programStatusHistory;
// TODO: Put a real value here
extern ProgramStatusHistoryClass<programStatusHistorySize, 0> programStatusHistory;


// TODO: Move this into .cpp file
template<std::size_t poolSize>
auto UpdateRingBufferEntry(fram::RingBuffer<ProgramStatusHistoryEntry, poolSize> & ringBuffer,
const std::int32_t startTime,
const ProgramId programId,
const ProgramStatus newStatus) -> bool
template<std::size_t poolSize, fram::Address startAddress>
auto UpdateRingBufferEntry(
fram::RingBuffer<ProgramStatusHistoryEntry, poolSize, startAddress> & ringBuffer,
const std::int32_t startTime,
const ProgramId programId,
const ProgramStatus newStatus) -> bool
{
for(std::uint32_t i = 0; i < poolSize; ++i)
{
Expand Down
76 changes: 30 additions & 46 deletions Sts1CobcSw/Periphery/FramRingBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,61 +14,28 @@

namespace sts1cobcsw::fram
{
using sts1cobcsw::Span;
using sts1cobcsw::TriviallySerializable;


template<typename T, std::size_t poolSize>
template<typename T, std::size_t size, Address startAddress>
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<T>;
fram::WriteTo(address, Span(Serialize(newdata)), 0);
writeIndex_++;

if(writeIndex_ >= poolSize)
{
writeIndex_ = 0;
}
if(occupiedCnt < poolSize)
{
occupiedCnt++;
}
writeCnt++;
currentWrite_ = UINT32_MAX;
}
RingBuffer() = default;

// TODO: Move this in .ipp file
// 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;
}
Expand All @@ -79,26 +46,43 @@ class RingBuffer
fromRing = Deserialize<T>(std::span(readData));

readIndex_++;
if(readIndex_ >= poolSize)
if(readIndex_ >= size)
{
readIndex_ = 0;
}

if(occupiedCnt > 0)
if(occupiedCount_ > 0)
{
occupiedCnt--;
occupiedCount_--;
}
readCnt++;
readCount_++;
}

auto GetLen() -> int
auto Capacity() -> std::size_t
{
return poolSize;
return capacity_;
}

auto Size() -> std::size_t
{
return size;
}

auto Push(T const & newData) -> void;
auto operator[](std::size_t index) -> T;
auto Front() -> T;
auto Back() -> T;

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 <Sts1CobcSw/Periphery/FramRingBuffer.ipp> // IWYU pragma: keep
80 changes: 80 additions & 0 deletions Sts1CobcSw/Periphery/FramRingBuffer.ipp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#pragma once


#include <Sts1CobcSw/Periphery/FramRingBuffer.hpp>


namespace sts1cobcsw::fram
{
template<typename T, std::size_t size, Address startAddress>
void RingBuffer<T, size, startAddress>::Push(T const & newData)
{
currentWriteIndex_ = writeIndex_;
auto const address = startAddress + writeIndex_ * serialSize<T>;
fram::WriteTo(address, Span(Serialize(newData)), 0);
writeIndex_++;

if(writeIndex_ >= size)
{
writeIndex_ = 0;
}
if(occupiedCount_ < size)
{
occupiedCount_++;
}
writeCount_++;
// TODO: iwyu
currentWriteIndex_ = UINT32_MAX;
}


template<typename T, std::size_t size, Address startAddress>
auto RingBuffer<T, size, startAddress>::Front() -> T
{
// TODO: Check if using RODOS ringbuffer logic is right

// Jump the current being written record
if(readIndex_ == currentWriteIndex_)
{
readIndex_++;
}
if(readIndex_ >= size)
{
readIndex_ = 0;
}

// readIndex should not pass write index if there is no data after it
if(writeCount_ < size && readIndex_ >= writeIndex_)
{
readIndex_ = 0;
}

auto const address = startAddress + readIndex_ * serialSize<T>;
// TODO: Add a real timeout value (spiTimeout in hw tests is 30ms, but for much more data)
auto readData = fram::ReadFrom<serialSize<T>>(address, 0);
auto fromRing = Deserialize<T>(std::span(readData));

readIndex_++;
if(readIndex_ >= size)
{
readIndex_ = 0;
}

if(occupiedCount_ > 0)
{
occupiedCount_--;
}
readCount_++;

return fromRing;
}

template<typename T, std::size_t size, Address startAddress>
auto RingBuffer<T, size, startAddress>::operator[](std::size_t index) -> T
{
// TODO: This assume that index not out of bounds
auto const address = startAddress + index * serialSize<T>;
auto readData = fram::ReadFrom<serialSize<T>>(address, 0);
return Deserialize<T>(std::span(readData));
}
}
Loading

0 comments on commit 5f33388

Please sign in to comment.