Skip to content

Commit

Permalink
Add an update method for fram buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
jeromehue committed Jun 5, 2024
1 parent 5faf8d9 commit f31eeb7
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 59 deletions.
7 changes: 1 addition & 6 deletions Sts1CobcSw/Edu/ProgramStatusHistory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,7 @@

namespace sts1cobcsw::edu
{

sts1cobcsw::fram::RingBuffer<ProgramStatusHistoryEntry, programStatusHistorySize>
programStatusHistory =
sts1cobcsw::fram::RingBuffer<ProgramStatusHistoryEntry, programStatusHistorySize>(0);

ProgramStatusHistoryClass<programStatusHistorySize> pObject =
ProgramStatusHistoryClass<programStatusHistorySize> programStatusHistory =
ProgramStatusHistoryClass<programStatusHistorySize>();
}

Expand Down
75 changes: 50 additions & 25 deletions Sts1CobcSw/Edu/ProgramStatusHistory.hpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
#pragma once


#include <Sts1CobcSw/ProgramId/ProgramId.hpp>
#include <Sts1CobcSw/Serial/Serial.hpp>

// clang-format off
#include <cstdint>
#include <cstdint> // NOLINT(llvm-include-order)
#include "Sts1CobcSw/Periphery/FramRingBuffer.hpp"
// ringbuffer.h does not include <cstdint> even though it requires it
#include <rodos/support/support-libs/ringbuffer.h>
// clang-format on

#include <bit>


namespace sts1cobcsw
{
using fram::RingBuffer;

namespace edu
{
enum class ProgramStatus : std::uint8_t
Expand All @@ -38,10 +36,18 @@ struct ProgramStatusHistoryEntry
std::int32_t startTime = 0;
ProgramStatus status = ProgramStatus::programRunning;
};
}


template<>
inline constexpr std::size_t serialSize<edu::ProgramStatusHistoryEntry> =
totalSerialSize<decltype(edu::ProgramStatusHistoryEntry::programId),
decltype(edu::ProgramStatusHistoryEntry::startTime),
decltype(edu::ProgramStatusHistoryEntry::status)>;

namespace edu
{
inline constexpr auto programStatusHistorySize = 20;
// TODO: Use a class that handle the dual storage (or cache) thing
extern RingBuffer<ProgramStatusHistoryEntry, programStatusHistorySize> programStatusHistory;

template<std::endian endianness>
[[nodiscard]] auto DeserializeFrom(void const * source, ProgramStatusHistoryEntry * data)
Expand All @@ -50,13 +56,22 @@ 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 size>
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)
Expand All @@ -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)
Expand All @@ -96,15 +103,33 @@ class ProgramStatusHistoryClass
RODOS::RingBuffer<ProgramStatusHistoryEntry, size> ramProgramStatusHistory_;
};

extern ProgramStatusHistoryClass<programStatusHistorySize> pObject;
}
}
extern ProgramStatusHistoryClass<programStatusHistorySize> programStatusHistory;

namespace sts1cobcsw

// 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<>
inline constexpr std::size_t serialSize<edu::ProgramStatusHistoryEntry> =
totalSerialSize<decltype(edu::ProgramStatusHistoryEntry::programId),
decltype(edu::ProgramStatusHistoryEntry::startTime),
decltype(edu::ProgramStatusHistoryEntry::status)>;
for(std::uint32_t i = 0; i < poolSize; ++i)
{
auto const address = ringBuffer.startAddress + i * serialSize<ProgramStatusHistoryEntry>;
auto readData = fram::ReadFrom<serialSize<ProgramStatusHistoryEntry>>(address, 0);
ProgramStatusHistoryEntry data =
Deserialize<ProgramStatusHistoryEntry>(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;
}
}
}
}
}
21 changes: 12 additions & 9 deletions Sts1CobcSw/EduListenerThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion Sts1CobcSw/EduProgramQueueThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class EduProgramQueueThread : public RODOS::StaticThread<stackSize>
}
else
{
edu::pObject.Put(
edu::programStatusHistory.Put(
edu::ProgramStatusHistoryEntry{.programId = programId,
.startTime = startTime,
.status = edu::ProgramStatus::programRunning});
Expand Down
15 changes: 7 additions & 8 deletions Sts1CobcSw/Periphery/FramRingBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,23 @@ template<typename T, std::size_t poolSize>
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<T>;
auto const address = startAddress + writeIndex_ * serialSize<T>;
fram::WriteTo(address, Span(Serialize(newdata)), 0);
writeIndex_++;

Expand Down Expand Up @@ -73,7 +73,7 @@ class RingBuffer
readIndex_ = 0;
}

auto const address = startAddress_ + readIndex_ * serialSize<T>;
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);
fromRing = Deserialize<T>(std::span(readData));
Expand All @@ -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;
Expand Down
10 changes: 0 additions & 10 deletions Tests/UnitTests/FramRingBuffer.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,6 @@ TEST_CASE("Simple put and get inlined")
}


namespace sts1cobcsw
{
template<>
constexpr std::size_t serialSize<edu::ProgramStatusHistoryEntry> =
totalSerialSize<decltype(edu::ProgramStatusHistoryEntry::programId),
decltype(edu::ProgramStatusHistoryEntry::startTime),
decltype(edu::ProgramStatusHistoryEntry::status)>;
}


namespace sts1cobcsw::edu
{
template<std::endian endianness>
Expand Down

0 comments on commit f31eeb7

Please sign in to comment.