ccsds handler wip
This commit is contained in:
parent
e2c26efe4a
commit
d54e2276d6
@ -90,6 +90,16 @@ static constexpr uint32_t SPI_MUX_BIT_5 = 17;
|
||||
static constexpr uint32_t SPI_MUX_BIT_6 = 9;
|
||||
static constexpr uint32_t EN_RW_CS = 17;
|
||||
|
||||
static constexpr char GPIO_VC_STATUS_SIGNALS_LABEL[] = "/amba_pl/gpio@81200000";
|
||||
static constexpr uint32_t VC0_PAPB_EMPTY_LINE = 0;
|
||||
static constexpr uint32_t VC0_PAPB_BUSY_LINE = 1;
|
||||
static constexpr uint32_t VC1_PAPB_EMPTY_LINE = 2;
|
||||
static constexpr uint32_t VC1_PAPB_BUSY_LINE = 3;
|
||||
static constexpr uint32_t VC2_PAPB_EMPTY_LINE = 4;
|
||||
static constexpr uint32_t VC2_PAPB_BUSY_LINE = 5;
|
||||
static constexpr uint32_t VC3_PAPB_EMPTY_LINE = 6;
|
||||
static constexpr uint32_t VC3_PAPB_BUSY_LINE = 7;
|
||||
|
||||
}
|
||||
|
||||
#endif /* BSP_Q7S_BOARDCONFIG_BUSCONF_H_ */
|
||||
|
@ -173,25 +173,55 @@ void ObjectFactory::produce(void* args) {
|
||||
|
||||
#endif /* TE7020 != 0 */
|
||||
|
||||
#if OBSW_USE_PTME_IP_CORE == 1
|
||||
GpioCookie* gpioCookiePtmeIp = new GpioCookie;
|
||||
GpiodRegular* vc0PapbBusyN = new GpiodRegular(std::string("gpiochip0"), 0, std::string("PAPBBusy_N"));
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::PAPB_BUSY_N, papbBusyN);
|
||||
GpiodRegular* vc0PapbEmpty = new GpiodRegular(st_d::string("gpiochip0"), 1,
|
||||
std::string("PAPBEmpty_VC0"));
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::PAPB_EMPTY, papbEmpty);
|
||||
gpioComIF->addGpios(gpioCookiePtmeIp);
|
||||
PapbVcInterface* vc0 = new PapbVcInterface(objects::PAPB_VC0, gpioComIF, )
|
||||
Ptme* ptme = new Ptme(objects::PTME);
|
||||
ptme->addVcInterface(0, vc0);
|
||||
ptme->addVcInterface(1, vc1);
|
||||
ptme->addVcInterface(2, vc2);
|
||||
ptme->addVcInterface(3, vc3);
|
||||
#if OBSW_USE_CCSDS_IP_CORE == 1
|
||||
|
||||
new CCSDSIPCoreBridge(objects::CCSDS_IP_CORE_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR,
|
||||
objects::TM_STORE, objects::TC_STORE, gpioComIF, std::string("/dev/uio0"),
|
||||
gpioIds::PAPB_BUSY_N, gpioIds::PAPB_EMPTY);
|
||||
#endif /* OBSW_USE_TMTC_IP_CORE_BRIDGE == 1 */
|
||||
// GPIO definitions of signals connected to the virtual channel interfaces of the PTME IP Core
|
||||
GpioCookie* gpioCookiePtmeIp = new GpioCookie;
|
||||
GpiodRegular* vcSignal = new GpiodRegular("PAPB VC0 Busy Signal",
|
||||
q7s::GPIO_VC_STATUS_SIGNALS_LABEL, q7s::VC0_PAPB_BUSY_LINE);
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_BUSY, vcSignal);
|
||||
vcSignal = new GpiodRegular("PAPB VC0 Empty Signal", q7s::GPIO_VC_STATUS_SIGNALS_LABEL,
|
||||
q7s::VC0_PAPB_EMPTY_LINE);
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::VC0_PAPB_EMPTY, vcSignal);
|
||||
vcSignal = new GpiodRegular("PAPB VC1 Busy Signal", q7s::GPIO_VC_STATUS_SIGNALS_LABEL,
|
||||
q7s::VC1_PAPB_BUSY_LINE);
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_BUSY, vcSignal);
|
||||
vcSignal = new GpiodRegular("PAPB VC1 Empty Signal", q7s::GPIO_VC_STATUS_SIGNALS_LABEL,
|
||||
q7s::VC1_PAPB_EMPTY_LINE);
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::VC1_PAPB_EMPTY, vcSignal);
|
||||
vcSignal = new GpiodRegular("PAPB VC2 Busy Signal", q7s::GPIO_VC_STATUS_SIGNALS_LABEL,
|
||||
q7s::VC2_PAPB_BUSY_LINE);
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_BUSY, vcSignal);
|
||||
vcSignal = new GpiodRegular("PAPB VC2 Empty Signal", q7s::GPIO_VC_STATUS_SIGNALS_LABEL,
|
||||
q7s::VC2_PAPB_EMPTY_LINE);
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::VC2_PAPB_EMPTY, vcSignal);
|
||||
vcSignal = new GpiodRegular("PAPB VC3 Busy Signal", q7s::GPIO_VC_STATUS_SIGNALS_LABEL,
|
||||
q7s::VC3_PAPB_BUSY_LINE);
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_BUSY, vcSignal);
|
||||
vcSignal = new GpiodRegular("PAPB VC3 Empty Signal", q7s::GPIO_VC_STATUS_SIGNALS_LABEL,
|
||||
q7s::VC3_PAPB_EMPTY_LINE);
|
||||
gpioCookiePtmeIp->addGpio(gpioIds::VC3_PAPB_EMPTY, vcSignal);
|
||||
|
||||
gpioComIF->addGpios(gpioCookiePtmeIp);
|
||||
|
||||
// Creating virtual channel interfaces
|
||||
PapbVcInterface* vc = new PapbVcInterface(objects::PAPB_VC0, gpioComIF, gpioIds::VC0_PAPB_BUSY,
|
||||
gpioIds::VC0_PAPB_EMPTY);
|
||||
PapbVcInterface* vc = new PapbVcInterface(objects::PAPB_VC1, gpioComIF, gpioIds::VC1_PAPB_BUSY,
|
||||
gpioIds::VC1_PAPB_EMPTY);
|
||||
PapbVcInterface* vc = new PapbVcInterface(objects::PAPB_VC2, gpioComIF, gpioIds::VC2_PAPB_BUSY,
|
||||
gpioIds::VC2_PAPB_EMPTY);
|
||||
PapbVcInterface* vc = new PapbVcInterface(objects::PAPB_VC3, gpioComIF, gpioIds::VC3_PAPB_BUSY,
|
||||
gpioIds::VC3_PAPB_EMPTY);
|
||||
|
||||
// Creating ptme object and adding virtual channel interfaces
|
||||
Ptme* ptme = new Ptme(objects::PTME);
|
||||
ptme->addVcInterface(0, vc);
|
||||
ptme->addVcInterface(1, vc);
|
||||
ptme->addVcInterface(2, vc);
|
||||
ptme->addVcInterface(3, vc);
|
||||
|
||||
#endif /* OBSW_USE_CCSDS_IP_CORE == 1 */
|
||||
|
||||
#if OBSW_USE_TMTC_TCP_BRIDGE == 0
|
||||
auto udpBridge = new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||
|
@ -8,7 +8,7 @@
|
||||
#define OBSW_USE_TMTC_TCP_BRIDGE 1
|
||||
// This will cause the OBSW to initialize the TMTC bridge responsible for exchanging data with the
|
||||
// CCSDS IP Cores.
|
||||
#define OBSW_USE_TMTC_IP_CORE_BRIDGE 0
|
||||
#define OBSW_USE_CCSDS_IP_CORE 1
|
||||
// Set to 1 if all telemetry should be sent to the PTME IP Core
|
||||
#define OBSW_TM_TO_PTME 0
|
||||
// Set to 1 if telecommands are received via the PDEC IP Core
|
||||
|
@ -13,9 +13,9 @@ enum commonObjects: uint32_t {
|
||||
FILE_SYSTEM_HANDLER = 0x50000500,
|
||||
PTME = 0x50000600,
|
||||
PAPB_VC0 = 0x50000700,
|
||||
PAPB_VC0 = 0x500007001,
|
||||
PAPB_VC0 = 0x500007002,
|
||||
PAPB_VC0 = 0x500007003,
|
||||
PAPB_VC1 = 0x500007001,
|
||||
PAPB_VC2 = 0x500007002,
|
||||
PAPB_VC3 = 0x500007003,
|
||||
|
||||
/* 0x43 ('C') for Controllers */
|
||||
THERMAL_CONTROLLER = 0x43400001,
|
||||
|
@ -89,7 +89,16 @@ enum gpioId_t {
|
||||
|
||||
EN_RW_CS,
|
||||
|
||||
SPI_MUX
|
||||
SPI_MUX,
|
||||
|
||||
VC0_PAPB_EMPTY,
|
||||
VC0_PAPB_BUSY,
|
||||
VC1_PAPB_EMPTY,
|
||||
VC1_PAPB_BUSY,
|
||||
VC2_PAPB_EMPTY,
|
||||
VC2_PAPB_BUSY,
|
||||
VC3_PAPB_EMPTY,
|
||||
VC3_PAPB_BUSY
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -53,12 +53,12 @@ ReturnValue_t PapbVcInterface::pollPapbBusySignal() {
|
||||
/** Check if PAPB interface is ready to receive data */
|
||||
result = gpioComIF->readGpio(papbBusyId, &papbBusyState);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PapbVcInterface::pollPapbBusySignal: Failed to read papb busy signal"
|
||||
sif::warning << "PapbVcInterface::pollPapbBusySignal: Failed to read papb busy signal"
|
||||
<< std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
if (!papbBusyState) {
|
||||
sif::debug << "PapbVcInterface::pollPapbBusySignal: PAPB busy" << std::endl;
|
||||
sif::warning << "PapbVcInterface::pollPapbBusySignal: PAPB busy" << std::endl;
|
||||
return PAPB_BUSY;
|
||||
}
|
||||
|
||||
@ -72,7 +72,7 @@ void PapbVcInterface::isVcInterfaceBufferEmpty() {
|
||||
result = gpioComIF->readGpio(papbEmptyId, &papbEmptyState);
|
||||
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PapbVcInterface::isVcInterfaceBufferEmpty: Failed to read papb empty signal"
|
||||
sif::warning << "PapbVcInterface::isVcInterfaceBufferEmpty: Failed to read papb empty signal"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
|
@ -1,13 +1,3 @@
|
||||
/*******************************
|
||||
* FLP Flight Software Framework (FSFW)
|
||||
* (c) 2016 IRS, Uni Stuttgart
|
||||
*******************************/
|
||||
/*
|
||||
* CCSDSHandler.cpp
|
||||
*
|
||||
* Created on: Feb 9, 2012
|
||||
* Author: baetz
|
||||
*/
|
||||
#include <framework/devicehandlers/DeviceHandlerIF.h>
|
||||
#include <framework/objectmanager/ObjectManagerIF.h>
|
||||
#include <framework/rmap/RMAPChannelIF.h>
|
||||
@ -121,9 +111,30 @@ ReturnValue_t CCSDSHandler::packetProcessingCheck(void) {
|
||||
|
||||
ReturnValue_t CCSDSHandler::performOperation(void) {
|
||||
readCommandQueue();
|
||||
handleTelemetry();
|
||||
handleTelecommands();
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void CCSDSHandler::addVirtualChannel(VcId_t virtualChannelId, VirtualChannel* virtualChannel) {
|
||||
auto status = virtualChannelMap.emplace(virtualChannelId, virtualChannel);
|
||||
if (status.second == false) {
|
||||
sif::warning << "CCSDSHandler::addVcInterface: Failed to add virtual channel with virtual "
|
||||
<< "channel id " << static_cast<unsigned int>(virtualChannelId) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void CCSDSHandler::handleTelemetry() {
|
||||
VirtualChannelMapIter iter;
|
||||
for (iter = virtualChannelMap.begin(); iter != VirtualChannelMap.end(); iter++) {
|
||||
iter->second.virtualChannel->performOperation();
|
||||
}
|
||||
}
|
||||
|
||||
void CCSDSHandler::handleTelecommands() {
|
||||
|
||||
}
|
||||
|
||||
void CCSDSHandler::searchFrame() {
|
||||
frameLength = this->boardHandler.findFrame();
|
||||
while (frameLength != 0) {
|
||||
@ -198,8 +209,9 @@ ReturnValue_t CCSDSHandler::initialize() {
|
||||
void CCSDSHandler::readCommandQueue(void) {
|
||||
CommandMessage commandMessage;
|
||||
ReturnValue_t result = RETURN_FAILED;
|
||||
while (commandQueue.receiveMessage(&commandMessage) == RETURN_OK) {
|
||||
|
||||
result = commandQueue.receiveMessage(&commandMessage);
|
||||
if (result == RETURN_OK) {
|
||||
result = parameterHelper.handleParameterMessage(&commandMessage);
|
||||
if (result == RETURN_OK) {
|
||||
return;
|
||||
@ -486,120 +498,15 @@ Submode_t CCSDSHandler::getSubmode() const {
|
||||
}
|
||||
|
||||
MessageQueueId_t CCSDSHandler::getReportReceptionQueue(uint8_t virtualChannel) {
|
||||
if (virtualChannel < Ptme::NUM_OF_VIRTUAL_CHANNELS) {
|
||||
if (virtualChannel < config::NUMBER_OF_VIRTUAL_CHANNELS) {
|
||||
return virtualChannels[virtualChannel]->getReportReceptionQueue();
|
||||
} else {
|
||||
sif::debug << "CCSDSHandler::getReportReceptionQueue: Invalid virtual channel requested";
|
||||
}
|
||||
}
|
||||
|
||||
void CCSDSHandler::executeAllWriteCommands() {
|
||||
ReturnValue_t returnValue = boardHandler.sendWriteCommands();
|
||||
if (returnValue != RETURN_OK) {
|
||||
triggerEvent(DeviceHandlerIF::DEVICE_SENDING_COMMAND_FAILED,
|
||||
returnValue, 0);
|
||||
}
|
||||
if (submode == SUBMODE_ACTIVE) {
|
||||
returnValue = this->packetProcessing();
|
||||
if (returnValue != RETURN_OK) {
|
||||
triggerEvent(DeviceHandlerIF::DEVICE_SENDING_COMMAND_FAILED,
|
||||
returnValue, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCSDSHandler::handleAllWriteReplies() {
|
||||
ReturnValue_t returnValue = boardHandler.getWriteReplys();
|
||||
if (returnValue != RETURN_OK) {
|
||||
triggerEvent(DeviceHandlerIF::DEVICE_SENDING_COMMAND_FAILED,
|
||||
returnValue, 0);
|
||||
}
|
||||
if (pendingWrite) {
|
||||
memoryHelper.completeLoad(returnValue);
|
||||
pendingWrite = false;
|
||||
}
|
||||
if (submode == SUBMODE_ACTIVE) {
|
||||
returnValue = packetProcessingCheck();
|
||||
} else {
|
||||
this->flushTmChannels();
|
||||
}
|
||||
}
|
||||
|
||||
void CCSDSHandler::executeAllReadCommands() {
|
||||
ReturnValue_t returnValue = boardHandler.sendReadCommands();
|
||||
if (returnValue != RETURN_OK) {
|
||||
triggerEvent(DeviceHandlerIF::DEVICE_REQUESTING_REPLY_FAILED,
|
||||
returnValue, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void CCSDSHandler::handleAllReadReplies() {
|
||||
if ((mode == MODE_ON) && (state == STATE_IDLE)) {
|
||||
ReturnValue_t returnValue = boardHandler.getReadReplys();
|
||||
if (returnValue == RETURN_OK) {
|
||||
searchFrame();
|
||||
} else {
|
||||
triggerEvent(DeviceHandlerIF::DEVICE_REQUESTING_REPLY_FAILED,
|
||||
returnValue, 0);
|
||||
//do nothing.
|
||||
}
|
||||
if (pendingRead) {
|
||||
uint8_t* tempBuffer;
|
||||
returnValue = boardHandler.getRegisterReadReply(&tempBuffer);
|
||||
memoryHelper.completeDump(returnValue, tempBuffer,
|
||||
BoardHandler::REGISTER_LENGTH);
|
||||
pendingRead = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t CCSDSHandler::getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ReturnValue_t CCSDSHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
|
||||
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
|
||||
uint16_t startAtIndex) {
|
||||
ReturnValue_t result = fdir.getParameter(domainId, parameterId,
|
||||
parameterWrapper, newValues, startAtIndex);
|
||||
if (result != INVALID_DOMAIN_ID) {
|
||||
return result;
|
||||
}
|
||||
if (domainId != DOMAIN_ID_BASE) {
|
||||
return INVALID_DOMAIN_ID;
|
||||
}
|
||||
switch (parameterId) {
|
||||
case 0:
|
||||
parameterWrapper->set(boardHandler.tmPhysicalLayerRegisterValue);
|
||||
break;
|
||||
case 1:
|
||||
parameterWrapper->set(boardHandler.tmCodingSublayerRegisterValue);
|
||||
break;
|
||||
default:
|
||||
return INVALID_MATRIX_ID;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CCSDSHandler::setHealth(HealthState health) {
|
||||
healthHelper.setHealth(health);
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
HasHealthIF::HealthState CCSDSHandler::getHealth() {
|
||||
return healthHelper.getHealth();
|
||||
}
|
||||
|
||||
CCSDSHandler::DataRateSet::DataRateSet() :
|
||||
ControllerSet(), dataRate(datapool::VC_DATA_RATE_RAW, this,
|
||||
PoolVariableIF::VAR_WRITE), dataRates(
|
||||
datapool::DATA_RATE_ASSIGN, this, PoolVariableIF::VAR_READ) {
|
||||
}
|
||||
|
||||
CCSDSHandler::DataRateSet::~DataRateSet() {
|
||||
}
|
||||
|
||||
void CCSDSHandler::DataRateSet::setToDefault() {
|
||||
dataRate.value = {0.0, 0.0, 0.0, 0.0};
|
||||
}
|
||||
|
||||
void CCSDSHandler::triggerEvent(Event event, uint32_t parameter1,
|
||||
uint32_t parameter2) {
|
||||
fdir.triggerEvent(event, parameter1, parameter2);
|
||||
}
|
||||
|
@ -16,7 +16,6 @@
|
||||
*/
|
||||
class CCSDSHandler: public SystemObject,
|
||||
public ExecutableObjectIF,
|
||||
public HasModesIF,
|
||||
public AcceptsTelemetryIF,
|
||||
public HasReturnvaluesIF,
|
||||
public ReceivesParameterMessagesIF {
|
||||
@ -80,27 +79,26 @@ public:
|
||||
*/
|
||||
ReturnValue_t initialize();
|
||||
MessageQueueId_t getCommandQueue() const;
|
||||
|
||||
/**
|
||||
* Method to configure the TC Virtual Channels in the TC Data Link Layer.
|
||||
* The call is forwarded to the #dataLinkLayer class.
|
||||
* @param virtualChannelId VCID to add.
|
||||
* @param object Pointer to the Virtual Channel object that is added.
|
||||
* @return See the #dataLinkLayer class.
|
||||
* @brief Function to add a virtual channel
|
||||
*
|
||||
* @param virtualChannelId ID of the virtual channel to add
|
||||
* @param virtualChannel Pointer to virtual channel object
|
||||
*
|
||||
* @return RETURN_OK if successful, otherwise RETURN_FAILED
|
||||
*/
|
||||
ReturnValue_t addVirtualChannel(uint8_t virtualChannelId,
|
||||
VirtualChannelReceptionIF* object);
|
||||
void addVirtualChannel(VcId_t virtualChannelId, VirtualChannel* virtualChannel);
|
||||
|
||||
Mode_t getMode() const;
|
||||
Submode_t getSubmode() const;
|
||||
void setParentQueue(MessageQueueId_t parentQueueId);
|
||||
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0);
|
||||
ReturnValue_t setHealth(HealthState health);
|
||||
HasHealthIF::HealthState getHealth();
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint16_t parameterId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex);
|
||||
void triggerEvent(Event event, uint32_t parameter1 = 0,
|
||||
uint32_t parameter2 = 0);
|
||||
|
||||
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
|
||||
ParameterWrapper *parameterWrapper, const ParameterWrapper *newValues,
|
||||
uint16_t startAtIndex);
|
||||
|
||||
protected:
|
||||
MessageQueue commandQueue; //!< Queue to receive control commands.
|
||||
VCGeneration* virtualChannels[BoardHandler::USED_VIRTUAL_CHANNELS_PER_BOARD];//!< An array of VCGeneration classes which each manage on TM Virtual Channel.
|
||||
@ -148,68 +146,15 @@ protected:
|
||||
void setToExternalControl();
|
||||
void announceMode(bool recursive);
|
||||
private:
|
||||
enum CcsdsState_t {
|
||||
STATE_IDLE,
|
||||
STATE_TURN_ON,
|
||||
STATE_TURN_OFF,
|
||||
STATE_DO_PASSIVATE_OFF,
|
||||
STATE_TURN_SWITCH_OFF,
|
||||
STATE_WAIT_ON,
|
||||
STATE_WAIT_LINK,
|
||||
STATE_WAIT_OFF,
|
||||
STATE_INITIALIZE_BOARD,
|
||||
STATE_SELECT_SUBMODE,
|
||||
STATE_WAIT_SUBMODE_ACTIVE,
|
||||
STATE_DO_PASSIVATE,
|
||||
STATE_WAIT_SUBMODE_PASSIVE,
|
||||
STATE_HANDLE_STARTUP,
|
||||
};
|
||||
CcsdsState_t state;
|
||||
enum CommState {
|
||||
SEND_WRITE, GET_WRITE, SEND_READ, GET_READ
|
||||
};
|
||||
CommState commState;
|
||||
Mode_t mode;
|
||||
Submode_t submode;
|
||||
BoardHandler boardHandler;//!< The class that handles the low-level communication with the board.
|
||||
DataLinkLayer dataLinkLayer;//!< The class that manages the TC Data Link Layer protocols.
|
||||
uint8_t frameBuffer[MAX_FRAME_SIZE]; //!< The main buffer to store single frames in.
|
||||
uint16_t frameLength; //!< Indicates the current length of the found frame.
|
||||
object_id_t channelId; //!< Defines the id of the RMAP Channel to use.
|
||||
MemoryHelper memoryHelper; //!< Helps handling memory messages.
|
||||
|
||||
bool pendingWrite; //!< Attribute to manage remote Memory write.
|
||||
using VcId_t = uint8_t;
|
||||
using VirtualChannelMap = std::unordered_map<VcId_t, VcInterfaceIF*>;
|
||||
using VirtualChannelMapIter = VirtualChannelMap::iterator;
|
||||
|
||||
bool pendingRead; //!< Attribute to manage remote Memory read.
|
||||
VirtualChannelMap virtualChannelMap;
|
||||
|
||||
ModeHelper modeHelper; //!< Helps handling mode messages.
|
||||
HealthHelper healthHelper; //!< Helps setting the health information correctly.
|
||||
ParameterHelper parameterHelper;
|
||||
PowerSwitcher powerSwitcher; //!< Helps switching switches on and off.
|
||||
|
||||
bool switchOffWasReported; //!< To avoid reporting SWITCH_WENT_OFF multiple times.
|
||||
|
||||
CCSDSBoardFailureIsolation fdir;
|
||||
class DataRateSet: public ControllerSet {
|
||||
public:
|
||||
DataRateSet();
|
||||
virtual ~DataRateSet();
|
||||
void setToDefault();
|
||||
PoolVector<float, BoardHandler::USED_VIRTUAL_CHANNELS_PER_BOARD> dataRate;
|
||||
PoolVector<float, BoardHandler::USED_VIRTUAL_CHANNELS_PER_BOARD> dataRates;
|
||||
};
|
||||
DataRateSet rateSet;
|
||||
void setMode(Mode_t newMode, Submode_t newSubmode); //!< Method to safely setMode and inform everyone interested about it.
|
||||
/**
|
||||
* State machine of the Handler.
|
||||
* Is responsible for handling mode transitions and for informing the modeHelper.
|
||||
* In addition, it watches the SpW link and changes the Mode in case a link down or a link up is detected.
|
||||
*/
|
||||
void doStateMachine();
|
||||
void executeAllWriteCommands();
|
||||
void handleAllWriteReplies();
|
||||
void executeAllReadCommands();
|
||||
void handleAllReadReplies();
|
||||
void handleTelemetry();
|
||||
void handleTelecommands();
|
||||
};
|
||||
|
||||
#endif /* CCSDSHANDLER_H_ */
|
||||
|
80
mission/tmtc/VirtualChannel.cpp
Normal file
80
mission/tmtc/VirtualChannel.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
#include "CCSDSHandler.h"
|
||||
#include "OBSWConfig.h"
|
||||
|
||||
#include "fsfw/serviceinterface/ServiceInterfaceStream.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
|
||||
|
||||
#include <framework/tmtcservices/TmTcMessage.h>
|
||||
|
||||
#include <mission/obc/ccsdsboard/VirtualChannel.h>
|
||||
|
||||
|
||||
VirtualChannel::VirtualChannel(uint8_t vcId, uint32_t tmQueueDepth) :
|
||||
vcId(vcId) {
|
||||
tmQueue = QueueFactory::instance()->createMessageQueue(tmQueueDepth,
|
||||
MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||
}
|
||||
|
||||
ReturnValue_t VirtualChannel::initialize() {
|
||||
tmStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TM_STORE);
|
||||
if(tmStore == nullptr) {
|
||||
sif::error << "VirtualChannel::initialize: Failed to get tm store" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t VirtualChannel::performOperation() {
|
||||
ReturnValue_t status = RETURN_OK;
|
||||
TmTcMessage message;
|
||||
|
||||
while(tmQueue->receiveMessage(&message) == RETURN_OK) {
|
||||
store_address_t storeId = message.getStorageId();
|
||||
const uint8_t* data = nullptr;
|
||||
size_t size = 0;
|
||||
result = tmStore->getData(storeId, &data, &size);
|
||||
if (result != RETURN_OK) {
|
||||
sif::warning << "VirtualChannel::performOperation: Failed to read data from IPC store"
|
||||
<< std::endl;
|
||||
tmStore->deleteData(storeId);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (linkIsUp) {
|
||||
result = ptme->writeToVc(virtualChannleId, data, size);
|
||||
}
|
||||
|
||||
tmStore->deleteData(storeId);
|
||||
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MessageQueueId_t VirtualChannel::getReportReceptionQueue(uint8_t virtualChannel) {
|
||||
return tmQueue.getId();
|
||||
}
|
||||
|
||||
void VirtualChannel::setPtmeObject(PtmeIF* ptme) {
|
||||
if (ptme == nullptr) {
|
||||
sif::warning << "VirtualChannel::setPtmeObject: Invalid ptme object" << std::endl;
|
||||
}
|
||||
ptme = ptme;
|
||||
}
|
||||
|
||||
void VirtualChannel::setIdlePacketIntervalMs(uint32_t idlePacketIntervalMs) {
|
||||
timer.timeout = idlePacketIntervalMs;
|
||||
}
|
||||
|
||||
ReturnValue_t VirtualChannel::flush() {
|
||||
TmTcMessage message;
|
||||
ReturnValue_t status = RETURN_FAILED;
|
||||
for (status = tmQueue.receiveMessage(&message); status == RETURN_OK;
|
||||
status = tmQueue.receiveMessage(&message)) {
|
||||
packetStore->deleteData(message.getStorageId());
|
||||
}
|
||||
boardHandler->resetVC(virtualChannelId);
|
||||
return status;
|
||||
}
|
110
mission/tmtc/VirtualChannel.h
Normal file
110
mission/tmtc/VirtualChannel.h
Normal file
@ -0,0 +1,110 @@
|
||||
#ifndef VIRTUALCHANNEL_H_
|
||||
#define VIRTUALCHANNEL_H_
|
||||
|
||||
#include "fsfw/tmtcservices/AcceptsTelemetryIF.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include <fsfw/ipc/MessageQueueIF.h>
|
||||
|
||||
#include <framework/ipc/MessageQueue.h>
|
||||
#include <framework/objectmanager/SystemObject.h>
|
||||
#include <framework/osal/OSAL.h>
|
||||
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <framework/storagemanager/StorageManagerIF.h>
|
||||
#include <framework/timemanager/Countdown.h>
|
||||
#include <framework/tmtcpacket/SpacePacket.h>
|
||||
#include <framework/tmtcservices/AcceptsTelemetryIF.h>
|
||||
#include <mission/obc/ccsdsboard/BoardHandler.h>
|
||||
|
||||
/**
|
||||
* @brief This class represents a virtual channel in the software.
|
||||
*
|
||||
* @author J. Meier
|
||||
*/
|
||||
class VirtualChannel: public AcceptsTelemetryIF, public HasReturnvaluesIF {
|
||||
public:
|
||||
|
||||
uint32_t tmSendLimitPerCycle; //!< Current maximum bytes per cycle.
|
||||
|
||||
static const uint32_t IDLE_INTERVAL_RT_CHANNEL = 2000; //!< Real Time channel (VC 0) idle interval.
|
||||
|
||||
static const uint16_t IDLE_PACKET_SIZE = 1015; //!< Size of generated idle packets.
|
||||
|
||||
static const uint32_t DEFAULT_IDLE_INTERVAL = 20000; //!< Default if too lazy to set.
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param vcId The virtual channel id assigned to this object
|
||||
* @param tmQueueDepth Queue depth of queue receiving telemetry from other objects
|
||||
*/
|
||||
VirtualChannel(uint8_t vcId, uint32_t tmQueueDepth);
|
||||
|
||||
ReturnValue_t initialize();
|
||||
|
||||
/**
|
||||
* One of the main public methods.
|
||||
* Checks the tmQueue, calls #handlePacket if packets were found and keeps track of the number of sent bytes,
|
||||
* to stop transmission before a buffer overflow occurs. If no packets were sent, an idle packet is generated.
|
||||
* @return Number of sent bytes. 0 if an error occurred.
|
||||
*/
|
||||
uint32_t packetProcessing(void);
|
||||
/**
|
||||
* Another important method to check successful forwarding of packets.
|
||||
* Checks how many packets have been forwarded to the CCSDS Board and tries to get as many
|
||||
* RMAP write replys. The pending messages are deleted here.
|
||||
* @return @c RETURN_OK on success, or one of many error codes, mainly coming from @c receiveVCAcknowledge.
|
||||
*/
|
||||
ReturnValue_t packetProcessingCheck(void);
|
||||
/**
|
||||
* Setter.
|
||||
* @param setStore Sets the #packetStore used.
|
||||
*/
|
||||
void setPacketStore(StorageManagerIF* setStore);
|
||||
MessageQueueId_t getReportReceptionQueue();
|
||||
|
||||
ReturnValue_t performOperation();
|
||||
|
||||
/**
|
||||
* @brief Sets the PTME object which handles access to the PTME IP Core.
|
||||
*
|
||||
* @param ptme Pointer to ptme object
|
||||
*/
|
||||
void setPtmeObject(Ptme* ptme);
|
||||
|
||||
private:
|
||||
|
||||
PtmeIF* ptme = nullptr;
|
||||
MessageQueueIF* tmQueue = nullptr;
|
||||
uint8_t virtualChannelId;
|
||||
bool linkIsUp;
|
||||
StorageManagerIF* tmStore = nullptr;
|
||||
|
||||
|
||||
BoardHandler* boardHandler; //!< A reference to the "hardware part" of handling the packets.
|
||||
store_address_t pendingTm[BoardHandler::TM_PACKETS_PER_CALL_PER_CHANNEL]; //!< List of packets sent to the board. Is used to check if all Space Packets sent received the CCSDS Board.
|
||||
uint16_t sendCount; //!< Counter to identify how many packets have been sent coming in to the board (without Idle Packets).
|
||||
Countdown timer;
|
||||
SpacePacket idlePacket;
|
||||
uint32_t accumulatedByteCount;
|
||||
|
||||
store_address_t pendingPacket;
|
||||
|
||||
static const uint32_t TM_SEND_LIMIT_PER_CYCLE = 1300; //!< The maximum number of bytes to send to the CCSDS Board VC per cycle.
|
||||
|
||||
/**
|
||||
* Helper method to send an idle packet.
|
||||
* @return @c RETURN_OK on success, @c RETURN_FAILED otherwise.
|
||||
*/
|
||||
ReturnValue_t sendIdlePacket(uint32_t size);
|
||||
/**
|
||||
* A helper method to handle incoming packets.
|
||||
* Reads a packet from #packetStore and tries to forward it to the CCSDS BoardHandler class.
|
||||
* Calls the hardware layer with @c writeToVc. Depending on what the "hardware" layer does,
|
||||
* it stores the sent packet id's to find out if they were all received by the CCSDS Board.
|
||||
* @param store_id ID of a packet in the #packetStore.
|
||||
* @return @c RETURN_OK on success, the return code of @c writeToVc otherwise.
|
||||
*/
|
||||
ReturnValue_t handlePacket(store_address_t storeId);
|
||||
};
|
||||
|
||||
#endif /* VIRTUALCHANNEL_H_ */
|
@ -46,7 +46,7 @@ ReturnValue_t TmFunnel::performOperation(uint8_t operationCode) {
|
||||
ReturnValue_t TmFunnel::handlePacket(TmTcMessage* message) {
|
||||
uint8_t* packetData = nullptr;
|
||||
size_t size = 0;
|
||||
ReturnValue_t result = tmPool->modifyData(message->getStorageId(),
|
||||
ReturnValue_t result = tmStore->modifyData(message->getStorageId(),
|
||||
&packetData, &size);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
return result;
|
||||
@ -60,7 +60,7 @@ ReturnValue_t TmFunnel::handlePacket(TmTcMessage* message) {
|
||||
|
||||
result = tmQueue->sendToDefault(message);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
tmPool->deleteData(message->getStorageId());
|
||||
tmStore->deleteData(message->getStorageId());
|
||||
sif::error << "TmFunnel::handlePacket: Error sending to downlink "
|
||||
"handler" << std::endl;
|
||||
return result;
|
||||
@ -69,7 +69,7 @@ ReturnValue_t TmFunnel::handlePacket(TmTcMessage* message) {
|
||||
if(storageDestination != objects::NO_OBJECT) {
|
||||
result = storageQueue->sendToDefault(message);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
tmPool->deleteData(message->getStorageId());
|
||||
tmStore->deleteData(message->getStorageId());
|
||||
sif::error << "TmFunnel::handlePacket: Error sending to storage "
|
||||
"handler" << std::endl;
|
||||
return result;
|
||||
@ -80,8 +80,8 @@ ReturnValue_t TmFunnel::handlePacket(TmTcMessage* message) {
|
||||
|
||||
ReturnValue_t TmFunnel::initialize() {
|
||||
|
||||
tmPool = ObjectManager::instance()->get<StorageManagerIF>(objects::TM_STORE);
|
||||
if(tmPool == nullptr) {
|
||||
tmStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TM_STORE);
|
||||
if(tmStore == nullptr) {
|
||||
sif::error << "TmFunnel::initialize: TM store not set."
|
||||
<< std::endl;
|
||||
sif::error << "Make sure the tm store is set up properly"
|
||||
|
@ -41,7 +41,7 @@ private:
|
||||
MessageQueueIF* tmQueue = nullptr;
|
||||
MessageQueueIF* storageQueue = nullptr;
|
||||
|
||||
StorageManagerIF* tmPool = nullptr;
|
||||
StorageManagerIF* tmStore = nullptr;
|
||||
uint32_t messageDepth = 0;
|
||||
|
||||
ReturnValue_t handlePacket(TmTcMessage* message);
|
||||
|
Loading…
Reference in New Issue
Block a user