refactoring to allow PUS c implementation

This commit is contained in:
Robin Müller 2021-04-12 21:17:53 +02:00
parent d7d52439d7
commit 9a5f717169
10 changed files with 398 additions and 234 deletions

View File

@ -5,4 +5,6 @@ target_sources(${LIB_FSFW_NAME}
TmPacketBase.cpp TmPacketBase.cpp
TmPacketMinimal.cpp TmPacketMinimal.cpp
TmPacketStored.cpp TmPacketStored.cpp
TmPacketPusA.cpp
TmPacketPusC.cpp
) )

View File

@ -11,35 +11,22 @@
TimeStamperIF* TmPacketBase::timeStamper = nullptr; TimeStamperIF* TmPacketBase::timeStamper = nullptr;
object_id_t TmPacketBase::timeStamperId = 0; object_id_t TmPacketBase::timeStamperId = 0;
TmPacketBase::TmPacketBase(uint8_t* setData) : TmPacketBase::TmPacketBase(uint8_t* setData):
SpacePacketBase(setData) { SpacePacketBase(setData) {
tmData = reinterpret_cast<TmPacketPointer*>(setData);
} }
TmPacketBase::~TmPacketBase() { TmPacketBase::~TmPacketBase() {
//Nothing to do. //Nothing to do.
} }
uint8_t TmPacketBase::getService() {
return tmData->data_field.service_type;
}
uint8_t TmPacketBase::getSubService() {
return tmData->data_field.service_subtype;
}
uint8_t* TmPacketBase::getSourceData() {
return &tmData->data;
}
uint16_t TmPacketBase::getSourceDataSize() { uint16_t TmPacketBase::getSourceDataSize() {
return getPacketDataLength() - sizeof(tmData->data_field) return getPacketDataLength() - getDataFieldSize() - CRC_SIZE + 1;
- CRC_SIZE + 1;
} }
uint16_t TmPacketBase::getErrorControl() { uint16_t TmPacketBase::getErrorControl() {
uint32_t size = getSourceDataSize() + CRC_SIZE; uint32_t size = getSourceDataSize() + CRC_SIZE;
uint8_t* p_to_buffer = &tmData->data; uint8_t* p_to_buffer = getSourceData();
return (p_to_buffer[size - 2] << 8) + p_to_buffer[size - 1]; return (p_to_buffer[size - 2] << 8) + p_to_buffer[size - 1];
} }
@ -51,10 +38,7 @@ void TmPacketBase::setErrorControl() {
getSourceData()[size + 1] = (crc) & 0X00FF; // CRCL getSourceData()[size + 1] = (crc) & 0X00FF; // CRCL
} }
void TmPacketBase::setData(const uint8_t* p_Data) {
SpacePacketBase::setData(p_Data);
tmData = (TmPacketPointer*) p_Data;
}
void TmPacketBase::print() { void TmPacketBase::print() {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
@ -77,45 +61,3 @@ bool TmPacketBase::checkAndSetStamper() {
return true; return true;
} }
ReturnValue_t TmPacketBase::getPacketTime(timeval* timestamp) const {
size_t tempSize = 0;
return CCSDSTime::convertFromCcsds(timestamp, tmData->data_field.time,
&tempSize, sizeof(tmData->data_field.time));
}
uint8_t* TmPacketBase::getPacketTimeRaw() const{
return tmData->data_field.time;
}
void TmPacketBase::initializeTmPacket(uint16_t apid, uint8_t service,
uint8_t subservice, uint8_t packetSubcounter) {
//Set primary header:
initSpacePacketHeader(false, true, apid);
//Set data Field Header:
//First, set to zero.
memset(&tmData->data_field, 0, sizeof(tmData->data_field));
// NOTE: In PUS-C, the PUS Version is 2 and specified for the first 4 bits.
// The other 4 bits of the first byte are the spacecraft time reference
// status. To change to PUS-C, set 0b00100000.
// Set CCSDS_secondary header flag to 0, version number to 001 and ack
// to 0000
tmData->data_field.version_type_ack = 0b00010000;
tmData->data_field.service_type = service;
tmData->data_field.service_subtype = subservice;
tmData->data_field.subcounter = packetSubcounter;
//Timestamp packet
if (checkAndSetStamper()) {
timeStamper->addTimeStamp(tmData->data_field.time,
sizeof(tmData->data_field.time));
}
}
void TmPacketBase::setSourceDataSize(uint16_t size) {
setPacketDataLength(size + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1);
}
size_t TmPacketBase::getTimestampSize() const {
return sizeof(tmData->data_field.time);
}

View File

@ -10,32 +10,6 @@ namespace Factory{
void setStaticFrameworkObjectIds(); void setStaticFrameworkObjectIds();
} }
/**
* This struct defines a byte-wise structured PUS TM Data Field Header.
* Any optional fields in the header must be added or removed here.
* Currently, no Destination field is present, but an eigth-byte representation
* for a time tag.
* @ingroup tmtcpackets
*/
struct PUSTmDataFieldHeader {
uint8_t version_type_ack;
uint8_t service_type;
uint8_t service_subtype;
uint8_t subcounter;
// uint8_t destination;
uint8_t time[TimeStamperIF::MISSION_TIMESTAMP_SIZE];
};
/**
* This struct defines the data structure of a PUS Telecommand Packet when
* accessed via a pointer.
* @ingroup tmtcpackets
*/
struct TmPacketPointer {
CCSDSPrimaryHeader primary;
PUSTmDataFieldHeader data_field;
uint8_t data;
};
/** /**
* This class is the basic data handler for any ECSS PUS Telemetry packet. * This class is the basic data handler for any ECSS PUS Telemetry packet.
@ -51,11 +25,7 @@ struct TmPacketPointer {
class TmPacketBase : public SpacePacketBase { class TmPacketBase : public SpacePacketBase {
friend void (Factory::setStaticFrameworkObjectIds)(); friend void (Factory::setStaticFrameworkObjectIds)();
public: public:
/**
* This constant defines the minimum size of a valid PUS Telemetry Packet.
*/
static const uint32_t TM_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) +
sizeof(PUSTmDataFieldHeader) + 2);
//! Maximum size of a TM Packet in this mission. //! Maximum size of a TM Packet in this mission.
//! TODO: Make this dependant on a config variable. //! TODO: Make this dependant on a config variable.
static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048; static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048;
@ -80,13 +50,13 @@ public:
* byte of the Data Field Header. * byte of the Data Field Header.
* @return The packet's PUS Service ID. * @return The packet's PUS Service ID.
*/ */
uint8_t getService(); virtual uint8_t getService() = 0;
/** /**
* This is a getter for the packet's PUS Service Subtype, which is the * This is a getter for the packet's PUS Service Subtype, which is the
* third byte of the Data Field Header. * third byte of the Data Field Header.
* @return The packet's PUS Service Subtype. * @return The packet's PUS Service Subtype.
*/ */
uint8_t getSubService(); virtual uint8_t getSubService() = 0;
/** /**
* This is a getter for a pointer to the packet's Source data. * This is a getter for a pointer to the packet's Source data.
* *
@ -94,7 +64,7 @@ public:
* the packet's source data. * the packet's source data.
* @return A pointer to the PUS Source Data. * @return A pointer to the PUS Source Data.
*/ */
uint8_t* getSourceData(); virtual uint8_t* getSourceData() = 0;
/** /**
* This method calculates the size of the PUS Source data field. * This method calculates the size of the PUS Source data field.
* *
@ -102,8 +72,35 @@ public:
* and subtracts the Data Field Header size and the CRC size. * and subtracts the Data Field Header size and the CRC size.
* @return The size of the PUS Source Data (without Error Control field) * @return The size of the PUS Source Data (without Error Control field)
*/ */
uint16_t getSourceDataSize(); virtual uint16_t getSourceDataSize() = 0;
/**
* Get size of data field which can differ based on implementation
* @return
*/
virtual uint16_t getDataFieldSize() = 0;
virtual size_t getPacketMinimumSize() const = 0;
/**
* Interprets the "time"-field in the secondary header and returns it in
* timeval format.
* @return Converted timestamp of packet.
*/
virtual ReturnValue_t getPacketTime(timeval* timestamp) const = 0;
/**
* Returns a raw pointer to the beginning of the time field.
* @return Raw pointer to time field.
*/
virtual uint8_t* getPacketTimeRaw() const = 0;
virtual size_t getTimestampSize() const = 0;
/**
* This is a debugging helper method that prints the whole packet content
* to the screen.
*/
void print();
/** /**
* With this method, the Error Control Field is updated to match the * With this method, the Error Control Field is updated to match the
* current content of the packet. This method is not protected because * current content of the packet. This method is not protected because
@ -111,7 +108,6 @@ public:
* like the sequence count. * like the sequence count.
*/ */
void setErrorControl(); void setErrorControl();
/** /**
* This getter returns the Error Control Field of the packet. * This getter returns the Error Control Field of the packet.
* *
@ -122,33 +118,7 @@ public:
*/ */
uint16_t getErrorControl(); uint16_t getErrorControl();
/**
* This is a debugging helper method that prints the whole packet content
* to the screen.
*/
void print();
/**
* Interprets the "time"-field in the secondary header and returns it in
* timeval format.
* @return Converted timestamp of packet.
*/
ReturnValue_t getPacketTime(timeval* timestamp) const;
/**
* Returns a raw pointer to the beginning of the time field.
* @return Raw pointer to time field.
*/
uint8_t* getPacketTimeRaw() const;
size_t getTimestampSize() const;
protected: protected:
/**
* A pointer to a structure which defines the data structure of
* the packet's data.
*
* To be hardware-safe, all elements are of byte size.
*/
TmPacketPointer* tmData;
/** /**
* The timeStamper is responsible for adding a timestamp to the packet. * The timeStamper is responsible for adding a timestamp to the packet.
* It is initialized lazy. * It is initialized lazy.
@ -157,34 +127,6 @@ protected:
//! The ID to use when looking for a time stamper. //! The ID to use when looking for a time stamper.
static object_id_t timeStamperId; static object_id_t timeStamperId;
/**
* Initializes the Tm Packet header.
* Does set the timestamp (to now), but not the error control field.
* @param apid APID used.
* @param service PUS Service
* @param subservice PUS Subservice
* @param packetSubcounter Additional subcounter used.
*/
void initializeTmPacket(uint16_t apid, uint8_t service, uint8_t subservice,
uint8_t packetSubcounter);
/**
* With this method, the packet data pointer can be redirected to another
* location.
*
* This call overwrites the parent's setData method to set both its
* @c tc_data pointer and the parent's @c data pointer.
*
* @param p_data A pointer to another PUS Telemetry Packet.
*/
void setData( const uint8_t* pData );
/**
* In case data was filled manually (almost never the case).
* @param size Size of source data (without CRC and data filed header!).
*/
void setSourceDataSize(uint16_t size);
/** /**
* Checks if a time stamper is available and tries to set it if not. * Checks if a time stamper is available and tries to set it if not.
* @return Returns false if setting failed. * @return Returns false if setting failed.

View File

@ -0,0 +1,8 @@
#ifndef FSFW_TMTCPACKET_PUS_TMPACKETIF_H_
#define FSFW_TMTCPACKET_PUS_TMPACKETIF_H_
#endif /* FSFW_TMTCPACKET_PUS_TMPACKETIF_H_ */

View File

@ -0,0 +1,121 @@
#include "TmPacketPusA.h"
#include "TmPacketBase.h"
#include "../../globalfunctions/CRC.h"
#include "../../globalfunctions/arrayprinter.h"
#include "../../objectmanager/ObjectManagerIF.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../timemanager/CCSDSTime.h"
#include <cstring>
TmPacketPusA::TmPacketPusA(uint8_t* setData) : TmPacketBase(setData) {
tmData = reinterpret_cast<TmPacketPointer*>(setData);
}
TmPacketPusA::~TmPacketPusA() {
//Nothing to do.
}
uint8_t TmPacketPusA::getService() {
return tmData->data_field.service_type;
}
uint8_t TmPacketPusA::getSubService() {
return tmData->data_field.service_subtype;
}
uint8_t* TmPacketPusA::getSourceData() {
return &tmData->data;
}
uint16_t TmPacketPusA::getSourceDataSize() {
return getPacketDataLength() - sizeof(tmData->data_field)
- CRC_SIZE + 1;
}
//uint16_t TmPacketPusA::getErrorControl() {
// uint32_t size = getSourceDataSize() + CRC_SIZE;
// uint8_t* p_to_buffer = &tmData->data;
// return (p_to_buffer[size - 2] << 8) + p_to_buffer[size - 1];
//}
//
//void TmPacketPusA::setErrorControl() {
// uint32_t full_size = getFullSize();
// uint16_t crc = CRC::crc16ccitt(getWholeData(), full_size - CRC_SIZE);
// uint32_t size = getSourceDataSize();
// getSourceData()[size] = (crc & 0XFF00) >> 8; // CRCH
// getSourceData()[size + 1] = (crc) & 0X00FF; // CRCL
//}
void TmPacketPusA::setData(const uint8_t* p_Data) {
SpacePacketBase::setData(p_Data);
tmData = (TmPacketPointer*) p_Data;
}
size_t TmPacketPusA::getPacketMinimumSize() const {
return TM_PACKET_MIN_SIZE;
}
uint16_t TmPacketPusA::getDataFieldSize() {
return sizeof(PUSTmDataFieldHeader);
}
bool TmPacketPusA::checkAndSetStamper() {
if (timeStamper == NULL) {
timeStamper = objectManager->get<TimeStamperIF>(timeStamperId);
if (timeStamper == NULL) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "TmPacketPusA::checkAndSetStamper: Stamper not found!"
<< std::endl;
#endif
return false;
}
}
return true;
}
ReturnValue_t TmPacketPusA::getPacketTime(timeval* timestamp) const {
size_t tempSize = 0;
return CCSDSTime::convertFromCcsds(timestamp, tmData->data_field.time,
&tempSize, sizeof(tmData->data_field.time));
}
uint8_t* TmPacketPusA::getPacketTimeRaw() const{
return tmData->data_field.time;
}
void TmPacketPusA::initializeTmPacket(uint16_t apid, uint8_t service,
uint8_t subservice, uint8_t packetSubcounter) {
//Set primary header:
initSpacePacketHeader(false, true, apid);
//Set data Field Header:
//First, set to zero.
memset(&tmData->data_field, 0, sizeof(tmData->data_field));
// NOTE: In PUS-C, the PUS Version is 2 and specified for the first 4 bits.
// The other 4 bits of the first byte are the spacecraft time reference
// status. To change to PUS-C, set 0b00100000.
// Set CCSDS_secondary header flag to 0, version number to 001 and ack
// to 0000
tmData->data_field.version_type_ack = 0b00010000;
tmData->data_field.service_type = service;
tmData->data_field.service_subtype = subservice;
tmData->data_field.subcounter = packetSubcounter;
//Timestamp packet
if (checkAndSetStamper()) {
timeStamper->addTimeStamp(tmData->data_field.time,
sizeof(tmData->data_field.time));
}
}
void TmPacketPusA::setSourceDataSize(uint16_t size) {
setPacketDataLength(size + sizeof(PUSTmDataFieldHeader) + CRC_SIZE - 1);
}
size_t TmPacketPusA::getTimestampSize() const {
return sizeof(tmData->data_field.time);
}

View File

@ -0,0 +1,137 @@
#ifndef FSFW_TMTCPACKET_PUS_TMPACKETPUSA_H_
#define FSFW_TMTCPACKET_PUS_TMPACKETPUSA_H_
#include "TmPacketBase.h"
#include "../SpacePacketBase.h"
#include "../../timemanager/TimeStamperIF.h"
#include "../../timemanager/Clock.h"
#include "../../objectmanager/SystemObjectIF.h"
namespace Factory{
void setStaticFrameworkObjectIds();
}
/**
* This struct defines a byte-wise structured PUS TM Data Field Header.
* Any optional fields in the header must be added or removed here.
* Currently, no Destination field is present, but an eigth-byte representation
* for a time tag.
* @ingroup tmtcpackets
*/
struct PUSTmDataFieldHeader {
uint8_t version_type_ack;
uint8_t service_type;
uint8_t service_subtype;
uint8_t subcounter;
// uint8_t destination;
uint8_t time[TimeStamperIF::MISSION_TIMESTAMP_SIZE];
};
/**
* This struct defines the data structure of a PUS Telecommand Packet when
* accessed via a pointer.
* @ingroup tmtcpackets
*/
struct TmPacketPointer {
CCSDSPrimaryHeader primary;
PUSTmDataFieldHeader data_field;
uint8_t data;
};
/**
* PUS A packet implementation
* @ingroup tmtcpackets
*/
class TmPacketPusA: public TmPacketBase {
friend void (Factory::setStaticFrameworkObjectIds)();
public:
/**
* This constant defines the minimum size of a valid PUS Telemetry Packet.
*/
static const uint32_t TM_PACKET_MIN_SIZE = (sizeof(CCSDSPrimaryHeader) +
sizeof(PUSTmDataFieldHeader) + 2);
//! Maximum size of a TM Packet in this mission.
//! TODO: Make this dependant on a config variable.
static const uint32_t MISSION_TM_PACKET_MAX_SIZE = 2048;
//! First byte of secondary header for PUS-A packets.
//! TODO: Maybe also support PUS-C via config?
static const uint8_t VERSION_NUMBER_BYTE_PUS_A = 0b00010000;
/**
* This is the default constructor.
* It sets its internal data pointer to the address passed and also
* forwards the data pointer to the parent SpacePacketBase class.
* @param set_address The position where the packet data lies.
*/
TmPacketPusA( uint8_t* setData );
/**
* This is the empty default destructor.
*/
virtual ~TmPacketPusA();
/* TmPacketBase implementations */
uint8_t getService() override;
uint8_t getSubService() override;
uint8_t* getSourceData() override;
uint16_t getSourceDataSize() override;
uint16_t getDataFieldSize() override;
/**
* Interprets the "time"-field in the secondary header and returns it in
* timeval format.
* @return Converted timestamp of packet.
*/
ReturnValue_t getPacketTime(timeval* timestamp) const override;
/**
* Returns a raw pointer to the beginning of the time field.
* @return Raw pointer to time field.
*/
uint8_t* getPacketTimeRaw() const override;
size_t getTimestampSize() const override;
size_t getPacketMinimumSize() const override;
protected:
/**
* A pointer to a structure which defines the data structure of
* the packet's data.
*
* To be hardware-safe, all elements are of byte size.
*/
TmPacketPointer* tmData;
/**
* Initializes the Tm Packet header.
* Does set the timestamp (to now), but not the error control field.
* @param apid APID used.
* @param service PUS Service
* @param subservice PUS Subservice
* @param packetSubcounter Additional subcounter used.
*/
void initializeTmPacket(uint16_t apid, uint8_t service, uint8_t subservice,
uint8_t packetSubcounter);
/**
* With this method, the packet data pointer can be redirected to another
* location.
*
* This call overwrites the parent's setData method to set both its
* @c tc_data pointer and the parent's @c data pointer.
*
* @param p_data A pointer to another PUS Telemetry Packet.
*/
void setData( const uint8_t* pData );
/**
* In case data was filled manually (almost never the case).
* @param size Size of source data (without CRC and data filed header!).
*/
void setSourceDataSize(uint16_t size);
/**
* Checks if a time stamper is available and tries to set it if not.
* @return Returns false if setting failed.
*/
bool checkAndSetStamper();
};
#endif /* FSFW_TMTCPACKET_PUS_TMPACKETPUSA_H_ */

View File

@ -0,0 +1,2 @@
#include "TmPacketPusC.h"

View File

@ -0,0 +1,8 @@
#ifndef FSFW_TMTCPACKET_PUS_TMPACKETPUSC_H_
#define FSFW_TMTCPACKET_PUS_TMPACKETPUSC_H_
#endif /* FSFW_TMTCPACKET_PUS_TMPACKETPUSC_H_ */

View File

@ -10,21 +10,21 @@ StorageManagerIF *TmPacketStored::store = nullptr;
InternalErrorReporterIF *TmPacketStored::internalErrorReporter = nullptr; InternalErrorReporterIF *TmPacketStored::internalErrorReporter = nullptr;
TmPacketStored::TmPacketStored(store_address_t setAddress) : TmPacketStored::TmPacketStored(store_address_t setAddress) :
TmPacketBase(nullptr), storeAddress(setAddress) { TmPacketPusA(nullptr), storeAddress(setAddress) {
setStoreAddress(storeAddress); setStoreAddress(storeAddress);
} }
TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service,
uint8_t subservice, uint8_t packetSubcounter, const uint8_t *data, uint8_t subservice, uint8_t packetSubcounter, const uint8_t *data,
uint32_t size, const uint8_t *headerData, uint32_t headerSize) : uint32_t size, const uint8_t *headerData, uint32_t headerSize) :
TmPacketBase(NULL) { TmPacketPusA(nullptr) {
storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
if (not checkAndSetStore()) { if (not checkAndSetStore()) {
return; return;
} }
uint8_t *pData = nullptr; uint8_t *pData = nullptr;
ReturnValue_t returnValue = store->getFreeElement(&storeAddress, ReturnValue_t returnValue = store->getFreeElement(&storeAddress,
(TmPacketBase::TM_PACKET_MIN_SIZE + size + headerSize), &pData); (getPacketMinimumSize() + size + headerSize), &pData);
if (returnValue != store->RETURN_OK) { if (returnValue != store->RETURN_OK) {
checkAndReportLostTm(); checkAndReportLostTm();
@ -41,7 +41,7 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service,
TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service, TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service,
uint8_t subservice, uint8_t packetSubcounter, SerializeIF *content, uint8_t subservice, uint8_t packetSubcounter, SerializeIF *content,
SerializeIF *header) : SerializeIF *header) :
TmPacketBase(NULL) { TmPacketPusA(nullptr) {
storeAddress.raw = StorageManagerIF::INVALID_ADDRESS; storeAddress.raw = StorageManagerIF::INVALID_ADDRESS;
if (not checkAndSetStore()) { if (not checkAndSetStore()) {
return; return;
@ -55,7 +55,7 @@ TmPacketStored::TmPacketStored(uint16_t apid, uint8_t service,
} }
uint8_t *p_data = NULL; uint8_t *p_data = NULL;
ReturnValue_t returnValue = store->getFreeElement(&storeAddress, ReturnValue_t returnValue = store->getFreeElement(&storeAddress,
(TmPacketBase::TM_PACKET_MIN_SIZE + sourceDataSize), &p_data); (getPacketMinimumSize() + sourceDataSize), &p_data);
if (returnValue != store->RETURN_OK) { if (returnValue != store->RETURN_OK) {
checkAndReportLostTm(); checkAndReportLostTm();
} }

View File

@ -2,7 +2,9 @@
#define FSFW_TMTCPACKET_PUS_TMPACKETSTORED_H_ #define FSFW_TMTCPACKET_PUS_TMPACKETSTORED_H_
#include "TmPacketBase.h" #include "TmPacketBase.h"
#include <FSFWConfig.h>
#include "../../tmtcpacket/pus/TmPacketPusA.h"
#include "../../serialize/SerializeIF.h" #include "../../serialize/SerializeIF.h"
#include "../../storagemanager/StorageManagerIF.h" #include "../../storagemanager/StorageManagerIF.h"
#include "../../internalError/InternalErrorReporterIF.h" #include "../../internalError/InternalErrorReporterIF.h"
@ -18,7 +20,7 @@
* packets in a store with the help of a storeAddress. * packets in a store with the help of a storeAddress.
* @ingroup tmtcpackets * @ingroup tmtcpackets
*/ */
class TmPacketStored : public TmPacketBase { class TmPacketStored : public TmPacketPusA {
public: public:
/** /**
* This is a default constructor which does not set the data pointer. * This is a default constructor which does not set the data pointer.