Skip to content

Commit

Permalink
WIP: Add a Fram ringbuffer
Browse files Browse the repository at this point in the history
  • Loading branch information
jeromehue committed May 28, 2024
1 parent ab9c466 commit 29336ac
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 0 deletions.
Empty file.
101 changes: 101 additions & 0 deletions Sts1CobcSw/Periphery/FramRingBuffer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#pragma once


#include <Sts1CobcSw/Periphery/Fram.hpp>

#include <array>
#include <cstddef>
#include <cstdint>
#include <span>


namespace sts1cobcsw::fram
{

template<class T, std::size_t poolSize>
class RingBuffer
{
public:
Address startAddress;
std::uint32_t writeIndex = 0;
std::uint32_t readIndex = 0;
std::uint32_t currentWrite = UINT32_MAX;
std::array<T, poolSize> vals;

public:
std::uint64_t writeCnt = 0;
std::uint64_t readCnt = 0;
std::uint32_t occupiedCnt = 0;

RingBuffer(Address startAddress) : startAddress(startAddress)
{
}

T * getNextEntryToPut()
{
return &vals[writeIndex];
}

void put(T const & newdata)
{
currentWrite = writeIndex;
Address address = startAddress + writeIndex * sizeof(T);

WriteTo(address, reinterpret_cast<Byte const *>(&newdata), sizeof(T), 0);
writeIndex++;

if(writeIndex >= poolSize)
{
writeIndex = 0;
}
if(occupiedCnt < poolSize)
{
occupiedCnt++;
}
writeCnt++;
currentWrite = UINT32_MAX;
}

// Get next item
void get(T & fromRing)
{
// Jump the current being written record
if(readIndex == currentWrite)
{
readIndex++;
}
if(readIndex >= poolSize)
{
readIndex = 0;
}

// readIndex should not pass write index if there is no data after it
if(writeCnt < poolSize && readIndex >= writeIndex)
{
readIndex = 0;
}

Address address = startAddress + readIndex * sizeof(T);
std::array<Byte, sizeof(T)> buffer;
ReadFrom(address, buffer, 0);
fromRing = *reinterpret_cast<T *>(buffer.data());

readIndex++;
if(readIndex >= poolSize)
{
readIndex = 0;
}

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

int getLen()
{
return poolSize;
}
};
}
3 changes: 3 additions & 0 deletions Tests/UnitTests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ target_link_libraries(
Sts1CobcSw_Utility
)

add_program(RingBuffer FramRingBuffer.test.cpp)
target_link_libraries(Sts1CobcSwTests_RingBuffer PRIVATE Catch2::Catch2WithMain)

# TODO: Enable again once problem with segmentation violation on CI is fixed
add_program(LfsRam LfsRam.test.cpp)
target_link_libraries(Sts1CobcSwTests_LfsRam PRIVATE Catch2::Catch2WithMain Sts1CobcSw_FileSystem)
Expand Down
61 changes: 61 additions & 0 deletions Tests/UnitTests/FramRingBuffer.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include <cstdint>
#include <rodos/support/support-libs/ringbuffer.h>
#include <catch2/catch_test_macros.hpp>


TEST_CASE("RODOS ringbuffer put and get operations")
{

RODOS::RingBuffer<int, 10> buffer;

REQUIRE(buffer.getLen() == 10);

int value = 42;
int result;
buffer.put(value);
buffer.get(result);
REQUIRE(value == result);
}

TEST_CASE("RODOS ringbuffer overwrite")
{

RODOS::RingBuffer<int, 10> buffer;
REQUIRE(buffer.getLen() == 10);

for(int i = 0; i < 15; i++)
{
buffer.put(i);
}

int result;
for(int i = 10; i < 15; ++i)
{
buffer.get(result);
REQUIRE(result == i);
}
}

TEST_CASE("RODOS ringbuffer wrapping")
{

RODOS::RingBuffer<int, 10> buffer;
for(int i = 0; i < 30; ++i)
{
buffer.put(i);
}

int result;
for(int i = 20; i < 30; ++i)
{
buffer.get(result);
REQUIRE(result == i);
}


}

// TODO: Split in differents tests or sections
TEST_CASE("RingBuffer put and get operations")
{
}

0 comments on commit 29336ac

Please sign in to comment.