diff --git a/CMakeLists.txt b/CMakeLists.txt index c1f78323..de827bfb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ include(cmake/clang-tidy-cache.cmake) find_package_and_notify(etl) find_rodos() find_package_and_notify(littlefs) +find_package_and_notify(NamedType) # ---- Declare targets ---- @@ -27,6 +28,7 @@ add_library(Sts1CobcSw_Dummy STATIC) add_library(Sts1CobcSw_Edu STATIC) add_library(Sts1CobcSw_FileSystem STATIC) add_library(Sts1CobcSw_Outcome INTERFACE) +add_library(Sts1CobcSw_ProgramId INTERFACE) add_library(Sts1CobcSw_Serial INTERFACE) add_library(Sts1CobcSw_Utility STATIC) add_library(Sts1CobcSw_Periphery STATIC) diff --git a/Sts1CobcSw/CommandParser.cpp b/Sts1CobcSw/CommandParser.cpp index 1c2fa9fa..3e4c3f06 100644 --- a/Sts1CobcSw/CommandParser.cpp +++ b/Sts1CobcSw/CommandParser.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -88,7 +89,7 @@ auto ParseAndAddQueueEntries(std::span queueEntries) -> void auto entry = Deserialize(queueEntries.first>()); - DEBUG_PRINT("Prog ID : %" PRIu16 "\n", entry.programId); + DEBUG_PRINT("Prog ID : %" PRIu16 "\n", entry.programId.get()); DEBUG_PRINT("Start Time : %" PRIi32 "\n", entry.startTime); DEBUG_PRINT("Timeout : %" PRIi16 "\n", entry.timeout); diff --git a/Sts1CobcSw/Edu/EduMock.cpp b/Sts1CobcSw/Edu/EduMock.cpp index 4f03100c..99c3ceed 100644 --- a/Sts1CobcSw/Edu/EduMock.cpp +++ b/Sts1CobcSw/Edu/EduMock.cpp @@ -47,7 +47,7 @@ auto TurnOff() -> void auto StoreProgram(StoreProgramData const & data) -> Result { PrintFormattedSystemUtc(); - DEBUG_PRINT("Call to StoreProgram(programId = %d)\n", data.programId); + DEBUG_PRINT("Call to StoreProgram(programId = %" PRIu16 ")\n", data.programId.get()); return outcome_v2::success(); } @@ -55,8 +55,9 @@ auto StoreProgram(StoreProgramData const & data) -> Result auto ExecuteProgram(ExecuteProgramData const & data) -> Result { PrintFormattedSystemUtc(); - DEBUG_PRINT("Call to ExecuteProgram(programId = %d, startTime = %" PRIi32 ", timeout = %d)\n", - data.programId, + DEBUG_PRINT("Call to ExecuteProgram(programId = %" PRIu16 ", startTime = %" PRIi32 + ", timeout = %d)\n", + data.programId.get(), data.startTime, data.timeout); return outcome_v2::success(); @@ -75,7 +76,7 @@ auto GetStatus() -> Result { PrintFormattedSystemUtc(); DEBUG_PRINT("Call to GetStatus()\n"); - return Status{.statusType = StatusType::invalid, .programId = 0, .startTime = 0, .exitCode = 0}; + return Status(); } diff --git a/Sts1CobcSw/Edu/ProgramQueue.cpp b/Sts1CobcSw/Edu/ProgramQueue.cpp index e682fe1e..1fb67ccd 100644 --- a/Sts1CobcSw/Edu/ProgramQueue.cpp +++ b/Sts1CobcSw/Edu/ProgramQueue.cpp @@ -1,5 +1,4 @@ #include -#include // TODO: Change namespace here too, or move it back to Sts1CobSw/ diff --git a/Sts1CobcSw/Edu/ProgramQueue.hpp b/Sts1CobcSw/Edu/ProgramQueue.hpp index eaaf4173..ec3dd9f6 100644 --- a/Sts1CobcSw/Edu/ProgramQueue.hpp +++ b/Sts1CobcSw/Edu/ProgramQueue.hpp @@ -1,6 +1,7 @@ #pragma once +#include #include #include @@ -16,7 +17,7 @@ namespace edu { struct QueueEntry { - std::uint16_t programId = 0; + ProgramId programId = ProgramId(0); std::int32_t startTime = 0; std::int16_t timeout = 0; }; diff --git a/Sts1CobcSw/Edu/ProgramStatusHistory.cpp b/Sts1CobcSw/Edu/ProgramStatusHistory.cpp index a06a3c9d..7678832e 100644 --- a/Sts1CobcSw/Edu/ProgramStatusHistory.cpp +++ b/Sts1CobcSw/Edu/ProgramStatusHistory.cpp @@ -6,7 +6,7 @@ namespace sts1cobcsw::edu RODOS::RingBuffer programStatusHistory; -auto UpdateProgramStatusHistory(std::uint16_t programId, +auto UpdateProgramStatusHistory(ProgramId programId, std::int32_t startTime, ProgramStatus newStatus) -> void { diff --git a/Sts1CobcSw/Edu/ProgramStatusHistory.hpp b/Sts1CobcSw/Edu/ProgramStatusHistory.hpp index b866dc7c..8fe86609 100644 --- a/Sts1CobcSw/Edu/ProgramStatusHistory.hpp +++ b/Sts1CobcSw/Edu/ProgramStatusHistory.hpp @@ -1,6 +1,8 @@ #pragma once +#include + // clang-format off #include // ringbuffer.h does not include even though it requires it @@ -25,7 +27,7 @@ enum class ProgramStatus : std::uint8_t struct ProgramStatusHistoryEntry { - std::uint16_t programId = 0; + ProgramId programId = ProgramId(0); std::int32_t startTime = 0; ProgramStatus status = ProgramStatus::programRunning; }; @@ -35,7 +37,7 @@ inline constexpr auto programStatusHistorySize = 20; extern RODOS::RingBuffer programStatusHistory; -auto UpdateProgramStatusHistory(std::uint16_t programId, +auto UpdateProgramStatusHistory(ProgramId programId, std::int32_t startTime, ProgramStatus newStatus) -> void; } diff --git a/Sts1CobcSw/Edu/Types.hpp b/Sts1CobcSw/Edu/Types.hpp index 2a2984e7..9ebc9322 100644 --- a/Sts1CobcSw/Edu/Types.hpp +++ b/Sts1CobcSw/Edu/Types.hpp @@ -1,6 +1,7 @@ #pragma once +#include #include #include @@ -42,14 +43,14 @@ enum class StatusType struct StoreProgramData { static constexpr auto id = 0x01_b; - std::uint16_t programId = 0; + ProgramId programId = ProgramId(0); }; struct ExecuteProgramData { static constexpr auto id = 0x02_b; - std::uint16_t programId = 0; + ProgramId programId = ProgramId(0); std::int32_t startTime = 0; std::int16_t timeout = 0; }; @@ -70,7 +71,7 @@ struct GetStatusData struct ReturnResultData { static constexpr auto id = 0x05_b; - std::uint16_t programId = 0; + ProgramId programId = ProgramId(0); std::int32_t startTime = 0; }; @@ -85,7 +86,7 @@ struct UpdateTimeData struct Status { StatusType statusType = StatusType::invalid; - std::uint16_t programId = 0; + ProgramId programId = ProgramId(0); std::int32_t startTime = 0; std::uint8_t exitCode = 0; }; @@ -100,7 +101,7 @@ struct NoEventData struct ProgramFinishedData { static constexpr auto id = 0x01_b; - std::uint16_t programId = 0; + ProgramId programId = ProgramId(0); std::int32_t startTime = 0; std::uint8_t exitCode = 0; }; @@ -109,7 +110,7 @@ struct ProgramFinishedData struct ResultsReadyData { static constexpr auto id = 0x02_b; - std::uint16_t programId = 0; + ProgramId programId = ProgramId(0); std::int32_t startTime = 0; }; diff --git a/Sts1CobcSw/EduProgramQueueThread.cpp b/Sts1CobcSw/EduProgramQueueThread.cpp index 896a8b7f..dff13bde 100644 --- a/Sts1CobcSw/EduProgramQueueThread.cpp +++ b/Sts1CobcSw/EduProgramQueueThread.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -125,7 +126,7 @@ class EduProgramQueueThread : public RODOS::StaticThread auto programId = edu::programQueue[edu::queueIndex].programId; auto timeout = edu::programQueue[edu::queueIndex].timeout; - DEBUG_PRINT("Executing program %d\n", programId); + DEBUG_PRINT("Executing program %" PRIu16 "\n", programId.get()); auto executeProgramData = edu::ExecuteProgramData{ .programId = programId, .startTime = startTime, .timeout = timeout}; // Start Process diff --git a/Sts1CobcSw/FileSystem/FileSystem.cpp b/Sts1CobcSw/FileSystem/FileSystem.cpp index 9013b5b5..7894342a 100644 --- a/Sts1CobcSw/FileSystem/FileSystem.cpp +++ b/Sts1CobcSw/FileSystem/FileSystem.cpp @@ -98,7 +98,7 @@ auto Unmount() -> int } -auto OpenProgramFile(std::uint16_t programId, int flags) -> int +auto OpenProgramFile(ProgramId programId, int flags) -> int { return 0; } diff --git a/Sts1CobcSw/FileSystem/FileSystem.hpp b/Sts1CobcSw/FileSystem/FileSystem.hpp index 992404f2..97845dfa 100644 --- a/Sts1CobcSw/FileSystem/FileSystem.hpp +++ b/Sts1CobcSw/FileSystem/FileSystem.hpp @@ -1,6 +1,7 @@ #pragma once +#include #include #include @@ -8,7 +9,6 @@ #include #include -#include namespace sts1cobcsw::fs::deprecated @@ -25,7 +25,7 @@ auto Mount() -> int; auto Unmount() -> int; // File stuff -auto OpenProgramFile(std::uint16_t programId, int flags) -> int; +auto OpenProgramFile(ProgramId programId, int flags) -> int; auto CloseProgramFile() -> int; template auto ReadProgramFile(etl::vector * buffer) -> int; diff --git a/Sts1CobcSw/FlashStartupTestThread.cpp b/Sts1CobcSw/FlashStartupTestThread.cpp index b5eeb0b2..3bb7269f 100644 --- a/Sts1CobcSw/FlashStartupTestThread.cpp +++ b/Sts1CobcSw/FlashStartupTestThread.cpp @@ -2,6 +2,8 @@ #include #include +#include + namespace sts1cobcsw { diff --git a/Sts1CobcSw/FramEpsStartupTestThread.cpp b/Sts1CobcSw/FramEpsStartupTestThread.cpp index 57d63b25..3d32b55b 100644 --- a/Sts1CobcSw/FramEpsStartupTestThread.cpp +++ b/Sts1CobcSw/FramEpsStartupTestThread.cpp @@ -3,6 +3,10 @@ #include #include +#include + +#include + namespace sts1cobcsw { diff --git a/Sts1CobcSw/ProgramId/CMakeLists.txt b/Sts1CobcSw/ProgramId/CMakeLists.txt new file mode 100644 index 00000000..21cda0da --- /dev/null +++ b/Sts1CobcSw/ProgramId/CMakeLists.txt @@ -0,0 +1 @@ +target_link_libraries(Sts1CobcSw_ProgramId INTERFACE NamedType::NamedType Sts1CobcSw_Serial) diff --git a/Sts1CobcSw/ProgramId/ProgramId.hpp b/Sts1CobcSw/ProgramId/ProgramId.hpp new file mode 100644 index 00000000..fe277a78 --- /dev/null +++ b/Sts1CobcSw/ProgramId/ProgramId.hpp @@ -0,0 +1,27 @@ +#pragma once + + +#include + +#include + +#include + + +namespace sts1cobcsw +{ +using ProgramId = fluent::NamedType; + +// TODO: Maybe make ProgramId completely serializable, i.e., overload (De-)Serialize() as well +template<> +inline constexpr std::size_t serialSize = totalSerialSize; + + +template +[[nodiscard]] inline auto SerializeTo(void * destination, ProgramId const & data) -> void *; +template +[[nodiscard]] inline auto DeserializeFrom(void const * source, ProgramId * data) -> void const *; +} + + +#include diff --git a/Sts1CobcSw/ProgramId/ProgramId.ipp b/Sts1CobcSw/ProgramId/ProgramId.ipp new file mode 100644 index 00000000..547bb5f3 --- /dev/null +++ b/Sts1CobcSw/ProgramId/ProgramId.ipp @@ -0,0 +1,21 @@ +#pragma once + + +#include + + +namespace sts1cobcsw +{ +template +inline auto SerializeTo(void * destination, ProgramId const & data) -> void * +{ + return SerializeTo(destination, data.get()); +} + + +template +inline auto DeserializeFrom(void const * source, ProgramId * data) -> void const * +{ + return DeserializeFrom(source, &(data->get())); +} +} diff --git a/Sts1CobcSw/RfStartupTestThread.cpp b/Sts1CobcSw/RfStartupTestThread.cpp index 4a7cf6bd..c3dcb340 100644 --- a/Sts1CobcSw/RfStartupTestThread.cpp +++ b/Sts1CobcSw/RfStartupTestThread.cpp @@ -2,6 +2,8 @@ #include #include +#include + namespace sts1cobcsw { diff --git a/Sts1CobcSw/Serial/Serial.hpp b/Sts1CobcSw/Serial/Serial.hpp index 70907840..87237d76 100644 --- a/Sts1CobcSw/Serial/Serial.hpp +++ b/Sts1CobcSw/Serial/Serial.hpp @@ -48,6 +48,7 @@ template inline constexpr std::size_t serialSize> = serialSize * size; template + requires((serialSize != 0) and ...) inline constexpr std::size_t totalSerialSize = (serialSize + ...); inline constexpr auto defaultEndianness = std::endian::little; diff --git a/Sts1CobcSw/SpiStartupTestAndSupervisorThread.cpp b/Sts1CobcSw/SpiStartupTestAndSupervisorThread.cpp index d5c2b5cc..29e51deb 100644 --- a/Sts1CobcSw/SpiStartupTestAndSupervisorThread.cpp +++ b/Sts1CobcSw/SpiStartupTestAndSupervisorThread.cpp @@ -1,6 +1,8 @@ #include #include +#include + namespace sts1cobcsw { diff --git a/Tests/GoldenTests/UpdateRingBuffer.test.cpp b/Tests/GoldenTests/UpdateRingBuffer.test.cpp index 96e8151e..01674d7c 100644 --- a/Tests/GoldenTests/UpdateRingBuffer.test.cpp +++ b/Tests/GoldenTests/UpdateRingBuffer.test.cpp @@ -38,7 +38,7 @@ void PrintBuffer() { RODOS::PRINTF("Vals[%d] = .id(%d), .status(%s)\n", i, - edu::programStatusHistory.vals[i].programId, + edu::programStatusHistory.vals[i].programId.get(), ToString(edu::programStatusHistory.vals[i].status).data()); } } @@ -50,14 +50,22 @@ class UpdateRingBufferTest : public RODOS::StaticThread<> { printfMask = 1; - edu::programStatusHistory.put(edu::ProgramStatusHistoryEntry{ - .programId = 1, .startTime = 1, .status = edu::ProgramStatus::programExecutionFailed}); - edu::programStatusHistory.put(edu::ProgramStatusHistoryEntry{ - .programId = 2, .startTime = 1, .status = edu::ProgramStatus::programRunning}); - edu::programStatusHistory.put(edu::ProgramStatusHistoryEntry{ - .programId = 3, .startTime = 1, .status = edu::ProgramStatus::programRunning}); - edu::programStatusHistory.put(edu::ProgramStatusHistoryEntry{ - .programId = 4, .startTime = 1, .status = edu::ProgramStatus::programRunning}); + edu::programStatusHistory.put( + edu::ProgramStatusHistoryEntry{.programId = ProgramId(1), + .startTime = 1, + .status = edu::ProgramStatus::programExecutionFailed}); + edu::programStatusHistory.put( + edu::ProgramStatusHistoryEntry{.programId = ProgramId(2), + .startTime = 1, + .status = edu::ProgramStatus::programRunning}); + edu::programStatusHistory.put( + edu::ProgramStatusHistoryEntry{.programId = ProgramId(3), + .startTime = 1, + .status = edu::ProgramStatus::programRunning}); + edu::programStatusHistory.put( + edu::ProgramStatusHistoryEntry{.programId = ProgramId(4), + .startTime = 1, + .status = edu::ProgramStatus::programRunning}); auto readCnt = edu::programStatusHistory.readCnt; @@ -66,11 +74,16 @@ class UpdateRingBufferTest : public RODOS::StaticThread<> PrintBuffer(); - edu::UpdateProgramStatusHistory(2, 1, edu::ProgramStatus::programExecutionSucceeded); - edu::UpdateProgramStatusHistory(4, 1, edu::ProgramStatus::programExecutionFailed); - edu::programStatusHistory.put(edu::ProgramStatusHistoryEntry{ - .programId = 5, .startTime = 1, .status = edu::ProgramStatus::programRunning}); - edu::UpdateProgramStatusHistory(5, 1, edu::ProgramStatus::programExecutionSucceeded); + edu::UpdateProgramStatusHistory( + ProgramId(2), 1, edu::ProgramStatus::programExecutionSucceeded); + edu::UpdateProgramStatusHistory( + ProgramId(4), 1, edu::ProgramStatus::programExecutionFailed); + edu::programStatusHistory.put( + edu::ProgramStatusHistoryEntry{.programId = ProgramId(5), + .startTime = 1, + .status = edu::ProgramStatus::programRunning}); + edu::UpdateProgramStatusHistory( + ProgramId(5), 1, edu::ProgramStatus::programExecutionSucceeded); // 1, because we did not read anything RODOS::PRINTF("readCnt unchanged : %d\n", diff --git a/Tests/HardwareTests/EduCommands.test.cpp b/Tests/HardwareTests/EduCommands.test.cpp index d4ca2a63..7e46c4dc 100644 --- a/Tests/HardwareTests/EduCommands.test.cpp +++ b/Tests/HardwareTests/EduCommands.test.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -83,8 +84,8 @@ class EduCommandsTest : public RODOS::StaticThread<> { PRINTF("Please enter a program ID (1 character)\n"); auto userInput = ReadCharacters<1>(); - std::uint16_t programId = 0; - std::from_chars(userInput.begin(), userInput.end(), programId); + auto programId = ProgramId(0); + std::from_chars(userInput.begin(), userInput.end(), programId.get()); PRINTF("Please enter a start time (1 character)\n"); userInput = ReadCharacters<1>(); @@ -99,7 +100,7 @@ class EduCommandsTest : public RODOS::StaticThread<> PRINTF("\n"); PRINTF("Sending ExecuteProgram(programId = %" PRIu16 ", startTime = %" PRIi32 ", timeout = %" PRIi16 ")\n", - programId, + programId.get(), startTime, timeout); auto executeProgramResult = edu::ExecuteProgram( @@ -137,8 +138,8 @@ class EduCommandsTest : public RODOS::StaticThread<> { PRINTF("Please enter a program ID (1 character)\n"); auto userInput = ReadCharacters<1>(); - std::uint16_t programId = 0; - std::from_chars(userInput.begin(), userInput.end(), programId); + auto programId = ProgramId(0); + std::from_chars(userInput.begin(), userInput.end(), programId.get()); PRINTF("Please enter a start time (1 character)\n"); userInput = ReadCharacters<1>(); @@ -148,7 +149,7 @@ class EduCommandsTest : public RODOS::StaticThread<> PRINTF("\n"); PRINTF("Sending ReturnResult(programId = %" PRIu16 ", startTime = %" PRIi32 ")\n", - programId, + programId.get(), startTime); auto returnResultResult = edu::ReturnResult( edu::ReturnResultData{.programId = programId, .startTime = startTime}); diff --git a/iwyu.imp b/iwyu.imp index 0826322c..f8758a5a 100644 --- a/iwyu.imp +++ b/iwyu.imp @@ -52,6 +52,7 @@ { include: ["\"Sts1CobcSw/Hal/Uart.ipp\"", "private", "", "public"] }, { include: ["\"Sts1CobcSw/Utility/Time.ipp\"", "private", "", "public"] }, { include: ["\"Sts1CobcSw/Periphery/Fram.ipp\"", "private", "", "public"] }, + { include: ["\"Sts1CobcSw/ProgramId/ProgramId.ipp\"", "private", "", "public"] }, { include: ["\"Sts1CobcSw/Serial/Byte.ipp\"", "private", "", "public"] }, { include: ["\"Sts1CobcSw/Serial/Serial.ipp\"", "private", "", "public"] }, { include: ["\"Sts1CobcSw/Utility/Span.ipp\"", "private", "", "public"] }, @@ -76,6 +77,7 @@ { include: ["\"Sts1CobcSw/Periphery/Fram.hpp\"", "public", "", "public"] }, { include: ["\"Sts1CobcSw/Periphery/PersistentState.hpp\"", "public", "", "public"] }, { include: ["\"Sts1CobcSw/Periphery/Rf.hpp\"", "public", "", "public"] }, + { include: ["\"Sts1CobcSw/ProgramId/ProgramId.hpp\"", "public", "", "public"] }, { include: ["\"Sts1CobcSw/Serial/Byte.hpp\"", "public", "", "public"] }, { include: ["\"Sts1CobcSw/Serial/Serial.hpp\"", "public", "", "public"] }, { include: ["\"Sts1CobcSw/Utility/Crc32.hpp\"", "public", "", "public"] },