Merge remote-tracking branch 'origin/develop' into mueller/acs-ss-init
All checks were successful
EIVE/eive-obsw/pipeline/pr-develop This commit looks good

This commit is contained in:
Robin Müller 2022-10-27 08:31:21 +02:00
commit 592cbf6fad
No known key found for this signature in database
GPG Key ID: 71B58F8A3CDFA9AC
31 changed files with 214 additions and 98 deletions

View File

@ -98,9 +98,30 @@ set(OBSW_ADD_ACS_BOARD
set(OBSW_ADD_GPS_CTRL
${INIT_VAL}
CACHE STRING "Add GPS controllers")
set(OBSW_ADD_CCSDS_IP_CORES
1
CACHE STRING "Add CCSDS IP cores")
set(OBSW_TM_TO_PTME
1
CACHE STRING "Send telemetry to PTME IP core")
set(OBSW_TC_FROM_PDEC
1
CACHE STRING "Poll telecommand from PDEC IP core")
set(OBSW_ADD_TCS_CTRL
${INIT_VAL}
CACHE STRING "Add TCS controllers")
set(OBSW_ADD_HEATERS
${INIT_VAL}
CACHE STRING "Add TCS heaters")
set(OBSW_ADD_PLOC_SUPERVISOR
${INIT_VAL}
CACHE STRING "Add PLOC supervisor handler")
set(OBSW_ADD_SA_DEPL
${INIT_VAL}
CACHE STRING "Add SA deployment handler")
set(OBSW_ADD_PLOC_MPSOC
${INIT_VAL}
CACHE STRING "Add MPSoC handler")
set(OBSW_ADD_ACS_CTRL
${INIT_VAL}
CACHE STRING "Add ACS controller")

View File

@ -16,7 +16,7 @@
debugging. */
#define OBSW_VEBOSE_LEVEL 1
#define OBSW_USE_CCSDS_IP_CORE 0
#define OBSW_ADD_CCSDS_IP_CORES 0
// 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

View File

@ -103,7 +103,7 @@
/*******************************************************************/
#cmakedefine EIVE_BUILD_GPSD_GPS_HANDLER
#define OBSW_USE_CCSDS_IP_CORE 0
#define OBSW_ADD_CCSDS_IP_CORES 0
// 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

View File

@ -14,18 +14,12 @@
/** All of the following flags should be enabled for mission code */
/*******************************************************************/
#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
#define OBSW_TC_FROM_PDEC 0
#define OBSW_ADD_GOMSPACE_PCDU @OBSW_ADD_GOMSPACE_PCDU@
#define OBSW_ADD_MGT @OBSW_ADD_MGT@
#define OBSW_ADD_BPX_BATTERY_HANDLER @OBSW_ADD_BPX_BATTERY_HANDLER@
#define OBSW_ADD_STAR_TRACKER @OBSW_ADD_STAR_TRACKER@
#define OBSW_ADD_PLOC_SUPERVISOR 1
#define OBSW_ADD_PLOC_MPSOC 1
#define OBSW_ADD_PLOC_SUPERVISOR @OBSW_ADD_PLOC_SUPERVISOR@
#define OBSW_ADD_PLOC_MPSOC @OBSW_ADD_PLOC_MPSOC@
#define OBSW_ADD_SUN_SENSORS @OBSW_ADD_SUN_SENSORS@
#define OBSW_ADD_SUS_BOARD_ASS @OBSW_ADD_SUS_BOARD_ASS@
#define OBSW_ADD_ACS_BOARD @OBSW_ADD_ACS_BOARD@
@ -34,11 +28,18 @@
#define OBSW_ADD_TCS_CTRL @OBSW_ADD_TCS_CTRL@
#define OBSW_ADD_RW @OBSW_ADD_RW@
#define OBSW_ADD_RTD_DEVICES @OBSW_ADD_RTD_DEVICES@
#define OBSW_ADD_SA_DEPL @OBSW_ADD_SA_DEPL@
#define OBSW_ADD_SCEX_DEVICE @OBSW_ADD_SCEX_DEVICE@
#define OBSW_ADD_HEATERS @OBSW_ADD_HEATERS@
#define OBSW_ADD_TMP_DEVICES @OBSW_ADD_TMP_DEVICES@
#define OBSW_ADD_RAD_SENSORS @OBSW_ADD_RAD_SENSORS@
#define OBSW_ADD_PL_PCDU @OBSW_ADD_PL_PCDU@
#define OBSW_ADD_SYRLINKS @OBSW_ADD_SYRLINKS@
#define OBSW_ADD_CCSDS_IP_CORES @OBSW_ADD_CCSDS_IP_CORES@
// Set to 1 if all telemetry should be sent to the PTME IP Core
#define OBSW_TM_TO_PTME @OBSW_TM_TO_PTME@
// Set to 1 if telecommands are received via the PDEC IP Core
#define OBSW_TC_FROM_PDEC @OBSW_TC_FROM_PDEC@
#define OBSW_ENABLE_SYRLINKS_TRANSMIT_TIMEOUT 0
// Configuration parameter which causes the core controller to try to keep at least one SD card

View File

@ -75,8 +75,10 @@ ReturnValue_t Q7STestTask::performOneShotAction() {
if (doTestProtHandler) {
testProtHandler();
}
FsOpCodes opCode = FsOpCodes::CREATE_EMPTY_FILE_IN_TMP;
testFileSystemHandlerDirect(opCode);
if (DO_TEST_FS_HANDLER) {
FsOpCodes opCode = FsOpCodes::CREATE_EMPTY_FILE_IN_TMP;
testFileSystemHandlerDirect(opCode);
}
return TestTask::performOneShotAction();
}

View File

@ -18,6 +18,7 @@ class Q7STestTask : public TestTask {
bool doTestScratchApi = false;
static constexpr bool DO_TEST_GOMSPACE_API = false;
static constexpr bool DO_TEST_GOMSPACE_GET_CONFIG = false;
static constexpr bool DO_TEST_FS_HANDLER = false;
bool doTestGpsShm = false;
bool doTestGpsSocket = false;
bool doTestProtHandler = false;

View File

@ -41,19 +41,19 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sen
uint8_t writeSize = 0;
gpioId_t gpioId = cookie->getChipSelectPin();
GpioIF* gpioIF = comIf->getGpioInterface();
GpioIF& gpioIF = comIf->getGpioInterface();
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
uint32_t timeoutMs = 0;
MutexIF* mutex = comIf->getCsMutex();
cookie->getMutexParams(timeoutType, timeoutMs);
if (mutex == nullptr or gpioIF == nullptr) {
if (mutex == nullptr) {
sif::debug << "rwSpiCallback::spiCallback: Mutex or GPIO interface invalid" << std::endl;
return returnvalue::FAILED;
}
int fileDescriptor = 0;
const std::string& dev = comIf->getSpiDev();
result = openSpi(dev, O_RDWR, gpioIF, gpioId, mutex, timeoutType, timeoutMs, fileDescriptor);
result = openSpi(dev, O_RDWR, &gpioIF, gpioId, mutex, timeoutType, timeoutMs, fileDescriptor);
if (result != returnvalue::OK) {
return result;
}
@ -75,7 +75,7 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sen
if (write(fileDescriptor, writeBuffer, writeSize) != static_cast<ssize_t>(writeSize)) {
sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl;
closeSpi(fileDescriptor, gpioId, gpioIF, mutex);
closeSpi(fileDescriptor, gpioId, &gpioIF, mutex);
return RwHandler::SPI_WRITE_FAILURE;
}
@ -100,7 +100,7 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sen
}
if (write(fileDescriptor, writeBuffer, writeSize) != static_cast<ssize_t>(writeSize)) {
sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl;
closeSpi(fileDescriptor, gpioId, gpioIF, mutex);
closeSpi(fileDescriptor, gpioId, &gpioIF, mutex);
return RwHandler::SPI_WRITE_FAILURE;
}
idx++;
@ -112,14 +112,14 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sen
if (write(fileDescriptor, writeBuffer, writeSize) != static_cast<ssize_t>(writeSize)) {
sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl;
closeSpi(fileDescriptor, gpioId, gpioIF, mutex);
closeSpi(fileDescriptor, gpioId, &gpioIF, mutex);
return RwHandler::SPI_WRITE_FAILURE;
}
uint8_t* rxBuf = nullptr;
result = comIf->getReadBuffer(cookie->getSpiAddress(), &rxBuf);
if (result != returnvalue::OK) {
closeSpi(fileDescriptor, gpioId, gpioIF, mutex);
closeSpi(fileDescriptor, gpioId, &gpioIF, mutex);
return result;
}
@ -127,9 +127,9 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sen
// There must be a delay of at least 20 ms after sending the command.
// Delay for 70 ms here and release the SPI bus for that duration.
closeSpi(fileDescriptor, gpioId, gpioIF, mutex);
closeSpi(fileDescriptor, gpioId, &gpioIF, mutex);
usleep(RwDefinitions::SPI_REPLY_DELAY);
result = openSpi(dev, O_RDWR, gpioIF, gpioId, mutex, timeoutType, timeoutMs, fileDescriptor);
result = openSpi(dev, O_RDWR, &gpioIF, gpioId, mutex, timeoutType, timeoutMs, fileDescriptor);
if (result != returnvalue::OK) {
return result;
}
@ -142,13 +142,13 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sen
for (int idx = 0; idx < 10; idx++) {
if (read(fileDescriptor, &byteRead, 1) != 1) {
sif::error << "rwSpiCallback::spiCallback: Read failed" << std::endl;
closeSpi(fileDescriptor, gpioId, gpioIF, mutex);
closeSpi(fileDescriptor, gpioId, &gpioIF, mutex);
return RwHandler::SPI_READ_FAILURE;
}
if (idx == 0) {
if (byteRead != FLAG_BYTE) {
sif::error << "Invalid data, expected start marker" << std::endl;
closeSpi(fileDescriptor, gpioId, gpioIF, mutex);
closeSpi(fileDescriptor, gpioId, &gpioIF, mutex);
return RwHandler::NO_START_MARKER;
}
}
@ -159,7 +159,7 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sen
if (idx == 9) {
sif::error << "rwSpiCallback::spiCallback: Empty frame timeout" << std::endl;
closeSpi(fileDescriptor, gpioId, gpioIF, mutex);
closeSpi(fileDescriptor, gpioId, &gpioIF, mutex);
return RwHandler::NO_REPLY;
}
}
@ -199,7 +199,7 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sen
continue;
} else {
sif::error << "rwSpiCallback::spiCallback: Invalid substitute" << std::endl;
closeSpi(fileDescriptor, gpioId, gpioIF, mutex);
closeSpi(fileDescriptor, gpioId, &gpioIF, mutex);
result = RwHandler::INVALID_SUBSTITUTE;
break;
}
@ -233,7 +233,7 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sen
cookie->setTransferSize(decodedFrameLen);
closeSpi(fileDescriptor, gpioId, gpioIF, mutex);
closeSpi(fileDescriptor, gpioId, &gpioIF, mutex);
return result;
}

View File

@ -3,6 +3,7 @@
#include <fsfw/events/EventManager.h>
#include <fsfw/filesystem/HasFileSystemIF.h>
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/tasks/TaskFactory.h>
#include "OBSWVersion.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
@ -78,6 +79,12 @@ void CoreController::performControlOperation() {
sdStateMachine();
performMountedSdCardOperations();
if (sdCardCheckCd.hasTimedOut()) {
if (shortSdCardCdCounter < 2) {
shortSdCardCdCounter++;
}
if (shortSdCardCdCounter == 2) {
sdCardCheckCd.setTimeout(DEFAULT_SD_CARD_CHECK_TIMEOUT);
}
performSdCardCheck();
sdCardCheckCd.resetTimer();
}
@ -929,6 +936,9 @@ ReturnValue_t CoreController::actionReboot(const uint8_t *data, size_t size) {
ReturnValue_t CoreController::gracefulShutdownTasks(xsc::Chip chip, xsc::Copy copy,
bool &protOpPerformed) {
sdcMan->setBlocking(true);
sdcMan->markUnusable();
// Wait two seconds to ensure no one uses the SD cards
TaskFactory::delayTask(2000);
// Attempt graceful shutdown by unmounting and switching off SD cards
sdcMan->switchOffSdCard(sd::SdCard::SLOT_0);
sdcMan->switchOffSdCard(sd::SdCard::SLOT_1);

View File

@ -70,6 +70,9 @@ class CoreController : public ExtendedControllerBase {
static constexpr char CHIP_1_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi1-nom-rootfs";
static constexpr char CHIP_1_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi1-gold-rootfs";
static constexpr dur_millis_t INIT_SD_CARD_CHECK_TIMEOUT = 5000;
static constexpr dur_millis_t DEFAULT_SD_CARD_CHECK_TIMEOUT = 60000;
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
static constexpr ActionId_t SWITCH_REBOOT_FILE_HANDLING = 5;
static constexpr ActionId_t RESET_REBOOT_COUNTERS = 6;
@ -210,6 +213,8 @@ class CoreController : public ExtendedControllerBase {
RebootFile rebootFile = {};
std::string currMntPrefix;
bool performOneShotSdCardOpsSwitch = false;
uint8_t shortSdCardCdCounter = 0;
Countdown sdCardCheckCd = Countdown(INIT_SD_CARD_CHECK_TIMEOUT);
/**
* Index 0: Chip 0 Copy 0
@ -229,7 +234,7 @@ class CoreController : public ExtendedControllerBase {
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
Countdown sdCardCheckCd = Countdown(120000);
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t* msToReachTheMode);
void performMountedSdCardOperations();

View File

@ -73,6 +73,7 @@ void initmission::initTasks() {
if (result != returnvalue::OK) {
initmission::printAddObjectError("CORE_CTRL", objects::CORE_CONTROLLER);
}
#if OBSW_ADD_SA_DEPL == 1
// Could add this to the core controller but the core controller does so many thing that I would
// prefer to have the solar array deployment in a seprate task.
PeriodicTaskIF* solarArrayDeplTask = factory->createPeriodicTask(
@ -81,6 +82,7 @@ void initmission::initTasks() {
if (result != returnvalue::OK) {
initmission::printAddObjectError("SOLAR_ARRAY_DEPL", objects::SOLAR_ARRAY_DEPL_HANDLER);
}
#endif
/* TMTC Distribution */
PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
@ -117,7 +119,7 @@ void initmission::initTasks() {
}
#endif
#if OBSW_USE_CCSDS_IP_CORE == 1
#if OBSW_ADD_CCSDS_IP_CORES == 1
PeriodicTaskIF* ccsdsHandlerTask = factory->createPeriodicTask(
"CCSDS_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
result = ccsdsHandlerTask->addComponent(objects::CCSDS_HANDLER);
@ -134,7 +136,7 @@ void initmission::initTasks() {
if (result != returnvalue::OK) {
initmission::printAddObjectError("PDEC Handler", objects::PDEC_HANDLER);
}
#endif /* OBSW_USE_CCSDS_IP_CORE == 1 */
#endif /* OBSW_ADD_CCSDS_IP_CORE == 1 */
#if OBSW_ADD_CFDP_COMPONENTS == 1
PeriodicTaskIF* cfdpTask = factory->createPeriodicTask(
@ -239,10 +241,12 @@ void initmission::initTasks() {
initmission::printAddObjectError("THERMAL_CONTROLLER", objects::THERMAL_CONTROLLER);
}
#endif
#if OBSW_ADD_HEATERS == 1
result = tcsSystemTask->addComponent(objects::HEATER_HANDLER);
if (result != returnvalue::OK) {
initmission::printAddObjectError("HEATER_HANDLER", objects::HEATER_HANDLER);
}
#endif
#if OBSW_ADD_STAR_TRACKER == 1
PeriodicTaskIF* strHelperTask = factory->createPeriodicTask(
@ -312,13 +316,15 @@ void initmission::initTasks() {
tmtcPollingTask->startTask();
#endif
#if OBSW_USE_CCSDS_IP_CORE == 1
#if OBSW_ADD_CCSDS_IP_CORES == 1
ccsdsHandlerTask->startTask();
pdecHandlerTask->startTask();
#endif /* OBSW_USE_CCSDS_IP_CORE == 1 */
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
sysCtrlTask->startTask();
// sysCtrlTask->startTask();
#if OBSW_ADD_SA_DEPL == 1
solarArrayDeplTask->startTask();
#endif
taskStarter(pstTasks, "PST task vector");
taskStarter(pusTasks, "PUS task vector");
@ -345,7 +351,9 @@ void initmission::initTasks() {
tcsPollingTask->startTask();
tcsTask->startTask();
#endif /* OBSW_ADD_RTD_DEVICES == 1 */
tcsSystemTask->startTask();
if (not tcsSystemTask->isEmpty()) {
tcsSystemTask->startTask();
}
#if OBSW_ADD_PLOC_SUPERVISOR == 1
supvHelperTask->startTask();
#endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */

View File

@ -147,10 +147,8 @@ void ObjectFactory::createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, Ua
new CspComIF(objects::CSP_COM_IF);
*i2cComIF = new I2cComIF(objects::I2C_COM_IF);
*uartComIF = new UartComIF(objects::UART_COM_IF);
*spiMainComIF = new SpiComIF(objects::SPI_MAIN_COM_IF, q7s::SPI_DEFAULT_DEV, *gpioComIF);
*spiRWComIF = new SpiComIF(objects::SPI_RW_COM_IF, q7s::SPI_RW_DEV, *gpioComIF);
/* Adding gpios for chip select decoding to the gpioComIf */
q7s::gpioCallbacks::initSpiCsDecoder(*gpioComIF);
*spiMainComIF = new SpiComIF(objects::SPI_MAIN_COM_IF, q7s::SPI_DEFAULT_DEV, **gpioComIF);
*spiRWComIF = new SpiComIF(objects::SPI_RW_COM_IF, q7s::SPI_RW_DEV, **gpioComIF);
}
void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF** pwrSwitcher) {
@ -195,8 +193,11 @@ void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchI
#endif
}
void ObjectFactory::createRadSensorComponent(LinuxLibgpioIF* gpioComIF) {
ReturnValue_t ObjectFactory::createRadSensorComponent(LinuxLibgpioIF* gpioComIF) {
using namespace gpio;
if(gpioComIF == nullptr) {
return returnvalue::FAILED;
}
GpioCookie* gpioCookieRadSensor = new GpioCookie;
std::stringstream consumer;
consumer << "0x" << std::hex << objects::RAD_SENSOR;
@ -222,6 +223,7 @@ void ObjectFactory::createRadSensorComponent(LinuxLibgpioIF* gpioComIF) {
#if OBSW_DEBUG_RAD_SENSOR == 1
radSensor->enablePeriodicDataPrint(true);
#endif
return returnvalue::OK;
}
void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF,

View File

@ -26,7 +26,7 @@ void createPcduComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF** pwrSwitcher
void createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF,
PowerSwitchIF* pwrSwitcher);
void createTmpComponents();
void createRadSensorComponent(LinuxLibgpioIF* gpioComIF);
ReturnValue_t createRadSensorComponent(LinuxLibgpioIF* gpioComIF);
void createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF,
PowerSwitchIF* pwrSwitcher);
void createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwitcher, HealthTableIF* healthTable);

View File

@ -1,3 +1,4 @@
#include <bsp_q7s/callbacks/q7sGpioCallbacks.h>
#include <fsfw/health/HealthTableIF.h>
#include <fsfw/power/DummyPowerSwitcher.h>
@ -24,6 +25,9 @@ void ObjectFactory::produce(void* args) {
I2cComIF* i2cComIF = nullptr;
SpiComIF* spiRwComIF = nullptr;
createCommunicationInterfaces(&gpioComIF, &uartComIF, &spiMainComIF, &i2cComIF, &spiRwComIF);
/* Adding gpios for chip select decoding to the gpioComIf */
q7s::gpioCallbacks::initSpiCsDecoder(gpioComIF);
gpioCallbacks::disableAllDecoder(gpioComIF);
// Hardware is usually not connected to EM, so we need to create dummies which replace lower
// level components.
@ -33,8 +37,8 @@ void ObjectFactory::produce(void* args) {
new CoreController(objects::CORE_CONTROLLER);
gpioCallbacks::disableAllDecoder(gpioComIF);
PowerSwitchIF* pwrSwitcher = new DummyPowerSwitcher(objects::PCDU_HANDLER, 18, 0);
static_cast<void>(pwrSwitcher);
// Regular FM code, does not work for EM if the hardware is not connected
// createPcduComponents(gpioComIF, &pwrSwitcher);
@ -44,19 +48,24 @@ void ObjectFactory::produce(void* args) {
// createRtdComponents(q7s::SPI_DEFAULT_DEV, gpioComIF, pwrSwitcher, spiMainComIF);
// createTmpComponents();
// createSolarArrayDeploymentComponents();
createRadSensorComponent(gpioComIF);
// createPayloadComponents(gpioComIF);
// createHeaterComponents(gpioComIF, pwrSwitcher, healthTable);
// TODO: Careful! Switching this on somehow messes with the communication with the ProASIC
// and will cause xsc_boot_copy commands to always boot to 0 0
// createRadSensorComponent(gpioComIF);
#if OBSW_ADD_ACS_BOARD == 1
createAcsBoardComponents(gpioComIF, uartComIF, pwrSwitcher);
#endif
createHeaterComponents(gpioComIF, pwrSwitcher, healthTable);
createPayloadComponents(gpioComIF);
#if OBSW_ADD_MGT == 1
createImtqComponents(pwrSwitcher);
#endif
#if OBSW_ADD_RW == 1
createReactionWheelComponents(gpioComIF, pwrSwitcher);
#endif
#if OBSW_ADD_BPX_BATTERY_HANDLER == 1
createBpxBatteryComponent();
@ -65,9 +74,9 @@ void ObjectFactory::produce(void* args) {
#if OBSW_ADD_STAR_TRACKER == 1
createStrComponents(pwrSwitcher);
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
#if OBSW_USE_CCSDS_IP_CORE == 1
#if OBSW_ADD_CCSDS_IP_CORES == 1
createCcsdsComponents(gpioComIF);
#endif /* OBSW_USE_CCSDS_IP_CORE == 1 */
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
/* Test Task */
#if OBSW_ADD_TEST_CODE == 1
createTestComponents(gpioComIF);
@ -76,7 +85,5 @@ void ObjectFactory::produce(void* args) {
createScexComponents(q7s::UART_SCEX_DEV, pwrSwitcher, *SdCardManager::instance(), true,
std::nullopt);
#endif
createMiscComponents();
createAcsController();
}

View File

@ -1,3 +1,4 @@
#include <bsp_q7s/callbacks/q7sGpioCallbacks.h>
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
#include "OBSWConfig.h"
@ -24,10 +25,11 @@ void ObjectFactory::produce(void* args) {
PowerSwitchIF* pwrSwitcher = nullptr;
SpiComIF* spiRwComIF = nullptr;
createCommunicationInterfaces(&gpioComIF, &uartComIF, &spiMainComIF, &i2cComIF, &spiRwComIF);
createTmpComponents();
new CoreController(objects::CORE_CONTROLLER);
/* Adding gpios for chip select decoding to the gpioComIf */
q7s::gpioCallbacks::initSpiCsDecoder(gpioComIF);
gpioCallbacks::disableAllDecoder(gpioComIF);
new CoreController(objects::CORE_CONTROLLER);
createPcduComponents(gpioComIF, &pwrSwitcher);
createRadSensorComponent(gpioComIF);
createSunSensorComponents(gpioComIF, spiMainComIF, pwrSwitcher, q7s::SPI_DEFAULT_DEV);
@ -56,9 +58,9 @@ void ObjectFactory::produce(void* args) {
#if OBSW_ADD_STAR_TRACKER == 1
createStrComponents(pwrSwitcher);
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
#if OBSW_USE_CCSDS_IP_CORE == 1
#if OBSW_ADD_CCSDS_IP_CORES == 1
createCcsdsComponents(gpioComIF);
#endif /* OBSW_USE_CCSDS_IP_CORE == 1 */
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
#if OBSW_ADD_SCEX_DEVICE == 1
createScexComponents(q7s::UART_SCEX_DEV, pwrSwitcher, *SdCardManager::instance(), false,

View File

@ -459,7 +459,14 @@ void SdCardManager::setBlocking(bool blocking) { this->blocking = blocking; }
void SdCardManager::setPrintCommandOutput(bool print) { this->printCmdOutput = print; }
bool SdCardManager::isSdCardUsable(sd::SdCard sdCard) {
bool SdCardManager::isSdCardUsable(std::optional<sd::SdCard> sdCard) {
{
MutexGuard mg(mutex);
if (markedUnusable) {
return false;
}
}
SdCardManager::SdStatePair active;
ReturnValue_t result = this->getSdCardsStatus(active);
@ -467,20 +474,30 @@ bool SdCardManager::isSdCardUsable(sd::SdCard sdCard) {
sif::debug << "SdCardManager::isSdCardMounted: Failed to get SD card active state";
return false;
}
if (not sdCard) {
if (active.first == sd::MOUNTED or active.second == sd::MOUNTED) {
return true;
}
return false;
}
if (sdCard == sd::SLOT_0) {
if (active.first == sd::MOUNTED) {
return true;
} else {
return false;
}
} else if (sdCard == sd::SLOT_1) {
}
if (sdCard == sd::SLOT_1) {
if (active.second == sd::MOUNTED) {
return true;
} else {
return false;
}
} else {
sif::debug << "SdCardManager::isSdCardMounted: Unknown SD card specified" << std::endl;
}
if (sdCard == sd::BOTH) {
if (active.first == sd::MOUNTED && active.second == sd::MOUNTED) {
return true;
}
}
return false;
}
@ -560,5 +577,13 @@ void SdCardManager::setActiveSdCard(sd::SdCard sdCard) {
std::optional<sd::SdCard> SdCardManager::getActiveSdCard() const {
MutexGuard mg(mutex);
if (markedUnusable) {
return std::nullopt;
}
return sdInfo.active;
}
void SdCardManager::markUnusable() {
MutexGuard mg(mutex);
markedUnusable = true;
}

View File

@ -206,7 +206,7 @@ class SdCardManager : public SystemObject, public SdCardMountedIF {
*
* @return true if mounted, otherwise false
*/
bool isSdCardUsable(sd::SdCard sdCard) override;
bool isSdCardUsable(std::optional<sd::SdCard> sdCard) override;
ReturnValue_t isSdCardMountedReadOnly(sd::SdCard sdcard, bool& readOnly);
@ -214,12 +214,15 @@ class SdCardManager : public SystemObject, public SdCardMountedIF {
ReturnValue_t performFsck(sd::SdCard sdcard, bool printOutput, int& linuxError);
void markUnusable();
private:
CommandExecutor cmdExecutor;
Operations currentOp = Operations::IDLE;
bool blocking = false;
bool sdCardActive = true;
bool printCmdOutput = true;
bool markedUnusable = false;
MutexIF* mutex = nullptr;
SdCardManager();

View File

@ -107,7 +107,7 @@ void initmission::initTasks() {
}
#endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */
#if OBSW_USE_CCSDS_IP_CORE == 1
#if OBSW_ADD_CCSDS_IP_CORE == 1
PeriodicTaskIF* ccsdsHandlerTask = factory->createPeriodicTask(
"CCSDS_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
result = ccsdsHandlerTask->addComponent(objects::CCSDS_HANDLER);
@ -124,7 +124,7 @@ void initmission::initTasks() {
if (result != returnvalue::OK) {
initmission::printAddObjectError("PDEC Handler", objects::PDEC_HANDLER);
}
#endif /* OBSW_USE_CCSDS_IP_CORE == 1 */
#endif /* OBSW_ADD_CCSDS_IP_CORE == 1 */
auto taskStarter = [](std::vector<PeriodicTaskIF*>& taskVector, std::string name) {
for (const auto& task : taskVector) {
@ -140,10 +140,10 @@ void initmission::initTasks() {
tmtcDistributor->startTask();
tmtcBridgeTask->startTask();
tmtcPollingTask->startTask();
#if OBSW_USE_CCSDS_IP_CORE == 1
#if OBSW_ADD_CCSDS_IP_CORE == 1
pdecHandlerTask->startTask();
ccsdsHandlerTask->startTask();
#endif /* #if OBSW_USE_CCSDS_IP_CORE == 1 */
#endif /* #if OBSW_ADD_CCSDS_IP_CORE == 1 */
#if OBSW_ADD_PLOC_SUPERVISOR == 1
supvHelperTask->startTask();
#endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */

View File

@ -13,7 +13,7 @@
/** All of the following flags should be enabled for mission code */
/*******************************************************************/
#define OBSW_USE_CCSDS_IP_CORE 0
#define OBSW_ADD_CCSDS_IP_CORE 0
// 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

View File

@ -55,7 +55,7 @@ namespace uart {
static constexpr size_t HYPERION_GPS_REPLY_MAX_BUFFER = 1024;
static constexpr UartBaudRate SYRLINKS_BAUD = UartBaudRate::RATE_38400;
static constexpr UartBaudRate SCEX_BAUD = UartBaudRate::RATE_57600;
static constexpr UartBaudRate SCEX_BAUD = UartBaudRate::RATE_38400;
static constexpr UartBaudRate GNSS_BAUD = UartBaudRate::RATE_9600;
static constexpr UartBaudRate PLOC_MPSOC_BAUD = UartBaudRate::RATE_115200;
static constexpr UartBaudRate PLOC_SUPV_BAUD = UartBaudRate::RATE_115200;

2
fsfw

@ -1 +1 @@
Subproject commit 11422a658cc927abd6dc2eee45e821365f22107b
Subproject commit fa01798ebb4fb35a88ddc1d632832b9ba3dc642e

View File

@ -118,10 +118,7 @@ ReturnValue_t ScexUartReader::initializeInterface(CookieIF *cookie) {
tty.c_cc[VTIME] = 0;
tty.c_cc[VMIN] = 0;
// The SCEX experiment has a fixed baud rate.
if (cfsetispeed(&tty, B38400) != 0) {
sif::warning << "ScexUartReader::initializeInterface: Setting baud rate failed" << std::endl;
}
uart::setBaudrate(tty, uartCookie->getBaudrate());
if (tcsetattr(serialPort, TCSANOW, &tty) != 0) {
sif::warning << "ScexUartReader::initializeInterface: tcsetattr call failed with error ["
<< errno << ", " << strerror(errno) << std::endl;

View File

@ -1917,6 +1917,11 @@ ReturnValue_t PlocSupervisorHandler::checkMramPacketApid() {
}
ReturnValue_t PlocSupervisorHandler::handleMramDumpFile(DeviceCommandId_t id) {
#ifdef XIPHOS_Q7S
if (not sdcMan->getActiveSdCard()) {
return HasFileSystemIF::FILESYSTEM_INACTIVE;
}
#endif
ReturnValue_t result = returnvalue::OK;
uint16_t packetLen = readSpacePacketLength(spacePacketBuffer);
uint8_t sequenceFlags = readSequenceFlags(spacePacketBuffer);

View File

@ -1,6 +1,7 @@
#include "PlocSupvHelper.h"
#include <etl/crc16_ccitt.h>
#include <fsfw/filesystem/HasFileSystemIF.h>
#include <cmath>
#include <filesystem>
@ -748,6 +749,11 @@ uint32_t PlocSupvHelper::getFileSize(std::string filename) {
ReturnValue_t PlocSupvHelper::handleEventBufferReception(ploc::SpTmReader& reader) {
ReturnValue_t result = returnvalue::OK;
#ifdef XIPHOS_Q7S
if (not sdcMan->getActiveSdCard()) {
return HasFileSystemIF::FILESYSTEM_INACTIVE;
}
#endif
std::string filename = Filenaming::generateAbsoluteFilename(
eventBufferReq.path, eventBufferReq.filename, timestamping);
std::ofstream file(filename, std::ios_base::app | std::ios_base::out);

View File

@ -1,5 +1,7 @@
#include "StrHelper.h"
#include <fsfw/filesystem/HasFileSystemIF.h>
#include <filesystem>
#include <fstream>
@ -176,6 +178,11 @@ void StrHelper::disableTimestamping() { timestamping = false; }
void StrHelper::enableTimestamping() { timestamping = true; }
ReturnValue_t StrHelper::performImageDownload() {
#ifdef XIPHOS_Q7S
if (not sdcMan->getActiveSdCard()) {
return HasFileSystemIF::FILESYSTEM_INACTIVE;
}
#endif
ReturnValue_t result;
#if OBSW_DEBUG_STARTRACKER == 1
ProgressPrinter progressPrinter("Image download", ImageDownload::LAST_POSITION);
@ -244,6 +251,11 @@ ReturnValue_t StrHelper::performImageUpload() {
uint32_t imageSize = 0;
struct UploadActionRequest uploadReq;
uploadReq.position = 0;
#ifdef XIPHOS_Q7S
if (not sdcMan->getActiveSdCard()) {
return HasFileSystemIF::FILESYSTEM_INACTIVE;
}
#endif
std::memset(&uploadReq.data, 0, sizeof(uploadReq.data));
if (not std::filesystem::exists(uploadImage.uploadFile)) {
triggerEvent(STR_HELPER_FILE_NOT_EXISTS, static_cast<uint32_t>(internalState));
@ -315,6 +327,11 @@ ReturnValue_t StrHelper::performFirmwareUpdate() {
}
ReturnValue_t StrHelper::performFlashWrite() {
#ifdef XIPHOS_Q7S
if (not sdcMan->getActiveSdCard()) {
return HasFileSystemIF::FILESYSTEM_INACTIVE;
}
#endif
ReturnValue_t result = returnvalue::OK;
uint32_t size = 0;
uint32_t bytesWritten = 0;
@ -394,6 +411,11 @@ ReturnValue_t StrHelper::performFlashWrite() {
}
ReturnValue_t StrHelper::performFlashRead() {
#ifdef XIPHOS_Q7S
if (not sdcMan->getActiveSdCard()) {
return HasFileSystemIF::FILESYSTEM_INACTIVE;
}
#endif
ReturnValue_t result;
#if OBSW_DEBUG_STARTRACKER == 1
ProgressPrinter progressPrinter("Flash read", flashRead.size);

View File

@ -460,20 +460,18 @@ ReturnValue_t pst::pstI2c(FixedTimeslotTaskIF *thisSequence) {
ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) {
// Length of a communication cycle
uint32_t length = thisSequence->getPeriodMs();
bool uartPstEmpty = true;
static_cast<void>(length);
#if OBSW_ADD_PLOC_MPSOC == 1
uartPstEmpty = false;
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0,
DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ);
#endif
thisSequence->addSlot(objects::PLOC_MEMORY_DUMPER, length * 0,
DeviceHandlerIF::PERFORM_OPERATION);
#endif
#if OBSW_ADD_PLOC_SUPERVISOR == 1
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0,
DeviceHandlerIF::PERFORM_OPERATION);
@ -485,7 +483,6 @@ ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) {
#endif
#if OBSW_ADD_SYRLINKS == 1
uartPstEmpty = false;
thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0,
DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::SYRLINKS_HK_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
@ -495,22 +492,13 @@ ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) {
#endif
#if OBSW_ADD_STAR_TRACKER == 1
uartPstEmpty = false;
thisSequence->addSlot(objects::STAR_TRACKER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::STAR_TRACKER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::STAR_TRACKER, length * 0.4, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::STAR_TRACKER, length * 0.6, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::STAR_TRACKER, length * 0.8, DeviceHandlerIF::GET_READ);
#endif
static_cast<void>(length);
if (uartPstEmpty) {
return returnvalue::OK;
}
if (thisSequence->checkSequence() != returnvalue::OK) {
sif::error << "UART PST initialization failed" << std::endl;
return returnvalue::FAILED;
}
return returnvalue::OK;
return thisSequence->checkSequence();
}
ReturnValue_t pst::pstGompaceCan(FixedTimeslotTaskIF *thisSequence) {

View File

@ -422,12 +422,12 @@ ReturnValue_t GyroADIS1650XHandler::spiSendCallback(SpiComIF *comIf, SpiCookie *
cookie->setTransferSize(2);
gpioId_t gpioId = cookie->getChipSelectPin();
GpioIF *gpioIF = comIf->getGpioInterface();
GpioIF& gpioIF = comIf->getGpioInterface();
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
uint32_t timeoutMs = 0;
MutexIF *mutex = comIf->getCsMutex();
cookie->getMutexParams(timeoutType, timeoutMs);
if (mutex == nullptr or gpioIF == nullptr) {
if (mutex == nullptr) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::warning << "GyroADIS16507Handler::spiSendCallback: "
"Mutex or GPIO interface invalid"
@ -453,7 +453,7 @@ ReturnValue_t GyroADIS1650XHandler::spiSendCallback(SpiComIF *comIf, SpiCookie *
while (idx < sendLen) {
// Pull SPI CS low. For now, no support for active high given
if (gpioId != gpio::NO_GPIO) {
gpioIF->pullLow(gpioId);
gpioIF.pullLow(gpioId);
}
// Execute transfer
@ -468,7 +468,7 @@ ReturnValue_t GyroADIS1650XHandler::spiSendCallback(SpiComIF *comIf, SpiCookie *
#endif /* FSFW_LINUX_SPI_WIRETAPPING == 1 */
if (gpioId != gpio::NO_GPIO) {
gpioIF->pullHigh(gpioId);
gpioIF.pullHigh(gpioId);
}
idx += 2;

View File

@ -321,7 +321,8 @@ ReturnValue_t ImtqHandler::scanForReply(const uint8_t* start, size_t remainingSi
break;
case (IMTQ::CC::PAST_AVAILABLE_RESPONSE_BYTES): {
sif::warning << "IMTQHandler::scanForReply: Read 0xFF command byte, reading past available "
"bytes. Keep 1 ms delay between I2C send and read" << std::endl;
"bytes. Keep 1 ms delay between I2C send and read"
<< std::endl;
result = IGNORE_REPLY_DATA;
break;
}

View File

@ -719,11 +719,11 @@ ReturnValue_t PayloadPcduHandler::transferAsTwo(SpiComIF* comIf, SpiCookie* cook
cookie->setTransferSize(transferLen);
gpioId_t gpioId = cookie->getChipSelectPin();
GpioIF* gpioIF = comIf->getGpioInterface();
GpioIF& gpioIF = comIf->getGpioInterface();
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
uint32_t timeoutMs = 0;
MutexIF* mutex = comIf->getCsMutex();
if (mutex == nullptr or gpioIF == nullptr) {
if (mutex == nullptr) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::warning << "GyroADIS16507Handler::spiSendCallback: "
"Mutex or GPIO interface invalid"
@ -753,7 +753,7 @@ ReturnValue_t PayloadPcduHandler::transferAsTwo(SpiComIF* comIf, SpiCookie* cook
transferStruct->len = transferLen;
// Pull SPI CS low. For now, no support for active high given
if (gpioId != gpio::NO_GPIO) {
gpioIF->pullLow(gpioId);
gpioIF.pullLow(gpioId);
}
// Execute transfer
@ -768,14 +768,14 @@ ReturnValue_t PayloadPcduHandler::transferAsTwo(SpiComIF* comIf, SpiCookie* cook
#endif /* FSFW_LINUX_SPI_WIRETAPPING == 1 */
if (gpioId != gpio::NO_GPIO) {
gpioIF->pullHigh(gpioId);
gpioIF.pullHigh(gpioId);
}
transferStruct->tx_buf += transferLen;
transferStruct->rx_buf += transferLen;
transferStruct->len = plpcdu::TEMP_REPLY_SIZE - 1;
if (gpioId != gpio::NO_GPIO) {
gpioIF->pullLow(gpioId);
gpioIF.pullLow(gpioId);
}
// Execute transfer
@ -790,7 +790,7 @@ ReturnValue_t PayloadPcduHandler::transferAsTwo(SpiComIF* comIf, SpiCookie* cook
#endif /* FSFW_LINUX_SPI_WIRETAPPING == 1 */
if (gpioId != gpio::NO_GPIO) {
gpioIF->pullHigh(gpioId);
gpioIF.pullHigh(gpioId);
}
transferStruct->tx_buf = origTx;

View File

@ -1,5 +1,6 @@
#include "ScexDeviceHandler.h"
#include <fsfw/filesystem/HasFileSystemIF.h>
#include <linux/devices/ScexHelper.h>
#include <mission/memory/SdCardMountedIF.h>
@ -200,6 +201,10 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons
ReturnValue_t status = OK;
auto oneFileHandler = [&](std::string cmdName) {
auto activeSd = sdcMan.getActiveSdCard();
if (not activeSd) {
return HasFileSystemIF::FILESYSTEM_INACTIVE;
}
fileId = date_time_string();
std::ostringstream oss;
auto prefix = sdcMan.getCurrentMountPrefix();
@ -216,6 +221,10 @@ ReturnValue_t ScexDeviceHandler::interpretDeviceReply(DeviceCommandId_t id, cons
};
auto multiFileHandler = [&](std::string cmdName) {
if ((helper.getPacketCounter() == 1) or (not fileNameSet)) {
auto activeSd = sdcMan.getActiveSdCard();
if (not activeSd) {
return HasFileSystemIF::FILESYSTEM_INACTIVE;
}
fileId = date_time_string();
std::ostringstream oss;
auto prefix = sdcMan.getCurrentMountPrefix();

View File

@ -1,5 +1,6 @@
#include "SolarArrayDeploymentHandler.h"
#include <fsfw/filesystem/HasFileSystemIF.h>
#include <fsfw/tasks/TaskFactory.h>
#include <filesystem>
@ -150,7 +151,7 @@ bool SolarArrayDeploymentHandler::autonomousDeplForFile(sd::SdCard sdCard, const
string line;
string word;
unsigned int lineNum = 0;
AutonomousDeplState deplState;
AutonomousDeplState deplState = AutonomousDeplState::INIT;
bool stateSwitch = false;
uint32_t secsSinceBoot = 0;
while (std::getline(file, line)) {

View File

@ -10,7 +10,7 @@ class SdCardMountedIF {
public:
virtual ~SdCardMountedIF(){};
virtual const std::string& getCurrentMountPrefix() const = 0;
virtual bool isSdCardUsable(sd::SdCard sdCard) = 0;
virtual bool isSdCardUsable(std::optional<sd::SdCard> sdCard) = 0;
virtual std::optional<sd::SdCard> getPreferredSdCard() const = 0;
virtual void setActiveSdCard(sd::SdCard sdCard) = 0;
virtual std::optional<sd::SdCard> getActiveSdCard() const = 0;