commanding of HeaterHandler and GpioIF working

This commit is contained in:
Jakob Meier 2021-02-01 11:17:20 +01:00
parent b9a7a30919
commit 26f16995e0
20 changed files with 474 additions and 264 deletions

View File

@ -12,6 +12,8 @@
#include <fsfw/tmtcpacket/pus/TmPacketStored.h>
#include <fsfw/osal/linux/TcUnixUdpPollingTask.h>
#include <fsfwconfig/devices/powerSwitcherList.h>
#include <mission/core/GenericFactory.h>
#include <mission/devices/PDU1Handler.h>
#include <mission/devices/PDU2Handler.h>
@ -19,6 +21,7 @@
#include <mission/devices/PCDUHandler.h>
#include <mission/devices/P60DockHandler.h>
#include <mission/devices/Tmp1075Handler.h>
#include <mission/devices/HeaterHandler.h>
#include <mission/devices/devicedefinitions/GomSpacePackets.h>
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
#include <mission/utility/TmFunnel.h>
@ -102,19 +105,20 @@ void ObjectFactory::produce(){
tmp1075Handler_2->setStartUpImmediately();
/* Thermal objects */
GpioCookie gpioCookie = new GpioCookie;
GpioCookie* gpioCookie = new GpioCookie;
#if TE0720 == 1
// Configuration for MIO0 on TE0720-03-1CFA
GpioConfig_t gpioConfigForDummyHeater(std::string("gpiochip0"), 0,
std::string("Heater0"), Gpio::OUT);
gpioCookie.add(gpioIds::HEATER_0, gpioConfigForDummyHeater);
gpioCookie->addGpio(gpioIds::HEATER_0, gpioConfigForDummyHeater);
#else
GpioConfig_t gpioConfigHeater0(std::string("gpiochip5"), 6,
std::string("Heater0"), Gpio::OUT);
gpioCookie.add(gpioIds::HEATER_0, gpioConfigHeater0);
gpioCookie->addGpio(gpioIds::HEATER_0, gpioConfigHeater0);
#endif
LinuxLibgpioIF linuxLibgpioIF = new LinuxLibgpioIF(objects::GPIO_IF);
new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, gpioCookie);
new LinuxLibgpioIF(objects::GPIO_IF);
new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, gpioCookie, objects::PCDU_HANDLER,
pcduSwitches::TCS_BOARD_8V_HEATER_IN);
new TmTcUnixUdpBridge(objects::UDP_BRIDGE,
objects::CCSDS_PACKET_DISTRIBUTOR,

View File

@ -14,7 +14,7 @@ typedef uint16_t gpioId_t;
class GpioIF : public HasReturnvaluesIF{
public:
virtual ~GpioIF();
virtual ~GpioIF() {};
/**
* @brief Called by the GPIO using object.

View File

@ -1,6 +1,9 @@
#include <bsp_q7s/gpio/LinuxLibgpioIF.h>
#include <gpio.h>
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
#include <utility>
#include <unistd.h>
#include <gpiod.h>
LinuxLibgpioIF::LinuxLibgpioIF(object_id_t objectId) : SystemObject(objectId) {
}
@ -14,16 +17,17 @@ ReturnValue_t LinuxLibgpioIF::initialize(CookieIF * cookie){
GpioMapIter mapToAddIter;
if(cookie == nullptr) {
return NULLPOINTER;
sif::error << "LinuxLibgpioIF::initialize: Invalid cookie" << std::endl;
return RETURN_FAILED;
}
GpioCookie* GpioCookie = dynamic_cast<GpioCookie*>(cookie);
if(GpioCookie == nullptr) {
GpioCookie* gpioCookie = dynamic_cast<GpioCookie*>(cookie);
if(gpioCookie == nullptr) {
sif::error << "LinuxLibgpioIF: Invalid Gpio Cookie!"
<< std::endl;
return NULLPOINTER;
return RETURN_FAILED;
}
mapToAdd = GpioCookie->getGpioMap();
mapToAdd = gpioCookie->getGpioMap();
result = checkForConflicts(mapToAdd);
if (result != HasReturnvaluesIF::RETURN_OK){
@ -31,20 +35,7 @@ ReturnValue_t LinuxLibgpioIF::initialize(CookieIF * cookie){
}
/* Register new GPIOs in gpioMap*/
result = initializeAndConfigure(mapToAdd);
if (result != HasReturnvaluesIF::RETURN_OK){
return result;
}
/* Register new GPIOs in gpioMap*/
std::pair insertionResult = gpioMap.insert(mapToAdd.begin(),
mapToAdd.end());
if (insertionResult.second() != true) {
sif::error << "LinuxLibgpioIF::initialize: Failed to add "
<< "GPIO with ID " << mapToAddIter.first << " to gpioMap"
<< std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
gpioMap.insert(mapToAdd.begin(), mapToAdd.end());
return HasReturnvaluesIF::RETURN_OK;
}
@ -60,41 +51,43 @@ ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId){
ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId,
unsigned int logiclevel) {
GpioMapIter gpioMapIter = gpioMap.find(gpioId);
char *chipname;
std::string chipname;
unsigned int lineNum;
struct gpiod_chip *chip;
struct gpiod_line *line;
int result;
Gpio::Direction direction;
std::string consumer;
/* Verify if GPIO has been configured as output */
direction = gpioMapIter.second.direction;
direction = gpioMapIter->second.direction;
if (direction != Gpio::OUT) {
sif::error << "LinuxLibgpioIF::pullHigh: GPIO with ID " << gpioId
sif::error << "LinuxLibgpioIF::driveGpio: GPIO with ID " << gpioId
<< "not configured as output" << std::endl;
return CONFIGURATION_FAILURE;
}
chipname = gpioMapIter.second.chipname;
chip = gpiod_chip_open_by_name(chipname);
chipname = gpioMapIter->second.chipname;
chip = gpiod_chip_open_by_name(chipname.c_str());
if (!chip) {
sif::error << "LinuxLibgpioIF::pullHigh: Failed to open chip "
sif::error << "LinuxLibgpioIF::driveGpio: Failed to open chip "
<< chipname << ". Gpio ID: " << gpioId << std::endl;
return OPEN_CHIP_FAILURE;
}
lineNum = gpioMapIter.second.lineNum;
lineNum = gpioMapIter->second.lineNum;
line = gpiod_chip_get_line(chip, lineNum);
if (!line) {
sif::error << "LinuxLibgpioIF::pullHigh: Failed to open line. Gpio ID "
sif::error << "LinuxLibgpioIF::driveGpio: Failed to open line. Gpio ID "
<< gpioId << std::endl;
gpiod_chip_close(chip);
return OPEN_LINE_FAILURE;
}
result = gpiod_line_request_output(line, CONSUMER, 0);
consumer = gpioMapIter->second.consumer;
result = gpiod_line_request_output(line, consumer.c_str(), 0);
if (result < 0) {
sif::error << "LinuxLibgpioIF::pullHigh: Failed to request line "
sif::error << "LinuxLibgpioIF::driveGpio: Failed to request line "
<< line << " from GPIO instance with ID: " << gpioId
<< std::endl;
gpiod_line_release(line);
@ -103,11 +96,12 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId,
result = gpiod_line_set_value(line, logiclevel);
if (result < 0) {
sif::error << "LinuxLibgpioIF::pullHigh: Failed to pull GPIO with ID "
sif::error << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID "
<< gpioId << "to low" << std::endl;
gpiod_line_release(line);
return PULLING_HIGH_FAILURE;
}
gpiod_line_release(line);
return HasReturnvaluesIF::RETURN_OK;
}
@ -116,13 +110,14 @@ ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap mapToAdd){
gpioId_t gpioId;
GpioMapIter mapToAddIter = mapToAdd.begin();
for(; mapToAddIter != mapToAdd.end(); mapToAddIter++){
gpio = mapToAddIter.first();
if(gpioMapIter.find(gpioId) != mapToAdd.end()){
gpioId = mapToAddIter->first;
gpioMapIter = gpioMap.find(gpioId);
if(gpioMapIter != mapToAdd.end()){
/* An entry for this GPIO already exists. Check if configuration
* of direction is equivalent */
if (mapToAddIter.second.direction != gpioMapIter.second.direction){
if (mapToAddIter->second.direction != gpioMapIter->second.direction){
sif::error << "LinuxLibgpioIF::checkForConflicts: Detected conflict "
<< "for GPIO " << mapToAddIter.first() << std::endl;
<< "for GPIO " << mapToAddIter->first << std::endl;
return HasReturnvaluesIF::RETURN_OK;
}
/* Remove element from map to add because a entry for this GPIO

View File

@ -4,6 +4,7 @@
#include <bsp_q7s/gpio/GpioIF.h>
#include <fsfwconfig/returnvalues/classIds.h>
#include <bsp_q7s/gpio/cookies/GpioCookie.h>
#include <fsfw/objectmanager/SystemObject.h>
/**
* @brief This class implements the GpioIF for a linux based system. The
@ -12,9 +13,11 @@
* @note The Petalinux SDK from Xilinx supports libgpiod since Petalinux
* 2019.1.
*/
class LinuxLibgpioIF: public GpioIF, public SystemObject {
class LinuxLibgpioIF : public GpioIF, public SystemObject {
public:
static const uint8_t INTERFACE_ID = CLASS_ID::LINUX_LIBGPIO_IF;
static const ReturnValue_t CONFIGURATION_FAILURE = MAKE_RETURN_CODE(0x1);
static const ReturnValue_t OPEN_CHIP_FAILURE = MAKE_RETURN_CODE(0x2);
static const ReturnValue_t OPEN_LINE_FAILURE = MAKE_RETURN_CODE(0x3);
@ -30,10 +33,9 @@ public:
private:
static const uint8_t INTERFACE_ID = CLASS_ID::LINUX_LIBGPIO_IF;
/*Holds the information and configuration of all used GPIOs */
GpioMap gpioMap;
GpioMapIter gpioMapIter;
/**
* @brief This functions drives line of a GPIO specified by the GPIO ID.

View File

@ -1,15 +1,16 @@
#include <bsp_q7s/gpio/cookies/GpioCookie.h>
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
GpioCookie::GpioCookie() {
}
void GpioCookie::addGpio(GpioMap newEntry){
gpioMapIter = gpioMap.find(newEntry);
void GpioCookie::addGpio(gpioId_t gpioId, GpioConfig_t gpioConfig){
gpioMapIter = gpioMap.find(gpioId);
if(gpioMapIter == gpioMap.end()) {
std::pair status = gpioMap.emplace(newEntry);
std::pair status = gpioMap.emplace(gpioId, gpioConfig);
if (status.second == false) {
sif::error << "GpioCookie::addGpio: Failed to add GPIO "
<< newEntry.first << "to GPIO map" << std::endl;
<< gpioId << "to GPIO map" << std::endl;
}
}
else {
@ -18,7 +19,7 @@ void GpioCookie::addGpio(GpioMap newEntry){
}
}
GpioMap getGpioMap() const{
GpioMap GpioCookie::getGpioMap() const{
return gpioMap;
}

View File

@ -5,6 +5,7 @@
#include <bsp_q7s/gpio/GpioIF.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <string>
#include <unordered_map>
namespace Gpio {
enum Direction {
@ -27,7 +28,7 @@ typedef struct GpioConfig {
GpioConfig(std::string chipname_, int lineNum_, std::string consumer_,
Gpio::Direction direction_) :
chipname(chipname_), lineNum(lineNum_), consumer(consumer_), direction(
directio_) {
direction_) {
}
std::string chipname;
int lineNum;
@ -54,7 +55,7 @@ public:
virtual ~GpioCookie();
void addGpio(GpioMap newEntry);
void addGpio(gpioId_t gpioId, GpioConfig_t gpioConfig);
/**
* @brief Get map with registered GPIOs.
*/

View File

@ -23,7 +23,7 @@ else()
)
endif()
# message(STATUS "Using sysroot path: ${SYSROOT_PATH}")
message(STATUS "Using sysroot path: ${SYSROOT_PATH}")
set(CROSS_COMPILE_CC "${CROSS_COMPILE}-gcc")
set(CROSS_COMPILE_CXX "${CROSS_COMPILE}-g++")
@ -40,7 +40,7 @@ find_program (CROSS_COMPILE_CC_FOUND ${CROSS_COMPILE_CC} REQUIRED)
find_program (CROSS_COMPILE_CXX_FOUND ${CROSS_COMPILE_CXX} REQUIRED)
set(CMAKE_CROSSCOMPILING TRUE)
# set(CMAKE_SYSROOT "${SYSROOT_PATH}")
set(CMAKE_SYSROOT "${SYSROOT_PATH}")
# Define name of the target system
set(CMAKE_SYSTEM_NAME "Linux")
@ -52,9 +52,16 @@ set(CMAKE_CXX_COMPILER ${CROSS_COMPILE_CXX})
# List of library dirs where LD has to look. Pass them directly through gcc.
set(LIB_DIRS
"${SYSROOT_PATH}/usr/include"
"${SYSROOT_PATH}/usr/include/linux"
"${SYSROOT_PATH}/usr/lib"
"${SYSROOT_PATH}/lib"
"${SYSROOT_PATH}"
"${SYSROOT_PATH}/usr/lib/arm-xiphos-linux-gnueabi"
)
# You can additionally check the linker paths if you add the
# flags ' -Xlinker --verbose'
set(COMMON_FLAGS "-I${SYSROOT_PATH}/usr/lib")
foreach(LIB ${LIB_DIRS})
set(COMMON_FLAGS "${COMMON_FLAGS} -L${LIB} -Wl,-rpath-link,${LIB}")
endforeach()
@ -65,7 +72,7 @@ set(CMAKE_PREFIX_PATH
)
set(CMAKE_C_FLAGS
"-mcpu=cortex-a9 -mfpu=neon-vfpv3 -mfloat-abi=hard ${COMMON_FLAGS}"
"-mcpu=cortex-a9 -mfpu=neon-vfpv3 -mfloat-abi=hard ${COMMON_FLAGS} -lgpiod"
CACHE STRING "C flags for Q7S"
)
set(CMAKE_CXX_FLAGS

View File

@ -12,7 +12,7 @@
// debugging.
#define OBSW_ENHANCED_PRINTOUT 1
#define TE0720 0
#define TE0720 1
#include "OBSWVersion.h"

View File

@ -2,7 +2,7 @@
#define FSFWCONFIG_DEVICES_HEATERSWITCHERLIST_H_
namespace heaterSwitches {
enum switcherList {
enum switcherList: uint8_t {
PAYLOAD_CAMERA,
NUMBER_OF_SWITCHES
};

View File

@ -1,16 +1,40 @@
#ifndef FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_
#define FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_
#include <fsfwconfig/OBSWConfig.h>
namespace pcduSwitches {
/* Switches are uint8_t datatype and go from 0 to 255 */
enum switcherList {
PCDU,
GPS0,
GPS1,
TCS_BOARD_8V_HEATER_IN,
DUMMY = 129,
Q7S,
PAYLOAD_PCDU_CH1,
RW,
TCS_BOARD_8V_HEATER_IN,
SUS_REDUNDANT,
DEPLOYMENT_MECHANISM,
PAYLOAD_PCDU_CH6,
ACS_BOARD_SIDE_B,
PAYLOAD_CAMERA,
NUMBER_OF_SWITCHES
};
static const uint8_t ON = 1;
static const uint8_t OFF = 0;
/* Output states after reboot of the PDUs */
static const uint8_t INIT_STATE_Q7S = ON;
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF;
static const uint8_t INIT_STATE_RW = OFF;
#if TE0720 == 1
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON;
#else
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF;
#endif
static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF;
static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF;
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF;
static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF;
static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF;
}

View File

@ -1,7 +1,7 @@
#include "ACUHandler.h"
ACUHandler::ACUHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie,
uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress, uint16 hkTableSize) :
uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress, uint16_t hkTableSize) :
GomspaceDeviceHandler(objectId, comIF, comCookie, maxConfigTableAddress, maxHkTableAddress,
hkTableSize) {
}

View File

@ -71,7 +71,11 @@ ReturnValue_t GomspaceDeviceHandler::buildCommandFromCommand(
break;
}
case(GOMSPACE::REQUEST_HK_TABLE): {
generateRequestFullHkTableCmd(hkTableSize);
result = generateRequestFullHkTableCmd(hkTableSize);
if(result != HasReturnvaluesIF::RETURN_OK){
return result;
}
break;
}
default:
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;

View File

@ -1,11 +1,13 @@
#include <mission/devices/HeaterHandler.h>
#include <fsfwconfig/devices/powerSwitcherList.h>
#include <fsfw/ipc/QueueFactory.h>
#include <devices/gpioIds.h>
HeaterHandler::HeaterHandler(object_id_t setObjectId, object_id_t gpioDriverId,
CookieIF * gpioCookie, object_id_t mainLineSwitcherObjectId, uint8_t mainLineSwitch) :
SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE), gpioDriverId(gpioDriver),
gpioCookie(gpioCookie), mainLineSwitcherObjectId(mainLineSwitcherObjectId), mainLineSwitch(
mainLineSwitch), actionHelper(this, nullptr) {
HeaterHandler::HeaterHandler(object_id_t setObjectId_, object_id_t gpioDriverId_,
CookieIF * gpioCookie_, object_id_t mainLineSwitcherObjectId_, uint8_t mainLineSwitch_) :
SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_), mainLineSwitcherObjectId(
mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_), actionHelper(this,
nullptr) {
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
MessageQueueMessage::MAX_MESSAGE_SIZE);
}
@ -20,7 +22,7 @@ ReturnValue_t HeaterHandler::performOperation(uint8_t operationCode) {
handleActiveCommands();
return RETURN_OK;
}
return RETURN_OK;
}
ReturnValue_t HeaterHandler::initialize() {
@ -40,7 +42,7 @@ ReturnValue_t HeaterHandler::initialize() {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = gpioInterface->initializeInterface(gpioCookie);
result = gpioInterface->initialize(gpioCookie);
if (result != RETURN_OK) {
sif::error << "HeaterHandler::initialize: Failed to initialize Gpio interface" << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
@ -70,9 +72,8 @@ ReturnValue_t HeaterHandler::initialize() {
}
ReturnValue_t HeaterHandler::initializeHeaterMap(){
heaterMapIter = heaterMap.begin();
HeaterCommandInfo_t heaterCommandInfo;
for(int switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) {
for(switchNr_t switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) {
std::pair status = heaterMap.emplace(switchNr, heaterCommandInfo);
if (status.second == false) {
sif::error << "HeaterHandler::initializeHeaterMap: Failed to initialize heater map"
@ -84,7 +85,7 @@ ReturnValue_t HeaterHandler::initializeHeaterMap(){
}
void HeaterHandler::setInitialSwitchStates() {
for (int switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) {
for (switchNr_t switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) {
switchStates[switchNr] = OFF;
}
}
@ -104,16 +105,16 @@ void HeaterHandler::readCommandQueue() {
ReturnValue_t HeaterHandler::executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
if (actionId != SWITCH_ON && actionId != SWITCH_OFF) {
ReturnValue_t result;
if (actionId != SWITCH_HEATER) {
result = COMMAND_NOT_SUPPORTED;
} else {
heaterMapIter = heaterMap.find(*data);
switchNr_t switchNr = *data;
HeaterMapIter heaterMapIter = heaterMap.find(switchNr);
if (heaterMapIter != heaterMap.end()) {
heaterMapIter.second.action = *(data + 1);
heaterMapIter.second.active = true;
heaterMapIter->second.action = *(data + 1);
heaterMapIter->second.active = true;
heaterMapIter->second.replyQueue = commandedBy;
}
else {
sif::error << "HeaterHandler::executeAction: Invalid switchNr" << std::endl;
@ -136,77 +137,42 @@ void HeaterHandler::sendSwitchCommand(uint8_t switchNr,
case PowerSwitchIF::SWITCH_ON:
commandData[0] = switchNr;
commandData[1] = SET_SWITCH_ON;
break;
case PowerSwitchIF::SWITCH_OFF:
commandData[0] = switchNr;
commandData[1] = SET_SWITCH_OFF;
break;
default:
sif::error << "HeaterHandler::sendSwitchCommand: Invalid switch request"
<< std::endl;
break;
}
result = IPCStore->addData(&storeAddress, commandData, sizeof(commandData));
if (result == RETURN_OK) {
CommandMessage message;
ActionMessage::setCommand(&message,
HeaterHandler::SWITCH_HEATER, storeAddress);
ActionMessage::setCommand(&message, SWITCH_HEATER, storeAddress);
/* Send heater command to own command queue */
result = commandQueue->sendMessage(commandQueue, &message, 0);
result = commandQueue->sendMessage(commandQueue->getId(), &message, 0);
if (result != RETURN_OK) {
debug << "HeaterHandler::sendSwitchCommand: Failed to send switch"
sif::debug << "HeaterHandler::sendSwitchCommand: Failed to send switch"
<< "message" << std::endl;
}
}
}
void HeaterHandler::handleActiveCommands(){
ReturnValue_t result;
heaterMapIter = heaterMap.begin();
for (; heaterMapIter != mapToAdd.end(); heaterMapIter++) {
if (heaterMapIter.second.active) {
switch(heaterMapIter.second.action) {
HeaterMapIter heaterMapIter = heaterMap.begin();
for (; heaterMapIter != heaterMap.end(); heaterMapIter++) {
if (heaterMapIter->second.active) {
switch(heaterMapIter->second.action) {
case SET_SWITCH_ON:
int switchNr = heaterMapIter.first();
/* Check state of main line switch */
if (mainLineSwitcher->getSwitchState(pcduSwitches::TCS_BOARD_8V_HEATER_IN)
== SWITCH_ON) {
if (!checkSwitchState(switchNr)) {
gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr);
result = gpioInterface->pullHigh(gpioId);
if (result != RETURN_OK) {
triggerEvent(GPIO_PULL_HIGH_FAILED, result);
}
}
else {
triggerEvent(SWITCH_ALREADY_ON, switchNr);
}
/* There is no need to send action finish replies if the sender was the
* HeaterHandler itself. */
if (heaterMapIter.second.replyQueue != commandQueue) {
actionHelper.finish(heaterMapIter.second.replyQueue,
heaterMapIter.second.action, result);
}
heaterMapIter.second.active = false;
}
else {
mainLineSwitcher->sendSwitchCommand(pcduSwitches::TCS_BOARD_8V_HEATER_IN);
}
handleSwitchOnCommand(heaterMapIter);
break;
case SET_SWITCH_OFF:
int switchNr = heaterMapIter.first();
if (checkSwitchState(switchNr)) {
gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr);
result = gpioInterface->pullLow(gpioId);
triggerEvent(GPIO_PULL_LOW_FAILED, result);
}
else {
triggerEvent(SWITCH_ALREADY_OFF, switchNr);
}
if (heaterCommand.replyQueue != NO_COMMANDER) {
actionHelper.finish(heaterMapIter.second.replyQueue,
heaterMapIter.second.action, result);
}
break;
handleSwitchOffCommand(heaterMapIter);
break;
default:
sif::error << "HeaterHandler::handleActiveCommands: Invalid action commanded"
<< std::endl;
@ -216,11 +182,93 @@ void HeaterHandler::handleActiveCommands(){
}
}
void HeaterHandler::handleSwitchOnCommand(HeaterMapIter heaterMapIter) {
ReturnValue_t result;
switchNr_t switchNr;
/* Check if command waits for main switch being set on and whether the timeout has expired */
if (heaterMapIter->second.waitMainSwitchOn
&& heaterMapIter->second.mainSwitchCountdown.hasTimedOut()) {
//TODO: This requires the initiation of an FDIR procedure
triggerEvent(MAIN_SWITCH_TIMEOUT);
heaterMapIter->second.active = false;
return;
}
switchNr = heaterMapIter->first;
/* Check state of main line switch */
ReturnValue_t mainSwitchState = mainLineSwitcher->getSwitchState(mainLineSwitch);
if (mainSwitchState == PowerSwitchIF::SWITCH_ON) {
if (!checkSwitchState(switchNr)) {
gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr);
result = gpioInterface->pullHigh(gpioId);
if (result != RETURN_OK) {
sif::error << "HeaterHandler::handleSwitchOffCommand: Failed to pull gpio with id"
<< gpioId << "high" << std::endl;
triggerEvent(GPIO_PULL_HIGH_FAILED, result);
}
else {
switchStates[switchNr] = ON;
}
}
else {
triggerEvent(SWITCH_ALREADY_ON, switchNr);
}
/* There is no need to send action finish replies if the sender was the
* HeaterHandler itself. */
if (heaterMapIter->second.replyQueue != commandQueue->getId()) {
actionHelper.finish(heaterMapIter->second.replyQueue,
heaterMapIter->second.action, result);
}
heaterMapIter->second.active = false;
}
else if (mainSwitchState == PowerSwitchIF::SWITCH_OFF) {
mainLineSwitcher->sendSwitchCommand(mainLineSwitch,
PowerSwitchIF::SWITCH_ON);
heaterMapIter->second.mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs());
}
else {
sif::debug << "HeaterHandler::handleActiveCommands: Failed to get state of"
<< " main line switch" << std::endl;
if (heaterMapIter->second.replyQueue != commandQueue->getId()) {
actionHelper.finish(heaterMapIter->second.replyQueue,
heaterMapIter->second.action, mainSwitchState);
}
heaterMapIter->second.active = false;
}
}
void HeaterHandler::handleSwitchOffCommand(HeaterMapIter heaterMapIter) {
ReturnValue_t result;
switchNr_t switchNr = heaterMapIter->first;
if (checkSwitchState(switchNr)) {
gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr);
result = gpioInterface->pullLow(gpioId);
if (result != RETURN_OK) {
sif::error << "HeaterHandler::handleSwitchOffCommand: Failed to pull gpio with id"
<< gpioId << " low" << std::endl;
triggerEvent(GPIO_PULL_LOW_FAILED, result);
}
else {
switchStates[switchNr] = OFF;
}
}
else {
triggerEvent(SWITCH_ALREADY_OFF, switchNr);
}
if (heaterMapIter->second.replyQueue != NO_COMMANDER) {
actionHelper.finish(heaterMapIter->second.replyQueue,
heaterMapIter->second.action, result);
}
heaterMapIter->second.active = false;
}
bool HeaterHandler::checkSwitchState(int switchNr) {
return switchStates[switchNr];
}
gpioId_t HeaterHandler::getGpioIdFromSwitchNr(switchNr) {
gpioId_t HeaterHandler::getGpioIdFromSwitchNr(int switchNr) {
gpioId_t gpioId = 0xFFFF;
switch(switchNr) {
case heaterSwitches::PAYLOAD_CAMERA:
@ -234,3 +282,21 @@ gpioId_t HeaterHandler::getGpioIdFromSwitchNr(switchNr) {
return gpioId;
}
MessageQueueId_t HeaterHandler::getCommandQueue() const {
return commandQueue->getId();
}
void HeaterHandler::sendFuseOnCommand(uint8_t fuseNr) const {
}
ReturnValue_t HeaterHandler::getSwitchState( uint8_t switchNr ) const {
return 0;
}
ReturnValue_t HeaterHandler::getFuseState( uint8_t fuseNr ) const {
return 0;
}
uint32_t HeaterHandler::getSwitchDelayMs(void) const {
return 0;
}

View File

@ -8,6 +8,11 @@
#include <fsfw/modes/HasModesIF.h>
#include <fsfw/power/PowerSwitchIF.h>
#include <fsfwconfig/devices/heaterSwitcherList.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/devicehandlers/CookieIF.h>
#include <fsfw/timemanager/Countdown.h>
#include <unordered_map>
#include <bsp_q7s/gpio/GpioIF.h>
/**
* @brief This class intends the control of heaters.
@ -15,35 +20,35 @@
* @author J. Meier
*/
class HeaterHandler: public ExecutableObjectIF,
public PowerSwitchIF,
public SystemObject,
public HasActionsIF,
public HasModesIF,
public HasReturnvaluesIF {
public PowerSwitchIF,
public SystemObject,
public HasActionsIF {
public:
/** Device command IDs */
static const DeviceCommandId_t SWITCH_HEATER;
static const DeviceCommandId_t SWITCH_HEATER = 0x0;
HeaterHandler(object_id_t setObjectId, object_id_t gpioDriverId, CookieIF * gpioCookie,
object_id_t mainLineSwitcherObjectId, uint8_t mainLineSwitch);
virtual ~HeaterHandler();
virtual ReturnValue_t performOperation(uint8_t operationCode = 0);
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
void sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) override;
virtual void sendFuseOnCommand(uint8_t fuseNr) override;
virtual void sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const override;
virtual void sendFuseOnCommand(uint8_t fuseNr) const override;
/**
* @brief This function will be called from the Heater object to check
* the current switch state.
*/
virtual ReturnValue_t getSwitchState( uint8_t switchNr ) override;
virtual ReturnValue_t getFuseState( uint8_t fuseNr ) override;
virtual uint32_t getSwitchDelayMs(void) override;
ReturnValue_t executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, size_t size)
override;
virtual ReturnValue_t getSwitchState( uint8_t switchNr ) const override;
virtual ReturnValue_t getFuseState( uint8_t fuseNr ) const override;
virtual uint32_t getSwitchDelayMs(void) const override;
virtual MessageQueueId_t getCommandQueue() const override;
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) override;
virtual ReturnValue_t initialize() override;
private:
@ -58,6 +63,79 @@ private:
static const Event GPIO_PULL_LOW_FAILED = MAKE_EVENT(1, severity::LOW);
static const Event SWITCH_ALREADY_ON = MAKE_EVENT(2, severity::LOW);
static const Event SWITCH_ALREADY_OFF = MAKE_EVENT(3, severity::LOW);
static const Event MAIN_SWITCH_TIMEOUT = MAKE_EVENT(4, severity::LOW);
static const MessageQueueId_t NO_COMMANDER = 0;
enum SwitchState : bool {
ON = true,
OFF = false
};
/**
* @brief Struct holding information about a heater command to execute.
*
* @param action The action to perform.
* @param replyQueue The queue of the commander to which status replies
* will be sent.
* @param active True if command is waiting for execution, otherwise false.
* @param waitSwitchOn True if the command is waiting for the main switch being set on.
* @param mainSwitchCountdown Sets timeout to wait for main switch being set on.
*/
typedef struct HeaterCommandInfo {
uint8_t action;
MessageQueueId_t replyQueue;
bool active = false;
bool waitMainSwitchOn = false;
Countdown mainSwitchCountdown;
} HeaterCommandInfo_t;
enum SwitchAction {
SET_SWITCH_OFF,
SET_SWITCH_ON
};
using switchNr_t = uint8_t;
using HeaterMap = std::unordered_map<switchNr_t, HeaterCommandInfo_t>;
using HeaterMapIter = HeaterMap::iterator;
HeaterMap heaterMap;
bool switchStates[heaterSwitches::NUMBER_OF_SWITCHES];
/** Size of command queue */
size_t cmdQueueSize = 20;
/**
* The object ID of the GPIO driver which enables and disables the
* heaters.
*/
object_id_t gpioDriverId;
CookieIF * gpioCookie;
GpioIF* gpioInterface;
/** Queue to receive messages from other objects. */
MessageQueueIF* commandQueue = nullptr;
object_id_t mainLineSwitcherObjectId;
/** Switch number of the heater power supply switch */
uint8_t mainLineSwitch;
/**
* Power switcher object which controls the 8V main line of the heater
* logic on the TCS board.
*/
PowerSwitchIF *mainLineSwitcher = nullptr;
ActionHelper actionHelper;
StorageManagerIF *IPCStore = nullptr;
void readCommandQueue();
ReturnValue_t buildCommandFromCommand(
DeviceCommandId_t deviceCommand, const uint8_t *commandData,
@ -72,7 +150,7 @@ private:
* @brief Returns the ID of the GPIO related to a heater identified by the switch number
* which is defined in the heaterSwitches list.
*/
gpioId_t getGpioIdFromSwitchNr(switchNr);
gpioId_t getGpioIdFromSwitchNr(int switchNr);
/**
* @brief This function runs commands waiting for execution.
@ -86,68 +164,10 @@ private:
*/
void setInitialSwitchStates();
enum SwitchState : bool {
ON = true,
OFF = false
};
void handleSwitchOnCommand(HeaterMapIter heaterMapIter);
void handleSwitchOffCommand(HeaterMapIter heaterMapIter);
/**
* @brief Struct holding information about a heater command to execute.
*
* @param action The action to perform.
* @param replyQueue The queue of the commander to which status replies
* will be sent.
* @param active True if command is waiting for execution, otherwise false.
*/
typedef struct HeaterCommandInfo {
uint8_t action;
MessageQueueId_t replyQueue;
bool active = false;
} HeaterCommandInfo_t;
enum SwitchAction {
SET_SWITCH_ON,
SET_SWITCH_OFF
};
using switchNr_t = int;
using HeaterMap = std::unordered_map<switchNr_t, HeaterCommandInfo_t>;
using HeaterMapIter = HeaterMap::iterator;
HeateerMap heaterMap;
HeaterMapIter heaterMapIter;
bool switchStates[heaterSwitches::NUMBER_OF_SWITCHES];
/** Size of command queue */
size_t cmdQueueSize = 20;
/**
* The object ID of the GPIO driver which enables and disables the
* heaters.
*/
object_id_t gpioDriverId;
GpioIF* gpioInterface;
/** Queue to receive messages from other objects. */
MessageQueueIF* commandQueue = nullptr;
object_id_t mainLineSwitcherObjectId;
/** Switch number of the heater power supply switch */
uint8_t mainLineSwitch;
/**
* Power switcher object which controls the 8V main line of the heater
* logic on the TCS board.
*/
PowerSwitchIF *mainLineSwitcher = nullptr;
ActionHelper actionHelper;
StorageManagerIF *IPCStore = nullptr;
};
#endif /* MISSION_DEVICES_HEATERHANDLER_H_ */

View File

@ -2,8 +2,8 @@
#include <fsfwconfig/objects/systemObjectList.h>
#include <mission/devices/devicedefinitions/GomSpacePackets.h>
#include <fsfw/ipc/QueueFactory.h>
#include <fsfwconfig/devices/powerSwitcherList.h>
#include <fsfw/housekeeping/HousekeepingPacketUpdate.h>
#include <fsfwconfig/OBSWConfig.h>
PCDUHandler::PCDUHandler(object_id_t setObjectId, size_t cmdQueueSize) :
SystemObject(setObjectId), poolManager(this, nullptr), pdu2HkTableDataset(this), cmdQueueSize(
@ -55,6 +55,18 @@ ReturnValue_t PCDUHandler::initialize() {
return RETURN_OK;
}
void PCDUHandler::initializeSwitchStates() {
switchStates[pcduSwitches::Q7S] = pcduSwitches::INIT_STATE_Q7S;
switchStates[pcduSwitches::PAYLOAD_PCDU_CH1] = pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH1;
switchStates[pcduSwitches::RW] = pcduSwitches::INIT_STATE_RW;
switchStates[pcduSwitches::TCS_BOARD_8V_HEATER_IN] = pcduSwitches::INIT_STATE_TCS_BOARD_8V_HEATER_IN;
switchStates[pcduSwitches::SUS_REDUNDANT] = pcduSwitches::INIT_STATE_SUS_REDUNDANT;
switchStates[pcduSwitches::DEPLOYMENT_MECHANISM] = pcduSwitches::INIT_STATE_DEPLOYMENT_MECHANISM;
switchStates[pcduSwitches::PAYLOAD_PCDU_CH6] = pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH6;
switchStates[pcduSwitches::ACS_BOARD_SIDE_B] = pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_B;
switchStates[pcduSwitches::PAYLOAD_CAMERA] = pcduSwitches::INIT_STATE_PAYLOAD_CAMERA;
}
void PCDUHandler::readCommandQueue() {
ReturnValue_t result;
CommandMessage command;
@ -75,7 +87,7 @@ void PCDUHandler::handleChangedDataset(sid_t sid, store_address_t storeId) {
if (sid == sid_t(objects::PCDU_HANDLER, PDU2::HK_TABLE_DATA_SET_ID)) {
HousekeepingPacketUpdate packetUpdate(reinterpret_cast<uint8_t*>(&timeStamp),
sizeof(timeStamp), &pdu2HkTableDataset);
const uint8_t** packet_ptr;
const uint8_t** packet_ptr = NULL;
size_t size;
result = IPCStore->getData(storeId, packet_ptr, &size);
if (result != RETURN_OK) {
@ -93,12 +105,36 @@ void PCDUHandler::handleChangedDataset(sid_t sid, store_address_t storeId) {
sif::error << "PCDUHandler::handleChangedDataset: Failed to deserialize packet in "
<< "pdu2HkTableDataset" << std::endl;
}
updatePdu2SwitchStates();
}
else {
sif::error << "PCDUHandler::handleChangedDataset: Invalid sid" << std::endl;
}
}
void PCDUHandler::updatePdu2SwitchStates() {
if (pdu2HkTableDataset.read() != RETURN_OK) {
switchStates[pcduSwitches::Q7S] = pdu2HkTableDataset.outEnabledQ7S.value;
switchStates[pcduSwitches::PAYLOAD_PCDU_CH1] = pdu2HkTableDataset.outEnabledPlPCDUCh1.value;
switchStates[pcduSwitches::RW] = pdu2HkTableDataset.outEnabledReactionWheels.value;
switchStates[pcduSwitches::TCS_BOARD_8V_HEATER_IN] = pdu2HkTableDataset.outEnabledTCSBoardHeaterIn.value;
switchStates[pcduSwitches::SUS_REDUNDANT] = pdu2HkTableDataset.outEnabledSUS.value;
switchStates[pcduSwitches::DEPLOYMENT_MECHANISM] = pdu2HkTableDataset.outEnabledDeplMechanism.value;
switchStates[pcduSwitches::PAYLOAD_PCDU_CH6] = pdu2HkTableDataset.outEnabledPlPCDUCh6.value;
switchStates[pcduSwitches::ACS_BOARD_SIDE_B] = pdu2HkTableDataset.outEnabledAcsBoard.value;
switchStates[pcduSwitches::PAYLOAD_CAMERA] = pdu2HkTableDataset.outEnabledPayloadCamera.value;
}
else {
sif::debug << "PCDUHandler::updatePdu2SwitchStates: Failed to read PDU2 Hk Dataset"
<< std::endl;
}
pdu2HkTableDataset.commit();
}
void PCDUHandler::updatePdu1SwitchStates() {
}
LocalDataPoolManager* PCDUHandler::getHkManagerHandle() {
return &poolManager;
}
@ -133,11 +169,13 @@ void PCDUHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const
return;
}
const uint8_t* parameterValuePtr = &parameterValue;
GomspaceSetParamMessage setParamMessage(memoryAddress, &parameterValuePtr, parameterValueSize);
size_t serializedLength = 0;
uint8_t command[4];
uint8_t* commandPtr = command;
size_t maxSize = sizeof(command);
GomspaceSetParamMessage setParamMessage(memoryAddress, &parameterValue, parameterValueSize);
setParamMessage.serialize(&commandPtr, &serializedLength, maxSize,
SerializeIF::Endianness::BIG);
@ -159,18 +197,16 @@ void PCDUHandler::sendFuseOnCommand(uint8_t fuseNr) const {
}
ReturnValue_t PCDUHandler::getSwitchState( uint8_t switchNr ) const {
switch (switchNr) {
case pcduSwitches::TCS_BOARD_8V_HEATER_IN:
if (pdu2HkTableDataset.outEnabledTCSBoardHeaterIn == 1) {
return PowerSwitchIF::SWITCH_ON;
}
else {
return PowerSwitchIF::SWITCH_OFF;
}
default:
sif::error << "PCDUHandler::getSwitchState: Invalid switchNr" << std::endl;
return RETURN_FAILED;
}
if (switchNr >= pcduSwitches::NUMBER_OF_SWITCHES) {
sif::debug << "PCDUHandler::getSwitchState: Invalid switch number" << std::endl;
return RETURN_FAILED;
}
if (switchStates[switchNr] == 1) {
return PowerSwitchIF::SWITCH_ON;
}
else {
return PowerSwitchIF::SWITCH_OFF;
}
}
ReturnValue_t PCDUHandler::getFuseState( uint8_t fuseNr ) const {
@ -178,34 +214,44 @@ ReturnValue_t PCDUHandler::getFuseState( uint8_t fuseNr ) const {
}
uint32_t PCDUHandler::getSwitchDelayMs(void) const {
return 0;
return 5000;
}
object_id_t PCDUHandler::getObjectId() const {
return SystemObject::getObjectId();
}
ReturnValue_t PCDUHandler::initializeLocalDataPool(
localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
ReturnValue_t PCDUHandler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_Q7S, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH1, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH1,
new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_RW, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_TCS_BOARD_HEATER_IN, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_TCS_BOARD_HEATER_IN,
new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_SUS_REDUNDANT, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_DEPLOYMENT_MECHANISM, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH6, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_ACS_BOARD_SIDE_B, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_DEPLOYMENT_MECHANISM,
new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH6,
new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_ACS_BOARD_SIDE_B,
new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_PAYLOAD_CAMERA, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_Q7S, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH1, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH1,
new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_RW, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_TCS_BOARD_HEATER_IN, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_TCS_BOARD_HEATER_IN,
new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_SUS_REDUNDANT, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_DEPLOYMENT_MECHANISM, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH6, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_ACS_BOARD_SIDE_B, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_DEPLOYMENT_MECHANISM,
new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH6,
new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_ACS_BOARD_SIDE_B,
new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_CAMERA, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VCC, new PoolEntry<int16_t>( { 0 }));
@ -213,15 +259,27 @@ ReturnValue_t PCDUHandler::initializeLocalDataPool(
localDataPoolMap.emplace(PDU::PDU2_TEMPERATURE, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CONV_EN, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_Q7S, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH1, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_RW, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_SUS_REDUNDANT, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_DEPLOYMENT_MECHANISM, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH6, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_ACS_BOARD_SIDE_B, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_CAMERA, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_Q7S, new PoolEntry<uint8_t>( {
pcduSwitches::INIT_STATE_Q7S }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH1, new PoolEntry<uint8_t>( {
pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH1 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_RW, new PoolEntry<uint8_t>( {
pcduSwitches::INIT_STATE_RW }));
#if TE0720 == 1
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry<uint8_t>( { 1 }));
#else
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry<uint8_t>( {pcduSwitches::INIT_STATE_TCS_BOARD_8V_HEATER_IN}));
#endif
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_SUS_REDUNDANT, new PoolEntry<uint8_t>( {
pcduSwitches::INIT_STATE_SUS_REDUNDANT }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_DEPLOYMENT_MECHANISM, new PoolEntry<uint8_t>( {
pcduSwitches::INIT_STATE_DEPLOYMENT_MECHANISM }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH6, new PoolEntry<uint8_t>( {
pcduSwitches::INIT_STATE_PAYLOAD_PCDU_CH6 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_ACS_BOARD_SIDE_B, new PoolEntry<uint8_t>( {
pcduSwitches::INIT_STATE_ACS_BOARD_SIDE_B }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_CAMERA, new PoolEntry<uint8_t>( {
pcduSwitches::INIT_STATE_PAYLOAD_CAMERA }));
localDataPoolMap.emplace(PDU::PDU2_BOOTCAUSE, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_BOOTCNT, new PoolEntry<uint32_t>( { 0 }));
@ -266,6 +324,8 @@ ReturnValue_t PCDUHandler::initializeAfterTaskCreation() {
}
this->poolManager.initializeAfterTaskCreation();
initializeSwitchStates();
return HasReturnvaluesIF::RETURN_OK;
}
@ -278,12 +338,10 @@ void PCDUHandler::setTaskIF(PeriodicTaskIF* task){
}
LocalPoolDataSetBase* PCDUHandler::getDataSetHandle(sid_t sid) {
switch (sid) {
case pdu2HkTableDataset.getSid():
if (sid == pdu2HkTableDataset.getSid()) {
return &pdu2HkTableDataset;
default:
} else {
sif::error << "PCDUHandler::getDataSetHandle: Invalid sid" << std::endl;
return nullptr;
break;
}
}

View File

@ -9,6 +9,7 @@
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfwconfig/devices/powerSwitcherList.h>
/**
* @brief The PCDUHandler provides a compact interface to handle all devices related to the
@ -43,12 +44,16 @@ public:
LocalDataPoolManager& poolManager) override;
virtual uint32_t getPeriodicOperationFrequency() const override;
virtual ReturnValue_t initializeAfterTaskCreation() override;
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
virtual void setTaskIF(PeriodicTaskIF* task_);
private:
uint32_t pstIntervalMs = 0;
/** Housekeeping manager. Handles updates of local pool variables. */
LocalDataPoolManager poolManager;
/**
* The dataset holding the hk table of PDU2. This dataset is a copy of the PDU2 HK dataset
* of the PDU2Handler. Each time the PDU2Handler updates his HK dataset, a copy is sent
@ -58,6 +63,7 @@ private:
/** The timeStamp of the current pdu2HkTableDataset */
CCSDSTime::CDS_short timeStamp;
uint8_t switchStates[pcduSwitches::NUMBER_OF_SWITCHES];
/**
* Pointer to the IPCStore.
* This caches the pointer received from the objectManager in the constructor.
@ -72,12 +78,27 @@ private:
size_t cmdQueueSize;
/** Housekeeping manager. Handles updates of local pool variables. */
LocalDataPoolManager poolManager;
PeriodicTaskIF* executingTask = nullptr;
void readCommandQueue();
/**
* @brief This function sets all switchStates to the initial switch configuration of the
* two PDUs after reboot.
*/
void initializeSwitchStates();
/**
* @brief Updates all switchStates related to the PDU2.
* Function is called each time a new hk dataset has been received from the PDU2Handler.
*/
void updatePdu2SwitchStates();
/**
* @brief Updates all switchStates related to the PDU1. Called each time the PDU1Handler
* sends a new hk dataset.
*/
void updatePdu1SwitchStates();
};
#endif /* MISSION_DEVICES_PCDUHANDLER_H_ */

View File

@ -1,9 +1,10 @@
#include "PDU1Handler.h"
#include <mission/devices/devicedefinitions/GomSpacePackets.h>
PDU1Handler::PDU1Handler(object_id_t objectId, object_id_t comIF,
CookieIF * comCookie, uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress,
uint16_t hkTableSize) : GomspaceDeviceHandler(objectId, comIF,
comCookie, maxConfigTableAddress, maxHkTableAddress, hkTableSize) {
PDU1Handler::PDU1Handler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie,
uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress, uint16_t hkTableSize) :
GomspaceDeviceHandler(objectId, comIF, comCookie, maxConfigTableAddress, maxHkTableAddress,
hkTableSize), hkTableDataset(this) {
}
PDU1Handler::~PDU1Handler() {
@ -19,7 +20,7 @@ void PDU1Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *pac
const uint8_t* payloadPtr = packet + GOMSPACE::GS_HDR_LENGTH;
size_t size = (size_t)hkTableSize;
hkTableDataset.deSerialize(&payloadPtr, &size, SerializeIF::Endianness::BIG);
FullTableReply fullTableReply(id, HK_TABLE_ID, hkTableDataset);
FullTableReply fullTableReply(id, HK_TABLE_ID, &hkTableDataset);
handleDeviceTM(&fullTableReply, id, true);
}

View File

@ -1,5 +1,6 @@
#include "PDU2Handler.h"
#include <mission/devices/devicedefinitions/GomSpacePackets.h>
#include <fsfwconfig/OBSWConfig.h>
PDU2Handler::PDU2Handler(object_id_t objectId, object_id_t comIF,
CookieIF * comCookie, uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress,
@ -41,6 +42,7 @@ ReturnValue_t PDU2Handler::initializeLocalDataPool(
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH1, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_RW, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_TCS_BOARD_HEATER_IN, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_TCS_BOARD_HEATER_IN, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_SUS_REDUNDANT, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_DEPLOYMENT_MECHANISM, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH6, new PoolEntry<int16_t>( { 0 }));
@ -55,7 +57,11 @@ ReturnValue_t PDU2Handler::initializeLocalDataPool(
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_Q7S, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH1, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_RW, new PoolEntry<uint8_t>( { 0 }));
#if TE0720 == 1
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry<uint8_t>( { 1 }));
#else
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry<uint8_t>( { 0 }));
#endif
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_SUS_REDUNDANT, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_DEPLOYMENT_MECHANISM, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH6, new PoolEntry<uint8_t>( { 0 }));

View File

@ -186,7 +186,7 @@ private:
class RequestFullTableCommand : public SerialLinkedListAdapter<SerializeIF> {
public:
RequestFullTableCommand(uint16_t querySize_, uint8_t tableId) :
RequestFullTableCommand(uint16_t querySize_, uint8_t tableId_) :
querySize(querySize_), tableId(tableId_) {
setLinks();
}
@ -337,8 +337,8 @@ private:
void setLinks() {
setStart(&action);
action.setNext(&tableId);
tableId.setNext(&tableLength);
tableLength.setNext(&tableDataset);
tableId.setNext(&tableDataset);
tableDataset.setNext(&tableDataset);
}
SerializeElement<uint8_t> action;
SerializeElement<uint8_t> tableId;
@ -404,11 +404,11 @@ public:
* @param parameterSize The size of the parameter.
*
*/
GomspaceSetParamMessage(uint16_t memoryAddress, uint8_t* parameterValue, uint8_t parameterSize) :
memoryAddress(memoryAddress) {
const uint8_t** buffer;
*buffer = parameterValue;
parameterInfo.deserialize(buffer, parameterSize, SerializeIF::Endianness::BIG);
GomspaceSetParamMessage(uint16_t memoryAddress, const uint8_t** parameterValue,
uint8_t parameterSize) :
memoryAddress(memoryAddress) {
size_t size = parameterSize;
parameterValueInfo.deSerialize(parameterValue, &size, SerializeIF::Endianness::BIG);
setLinks();
}
@ -416,7 +416,7 @@ private:
GomspaceSetParamMessage(const FullTableReply &reply);
void setLinks() {
setStart(&memoryAddress);
memoryAddress.setNext(&parameter);
memoryAddress.setNext(&parameterValueInfo);
}
SerializeElement<uint16_t> memoryAddress;
SerializeElement<SerialFixedArrayListAdapter<uint8_t, MAX_SIZE, uint8_t>> parameterValueInfo;

2
tmtc

@ -1 +1 @@
Subproject commit 6b840eff43440a7b44df1cc089338f600a4a6d88
Subproject commit 39e8ff713431ed1a6484f6980b518aecd0d8288b