FSFW Update #26

Merged
meierj merged 24 commits from mueller/sw-update into eive/develop 2021-12-15 10:01:34 +01:00
15 changed files with 285 additions and 96 deletions
Showing only changes of commit 9c5e3565c6 - Show all commits

View File

@ -186,7 +186,7 @@ ReturnValue_t MgmRM3100Handler::interpretDeviceReply(DeviceCommandId_t id, const
uint8_t cmmValue = packet[1]; uint8_t cmmValue = packet[1];
// We clear the seventh bit in any case // We clear the seventh bit in any case
// because this one is zero sometimes for some reason // because this one is zero sometimes for some reason
bitutil::bitClear(&cmmValue, 6); bitutil::clear(&cmmValue, 6);
if(cmmValue == cmmRegValue and internalState == InternalState::READ_CMM) { if(cmmValue == cmmRegValue and internalState == InternalState::READ_CMM) {
commandExecuted = true; commandExecuted = true;
} }

View File

@ -110,7 +110,7 @@ ReturnValue_t LocalPoolDataSetBase::serializeWithValidityBuffer(uint8_t **buffer
for (uint16_t count = 0; count < fillCount; count++) { for (uint16_t count = 0; count < fillCount; count++) {
if(registeredVariables[count]->isValid()) { if(registeredVariables[count]->isValid()) {
/* Set bit at correct position */ /* Set bit at correct position */
bitutil::bitSet(validityPtr + validBufferIndex, validBufferIndexBit); bitutil::set(validityPtr + validBufferIndex, validBufferIndexBit);
} }
if(validBufferIndexBit == 7) { if(validBufferIndexBit == 7) {
validBufferIndex ++; validBufferIndex ++;
@ -156,8 +156,8 @@ ReturnValue_t LocalPoolDataSetBase::deSerializeWithValidityBuffer(
uint8_t validBufferIndexBit = 0; uint8_t validBufferIndexBit = 0;
for (uint16_t count = 0; count < fillCount; count++) { for (uint16_t count = 0; count < fillCount; count++) {
// set validity buffer here. // set validity buffer here.
bool nextVarValid = bitutil::bitGet(*buffer + bool nextVarValid = false;
validBufferIndex, validBufferIndexBit); bitutil::get(*buffer + validBufferIndex, validBufferIndexBit, nextVarValid);
registeredVariables[count]->setValid(nextVarValid); registeredVariables[count]->setValid(nextVarValid);
if(validBufferIndexBit == 7) { if(validBufferIndexBit == 7) {

View File

@ -3,18 +3,17 @@
PeriodicOperationDivider::PeriodicOperationDivider(uint32_t divider, PeriodicOperationDivider::PeriodicOperationDivider(uint32_t divider,
bool resetAutomatically): resetAutomatically(resetAutomatically), bool resetAutomatically): resetAutomatically(resetAutomatically),
counter(divider), divider(divider) { divider(divider) {
} }
bool PeriodicOperationDivider::checkAndIncrement() { bool PeriodicOperationDivider::checkAndIncrement() {
bool opNecessary = check(); bool opNecessary = check();
if(opNecessary) { if(opNecessary and resetAutomatically) {
if(resetAutomatically) { resetCounter();
counter = 0;
} }
return opNecessary; else {
counter++;
} }
counter ++;
return opNecessary; return opNecessary;
} }
@ -25,10 +24,8 @@ bool PeriodicOperationDivider::check() {
return false; return false;
} }
void PeriodicOperationDivider::resetCounter() { void PeriodicOperationDivider::resetCounter() {
counter = 0; counter = 1;
} }
void PeriodicOperationDivider::setDivider(uint32_t newDivider) { void PeriodicOperationDivider::setDivider(uint32_t newDivider) {

View File

@ -16,16 +16,15 @@ public:
/** /**
* Initialize with the desired divider and specify whether the internal * Initialize with the desired divider and specify whether the internal
* counter will be reset automatically. * counter will be reset automatically.
* @param divider * @param divider Value of 0 or 1 will cause #check and #checkAndIncrement to always return
* true
* @param resetAutomatically * @param resetAutomatically
*/ */
PeriodicOperationDivider(uint32_t divider, bool resetAutomatically = true); PeriodicOperationDivider(uint32_t divider, bool resetAutomatically = true);
/** /**
* Check whether operation is necessary. * Check whether operation is necessary. If an operation is necessary and the class has been
* If an operation is necessary and the class has been * configured to be reset automatically, the counter will be reset to 1 automatically
* configured to be reset automatically, the counter will be reset.
* *
* @return * @return
* -@c true if the counter is larger or equal to the divider * -@c true if the counter is larger or equal to the divider
@ -34,8 +33,7 @@ public:
bool checkAndIncrement(); bool checkAndIncrement();
/** /**
* Checks whether an operation is necessary. * Checks whether an operation is necessary. This function will not increment the counter.
* This function will not increment the counter!
* @return * @return
* -@c true if the counter is larger or equal to the divider * -@c true if the counter is larger or equal to the divider
* -@c false otherwise * -@c false otherwise
@ -43,7 +41,7 @@ public:
bool check(); bool check();
/** /**
* Can be used to reset the counter to 0 manually. * Can be used to reset the counter to 1 manually
*/ */
void resetCounter(); void resetCounter();
uint32_t getCounter() const; uint32_t getCounter() const;
@ -54,9 +52,10 @@ public:
*/ */
void setDivider(uint32_t newDivider); void setDivider(uint32_t newDivider);
uint32_t getDivider() const; uint32_t getDivider() const;
private: private:
bool resetAutomatically = true; bool resetAutomatically = true;
uint32_t counter = 0; uint32_t counter = 1;
uint32_t divider = 0; uint32_t divider = 0;
}; };

View File

@ -1,6 +1,6 @@
#include "fsfw/globalfunctions/bitutility.h" #include "fsfw/globalfunctions/bitutility.h"
void bitutil::bitSet(uint8_t *byte, uint8_t position) { void bitutil::set(uint8_t *byte, uint8_t position) {
if(position > 7) { if(position > 7) {
return; return;
} }
@ -8,7 +8,7 @@ void bitutil::bitSet(uint8_t *byte, uint8_t position) {
*byte |= 1 << shiftNumber; *byte |= 1 << shiftNumber;
} }
void bitutil::bitToggle(uint8_t *byte, uint8_t position) { void bitutil::toggle(uint8_t *byte, uint8_t position) {
if(position > 7) { if(position > 7) {
return; return;
} }
@ -16,7 +16,7 @@ void bitutil::bitToggle(uint8_t *byte, uint8_t position) {
*byte ^= 1 << shiftNumber; *byte ^= 1 << shiftNumber;
} }
void bitutil::bitClear(uint8_t *byte, uint8_t position) { void bitutil::clear(uint8_t *byte, uint8_t position) {
if(position > 7) { if(position > 7) {
return; return;
} }
@ -24,10 +24,11 @@ void bitutil::bitClear(uint8_t *byte, uint8_t position) {
*byte &= ~(1 << shiftNumber); *byte &= ~(1 << shiftNumber);
} }
bool bitutil::bitGet(const uint8_t *byte, uint8_t position) { bool bitutil::get(const uint8_t *byte, uint8_t position, bool& bit) {
if(position > 7) { if(position > 7) {
return false; return false;
} }
uint8_t shiftNumber = position + (7 - 2 * position); uint8_t shiftNumber = position + (7 - 2 * position);
return *byte & (1 << shiftNumber); bit = *byte & (1 << shiftNumber);
return true;
} }

View File

@ -5,13 +5,36 @@
namespace bitutil { namespace bitutil {
/* Helper functions for manipulating the individual bits of a byte. // Helper functions for manipulating the individual bits of a byte.
Position refers to n-th bit of a byte, going from 0 (most significant bit) to // Position refers to n-th bit of a byte, going from 0 (most significant bit) to
7 (least significant bit) */ // 7 (least significant bit)
void bitSet(uint8_t* byte, uint8_t position);
void bitToggle(uint8_t* byte, uint8_t position); /**
void bitClear(uint8_t* byte, uint8_t position); * @brief Set the bit in a given byte
bool bitGet(const uint8_t* byte, uint8_t position); * @param byte
* @param position
*/
void set(uint8_t* byte, uint8_t position);
/**
* @brief Toggle the bit in a given byte
* @param byte
* @param position
*/
void toggle(uint8_t* byte, uint8_t position);
/**
* @brief Clear the bit in a given byte
* @param byte
* @param position
*/
void clear(uint8_t* byte, uint8_t position);
/**
* @brief Get the bit in a given byte
* @param byte
* @param position
* @param If the input is valid, this will be set to true if the bit is set and false otherwise.
* @return False if position is invalid, True otherwise
*/
bool get(const uint8_t* byte, uint8_t position, bool& bit);
} }

View File

@ -0,0 +1,13 @@
#ifndef FSFW_SRC_FSFW_MEMORY_FILESYSTEMARGS_H_
#define FSFW_SRC_FSFW_MEMORY_FILESYSTEMARGS_H_
/**
* Empty base interface which can be implemented by to pass arguments via the HasFileSystemIF.
* Users can then dynamic_cast the base pointer to the require child pointer.
*/
class FileSystemArgsIF {
public:
virtual~ FileSystemArgsIF() {};
};
#endif /* FSFW_SRC_FSFW_MEMORY_FILESYSTEMARGS_H_ */

View File

@ -1,9 +1,10 @@
#ifndef FSFW_MEMORY_HASFILESYSTEMIF_H_ #ifndef FSFW_MEMORY_HASFILESYSTEMIF_H_
#define FSFW_MEMORY_HASFILESYSTEMIF_H_ #define FSFW_MEMORY_HASFILESYSTEMIF_H_
#include "../returnvalues/HasReturnvaluesIF.h" #include "FileSystemArgsIF.h"
#include "../returnvalues/FwClassIds.h" #include "fsfw/returnvalues/HasReturnvaluesIF.h"
#include "../ipc/messageQueueDefinitions.h" #include "fsfw/returnvalues/FwClassIds.h"
#include "fsfw/ipc/messageQueueDefinitions.h"
#include <cstddef> #include <cstddef>
@ -59,7 +60,7 @@ public:
*/ */
virtual ReturnValue_t appendToFile(const char* repositoryPath, virtual ReturnValue_t appendToFile(const char* repositoryPath,
const char* filename, const uint8_t* data, size_t size, const char* filename, const uint8_t* data, size_t size,
uint16_t packetNumber, void* args = nullptr) = 0; uint16_t packetNumber, FileSystemArgsIF* args = nullptr) = 0;
/** /**
* @brief Generic function to create a new file. * @brief Generic function to create a new file.
@ -72,7 +73,7 @@ public:
*/ */
virtual ReturnValue_t createFile(const char* repositoryPath, virtual ReturnValue_t createFile(const char* repositoryPath,
const char* filename, const uint8_t* data = nullptr, const char* filename, const uint8_t* data = nullptr,
size_t size = 0, void* args = nullptr) = 0; size_t size = 0, FileSystemArgsIF* args = nullptr) = 0;
/** /**
* @brief Generic function to delete a file. * @brief Generic function to delete a file.
@ -81,24 +82,30 @@ public:
* @param args Any other arguments which an implementation might require * @param args Any other arguments which an implementation might require
* @return * @return
*/ */
virtual ReturnValue_t deleteFile(const char* repositoryPath, virtual ReturnValue_t removeFile(const char* repositoryPath,
const char* filename, void* args = nullptr) = 0; const char* filename, FileSystemArgsIF* args = nullptr) = 0;
/** /**
* @brief Generic function to create a directory * @brief Generic function to create a directory
* @param repositoryPath * @param repositoryPath
* @param Equivalent to the -p flag in Unix systems. If some required parent directories
* do not exist, create them as well
* @param args Any other arguments which an implementation might require * @param args Any other arguments which an implementation might require
* @return * @return
*/ */
virtual ReturnValue_t createDirectory(const char* repositoryPath, void* args = nullptr) = 0; virtual ReturnValue_t createDirectory(const char* repositoryPath, const char* dirname,
bool createParentDirs, FileSystemArgsIF* args = nullptr) = 0;
/** /**
* @brief Generic function to remove a directory * @brief Generic function to remove a directory
* @param repositoryPath * @param repositoryPath
* @param args Any other arguments which an implementation might require * @param args Any other arguments which an implementation might require
*/ */
virtual ReturnValue_t removeDirectory(const char* repositoryPath, virtual ReturnValue_t removeDirectory(const char* repositoryPath, const char* dirname,
bool deleteRecurively = false, void* args = nullptr) = 0; bool deleteRecurively = false, FileSystemArgsIF* args = nullptr) = 0;
virtual ReturnValue_t renameFile(const char* repositoryPath, const char* oldFilename,
const char* newFilename, FileSystemArgsIF* args = nullptr) = 0;
}; };

View File

@ -73,7 +73,7 @@ namespace spacepacket {
constexpr uint16_t getSpacePacketIdFromApid(bool isTc, uint16_t apid, constexpr uint16_t getSpacePacketIdFromApid(bool isTc, uint16_t apid,
bool secondaryHeaderFlag = true) { bool secondaryHeaderFlag = true) {
return (((isTc << 5) & 0x10) | ((secondaryHeaderFlag << 4) & 0x08) | return ((isTc << 4) | (secondaryHeaderFlag << 3) |
((apid >> 8) & 0x07)) << 8 | (apid & 0x00ff); ((apid >> 8) & 0x07)) << 8 | (apid & 0x00ff);
} }

View File

@ -171,14 +171,19 @@ TEST_CASE("DataSetTest" , "[DataSetTest]") {
/* We can do it like this because the buffer only has one byte for /* We can do it like this because the buffer only has one byte for
less than 8 variables */ less than 8 variables */
uint8_t* validityByte = buffer + sizeof(buffer) - 1; uint8_t* validityByte = buffer + sizeof(buffer) - 1;
CHECK(bitutil::bitGet(validityByte, 0) == true); bool bitSet = false;
CHECK(bitutil::bitGet(validityByte, 1) == false); bitutil::get(validityByte, 0, bitSet);
CHECK(bitutil::bitGet(validityByte, 2) == true);
CHECK(bitSet == true);
bitutil::get(validityByte, 1, bitSet);
CHECK(bitSet == false);
bitutil::get(validityByte, 2, bitSet);
CHECK(bitSet == true);
/* Now we manipulate the validity buffer for the deserialization */ /* Now we manipulate the validity buffer for the deserialization */
bitutil::bitClear(validityByte, 0); bitutil::clear(validityByte, 0);
bitutil::bitSet(validityByte, 1); bitutil::set(validityByte, 1);
bitutil::bitClear(validityByte, 2); bitutil::clear(validityByte, 2);
/* Zero out everything except validity buffer */ /* Zero out everything except validity buffer */
std::memset(buffer, 0, sizeof(buffer) - 1); std::memset(buffer, 0, sizeof(buffer) - 1);
sizeToDeserialize = maxSize; sizeToDeserialize = maxSize;
@ -239,8 +244,11 @@ TEST_CASE("DataSetTest" , "[DataSetTest]") {
std::memcpy(validityBuffer.data(), buffer + 9 + sizeof(uint16_t) * 3, 2); std::memcpy(validityBuffer.data(), buffer + 9 + sizeof(uint16_t) * 3, 2);
/* The first 9 variables should be valid */ /* The first 9 variables should be valid */
CHECK(validityBuffer[0] == 0xff); CHECK(validityBuffer[0] == 0xff);
CHECK(bitutil::bitGet(validityBuffer.data() + 1, 0) == true); bool bitSet = false;
CHECK(bitutil::bitGet(validityBuffer.data() + 1, 1) == false); bitutil::get(validityBuffer.data() + 1, 0, bitSet);
CHECK(bitSet == true);
bitutil::get(validityBuffer.data() + 1, 1, bitSet);
CHECK(bitSet == false);
/* Now we invert the validity */ /* Now we invert the validity */
validityBuffer[0] = 0; validityBuffer[0] = 0;

View File

@ -1,3 +1,5 @@
target_sources(${FSFW_TEST_TGT} PRIVATE target_sources(${FSFW_TEST_TGT} PRIVATE
testDleEncoder.cpp testDleEncoder.cpp
testOpDivider.cpp
testBitutil.cpp
) )

View File

@ -0,0 +1,64 @@
#include "fsfw/globalfunctions/bitutility.h"
#include <catch2/catch_test_macros.hpp>
TEST_CASE("Bitutility" , "[Bitutility]") {
uint8_t dummyByte = 0;
bool bitSet = false;
for(uint8_t pos = 0; pos < 8; pos++) {
bitutil::set(&dummyByte, pos);
REQUIRE(dummyByte == (1 << (7 - pos)));
bitutil::get(&dummyByte, pos, bitSet);
REQUIRE(bitSet == 1);
dummyByte = 0;
}
dummyByte = 0xff;
for(uint8_t pos = 0; pos < 8; pos++) {
bitutil::get(&dummyByte, pos, bitSet);
REQUIRE(bitSet == 1);
bitutil::clear(&dummyByte, pos);
bitutil::get(&dummyByte, pos, bitSet);
REQUIRE(bitSet == 0);
dummyByte = 0xff;
}
dummyByte = 0xf0;
for(uint8_t pos = 0; pos < 8; pos++) {
if(pos < 4) {
bitutil::get(&dummyByte, pos, bitSet);
REQUIRE(bitSet == 1);
bitutil::toggle(&dummyByte, pos);
bitutil::get(&dummyByte, pos, bitSet);
REQUIRE(bitSet == 0);
}
else {
bitutil::get(&dummyByte, pos, bitSet);
REQUIRE(bitSet == false);
bitutil::toggle(&dummyByte, pos);
bitutil::get(&dummyByte, pos, bitSet);
REQUIRE(bitSet == true);
}
}
REQUIRE(dummyByte == 0x0f);
dummyByte = 0;
bitutil::set(&dummyByte, 8);
REQUIRE(dummyByte == 0);
bitutil::set(&dummyByte, -1);
REQUIRE(dummyByte == 0);
dummyByte = 0xff;
bitutil::clear(&dummyByte, 8);
REQUIRE(dummyByte == 0xff);
bitutil::clear(&dummyByte, -1);
REQUIRE(dummyByte == 0xff);
dummyByte = 0x00;
bitutil::toggle(&dummyByte, 8);
REQUIRE(dummyByte == 0x00);
bitutil::toggle(&dummyByte, -1);
REQUIRE(dummyByte == 0x00);
REQUIRE(bitutil::get(&dummyByte, 8, bitSet) == false);
}

View File

@ -0,0 +1,64 @@
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
#include <catch2/catch_test_macros.hpp>
TEST_CASE("OpDivider" , "[OpDivider]") {
auto opDivider = PeriodicOperationDivider(1);
REQUIRE(opDivider.getDivider() == 1);
REQUIRE(opDivider.getCounter() == 1);
REQUIRE(opDivider.check() == true);
REQUIRE(opDivider.checkAndIncrement() == true);
REQUIRE(opDivider.getCounter() == 1);
REQUIRE(opDivider.check() == true);
REQUIRE(opDivider.checkAndIncrement() == true);
REQUIRE(opDivider.checkAndIncrement() == true);
opDivider.setDivider(0);
REQUIRE(opDivider.getCounter() == 1);
REQUIRE(opDivider.checkAndIncrement() == true);
REQUIRE(opDivider.getCounter() == 1);
REQUIRE(opDivider.checkAndIncrement() == true);
REQUIRE(opDivider.checkAndIncrement() == true);
opDivider.setDivider(2);
opDivider.resetCounter();
REQUIRE(opDivider.getDivider() == 2);
REQUIRE(opDivider.getCounter() == 1);
REQUIRE(opDivider.check() == false);
REQUIRE(opDivider.checkAndIncrement() == false);
REQUIRE(opDivider.getCounter() == 2);
REQUIRE(opDivider.check() == true);
REQUIRE(opDivider.checkAndIncrement() == true);
REQUIRE(opDivider.getCounter() == 1);
REQUIRE(opDivider.check() == false);
REQUIRE(opDivider.checkAndIncrement() == false);
REQUIRE(opDivider.getCounter() == 2);
REQUIRE(opDivider.checkAndIncrement() == true);
REQUIRE(opDivider.checkAndIncrement() == false);
REQUIRE(opDivider.checkAndIncrement() == true);
REQUIRE(opDivider.checkAndIncrement() == false);
opDivider.setDivider(3);
opDivider.resetCounter();
REQUIRE(opDivider.checkAndIncrement() == false);
REQUIRE(opDivider.checkAndIncrement() == false);
REQUIRE(opDivider.getCounter() == 3);
REQUIRE(opDivider.checkAndIncrement() == true);
REQUIRE(opDivider.getCounter() == 1);
REQUIRE(opDivider.checkAndIncrement() == false);
auto opDividerNonResetting = PeriodicOperationDivider(2, false);
REQUIRE(opDividerNonResetting.getCounter() == 1);
REQUIRE(opDividerNonResetting.check() == false);
REQUIRE(opDividerNonResetting.checkAndIncrement() == false);
REQUIRE(opDividerNonResetting.getCounter() == 2);
REQUIRE(opDividerNonResetting.check() == true);
REQUIRE(opDividerNonResetting.checkAndIncrement() == true);
REQUIRE(opDividerNonResetting.getCounter() == 3);
REQUIRE(opDividerNonResetting.checkAndIncrement() == true);
REQUIRE(opDividerNonResetting.getCounter() == 4);
opDividerNonResetting.resetCounter();
REQUIRE(opDividerNonResetting.getCounter() == 1);
REQUIRE(opDividerNonResetting.check() == false);
REQUIRE(opDividerNonResetting.checkAndIncrement() == false);
REQUIRE(opDividerNonResetting.getCounter() == 2);
}

View File

@ -1,3 +1,3 @@
target_sources(${FSFW_TEST_TGT} PRIVATE target_sources(${FSFW_TEST_TGT} PRIVATE
PusTmTest.cpp testCcsds.cpp
) )

View File

@ -0,0 +1,11 @@
#include <catch2/catch_test_macros.hpp>
#include "fsfw/tmtcpacket/SpacePacket.h"
TEST_CASE( "CCSDS Test" , "[ccsds]") {
REQUIRE(spacepacket::getTcSpacePacketIdFromApid(0x22) == 0x1822);
REQUIRE(spacepacket::getTmSpacePacketIdFromApid(0x22) == 0x0822);
REQUIRE(spacepacket::getTcSpacePacketIdFromApid(0x7ff) == 0x1fff);
REQUIRE(spacepacket::getTmSpacePacketIdFromApid(0x7ff) == 0xfff);
}