local parameter handler wip

This commit is contained in:
Jakob Meier 2023-02-13 11:28:27 +01:00
parent 305f8aa561
commit 60c99fdbfb
15 changed files with 417 additions and 152 deletions

View File

@ -51,6 +51,8 @@
#include "mission/system/tree/comModeTree.h" #include "mission/system/tree/comModeTree.h"
#include "mission/system/tree/payloadModeTree.h" #include "mission/system/tree/payloadModeTree.h"
#include "mission/system/tree/tcsModeTree.h" #include "mission/system/tree/tcsModeTree.h"
#include "mission/utility/GlobalConfigHandler.h"
#include "mission/config/configfile.h"
#include "tmtc/pusIds.h" #include "tmtc/pusIds.h"
#if OBSW_TEST_LIBGPIOD == 1 #if OBSW_TEST_LIBGPIOD == 1
#include "linux/boardtest/LibgpiodTest.h" #include "linux/boardtest/LibgpiodTest.h"
@ -966,3 +968,7 @@ void ObjectFactory::testAcsBrdAss(AcsBoardAssembly* acsAss) {
sif::warning << "Sending mode command failed" << std::endl; sif::warning << "Sending mode command failed" << std::endl;
} }
} }
void ObjectFactory::createGlobalConfigHandler() {
new GlobalConfigHandler(objects::GLOBAL_JSON_CFG, configfile::sdrelative);
}

View File

@ -48,6 +48,8 @@ void createTestComponents(LinuxLibgpioIF* gpioComIF);
void testAcsBrdAss(AcsBoardAssembly* assAss); void testAcsBrdAss(AcsBoardAssembly* assAss);
void createGlobalConfigHandler();
}; // namespace ObjectFactory }; // namespace ObjectFactory
#endif /* BSP_Q7S_OBJECTFACTORY_H_ */ #endif /* BSP_Q7S_OBJECTFACTORY_H_ */

View File

@ -86,6 +86,8 @@ void ObjectFactory::produce(void* args) {
createTestComponents(gpioComIF); createTestComponents(gpioComIF);
#endif /* OBSW_ADD_TEST_CODE == 1 */ #endif /* OBSW_ADD_TEST_CODE == 1 */
createGlobalConfigHandler();
createMiscComponents(); createMiscComponents();
createThermalController(); createThermalController();
createAcsController(true); createAcsController(true);

View File

@ -1 +1 @@
target_sources(${OBSW_NAME} PRIVATE scratchApi.cpp) target_sources(${OBSW_NAME} PRIVATE scratchApi.cpp LocalParameterHandler.cpp)

View File

@ -0,0 +1,22 @@
#include "LocalParameterHandler.h"
#include <fsfw/serviceinterface/ServiceInterface.h>
LocalParameterHandler::LocalParameterHandler(std::string sdRelativeName, SdCardMountedIF* sdcMan)
: sdRelativeName(sdRelativeName), sdcMan(sdcMan) {}
LocalParameterHandler::~LocalParameterHandler() {
}
ReturnValue_t LocalParameterHandler::initialize() {
std::string mountPrefix = sdcMan->getCurrentMountPrefix();
std::string fullname = mountPrefix + "/" + sdRelativeName;
setFullName(fullname);
ReturnValue_t result = readJsonFile();
if (result != returnvalue::OK) {
sif::warning << "LocalParameterHandler::initialize: Failed to read json file"
<< getFullName() << std::endl;
return result;
}
return returnvalue::OK;
}

View File

@ -0,0 +1,66 @@
#ifndef BSP_Q7S_MEMORY_LOCALPARAMETERHANDLER_H_
#define BSP_Q7S_MEMORY_LOCALPARAMETERHANDLER_H_
#include <string>
#include <mission/memory/NVMParameterBase.h>
#include <mission/memory/SdCardMountedIF.h>
/**
* @brief Class to handle persistent parameters
*
* @details Use the insertValue function to add parameters
*/
class LocalParameterHandler : public NVMParameterBase {
public:
/**
* @brief Constructor
*
* @param sdRelativeName Absolute name of json file relative to mount
* directory of SD card. E.g. conf/example.json
* @param sdcMan Pointer to SD card manager
*/
LocalParameterHandler(std::string sdRelativeName, SdCardMountedIF* sdcMan);
virtual ~LocalParameterHandler();
/**
* @brief Will initialize the local parameter handler
*
* @return OK if successful, otherwise error return value
*/
ReturnValue_t initialize();
/**
* @brief Function to add parameter to json file
*
* @param key The string to identify the parameter
* @param value The value to set for this parameter
*
* @return OK if successful, otherwise error return value
*
* @details The function will add the parameter only if it is not already
* present in the json file
*/
template<typename T> ReturnValue_t addParameter(std::string key, T value);
private:
// Name relative to mount point of SD card where parameters will be stored
std::string sdRelativeName;
SdCardMountedIF* sdcMan;
};
template<typename T> inline ReturnValue_t LocalParameterHandler::addParameter(std::string key, T value) {
ReturnValue_t result = insertValue(key, value);
if (result != returnvalue::OK) {
return result;
}
result = writeJsonFile();
if (result != returnvalue::OK) {
return result;
}
return returnvalue::OK;
}
#endif /* BSP_Q7S_MEMORY_LOCALPARAMETERHANDLER_H_ */

View File

@ -2,41 +2,126 @@
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
PdecConfig::PdecConfig() { initialize(); } PdecConfig::PdecConfig()
: localParameterHandler("conf/pdecconfig", SdCardManager::instance()) {
}
PdecConfig::~PdecConfig() {} PdecConfig::~PdecConfig() {}
void PdecConfig::initialize() { void PdecConfig::setMemoryBaseAddress(uint32_t* memoryBaseAddress_) {
uint32_t word = 0; memoryBaseAddress = memoryBaseAddress_;
word |= (VERSION_ID << 30);
// Setting the bypass flag and the control command flag should not have any
// implication on the operation of the PDEC IP Core
word |= (BYPASS_FLAG << 29);
word |= (CONTROL_COMMAND_FLAG << 28);
word |= (RESERVED_FIELD_A << 26);
word |= (SPACECRAFT_ID << 16);
word |= (VIRTUAL_CHANNEL << 10);
word |= (DUMMY_BITS << 8);
word |= POSITIVE_WINDOW;
configWords[0] = word;
word = 0;
word |= (NEGATIVE_WINDOW << 24);
word |= (HIGH_AU_MAP_ID << 16);
word |= (ENABLE_DERANDOMIZER << 8);
configWords[1] = word;
} }
uint32_t PdecConfig::getConfigWord(uint8_t wordNo) { ReturnValue_t PdecConfig::write() {
if (wordNo >= CONFIG_WORDS_NUM) { if (memoryBaseAddress == nullptr) {
sif::error << "PdecConfig::getConfigWord: Invalid word number" << std::endl; sif::error << "PdecConfig::write: Memory base address not set" << std::endl;
return 0; return returnvalue::FAILED;
} }
return configWords[wordNo];
writeFrameHeaderFirstOctet();
writeFrameHeaderSecondOctet();
writeMapConfig();
return returnvalue::FAILED;
} }
uint32_t PdecConfig::getImrReg() { uint32_t PdecConfig::getImrReg() {
return static_cast<uint32_t>(enableNewFarIrq << 2) | return static_cast<uint32_t>(enableNewFarIrq << 2) |
static_cast<uint32_t>(enableTcAbortIrq << 1) | static_cast<uint32_t>(enableTcNewIrq); static_cast<uint32_t>(enableTcAbortIrq << 1) | static_cast<uint32_t>(enableTcNewIrq);
} }
ReturnValue_t PdecConfig::setPositiveWindow(uint8_t pw) {
if (memoryBaseAddress == nullptr) {
sif::error << "PdecConfig::setPositiveWindow: Memory base address not set"
<< std::endl;
return returnvalue::FAILED;
}
positiveWindow = pw;
// Rewrite second config word which contains the positive window parameter
writeFrameHeaderSecondOctet();
return returnvalue::OK;
}
ReturnValue_t PdecConfig::setNegativeWindow(uint8_t nw) {
if (memoryBaseAddress == nullptr) {
sif::error << "PdecConfig::setPositiveWindow: Memory base address not set"
<< std::endl;
return returnvalue::FAILED;
}
negativeWindow = nw;
// Rewrite second config word which contains the negative window parameter
writeFrameHeaderSecondOctet();
return returnvalue::OK;
}
uint8_t PdecConfig::getPositiveWindow() {
return positiveWindow;
}
uint8_t PdecConfig::getNegativeWindow() {
return negativeWindow;
}
void PdecConfig::writeFrameHeaderFirstOctet() {
uint32_t word = 0;
word |= (VERSION_ID << 30);
// Setting the bypass flag and the control command flag should not have any
// implication on the operation of the PDEC IP Core
word |= (BYPASS_FLAG << 29);
word |= (CONTROL_COMMAND_FLAG << 28);
word |= (RESERVED_FIELD_A << 26);
word |= (SPACECRAFT_ID << 16);
word |= (VIRTUAL_CHANNEL << 10);
word |= (DUMMY_BITS << 8);
word |= positiveWindow;
*(memoryBaseAddress + FRAME_HEADER_OFFSET) = word;
}
void PdecConfig::writeFrameHeaderSecondOctet() {
uint32_t word = 0;
word = 0;
word |= (negativeWindow << 24);
word |= (HIGH_AU_MAP_ID << 16);
word |= (ENABLE_DERANDOMIZER << 8);
*(memoryBaseAddress + FRAME_HEADER_OFFSET + 1) = word;
}
void PdecConfig::writeMapConfig() {
// Configure all MAP IDs as invalid
for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) {
*(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + idx / 4) =
NO_DESTINATION << 24 | NO_DESTINATION << 16 | NO_DESTINATION << 8 | NO_DESTINATION;
}
// All TCs with MAP ID 7 will be routed to the PM module (can then be read from memory)
uint8_t routeToPm = calcMapAddrEntry(PM_BUFFER);
*(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + 1) =
(NO_DESTINATION << 24) | (NO_DESTINATION << 16) | (NO_DESTINATION << 8) | routeToPm;
// Write map id clock frequencies
for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) {
*(memoryBaseAddress + MAP_CLK_FREQ_OFFSET + idx / 4) =
MAP_CLK_FREQ << 24 | MAP_CLK_FREQ << 16 | MAP_CLK_FREQ << 8 | MAP_CLK_FREQ;
}
}
uint8_t PdecConfig::calcMapAddrEntry(uint8_t moduleId) {
uint8_t lutEntry = 0;
uint8_t parity = getOddParity(moduleId | (1 << VALID_POSITION));
lutEntry = (parity << PARITY_POSITION) | (1 << VALID_POSITION) | moduleId;
return lutEntry;
}
uint8_t PdecConfig::getOddParity(uint8_t number) {
uint8_t parityBit = 0;
uint8_t countBits = 0;
for (unsigned int idx = 0; idx < sizeof(number) * 8; idx++) {
countBits += (number >> idx) & 0x1;
}
parityBit = ~(countBits & 0x1) & 0x1;
return parityBit;
}

View File

@ -3,28 +3,51 @@
#include <cstring> #include <cstring>
#include "bsp_q7s/memory/LocalParameterHandler.h"
#include "bsp_q7s/fs/SdCardManager.h"
#include "fsfw/returnvalues/returnvalue.h" #include "fsfw/returnvalues/returnvalue.h"
#include "pdec.h"
/** /**
* @brief This class generates the configuration words for the configuration memory of the PDEC * @brief This class generates the configuration words for the configuration memory of the PDEC
* IP Cores. * IP Cores.
* *
* @details Fields are initialized according to pecification in PDEC datasheet section 6.11.3.1 * @details Fields are initialized according to specification in PDEC datasheet section 6.11.3.1
* PROM usage. * PROM usage.
* *
* @author J. Meier * @author J. Meier
*/ */
class PdecConfig { class PdecConfig {
public: public:
/**
* @brief Constructor
*/
PdecConfig(); PdecConfig();
virtual ~PdecConfig(); virtual ~PdecConfig();
/** /**
* @brief Returns the configuration word by specifying the position. * @brief Sets the memory base address pointer
*/
void setMemoryBaseAddress(uint32_t* memoryBaseAddress_);
/**
* @brief Will write the config to the PDEC configuration memory. New config
* becomes active after resetting PDEC.
*/
ReturnValue_t write();
/**
* @brief Returns the value to write to the interrupt mask register. This
* value defines which interrupts should be enabled/disabled.
*/ */
uint32_t getConfigWord(uint8_t wordNo);
uint32_t getImrReg(); uint32_t getImrReg();
ReturnValue_t setPositiveWindow(uint8_t pw);
ReturnValue_t setNegativeWindow(uint8_t nw);
uint8_t getPositiveWindow();
uint8_t getNegativeWindow();
private: private:
// TC transfer frame configuration parameters // TC transfer frame configuration parameters
static const uint8_t VERSION_ID = 0; static const uint8_t VERSION_ID = 0;
@ -36,21 +59,73 @@ class PdecConfig {
static const uint8_t RESERVED_FIELD_A = 0; static const uint8_t RESERVED_FIELD_A = 0;
static const uint16_t SPACECRAFT_ID = 0x3DC; static const uint16_t SPACECRAFT_ID = 0x3DC;
static const uint16_t DUMMY_BITS = 0; static const uint16_t DUMMY_BITS = 0;
// Parameters to control the FARM for AD frames
// Set here for future use
static const uint8_t POSITIVE_WINDOW = 10;
static const uint8_t NEGATIVE_WINDOW = 151;
static const uint8_t HIGH_AU_MAP_ID = 0xF; static const uint8_t HIGH_AU_MAP_ID = 0xF;
static const uint8_t ENABLE_DERANDOMIZER = 1; static const uint8_t ENABLE_DERANDOMIZER = 1;
static const uint8_t CONFIG_WORDS_NUM = 2; static const uint8_t CONFIG_WORDS_NUM = 2;
// 0x200 / 4 = 0x80
static const uint32_t FRAME_HEADER_OFFSET = 0x80;
static const uint32_t MAP_ADDR_LUT_OFFSET = 0xA0;
static const uint32_t MAP_CLK_FREQ_OFFSET = 0x90;
// MAP clock frequency. Must be a value between 1 and 13 otherwise the TC segment will be
// discarded
static const uint8_t MAP_CLK_FREQ = 2;
static const uint8_t MAX_MAP_ADDR = 63;
// Writing this to the map address in the look up table will invalidate a MAP ID.
static const uint8_t NO_DESTINATION = 0;
static const uint8_t VALID_POSITION = 6;
static const uint8_t PARITY_POSITION = 7;
/**
* TCs with map addresses (also know as Map IDs) assigned to this channel will be stored in
* the PDEC memory.
*/
static const uint8_t PM_BUFFER = 7;
uint32_t* memoryBaseAddress = nullptr;
// Pointer to object providing access to persistent configuration parameters
LocalParameterHandler localParameterHandler;
uint32_t configWords[CONFIG_WORDS_NUM]; uint32_t configWords[CONFIG_WORDS_NUM];
bool enableTcNewIrq = true; bool enableTcNewIrq = true;
bool enableTcAbortIrq = true; bool enableTcAbortIrq = true;
bool enableNewFarIrq = true; bool enableNewFarIrq = true;
void initialize(); NVMParameterBase persistenParams;
// Parameters to control the FARM for AD frames
// Set here for future use
uint8_t positiveWindow = 10;
uint8_t negativeWindow = 151;
void writeFrameHeaderFirstOctet();
void writeFrameHeaderSecondOctet();
void writeMapConfig();
/**
* @brief This function calculates the entry for the configuration of the MAP ID routing.
*
* @param mapAddr The MAP ID to configure
* @param moduleId The destination module where all TCs with the map id mapAddr will be routed
* to.
*
* @details The PDEC has different modules where the TCs can be routed to. A lookup table is
* used which links the MAP ID field to the destination module. The entry for this
* lookup table is created by this function and must be stored in the configuration
* memory region of the PDEC. The entry has a specific format
*/
uint8_t calcMapAddrEntry(uint8_t moduleId);
/**
* @brief This functions calculates the odd parity of the bits in number.
*
* @param number The number from which to calculate the odd parity.
*/
uint8_t getOddParity(uint8_t number);
}; };
#endif /* LINUX_OBC_PDECCONFIG_H_ */ #endif /* LINUX_OBC_PDECCONFIG_H_ */

View File

@ -22,13 +22,15 @@ using namespace pdec;
uint32_t PdecHandler::CURRENT_FAR = 0; uint32_t PdecHandler::CURRENT_FAR = 0;
PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId, PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId,
LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, UioNames names) LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, UioNames names,
object_id_t globalConfigHandlerId)
: SystemObject(objectId), : SystemObject(objectId),
tcDestinationId(tcDestinationId), tcDestinationId(tcDestinationId),
gpioComIF(gpioComIF), gpioComIF(gpioComIF),
pdecReset(pdecReset), pdecReset(pdecReset),
actionHelper(this, nullptr), actionHelper(this, nullptr),
uioNames(names) { uioNames(names),
globalConfigHandlerId(globalConfigHandlerId) {
auto mqArgs = MqArgs(objectId, static_cast<void*>(this)); auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
commandQueue = QueueFactory::instance()->createMessageQueue( commandQueue = QueueFactory::instance()->createMessageQueue(
QUEUE_SIZE, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs); QUEUE_SIZE, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
@ -61,6 +63,8 @@ ReturnValue_t PdecHandler::initialize() {
result = configMemMapper.getMappedAdress(&memoryBaseAddress, UioMapper::Permissions::READ_WRITE); result = configMemMapper.getMappedAdress(&memoryBaseAddress, UioMapper::Permissions::READ_WRITE);
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return ObjectManagerIF::CHILD_INIT_FAILED; return ObjectManagerIF::CHILD_INIT_FAILED;
} else {
pdecConfig.setMemoryBaseAddress(memoryBaseAddress);
} }
UioMapper ramMapper(uioNames.ramMemory); UioMapper ramMapper(uioNames.ramMemory);
result = ramMapper.getMappedAdress(&ramBaseAddress, UioMapper::Permissions::READ_WRITE); result = ramMapper.getMappedAdress(&ramBaseAddress, UioMapper::Permissions::READ_WRITE);
@ -72,8 +76,19 @@ ReturnValue_t PdecHandler::initialize() {
sif::error << "Can not use IRQ mode if IRQ UIO name is invalid" << std::endl; sif::error << "Can not use IRQ mode if IRQ UIO name is invalid" << std::endl;
return returnvalue::FAILED; return returnvalue::FAILED;
} }
PdecConfig pdecConfig;
writePdecConfigDuringReset(pdecConfig); globalConfigHandler = ObjectManager::instance()->get<StorageManagerIF>(objects::GLOBAL_JSON_CFG);
if (globalConfigHandler == nullptr) {
sif::error << "PdecHandler::initialize: Invalid global config handler" << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
pdecConfig.setGlobalConfigHandler(globalConfigHandler);
result = pdecConfig.write();
if (result != returnvalue::OK) {
sif::error << "PdecHandler::initialize: Failed to write PDEC config" << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = releasePdec(); result = releasePdec();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
@ -233,26 +248,45 @@ void PdecHandler::readCommandQueue(void) {
MessageQueueId_t PdecHandler::getCommandQueue() const { return commandQueue->getId(); } MessageQueueId_t PdecHandler::getCommandQueue() const { return commandQueue->getId(); }
void PdecHandler::writePdecConfigDuringReset(PdecConfig& pdecConfig) { ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
*(memoryBaseAddress + FRAME_HEADER_OFFSET) = pdecConfig.getConfigWord(0); const uint8_t* data, size_t size) {
*(memoryBaseAddress + FRAME_HEADER_OFFSET + 1) = pdecConfig.getConfigWord(1); switch (actionId) {
case PRINT_CLCW:
// Configure all MAP IDs as invalid printClcw();
for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) { return EXECUTION_FINISHED;
*(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + idx / 4) = case PRINT_PDEC_MON:
NO_DESTINATION << 24 | NO_DESTINATION << 16 | NO_DESTINATION << 8 | NO_DESTINATION; printPdecMon();
return EXECUTION_FINISHED;
default:
return COMMAND_NOT_IMPLEMENTED;
} }
}
// All TCs with MAP ID 7 will be routed to the PM module (can then be read from memory) ReturnValue_t PdecHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
uint8_t routeToPm = calcMapAddrEntry(PM_BUFFER); ParameterWrapper* parameterWrapper,
*(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + 1) = const ParameterWrapper* newValues, uint16_t startAtIndex) {
(NO_DESTINATION << 24) | (NO_DESTINATION << 16) | (NO_DESTINATION << 8) | routeToPm; if ((domainId == 0) and (uniqueIdentifier == ParameterId::POSITIVE_WINDOW)) {
uint8_t newVal = 0;
// Write map id clock frequencies ReturnValue_t result = newValues->getElement(&newVal);
for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) { if (result != returnvalue::OK) {
*(memoryBaseAddress + MAP_CLK_FREQ_OFFSET + idx / 4) = return result;
MAP_CLK_FREQ << 24 | MAP_CLK_FREQ << 16 | MAP_CLK_FREQ << 8 | MAP_CLK_FREQ; }
parameterWrapper->set();
com::setCurrentDatarate(static_cast<com::Datarate>(newVal));
return returnvalue::OK;
} else if ((domainId == 0) and
(uniqueIdentifier == static_cast<uint8_t>(com::ParameterId::TRANSMITTER_TIMEOUT))) {
uint8_t newVal = 0;
ReturnValue_t result = newValues->getElement(&newVal);
if (result != returnvalue::OK) {
return result;
}
parameterWrapper->set(transmitterTimeout);
transmitterTimeout = newVal;
transmitterCountdown.setTimeout(transmitterTimeout);
return returnvalue::OK;
} }
return returnvalue::OK;
} }
ReturnValue_t PdecHandler::resetFarStatFlag() { ReturnValue_t PdecHandler::resetFarStatFlag() {
@ -518,23 +552,6 @@ void PdecHandler::printTC(uint32_t tcLength) {
sif::info << tcSegmentStream.str() << std::endl; sif::info << tcSegmentStream.str() << std::endl;
} }
uint8_t PdecHandler::calcMapAddrEntry(uint8_t moduleId) {
uint8_t lutEntry = 0;
uint8_t parity = getOddParity(moduleId | (1 << VALID_POSITION));
lutEntry = (parity << PARITY_POSITION) | (1 << VALID_POSITION) | moduleId;
return lutEntry;
}
uint8_t PdecHandler::getOddParity(uint8_t number) {
uint8_t parityBit = 0;
uint8_t countBits = 0;
for (unsigned int idx = 0; idx < sizeof(number) * 8; idx++) {
countBits += (number >> idx) & 0x1;
}
parityBit = ~(countBits & 0x1) & 0x1;
return parityBit;
}
uint32_t PdecHandler::getClcw() { return *(registerBaseAddress + PDEC_CLCW_OFFSET); } uint32_t PdecHandler::getClcw() { return *(registerBaseAddress + PDEC_CLCW_OFFSET); }
uint32_t PdecHandler::getPdecMon() { return *(registerBaseAddress + PDEC_MON_OFFSET); } uint32_t PdecHandler::getPdecMon() { return *(registerBaseAddress + PDEC_MON_OFFSET); }
@ -620,17 +637,3 @@ std::string PdecHandler::getMonStatusString(uint32_t status) {
break; break;
} }
} }
ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) {
switch (actionId) {
case PRINT_CLCW:
printClcw();
return EXECUTION_FINISHED;
case PRINT_PDEC_MON:
printPdecMon();
return EXECUTION_FINISHED;
default:
return COMMAND_NOT_IMPLEMENTED;
}
}

View File

@ -8,6 +8,8 @@
#include "eive/definitions.h" #include "eive/definitions.h"
#include "fsfw/action/ActionHelper.h" #include "fsfw/action/ActionHelper.h"
#include "fsfw/action/HasActionsIF.h" #include "fsfw/action/HasActionsIF.h"
#include "fsfw/parameters/HasParametersIF.h"
#include "fsfw/parameters/ParameterHelper.h"
#include "fsfw/objectmanager/SystemObject.h" #include "fsfw/objectmanager/SystemObject.h"
#include "fsfw/returnvalues/returnvalue.h" #include "fsfw/returnvalues/returnvalue.h"
#include "fsfw/storagemanager/StorageManagerIF.h" #include "fsfw/storagemanager/StorageManagerIF.h"
@ -15,6 +17,7 @@
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h" #include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
#include "fsfw_hal/common/gpio/gpioDefinitions.h" #include "fsfw_hal/common/gpio/gpioDefinitions.h"
#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h" #include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h"
#include "mission/utility/GlobalConfigHandler.h"
struct UioNames { struct UioNames {
const char* configMemory; const char* configMemory;
@ -41,7 +44,10 @@ struct UioNames {
* *
* @author J. Meier * @author J. Meier
*/ */
class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasActionsIF { class PdecHandler : public SystemObject,
public ExecutableObjectIF,
public HasActionsIF,
public HasParametersIF {
public: public:
static constexpr dur_millis_t IRQ_TIMEOUT_MS = 500; static constexpr dur_millis_t IRQ_TIMEOUT_MS = 500;
@ -55,9 +61,10 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc
* @param pdecReset GPIO ID of GPIO connected to the reset signal of the PDEC. * @param pdecReset GPIO ID of GPIO connected to the reset signal of the PDEC.
* @param uioConfigMemory String of uio device file same mapped to the PDEC memory space * @param uioConfigMemory String of uio device file same mapped to the PDEC memory space
* @param uioregsiters String of uio device file same mapped to the PDEC register space * @param uioregsiters String of uio device file same mapped to the PDEC register space
* @param globalConfigHandler Object ID of global config file handler
*/ */
PdecHandler(object_id_t objectId, object_id_t tcDestinationId, LinuxLibgpioIF* gpioComIF, PdecHandler(object_id_t objectId, object_id_t tcDestinationId, LinuxLibgpioIF* gpioComIF,
gpioId_t pdecReset, UioNames names); gpioId_t pdecReset, UioNames names, object_id_t globalConfigHandlerId);
virtual ~PdecHandler(); virtual ~PdecHandler();
@ -70,6 +77,10 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy, ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) override; const uint8_t* data, size_t size) override;
ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueIdentifier,
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
uint16_t startAtIndex) override;
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER; static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER;
//! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame //! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame
@ -138,9 +149,6 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc
static const int REGISTER_MAP_SIZE = 0x4000; static const int REGISTER_MAP_SIZE = 0x4000;
#endif /* BOARD_TE0720 == 1 */ #endif /* BOARD_TE0720 == 1 */
// 0x200 / 4 = 0x80
static const uint32_t FRAME_HEADER_OFFSET = 0x80;
static const size_t MAX_TC_SEGMENT_SIZE = 1017; static const size_t MAX_TC_SEGMENT_SIZE = 1017;
static const uint8_t MAP_ID_MASK = 0x3F; static const uint8_t MAP_ID_MASK = 0x3F;
@ -150,15 +158,6 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc
static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x26000000; static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x26000000;
#endif #endif
static const uint32_t MAP_ADDR_LUT_OFFSET = 0xA0;
static const uint32_t MAP_CLK_FREQ_OFFSET = 0x90;
static const uint8_t MAX_MAP_ADDR = 63;
// Writing this to the map address in the look up table will invalidate a MAP ID.
static const uint8_t NO_DESTINATION = 0;
static const uint8_t VALID_POSITION = 6;
static const uint8_t PARITY_POSITION = 7;
// Expected value stored in FAR register after reset // Expected value stored in FAR register after reset
static const uint32_t FAR_RESET = 0x7FE0; static const uint32_t FAR_RESET = 0x7FE0;
@ -167,15 +166,13 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc
static const uint32_t NO_RF_MASK = 0x8000; static const uint32_t NO_RF_MASK = 0x8000;
static const uint32_t NO_BITLOCK_MASK = 0x4000; static const uint32_t NO_BITLOCK_MASK = 0x4000;
/** class ParameterId {
* TCs with map addresses (also know as Map IDs) assigned to this channel will be stored in public:
* the PDEC memory. // ID of the parameter to update the positive window of AD frames
*/ static const uint8_t POSITIVE_WINDOW = 0;
static const uint8_t PM_BUFFER = 7; // ID of the parameter to update the negative window of AD frames
static const uint8_t NEGATIVE_WINDOW = 1;
// MAP clock frequency. Must be a value between 1 and 13 otherwise the TC segment will be };
// discarded
static const uint8_t MAP_CLK_FREQ = 2;
enum class FrameAna_t : uint8_t { enum class FrameAna_t : uint8_t {
ABANDONED_CLTU, ABANDONED_CLTU,
@ -249,6 +246,15 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc
UioNames uioNames; UioNames uioNames;
// Object ID of global config file handler
object_id_t globalConfigHandlerId;
ParameterHelper paramHelper;
GlobalConfigHandler* globalConfigHandler = nullptr;
PdecConfig pdecConfig;
/** /**
* @brief Reads and handles messages stored in the commandQueue * @brief Reads and handles messages stored in the commandQueue
*/ */
@ -341,12 +347,6 @@ class PdecHandler : public SystemObject, public ExecutableObjectIF, public HasAc
*/ */
uint8_t calcMapAddrEntry(uint8_t moduleId); uint8_t calcMapAddrEntry(uint8_t moduleId);
/**
* @brief This functions calculates the odd parity of the bits in number.
*
* @param number The number from which to calculate the odd parity.
*/
uint8_t getOddParity(uint8_t number);
/** /**
* brief Returns the 32-bit wide communication link control word (CLCW) * brief Returns the 32-bit wide communication link control word (CLCW)

View File

@ -0,0 +1,9 @@
#ifndef MISSION_CONFIG_CONFIGFILE_H_
#define MISSION_CONFIG_CONFIGFILE_H_
namespace configfile {
// Name of global config file relative to currently mounted SD card
static const char sdrelative[] = "config/global_config.json";
}
#endif /* MISSION_CONFIG_CONFIGFILE_H_ */

View File

@ -50,6 +50,7 @@ class ComSubsystem : public Subsystem, public ReceivesParameterMessagesIF {
// Maximum time after which the transmitter will be turned of. This is a // Maximum time after which the transmitter will be turned of. This is a
// protection mechanism due prevent the syrlinks from overheating // protection mechanism due prevent the syrlinks from overheating
uint32_t transmitterTimeout = 0; uint32_t transmitterTimeout = 0;
ParameterHelper paramHelper; ParameterHelper paramHelper;
MessageQueueIF* eventQueue = nullptr; MessageQueueIF* eventQueue = nullptr;

View File

@ -15,6 +15,8 @@ enum ParamIds : uint8_t {
PARAM0 = 0, PARAM0 = 0,
PARAM1 = 1, PARAM1 = 1,
PARAM2 = 2, PARAM2 = 2,
PDEC_PW = 3,
PDEC_NW = 4
}; };
#endif /* MISSION_UTILITY_GLOBALCONFIGFILEDEFINITIONS_H_ */ #endif /* MISSION_UTILITY_GLOBALCONFIGFILEDEFINITIONS_H_ */

View File

@ -23,23 +23,24 @@ GlobalConfigHandler::GlobalConfigHandler(object_id_t objectId, std::string confi
CONFIG_LOCK = MutexFactory::instance()->createMutex(); CONFIG_LOCK = MutexFactory::instance()->createMutex();
} }
} }
ReturnValue_t GlobalConfigHandler::initialize() { ReturnValue_t GlobalConfigHandler::initialize() {
ReturnValue_t result = SystemObject::initialize(); ReturnValue_t result = SystemObject::initialize();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
#if OBSW_VERBOSE_LEVEL >= 1 #if OBSW_VERBOSE_LEVEL >= 1
sif::info << "GlobalConfigHandler::initialize: SystemObject::initialize() failed with " sif::info << "GlobalConfigHandler::initialize: SystemObject::initialize failed with "
<< result << std::endl; << result << std::endl;
#endif #endif
return result; return result;
} }
result = ReadConfigFile(); result = readConfigFile();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
#if OBSW_VERBOSE_LEVEL >= 1 #if OBSW_VERBOSE_LEVEL >= 1
sif::info << "GlobalConfigHandler::initialize: Creating JSON file at " << getFullName() sif::info << "GlobalConfigHandler::initialize: Creating JSON file at " << getFullName()
<< std::endl; << std::endl;
#endif #endif
result = ResetConfigFile(); result = resetConfigFile();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
return result; return result;
} }
@ -63,6 +64,7 @@ ReturnValue_t GlobalConfigHandler::lockConfigFile() {
result = CONFIG_LOCK->lockMutex(MutexIF::TimeoutType::WAITING, 10); result = CONFIG_LOCK->lockMutex(MutexIF::TimeoutType::WAITING, 10);
return result; return result;
} }
ReturnValue_t GlobalConfigHandler::unlockConfigFile() { ReturnValue_t GlobalConfigHandler::unlockConfigFile() {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
result = CONFIG_LOCK->unlockMutex(); result = CONFIG_LOCK->unlockMutex();
@ -70,34 +72,21 @@ ReturnValue_t GlobalConfigHandler::unlockConfigFile() {
} }
template <typename T> template <typename T>
ReturnValue_t GlobalConfigHandler::setConfigFileValue(ParamIds paramID, T data) { ReturnValue_t GlobalConfigHandler::setConfigFileValue(std::string paramName, T data) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
ReturnValue_t resultSet = returnvalue::OK; ReturnValue_t resultSet = returnvalue::OK;
result = lockConfigFile(); result = lockConfigFile();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
#if OBSW_VERBOSE_LEVEL >= 1 #if OBSW_VERBOSE_LEVEL >= 1
sif::info << "GlobalConfigHandler::setConfigFileValue lock mutex failed with " << result sif::info << "GlobalConfigHandler::setConfigFileValue: Lock mutex failed with " << result
<< std::endl; << std::endl;
#endif #endif
return result; return result;
} }
std::string paramString; // If value exists it is updated otherwise a new entry will be created
paramString = PARAM_KEY_MAP[paramID]; resultSet = insertValue(paramName, data);
// Check if key exists in map before setting value. No check is done in setValue! Somehow
// PARAM_KEY_MAP.count(paramID) == 0 does not work
if (paramString.empty() == true) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "GlobalConfigHandler::setConfigFileValue ParamId " << PARAM_KEY_MAP[paramID]
<< " not found!" << std::endl;
#endif
triggerEvent(SET_CONFIGFILEVALUE_FAILED, 1, 0);
return returnvalue::FAILED;
}
resultSet = setValue(PARAM_KEY_MAP[paramID], data);
if (resultSet != returnvalue::OK) { if (resultSet != returnvalue::OK) {
triggerEvent(SET_CONFIGFILEVALUE_FAILED, 0, 0); triggerEvent(SET_CONFIGFILEVALUE_FAILED, 0, 0);
#if OBSW_VERBOSE_LEVEL >= 1 #if OBSW_VERBOSE_LEVEL >= 1
@ -117,6 +106,7 @@ ReturnValue_t GlobalConfigHandler::setConfigFileValue(ParamIds paramID, T data)
return resultSet; return resultSet;
} }
template <typename T> template <typename T>
ReturnValue_t GlobalConfigHandler::getConfigFileValue(ParamIds paramID, T& data) { ReturnValue_t GlobalConfigHandler::getConfigFileValue(ParamIds paramID, T& data) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
@ -161,8 +151,10 @@ ReturnValue_t GlobalConfigHandler::resetConfigFileValues() {
#endif #endif
return result; return result;
} }
insertValue(PARAM_KEY_MAP[PARAM0], PARAM0_DEFAULT);
insertValue(PARAM_KEY_MAP[PARAM1], PARAM1_DEFAULT); for(const auto& keyMap: PARAM_KEY_MAP) {
insertValue(keyMap.second, PARAM0_DEFAULT);
}
result = unlockConfigFile(); result = unlockConfigFile();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
@ -174,7 +166,8 @@ ReturnValue_t GlobalConfigHandler::resetConfigFileValues() {
} }
return result; return result;
} }
ReturnValue_t GlobalConfigHandler::WriteConfigFile() {
ReturnValue_t GlobalConfigHandler::writeConfigFile() {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
ReturnValue_t resultWrite = returnvalue::OK; ReturnValue_t resultWrite = returnvalue::OK;
result = lockConfigFile(); result = lockConfigFile();
@ -205,7 +198,8 @@ ReturnValue_t GlobalConfigHandler::WriteConfigFile() {
} }
return resultWrite; return resultWrite;
} }
ReturnValue_t GlobalConfigHandler::ReadConfigFile() {
ReturnValue_t GlobalConfigHandler::readConfigFile() {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
ReturnValue_t resultRead = returnvalue::OK; ReturnValue_t resultRead = returnvalue::OK;
result = lockConfigFile(); result = lockConfigFile();
@ -237,7 +231,8 @@ ReturnValue_t GlobalConfigHandler::ReadConfigFile() {
return resultRead; return resultRead;
} }
ReturnValue_t GlobalConfigHandler::ResetConfigFile() {
ReturnValue_t GlobalConfigHandler::resetConfigFile() {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
result = resetConfigFileValues(); result = resetConfigFileValues();
if (result != returnvalue::OK) { if (result != returnvalue::OK) {
@ -253,7 +248,7 @@ ReturnValue_t GlobalConfigHandler::ResetConfigFile() {
ReturnValue_t GlobalConfigHandler::setConfigFileName(std::string configFileName) { ReturnValue_t GlobalConfigHandler::setConfigFileName(std::string configFileName) {
ReturnValue_t result = returnvalue::OK; ReturnValue_t result = returnvalue::OK;
setFullName(configFileName); setFullName(configFileName);
result = ResetConfigFile(); result = resetConfigFile();
return result; return result;
} }
std::string GlobalConfigHandler::getConfigFileName() { return getFullName(); } std::string GlobalConfigHandler::getConfigFileName() { return getFullName(); }

View File

@ -15,6 +15,7 @@
#include <fsfw/storagemanager/StorageManagerIF.h> #include <fsfw/storagemanager/StorageManagerIF.h>
#include <fsfw/tasks/ExecutableObjectIF.h> #include <fsfw/tasks/ExecutableObjectIF.h>
#include <utility>
#include <sstream> #include <sstream>
#include <string> #include <string>
@ -24,10 +25,6 @@
#include "fsfw/parameters/ParameterHelper.h" #include "fsfw/parameters/ParameterHelper.h"
#include "mission/memory/NVMParameterBase.h" #include "mission/memory/NVMParameterBase.h"
static std::map<ParamIds, std::string> PARAM_KEY_MAP = {
{PARAM0, "Parameter0"},
{PARAM1, "Parameter1"},
};
/* /*
* Idea: This class is intended to be used as a subclass for the Core Controller. * Idea: This class is intended to be used as a subclass for the Core Controller.
* Its tasks is managing a configuration JSON file containing config values important for various * Its tasks is managing a configuration JSON file containing config values important for various
@ -54,12 +51,12 @@ class GlobalConfigHandler : public SystemObject,
ReturnValue_t initialize(); ReturnValue_t initialize();
template <typename T> template <typename T>
ReturnValue_t setConfigFileValue(ParamIds paramID, T data); ReturnValue_t setConfigFileValue(std::string paramName, T data);
template <typename T> template <typename T>
ReturnValue_t getConfigFileValue(ParamIds paramID, T& data); ReturnValue_t getConfigFileValue(std::string paramName, T& data);
ReturnValue_t ResetConfigFile(); ReturnValue_t resetConfigFile();
ReturnValue_t WriteConfigFile(); ReturnValue_t writeConfigFile();
std::string getConfigFileName(); std::string getConfigFileName();
private: private:
@ -71,7 +68,7 @@ class GlobalConfigHandler : public SystemObject,
ReturnValue_t setConfigFileName(std::string configFileName); ReturnValue_t setConfigFileName(std::string configFileName);
ReturnValue_t ReadConfigFile(); ReturnValue_t readConfigFile();
MessageQueueIF* commandQueue; MessageQueueIF* commandQueue;
}; };