Compare commits

..

11 Commits

Author SHA1 Message Date
c12706ef05 Merge branch 'main' into auto-switch-image-feature
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
EIVE/eive-obsw/pipeline/head This commit looks good
2023-10-30 15:02:23 +01:00
8e1f95ebf2 Merge remote-tracking branch 'origin/main' into auto-switch-image-feature
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-30 14:45:13 +01:00
4e0842c607 add link
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-23 13:39:47 +02:00
4fd18e94fd changelog
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-23 13:30:45 +02:00
18bcb434e9 tiny tweak
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-19 15:24:52 +02:00
f0ade7274a works
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-19 15:23:23 +02:00
674202c6fb delay
Some checks failed
EIVE/eive-obsw/pipeline/pr-main There was a failure building this commit
2023-10-19 15:18:39 +02:00
fecaad7af7 better printout 2023-10-19 15:18:06 +02:00
befe7ec441 bump tmtc
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-19 15:06:26 +02:00
01ce1f154e that should get the job done
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-19 14:43:29 +02:00
2e210a0572 start impl auto switch feature
All checks were successful
EIVE/eive-obsw/pipeline/head This commit looks good
EIVE/eive-obsw/pipeline/pr-main This commit looks good
2023-10-19 13:31:43 +02:00
16 changed files with 105 additions and 67 deletions

View File

@@ -16,17 +16,12 @@ will consitute of a breaking change warranting a new major release:
# [unreleased]
# [v7.3.0] 2023-11-07
## Changed
- Changed PDEC addresses depending on which firmware version is used. It is suspected that
the previous addresses were invalid and not properly covered by the Linux memory protection.
The OBSW will use the old addresses for older FW versions.
## Added
- Always add PLOC MPSoC and PLOC SUPV components for the EM as well.
- Added a new safety mechanism where the ProASIC scratch buffer can be used to trigger an
auto-boot to another image. The auto-boot is currently implemented as a one-shot mechanism:
The key-value pair which triggers the auto-boot will be removed from the scratch buffer.
See more information [here](https://egit.irs.uni-stuttgart.de/redmine/projects/eive-flight-manual/wiki/OBC_Auto_Switch_Image)
# [v7.2.0] 2023-10-27

View File

@@ -10,7 +10,7 @@
cmake_minimum_required(VERSION 3.13)
set(OBSW_VERSION_MAJOR 7)
set(OBSW_VERSION_MINOR 3)
set(OBSW_VERSION_MINOR 2)
set(OBSW_VERSION_REVISION 0)
# set(CMAKE_VERBOSE TRUE)
@@ -126,13 +126,13 @@ set(OBSW_ADD_HEATERS
1
CACHE STRING "Add TCS heaters")
set(OBSW_ADD_PLOC_SUPERVISOR
1
${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
1
${INIT_VAL}
CACHE STRING "Add MPSoC handler")
set(OBSW_ADD_ACS_CTRL
${INIT_VAL}

View File

@@ -18,8 +18,7 @@ static constexpr char I2C_Q7_EIVE[] = "/dev/i2c_q7";
static constexpr char UART_GNSS_DEV[] = "/dev/gps0";
static constexpr char UART_PLOC_MPSOC_DEV[] = "/dev/ul_plmpsoc";
static constexpr char UART_PLOC_SUPERVISOR_DEV_FALLBACK[] = "/dev/ttyUL4";
static constexpr char UART_PLOC_SUPERVISOR_DEV[] = "/dev/ploc_supv";
static constexpr char UART_PLOC_SUPERVSIOR_DEV[] = "/dev/ploc_supv";
static constexpr char UART_SYRLINKS_DEV[] = "/dev/ul_syrlinks";
static constexpr char UART_STAR_TRACKER_DEV[] = "/dev/ul_str";
static constexpr char UART_SCEX_DEV[] = "/dev/scex";

View File

@@ -359,6 +359,29 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
case (OBSW_UPDATE_FROM_TMP): {
return executeSwUpdate(SwUpdateSources::TMP_DIR, data, size);
}
case (ENABLE_AUTO_SWITCH): {
if (size < 2) {
return HasActionsIF::INVALID_PARAMETERS;
}
uint8_t chip = data[0];
uint8_t copy = data[1];
if (chip > 1 or copy > 1) {
return HasActionsIF::INVALID_PARAMETERS;
}
std::string value = std::to_string(chip) + std::to_string(copy);
ReturnValue_t result = scratch::writeString(scratch::AUTO_SWITCH_IMAGE, value);
if (result == returnvalue::OK) {
return EXECUTION_FINISHED;
}
return result;
}
case (DISABLE_AUTO_SWITCH): {
ReturnValue_t result = scratch::clearValue(scratch::AUTO_SWITCH_IMAGE);
if (result != returnvalue::OK and result != scratch::KEY_NOT_FOUND) {
return result;
}
return EXECUTION_FINISHED;
}
case (SWITCH_TO_SD_0): {
if (not startSdStateMachine(sd::SdCard::SLOT_0, SdCfgMode::COLD_REDUNDANT, commandedBy,
actionId)) {

View File

@@ -163,8 +163,8 @@ void ObjectFactory::produce(void* args) {
#if OBSW_ADD_CCSDS_IP_CORES == 1
CcsdsIpCoreHandler* ipCoreHandler = nullptr;
CcsdsComponentArgs ccsdsArgs(*gpioComIF, *ipcStore, *tmStore, stores, *pusFunnel, *cfdpFunnel,
&ipCoreHandler, 0, 0);
createCcsdsIpComponentsWrapper(ccsdsArgs);
&ipCoreHandler);
createCcsdsIpComponentsAddTmRouting(ccsdsArgs);
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
/* Test Task */

View File

@@ -115,8 +115,8 @@ void ObjectFactory::produce(void* args) {
#if OBSW_ADD_CCSDS_IP_CORES == 1
CcsdsIpCoreHandler* ipCoreHandler = nullptr;
CcsdsComponentArgs ccsdsArgs(*gpioComIF, *ipcStore, *tmStore, stores, *pusFunnel, *cfdpFunnel,
&ipCoreHandler, 0, 0);
createCcsdsIpComponentsWrapper(ccsdsArgs);
&ipCoreHandler);
createCcsdsIpComponentsAddTmRouting(ccsdsArgs);
#endif /* OBSW_ADD_CCSDS_IP_CORES == 1 */
#if OBSW_ADD_SCEX_DEVICE == 1

View File

@@ -19,6 +19,7 @@ namespace scratch {
static constexpr char PREFERED_SDC_KEY[] = "PREFSD";
static constexpr char ALLOC_FAILURE_COUNT[] = "ALLOCERR";
static constexpr char AUTO_SWITCH_IMAGE[] = "ASWI";
static constexpr uint8_t INTERFACE_ID = CLASS_ID::SCRATCH_BUFFER;
static constexpr ReturnValue_t KEY_NOT_FOUND = returnvalue::makeCode(INTERFACE_ID, 0);
@@ -76,7 +77,6 @@ ReturnValue_t readToFile(std::string name, std::ifstream& file, std::string& fil
int result = std::system(oss.str().c_str());
if (result != 0) {
if (WEXITSTATUS(result) == 1) {
sif::warning << "scratch::readToFile: Key " << name << " does not exist" << std::endl;
// Could not find value
std::remove(filename.c_str());
return KEY_NOT_FOUND;

View File

@@ -642,13 +642,9 @@ void ObjectFactory::createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwit
auto supvGpioCookie = new GpioCookie;
supvGpioCookie->addGpio(gpioIds::ENABLE_SUPV_UART, gpioConfigSupv);
gpioComIF->addGpios(supvGpioCookie);
const char* plocSupvDev = q7s::UART_PLOC_SUPERVISOR_DEV;
if (not std::filesystem::exists(plocSupvDev)) {
plocSupvDev = q7s::UART_PLOC_SUPERVISOR_DEV_FALLBACK;
}
auto supervisorCookie =
new SerialCookie(objects::PLOC_SUPERVISOR_HANDLER, plocSupvDev, serial::PLOC_SUPV_BAUD,
supv::MAX_PACKET_SIZE * 20, UartModes::NON_CANONICAL);
auto supervisorCookie = new SerialCookie(objects::PLOC_SUPERVISOR_HANDLER,
q7s::UART_PLOC_SUPERVSIOR_DEV, serial::PLOC_SUPV_BAUD,
supv::MAX_PACKET_SIZE * 20, UartModes::NON_CANONICAL);
supervisorCookie->setNoFixedSizeReply();
auto supvHelper = new PlocSupvUartManager(objects::PLOC_SUPERVISOR_HELPER);
auto* supvHandler = new PlocSupervisorHandler(objects::PLOC_SUPERVISOR_HANDLER, supervisorCookie,
@@ -840,7 +836,7 @@ ReturnValue_t ObjectFactory::createCcsdsComponents(CcsdsComponentArgs& args) {
uioNames.registers = q7s::UIO_PDEC_REGISTERS;
uioNames.irq = q7s::UIO_PDEC_IRQ;
new PdecHandler(objects::PDEC_HANDLER, objects::CCSDS_HANDLER, &args.gpioComIF,
gpioIds::PDEC_RESET, uioNames, args.pdecCfgMemBaseAddr, args.pdecRamBaseAddr);
gpioIds::PDEC_RESET, uioNames);
GpioCookie* gpioRS485Chip = new GpioCookie;
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver",
Direction::OUT, Levels::LOW);
@@ -1066,13 +1062,7 @@ ReturnValue_t ObjectFactory::readFirmwareVersion() {
return returnvalue::OK;
}
ReturnValue_t ObjectFactory::createCcsdsIpComponentsWrapper(CcsdsComponentArgs& ccsdsArgs) {
ccsdsArgs.pdecCfgMemBaseAddr = config::pdec::PDEC_CONFIG_BASE_ADDR;
ccsdsArgs.pdecRamBaseAddr = config::pdec::PDEC_RAM_ADDR;
if (core::FW_VERSION_MAJOR < 6) {
ccsdsArgs.pdecCfgMemBaseAddr = config::pdec::PDEC_CONFIG_BASE_ADDR_LEGACY;
ccsdsArgs.pdecRamBaseAddr = config::pdec::PDEC_RAM_ADDR_LEGACY;
}
ReturnValue_t ObjectFactory::createCcsdsIpComponentsAddTmRouting(CcsdsComponentArgs& ccsdsArgs) {
ReturnValue_t result = createCcsdsComponents(ccsdsArgs);
#if OBSW_TM_TO_PTME == 1
if (ccsdsArgs.normalLiveTmDest != MessageQueueIF::NO_QUEUE) {

View File

@@ -31,17 +31,14 @@ namespace ObjectFactory {
struct CcsdsComponentArgs {
CcsdsComponentArgs(LinuxLibgpioIF& gpioIF, StorageManagerIF& ipcStore, StorageManagerIF& tmStore,
PersistentTmStores& stores, PusTmFunnel& pusFunnel, CfdpTmFunnel& cfdpFunnel,
CcsdsIpCoreHandler** ipCoreHandler, uint32_t pdecCfgMemBaseAddr,
uint32_t pdecRamBaseAddr)
CcsdsIpCoreHandler** ipCoreHandler)
: gpioComIF(gpioIF),
ipcStore(ipcStore),
tmStore(tmStore),
stores(stores),
pusFunnel(pusFunnel),
cfdpFunnel(cfdpFunnel),
ipCoreHandler(ipCoreHandler),
pdecCfgMemBaseAddr(pdecCfgMemBaseAddr),
pdecRamBaseAddr(pdecRamBaseAddr) {}
ipCoreHandler(ipCoreHandler) {}
LinuxLibgpioIF& gpioComIF;
StorageManagerIF& ipcStore;
StorageManagerIF& tmStore;
@@ -49,8 +46,6 @@ struct CcsdsComponentArgs {
PusTmFunnel& pusFunnel;
CfdpTmFunnel& cfdpFunnel;
CcsdsIpCoreHandler** ipCoreHandler;
uint32_t pdecCfgMemBaseAddr;
uint32_t pdecRamBaseAddr;
MessageQueueId_t normalLiveTmDest = MessageQueueIF::NO_QUEUE;
MessageQueueId_t cfdpLiveTmDest = MessageQueueIF::NO_QUEUE;
};
@@ -80,7 +75,7 @@ void createSolarArrayDeploymentComponents(PowerSwitchIF& pwrSwitcher, GpioIF& gp
void createSyrlinksComponents(PowerSwitchIF* pwrSwitcher);
void createPayloadComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF& pwrSwitcher);
void createReactionWheelComponents(LinuxLibgpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher);
ReturnValue_t createCcsdsIpComponentsWrapper(CcsdsComponentArgs& args);
ReturnValue_t createCcsdsIpComponentsAddTmRouting(CcsdsComponentArgs& args);
ReturnValue_t createCcsdsComponents(CcsdsComponentArgs& args);
ReturnValue_t readFirmwareVersion();
void createMiscComponents();

View File

@@ -1,5 +1,6 @@
#include "obsw.h"
#include <libxiphos.h>
#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>
@@ -13,6 +14,7 @@
#include "commonConfig.h"
#include "fsfw/tasks/TaskFactory.h"
#include "fsfw/version.h"
#include "memory/scratchApi.h"
#include "mission/acs/defs.h"
#include "mission/com/defs.h"
#include "mission/system/systemTree.h"
@@ -50,6 +52,8 @@ int obsw::obsw(int argc, char* argv[]) {
}
#endif
autoSwitchHandling();
// Delay the boot if applicable.
bootDelayHandling();
@@ -82,6 +86,33 @@ int obsw::obsw(int argc, char* argv[]) {
return 0;
}
void obsw::autoSwitchHandling() {
std::string autoSwitchTarget;
auto switchToTarget = [&](xsc_libnor_chip_t chip, xsc_libnor_copy_t copy) {
sif::warning << "Detected ASWI=" << autoSwitchTarget
<< " in ProASIC scratch buffer, auto-switching to image " << int(chip) << " "
<< int(copy) << std::endl;
scratch::clearValue(scratch::AUTO_SWITCH_IMAGE);
// A bit of delay to ensure printout works..
TaskFactory::delayTask(500);
xsc_boot_copy(chip, copy);
};
if (scratch::readString(scratch::AUTO_SWITCH_IMAGE, autoSwitchTarget) == returnvalue::OK) {
if (autoSwitchTarget == "00") {
switchToTarget(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_NOMINAL);
} else if (autoSwitchTarget == "01") {
switchToTarget(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_GOLD);
} else if (autoSwitchTarget == "10") {
switchToTarget(XSC_LIBNOR_CHIP_1, XSC_LIBNOR_COPY_NOMINAL);
} else if (autoSwitchTarget == "11") {
switchToTarget(XSC_LIBNOR_CHIP_1, XSC_LIBNOR_COPY_GOLD);
} else {
sif::warning << "Invalid Auto Switch Image (ASWI) value detected: " << autoSwitchTarget
<< std::endl;
}
}
}
void obsw::bootDelayHandling() {
const char* homedir = nullptr;
homedir = getenv("HOME");

View File

@@ -5,6 +5,12 @@ namespace obsw {
int obsw(int argc, char* argv[]);
/**
* This is a safety mechanism where the ProASIC scratch buffer can be used to trigger an
* auto-boot to another image. The auto-boot is currently implemented as a one-shot mechanism:
* The key-value pair which triggers the auto-boot will be removed from the scratch buffer.
*/
void autoSwitchHandling();
void bootDelayHandling();
void commandEiveSystemToSafe();
void commandComSubsystemRxOnly();

View File

@@ -115,18 +115,6 @@ static constexpr float SCHED_BLOCK_10_PERIOD =
} // namespace spiSched
namespace pdec {
// Pre FW v6.0.0
static constexpr uint32_t PDEC_CONFIG_BASE_ADDR_LEGACY = 0x24000000;
static constexpr uint32_t PDEC_RAM_ADDR_LEGACY = 0x26000000;
// Post FW v6.0.0
static constexpr uint32_t PDEC_CONFIG_BASE_ADDR = 0x4000000;
static constexpr uint32_t PDEC_RAM_ADDR = 0x7000000;
} // namespace pdec
} // namespace config
#endif /* COMMON_CONFIG_DEFINITIONS_H_ */

View File

@@ -24,15 +24,12 @@ using namespace pdec;
uint32_t PdecHandler::CURRENT_FAR = 0;
PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId,
LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, UioNames names,
uint32_t cfgMemPhyAddr, uint32_t pdecRamPhyAddr)
LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, UioNames names)
: SystemObject(objectId),
tcDestinationId(tcDestinationId),
gpioComIF(gpioComIF),
pdecReset(pdecReset),
actionHelper(this, nullptr),
cfgMemBaseAddr(cfgMemPhyAddr),
pdecRamBaseAddr(pdecRamPhyAddr),
uioNames(names),
paramHelper(this) {
auto mqArgs = MqArgs(objectId, static_cast<void*>(this));
@@ -70,7 +67,7 @@ ReturnValue_t PdecHandler::initialize() {
};
memoryBaseAddress = static_cast<uint32_t*>(
mmap(0, PDEC_CFG_MEM_SIZE, static_cast<int>(UioMapper::Permissions::READ_WRITE), MAP_SHARED,
fd, cfgMemBaseAddr));
fd, PDEC_CFG_MEM_PHY_ADDR));
if (memoryBaseAddress == nullptr) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
@@ -78,7 +75,7 @@ ReturnValue_t PdecHandler::initialize() {
ramBaseAddress = static_cast<uint32_t*>(mmap(0, PDEC_RAM_SIZE,
static_cast<int>(UioMapper::Permissions::READ_WRITE),
MAP_SHARED, fd, pdecRamBaseAddr));
MAP_SHARED, fd, PDEC_RAM_PHY_ADDR));
if (ramBaseAddress == nullptr) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
@@ -468,7 +465,14 @@ bool PdecHandler::newTcReceived() {
return true;
}
void PdecHandler::doPeriodicWork() { checkLocks(); }
void PdecHandler::doPeriodicWork() {
// scuffed test code
// if(testCntr < 30) {
// triggerEvent(pdec::INVALID_TC_FRAME, FRAME_DIRTY_RETVAL);
// testCntr++;
// }
checkLocks();
}
bool PdecHandler::checkFrameAna(uint32_t pdecFar) {
bool frameValid = false;
@@ -641,7 +645,7 @@ void PdecHandler::handleNewTc() {
}
ReturnValue_t PdecHandler::readTc(uint32_t& tcLength) {
uint32_t tcOffset = (*(registerBaseAddress + PDEC_BPTR_OFFSET) - pdecRamBaseAddr) / 4;
uint32_t tcOffset = (*(registerBaseAddress + PDEC_BPTR_OFFSET) - PHYSICAL_RAM_BASE_ADDRESS) / 4;
#if OBSW_DEBUG_PDEC_HANDLER == 1
sif::debug << "PdecHandler::readTc: TC offset: 0x" << std::hex << tcOffset << std::endl;

View File

@@ -52,7 +52,9 @@ class PdecHandler : public SystemObject,
public:
static constexpr dur_millis_t IRQ_TIMEOUT_MS = 500;
static constexpr uint32_t PDEC_CFG_MEM_SIZE = 0x1000;
static constexpr uint32_t PDEC_CFG_MEM_PHY_ADDR = 0x24000000;
static constexpr uint32_t PDEC_RAM_SIZE = 0x10000;
static constexpr uint32_t PDEC_RAM_PHY_ADDR = 0x26000000;
enum class Modes { POLLED, IRQ };
@@ -66,7 +68,7 @@ class PdecHandler : public SystemObject,
* @param uioregsiters String of uio device file same mapped to the PDEC register space
*/
PdecHandler(object_id_t objectId, object_id_t tcDestinationId, LinuxLibgpioIF* gpioComIF,
gpioId_t pdecReset, UioNames names, uint32_t cfgMemPhyAddr, uint32_t pdecRamPhyAddr);
gpioId_t pdecReset, UioNames names);
virtual ~PdecHandler();
@@ -101,6 +103,12 @@ class PdecHandler : public SystemObject,
static const size_t MAX_TC_SEGMENT_SIZE = 1017;
static const uint8_t MAP_ID_MASK = 0x3F;
#ifdef TE0720_1CFA
static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x32000000;
#else
static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x26000000;
#endif
// Expected value stored in FAR register after reset
static const uint32_t FAR_RESET = 0x7FE0;
@@ -187,9 +195,6 @@ class PdecHandler : public SystemObject,
MessageQueueId_t commandedBy = MessageQueueIF::NO_QUEUE;
bool ptmeResetWithReinitializationPending = false;
uint32_t cfgMemBaseAddr;
uint32_t pdecRamBaseAddr;
UioNames uioNames;
ParameterHelper paramHelper;

View File

@@ -75,6 +75,8 @@ static constexpr ActionId_t OBSW_UPDATE_FROM_TMP = 12;
static constexpr ActionId_t SWITCH_TO_SD_0 = 16;
static constexpr ActionId_t SWITCH_TO_SD_1 = 17;
static constexpr ActionId_t SWITCH_TO_BOTH_SD_CARDS = 18;
static constexpr ActionId_t ENABLE_AUTO_SWITCH = 19;
static constexpr ActionId_t DISABLE_AUTO_SWITCH = 20;
//! Reboot using the xsc_boot_copy command
static constexpr ActionId_t XSC_REBOOT_OBC = 32;

2
tmtc

Submodule tmtc updated: 99c6c8bbd0...92fe9d92de