Merge remote-tracking branch 'origin/develop' into mueller/system-subsystems
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit

This commit is contained in:
Robin Müller 2022-03-02 15:09:14 +01:00
commit 0b200cd296
No known key found for this signature in database
GPG Key ID: 11D4952C8CCEF814
100 changed files with 7562 additions and 4102 deletions

2
.gitignore vendored
View File

@ -9,7 +9,7 @@
!misc/eclipse/**/.project !misc/eclipse/**/.project
#vscode #vscode
.vscode /.vscode
# Python # Python
__pycache__ __pycache__

View File

@ -99,7 +99,7 @@ pre_source_hw_os_config()
if(TGT_BSP) if(TGT_BSP)
if(TGT_BSP MATCHES "arm/q7s" OR TGT_BSP MATCHES "arm/raspberrypi" if(TGT_BSP MATCHES "arm/q7s" OR TGT_BSP MATCHES "arm/raspberrypi"
OR TGT_BSP MATCHES "arm/beagleboneblack" OR TGT_BSP MATCHES "arm/beagleboneblack" OR TGT_BSP MATCHES "arm/egse"
) )
set(FSFW_CONFIG_PATH "linux/fsfwconfig") set(FSFW_CONFIG_PATH "linux/fsfwconfig")
if(NOT BUILD_Q7S_SIMPLE_MODE) if(NOT BUILD_Q7S_SIMPLE_MODE)
@ -115,6 +115,12 @@ if(TGT_BSP)
set(FSFW_HAL_ADD_RASPBERRY_PI ON) set(FSFW_HAL_ADD_RASPBERRY_PI ON)
endif() endif()
if(TGT_BSP MATCHES "arm/egse")
# Used by configure file
set(EGSE ON)
set(FSFW_HAL_LINUX_ADD_LIBGPIOD OFF)
endif()
if(TGT_BSP MATCHES "arm/beagleboneblack") if(TGT_BSP MATCHES "arm/beagleboneblack")
# Used by configure file # Used by configure file
set(BEAGLEBONEBLACK ON) set(BEAGLEBONEBLACK ON)
@ -140,7 +146,7 @@ configure_file(${FSFW_CONFIG_PATH}/FSFWConfig.h.in FSFWConfig.h)
configure_file(${FSFW_CONFIG_PATH}/OBSWConfig.h.in OBSWConfig.h) configure_file(${FSFW_CONFIG_PATH}/OBSWConfig.h.in OBSWConfig.h)
if(TGT_BSP MATCHES "arm/q7s") if(TGT_BSP MATCHES "arm/q7s")
configure_file(${BSP_PATH}/boardconfig/q7sConfig.h.in q7sConfig.h) configure_file(${BSP_PATH}/boardconfig/q7sConfig.h.in q7sConfig.h)
elseif(TGT_BSP MATCHES "arm/raspberrypi") elseif(TGT_BSP MATCHES "arm/raspberrypi" OR TGT_BSP MATCHES "arm/egse")
configure_file(${BSP_PATH}/boardconfig/rpiConfig.h.in rpiConfig.h) configure_file(${BSP_PATH}/boardconfig/rpiConfig.h.in rpiConfig.h)
endif() endif()
@ -266,7 +272,11 @@ if(TGT_BSP MATCHES "arm/q7s")
) )
endif() endif()
if(TGT_BSP MATCHES "arm/egse")
target_link_libraries(${OBSW_NAME} PRIVATE
${LIB_ARCSEC}
)
endif()
if(ADD_CSP_LIB) if(ADD_CSP_LIB)
target_link_libraries(${OBSW_NAME} PRIVATE target_link_libraries(${OBSW_NAME} PRIVATE
@ -305,7 +315,7 @@ target_include_directories(${LIB_EIVE_MISSION} PUBLIC
${LIB_ARCSEC_PATH} ${LIB_ARCSEC_PATH}
) )
if(TGT_BSP MATCHES "arm/q7s") if(TGT_BSP MATCHES "arm/q7s" OR TGT_BSP MATCHES "arm/egse")
target_include_directories(${LIB_EIVE_MISSION} PUBLIC target_include_directories(${LIB_EIVE_MISSION} PUBLIC
${ARCSEC_LIB_PATH} ${ARCSEC_LIB_PATH}
) )

View File

@ -19,9 +19,10 @@
12. [Static Code Analysis](#static-code-analysis) 12. [Static Code Analysis](#static-code-analysis)
13. [Eclipse](#eclipse) 13. [Eclipse](#eclipse)
14. [Running the OBSW on a Raspberry Pi](#rpi) 14. [Running the OBSW on a Raspberry Pi](#rpi)
15. [Manually preparing sysroots to compile gpsd](#gpsd) 15. [Running OBSW on EGSE](#egse)
16. [FSFW](#fsfw) 16. [Manually preparing sysroots to compile gpsd](#gpsd)
17. [Coding Style](#coding-style) 17. [FSFW](#fsfw)
18. [Coding Style](#coding-style)
# <a id="general"></a> General information # <a id="general"></a> General information
@ -441,12 +442,24 @@ Beagle Bone Black for download here
Download it and unzip it somewhere in the Xilinx installation folder. Download it and unzip it somewhere in the Xilinx installation folder.
You can use the following command if `wget` can be used or for CI/CD: You can use the following command if `wget` can be used or for CI/CD:
``` ```sh
wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/agnJGYeRf6fw2ci/download/cortexa9hf-neon-xiphos-linux-gnueabi.tar.gz wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/SyXpdBBQX32xPgE/download/cortexa9hf-neon-xiphos-linux-gnueabi.tar.gz
``` ```
Then, create a new environmental variables `Q7S_SYSROOT` and set it to the local system root path. Then, create a new environmental variables `Q7S_SYSROOT` and set it to the local system root path.
### Updating system root for CI
If the system root is updated, it needs to be manually updated on the buggy file server.
If access on `buggy.irs.uni-stuttgart.de` is possible with `ssh` and the rootfs in the cloud
[was updated](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/rootfs&fileid=831849)
as well, you can update the rootfs like this:
```sh
cd /var/www/eive/tools
wget https://eive-cloud.irs.uni-stuttgart.de/index.php/s/SyXpdBBQX32xPgE/download/cortexa9hf-neon-xiphos-linux-gnueabi.tar.gz
```
## Setting up UNIX environment for real-time functionalities ## Setting up UNIX environment for real-time functionalities
Please note that on most UNIX environments (e.g. Ubuntu), the real time functionalities Please note that on most UNIX environments (e.g. Ubuntu), the real time functionalities
@ -1140,6 +1153,35 @@ sudo apt-get install gpiod libgpiod-dev
to install the required GPIO libraries before cloning the system root folder. to install the required GPIO libraries before cloning the system root folder.
# <a id="egse"></a> Running OBSW on EGSE
The EGSE is a test system from arcsec build arround a raspberry pi 4 to test the star tracker. The IP address of the EGSE (raspberry pi) is 192.168.18.31. An ssh session can be opened with
````
ssh pi@192.168.18.31
````
Password: raspberry
To run the obsw perform the following steps:
1. Build the cmake EGSE Configuration
* the sysroots for the EGSE can be found [here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/egse&fileid=1190471)
* toolchain for linux host can be downloaded from [here](https://github.com/Pro/raspi-toolchain)
* toolchain for windows host from [here](https://gnutoolchains.com/raspberry/) (the raspios-buster-armhf toolchain is the right one for the EGSE)
2. Disable the ser2net systemd service on the EGSE
````sh
$ sudo systemctl stop ser2net.service
````
3. Power on the star tracker by running
````sh
$ ~/powerctrl/enable0.sh`
````
4. Run portforwarding script for tmtc tcp connection and tcf agent on host PC
````sh
$ ./scripts/egse-port.sh
````
5. The star tracker can be powered off by running
````sh
$ ~/powerctrl/disable0.sh
````
# <a id="gpsd"></a> Manually preparing sysroots to compile gpsd # <a id="gpsd"></a> Manually preparing sysroots to compile gpsd
Copy all header files from [here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/gpsd&fileid=1189985) to the /usr/include directory and all static libraries to /usr/lib. Copy all header files from [here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/gpsd&fileid=1189985) to the /usr/include directory and all static libraries to /usr/lib.

7
bsp_egse/CMakeLists.txt Normal file
View File

@ -0,0 +1,7 @@
target_sources(${OBSW_NAME} PUBLIC
InitMission.cpp
main.cpp
ObjectFactory.cpp
)
add_subdirectory(boardconfig)

192
bsp_egse/InitMission.cpp Normal file
View File

@ -0,0 +1,192 @@
#include "InitMission.h"
#include <fsfw/objectmanager/ObjectManager.h>
#include <fsfw/objectmanager/ObjectManagerIF.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
#include <fsfw/tasks/PeriodicTaskIF.h>
#include <fsfw/tasks/TaskFactory.h>
#include <mission/utility/InitMission.h>
#include <iostream>
#include "OBSWConfig.h"
#include "ObjectFactory.h"
#include "objects/systemObjectList.h"
#include "pollingsequence/pollingSequenceFactory.h"
ServiceInterfaceStream sif::debug("DEBUG");
ServiceInterfaceStream sif::info("INFO");
ServiceInterfaceStream sif::warning("WARNING");
ServiceInterfaceStream sif::error("ERROR");
ObjectManagerIF* objectManager = nullptr;
void initmission::initMission() {
sif::info << "Make sure the systemd service ser2net on the egse has been stopped "
<< "(alias stop-ser2net)" << std::endl;
sif::info << "Make sure the power lines of the star tracker have been enabled "
<< "(alias enable-startracker)" << std::endl;
sif::info << "Building global objects.." << std::endl;
/* Instantiate global object manager and also create all objects */
ObjectManager::instance()->setObjectFactoryFunction(ObjectFactory::produce, nullptr);
sif::info << "Initializing all objects.." << std::endl;
ObjectManager::instance()->initialize();
/* This function creates and starts all tasks */
initTasks();
}
void initmission::initTasks() {
TaskFactory* factory = TaskFactory::instance();
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
if (factory == nullptr) {
/* Should never happen ! */
return;
}
#if OBSW_PRINT_MISSED_DEADLINES == 1
void (*missedDeadlineFunc)(void) = TaskFactory::printMissedDeadline;
#else
void (*missedDeadlineFunc)(void) = nullptr;
#endif
/* TMTC Distribution */
PeriodicTaskIF* tmtcDistributor = factory->createPeriodicTask(
"DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
result = tmtcDistributor->addComponent(objects::CCSDS_PACKET_DISTRIBUTOR);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Object add component failed" << std::endl;
}
result = tmtcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Object add component failed" << std::endl;
}
result = tmtcDistributor->addComponent(objects::TM_FUNNEL);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Object add component failed" << std::endl;
}
PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask(
"TMTC_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
result = tmtcBridgeTask->addComponent(objects::TMTC_BRIDGE);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Add component TMTC Bridge failed" << std::endl;
}
PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask(
"TMTC_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
result = tmtcPollingTask->addComponent(objects::TMTC_POLLING_TASK);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Add component TMTC Polling failed" << std::endl;
}
/* PUS Services */
std::vector<PeriodicTaskIF*> pusTasks;
createPusTasks(*factory, missedDeadlineFunc, pusTasks);
std::vector<PeriodicTaskIF*> pstTasks;
FixedTimeslotTaskIF* pst = factory->createFixedTimeslotTask(
"STAR_TRACKER_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.5, missedDeadlineFunc);
result = pst::pstUart(pst);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
}
pstTasks.push_back(pst);
PeriodicTaskIF* strHelperTask = factory->createPeriodicTask(
"STR_HELPER", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
result = strHelperTask->addComponent(objects::STR_HELPER);
if (result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("STR_HELPER", objects::STR_HELPER);
}
pstTasks.push_back(strHelperTask);
auto taskStarter = [](std::vector<PeriodicTaskIF*>& taskVector, std::string name) {
for (const auto& task : taskVector) {
if (task != nullptr) {
task->startTask();
} else {
sif::error << "Task in vector " << name << " is invalid!" << std::endl;
}
}
};
sif::info << "Starting tasks.." << std::endl;
tmtcDistributor->startTask();
tmtcBridgeTask->startTask();
tmtcPollingTask->startTask();
taskStarter(pstTasks, "PST Tasks");
taskStarter(pusTasks, "PUS Tasks");
sif::info << "Tasks started.." << std::endl;
}
void initmission::createPusTasks(TaskFactory& factory,
TaskDeadlineMissedFunction missedDeadlineFunc,
std::vector<PeriodicTaskIF*>& taskVec) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
PeriodicTaskIF* pusVerification = factory.createPeriodicTask(
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Object add component failed" << std::endl;
}
taskVec.push_back(pusVerification);
PeriodicTaskIF* pusEvents = factory.createPeriodicTask(
"PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusEvents->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
if (result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING);
}
result = pusEvents->addComponent(objects::EVENT_MANAGER);
if (result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS_MGMT", objects::EVENT_MANAGER);
}
taskVec.push_back(pusEvents);
PeriodicTaskIF* pusHighPrio = factory.createPeriodicTask(
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
if (result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS);
}
result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
if (result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT);
}
taskVec.push_back(pusHighPrio);
PeriodicTaskIF* pusMedPrio = factory.createPeriodicTask(
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
if (result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
}
result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
if (result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT);
}
result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS);
if (result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS);
}
result = pusMedPrio->addComponent(objects::PUS_SERVICE_3_HOUSEKEEPING);
if (result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS3", objects::PUS_SERVICE_3_HOUSEKEEPING);
}
taskVec.push_back(pusMedPrio);
PeriodicTaskIF* pusLowPrio = factory.createPeriodicTask(
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
if (result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST);
}
result = pusLowPrio->addComponent(objects::INTERNAL_ERROR_REPORTER);
if (result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("INT_ERR_RPRT", objects::INTERNAL_ERROR_REPORTER);
}
taskVec.push_back(pusLowPrio);
}

21
bsp_egse/InitMission.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef BSP_LINUX_INITMISSION_H_
#define BSP_LINUX_INITMISSION_H_
#include <vector>
#include "fsfw/tasks/Typedef.h"
class PeriodicTaskIF;
class TaskFactory;
namespace initmission {
void initMission();
void initTasks();
void createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc,
std::vector<PeriodicTaskIF*>& taskVec);
void createPusTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc,
std::vector<PeriodicTaskIF*>& taskVec);
}; // namespace initmission
#endif /* BSP_LINUX_INITMISSION_H_ */

View File

@ -0,0 +1,49 @@
#include "ObjectFactory.h"
#include <devConf.h>
#include <fsfw_hal/linux/uart/UartComIF.h>
#include <fsfw_hal/linux/uart/UartCookie.h>
#include <mission/devices/GPSHyperionHandler.h>
#include "OBSWConfig.h"
#include "busConf.h"
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
#include "fsfw/tmtcpacket/pus/tm.h"
#include "fsfw/tmtcservices/CommandingServiceBase.h"
#include "fsfw/tmtcservices/PusServiceBase.h"
#include "linux/devices/devicedefinitions/StarTrackerDefinitions.h"
#include "linux/devices/startracker/StarTrackerHandler.h"
#include "mission/core/GenericFactory.h"
#include "mission/utility/TmFunnel.h"
#include "objects/systemObjectList.h"
#include "tmtc/apid.h"
#include "tmtc/pusIds.h"
void Factory::setStaticFrameworkObjectIds() {
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
PusServiceBase::packetDestination = objects::TM_FUNNEL;
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
TmFunnel::downlinkDestination = objects::TMTC_BRIDGE;
TmFunnel::storageDestination = objects::NO_OBJECT;
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
TmPacketBase::timeStamperId = objects::TIME_STAMPER;
}
void ObjectFactory::produce(void* args) {
Factory::setStaticFrameworkObjectIds();
ObjectFactory::produceGenericObjects();
UartCookie* starTrackerCookie =
new UartCookie(objects::STAR_TRACKER, egse::STAR_TRACKER_UART, UartModes::NON_CANONICAL,
uart::STAR_TRACKER_BAUD, startracker::MAX_FRAME_SIZE * 2 + 2);
new UartComIF(objects::UART_COM_IF);
starTrackerCookie->setNoFixedSizeReply();
StrHelper* strHelper = new StrHelper(objects::STR_HELPER);
StarTrackerHandler* starTrackerHandler = new StarTrackerHandler(
objects::STAR_TRACKER, objects::UART_COM_IF, starTrackerCookie, strHelper);
starTrackerHandler->setStartUpImmediately();
}

8
bsp_egse/ObjectFactory.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef BSP_LINUX_OBJECTFACTORY_H_
#define BSP_LINUX_OBJECTFACTORY_H_
namespace ObjectFactory {
void produce(void* args);
}; // namespace ObjectFactory
#endif /* BSP_LINUX_OBJECTFACTORY_H_ */

View File

@ -0,0 +1,7 @@
target_sources(${OBSW_NAME} PRIVATE
print.c
)
target_include_directories(${OBSW_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)

View File

@ -0,0 +1,8 @@
#ifndef BSP_EGSE_BOARDCONFIG_BUSCONF_H_
#define BSP_EGSE_BOARDCONFIG_BUSCONF_H_
namespace egse {
static constexpr char STAR_TRACKER_UART[] = "/dev/serial0";
}
#endif /* BSP_EGSE_BOARDCONFIG_BUSCONF_H_ */

View File

@ -0,0 +1,38 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2019 jwellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef __ETL_PROFILE_H__
#define __ETL_PROFILE_H__
#define ETL_CHECK_PUSH_POP
#define ETL_CPP11_SUPPORTED 1
#define ETL_NO_NULLPTR_SUPPORT 0
#endif

View File

@ -0,0 +1,15 @@
#ifndef LINUX_GCOV_H_
#define LINUX_GCOV_H_
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
#ifdef GCOV
extern "C" void __gcov_flush();
#else
void __gcov_flush() {
sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if "
"coverage information is desired.\n"
<< std::flush;
}
#endif
#endif /* LINUX_GCOV_H_ */

View File

@ -0,0 +1,10 @@
#include <bsp_egse/boardconfig/print.h>
#include <stdio.h>
void printChar(const char* character, bool errStream) {
if (errStream) {
putc(*character, stderr);
return;
}
putc(*character, stdout);
}

View File

@ -0,0 +1,8 @@
#ifndef HOSTED_BOARDCONFIG_PRINT_H_
#define HOSTED_BOARDCONFIG_PRINT_H_
#include <stdbool.h>
void printChar(const char* character, bool errStream);
#endif /* HOSTED_BOARDCONFIG_PRINT_H_ */

View File

@ -0,0 +1,6 @@
#ifndef BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_
#define BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_
#include <cstdint>
#endif /* BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ */

28
bsp_egse/main.cpp Normal file
View File

@ -0,0 +1,28 @@
#include <iostream>
#include "InitMission.h"
#include "OBSWConfig.h"
#include "OBSWVersion.h"
#include "fsfw/FSFWVersion.h"
#include "fsfw/tasks/TaskFactory.h"
/**
* @brief This is the main program entry point for the egse (raspberry pi 4)
* @return
*/
int main(void) {
std::cout << "-- EIVE OBSW --" << std::endl;
std::cout << "-- Compiled for EGSE from Arcsec"
<< " --" << std::endl;
std::cout << "-- OBSW " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION << "."
<< SW_REVISION << ", FSFW v" << FSFW_VERSION << "." << FSFW_SUBVERSION << FSFW_REVISION
<< "--" << std::endl;
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
initmission::initMission();
for (;;) {
/* Suspend main thread by sleeping it. */
TaskFactory::delayTask(5000);
}
}

View File

@ -64,17 +64,17 @@ void initmission::initTasks() {
} }
/* UDP bridge */ /* UDP bridge */
PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask(
"UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); "TMTC_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
result = udpBridgeTask->addComponent(objects::TMTC_BRIDGE); result = tmtcBridgeTask->addComponent(objects::TMTC_BRIDGE);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Add component UDP Unix Bridge failed" << std::endl; sif::error << "Add component TMTC Bridge failed" << std::endl;
} }
PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask( PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask(
"UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); "TMTC_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
result = udpPollingTask->addComponent(objects::TMTC_POLLING_TASK); result = tmtcPollingTask->addComponent(objects::TMTC_POLLING_TASK);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "Add component UDP Polling failed" << std::endl; sif::error << "Add component TMTC Polling failed" << std::endl;
} }
/* PUS Services */ /* PUS Services */
@ -100,8 +100,8 @@ void initmission::initTasks() {
sif::info << "Starting tasks.." << std::endl; sif::info << "Starting tasks.." << std::endl;
tmTcDistributor->startTask(); tmTcDistributor->startTask();
udpBridgeTask->startTask(); tmtcBridgeTask->startTask();
udpPollingTask->startTask(); tmtcPollingTask->startTask();
taskStarter(pusTasks, "PUS Tasks"); taskStarter(pusTasks, "PUS Tasks");
#if OBSW_ADD_TEST_CODE == 1 #if OBSW_ADD_TEST_CODE == 1

View File

@ -1,4 +1,4 @@
#include <bsp_q7s/boardconfig/print.h> #include <bsp_linux_board/boardconfig/print.h>
#include <stdio.h> #include <stdio.h>
void printChar(const char* character, bool errStream) { void printChar(const char* character, bool errStream) {

View File

@ -142,13 +142,13 @@ void Q7STestTask::testDummyParams() {
param.print(); param.print();
int test = 0; int test = 0;
result = param.getValue<int>(DummyParameter::DUMMY_KEY_PARAM_1, &test); result = param.getValue<int>(DummyParameter::DUMMY_KEY_PARAM_1, test);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Q7STestTask::testDummyParams: Key " << DummyParameter::DUMMY_KEY_PARAM_1 sif::warning << "Q7STestTask::testDummyParams: Key " << DummyParameter::DUMMY_KEY_PARAM_1
<< " does not exist" << std::endl; << " does not exist" << std::endl;
} }
std::string test2; std::string test2;
result = param.getValue<std::string>(DummyParameter::DUMMY_KEY_PARAM_2, &test2); result = param.getValue<std::string>(DummyParameter::DUMMY_KEY_PARAM_2, test2);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Q7STestTask::testDummyParams: Key " << DummyParameter::DUMMY_KEY_PARAM_1 sif::warning << "Q7STestTask::testDummyParams: Key " << DummyParameter::DUMMY_KEY_PARAM_1
<< " does not exist" << std::endl; << " does not exist" << std::endl;
@ -170,15 +170,15 @@ void Q7STestTask::testProtHandler() {
bool opPerformed = false; bool opPerformed = false;
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
// If any chips are unlocked, lock them here // If any chips are unlocked, lock them here
result = coreController->setBootCopyProtection( result = coreController->setBootCopyProtection(xsc::Chip::ALL_CHIP, xsc::Copy::ALL_COPY, true,
CoreController::Chip::ALL_CHIP, CoreController::Copy::ALL_COPY, true, opPerformed, true); opPerformed, true);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl; sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
} }
// unlock own copy // unlock own copy
result = coreController->setBootCopyProtection( result = coreController->setBootCopyProtection(xsc::Chip::SELF_CHIP, xsc::Copy::SELF_COPY, false,
CoreController::Chip::SELF_CHIP, CoreController::Copy::SELF_COPY, false, opPerformed, true); opPerformed, true);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl; sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
} }
@ -191,8 +191,8 @@ void Q7STestTask::testProtHandler() {
} }
// lock own copy // lock own copy
result = coreController->setBootCopyProtection( result = coreController->setBootCopyProtection(xsc::Chip::SELF_CHIP, xsc::Copy::SELF_COPY, true,
CoreController::Chip::SELF_CHIP, CoreController::Copy::SELF_COPY, true, opPerformed, true); opPerformed, true);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl; sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
} }
@ -205,8 +205,8 @@ void Q7STestTask::testProtHandler() {
} }
// unlock specific copy // unlock specific copy
result = coreController->setBootCopyProtection( result = coreController->setBootCopyProtection(xsc::Chip::CHIP_1, xsc::Copy::COPY_1, false,
CoreController::Chip::CHIP_1, CoreController::Copy::COPY_1, false, opPerformed, true); opPerformed, true);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl; sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
} }
@ -219,8 +219,8 @@ void Q7STestTask::testProtHandler() {
} }
// lock specific copy // lock specific copy
result = coreController->setBootCopyProtection( result = coreController->setBootCopyProtection(xsc::Chip::CHIP_1, xsc::Copy::COPY_1, true,
CoreController::Chip::CHIP_1, CoreController::Copy::COPY_1, true, opPerformed, true); opPerformed, true);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl; sif::warning << "Q7STestTask::testProtHandler: Op failed" << std::endl;
} }

View File

@ -12,6 +12,7 @@ namespace gpioCallbacks {
GpioIF* gpioComInterface; GpioIF* gpioComInterface;
void initSpiCsDecoder(GpioIF* gpioComIF) { void initSpiCsDecoder(GpioIF* gpioComIF) {
using namespace gpio;
ReturnValue_t result; ReturnValue_t result;
if (gpioComIF == nullptr) { if (gpioComIF == nullptr) {
@ -26,29 +27,29 @@ void initSpiCsDecoder(GpioIF* gpioComIF) {
GpiodRegularByLineName* spiMuxBit = nullptr; GpiodRegularByLineName* spiMuxBit = nullptr;
/** Setting mux bit 1 to low will disable IC21 on the interface board */ /** Setting mux bit 1 to low will disable IC21 on the interface board */
spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_0_PIN, "SPI Mux Bit 1", spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_0_PIN, "SPI Mux Bit 1",
gpio::DIR_OUT, gpio::HIGH); Direction::OUT, Levels::HIGH);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_0, spiMuxBit); spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_0, spiMuxBit);
/** Setting mux bit 2 to low disables IC1 on the TCS board */ /** Setting mux bit 2 to low disables IC1 on the TCS board */
spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_1_PIN, "SPI Mux Bit 2", spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_1_PIN, "SPI Mux Bit 2",
gpio::DIR_OUT, gpio::HIGH); Direction::OUT, Levels::HIGH);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_1, spiMuxBit); spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_1, spiMuxBit);
/** Setting mux bit 3 to low disables IC2 on the TCS board and IC22 on the interface board */ /** Setting mux bit 3 to low disables IC2 on the TCS board and IC22 on the interface board */
spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_2_PIN, "SPI Mux Bit 3", spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_2_PIN, "SPI Mux Bit 3",
gpio::DIR_OUT, gpio::LOW); Direction::OUT, Levels::LOW);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_2, spiMuxBit); spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_2, spiMuxBit);
/** The following gpios can take arbitrary initial values */ /** The following gpios can take arbitrary initial values */
spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_3_PIN, "SPI Mux Bit 4", spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_3_PIN, "SPI Mux Bit 4",
gpio::DIR_OUT, gpio::LOW); Direction::OUT, Levels::LOW);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_3, spiMuxBit); spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_3, spiMuxBit);
spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_4_PIN, "SPI Mux Bit 5", spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_4_PIN, "SPI Mux Bit 5",
gpio::DIR_OUT, gpio::LOW); Direction::OUT, Levels::LOW);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_4, spiMuxBit); spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_4, spiMuxBit);
spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_5_PIN, "SPI Mux Bit 6", spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_5_PIN, "SPI Mux Bit 6",
gpio::DIR_OUT, gpio::LOW); Direction::OUT, Levels::LOW);
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_5, spiMuxBit); spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_5, spiMuxBit);
GpiodRegularByLineName* enRwDecoder = GpiodRegularByLineName* enRwDecoder = new GpiodRegularByLineName(
new GpiodRegularByLineName(q7s::gpioNames::EN_RW_CS, "EN_RW_CS", gpio::DIR_OUT, gpio::HIGH); q7s::gpioNames::EN_RW_CS, "EN_RW_CS", Direction::OUT, Levels::HIGH);
spiMuxGpios->addGpio(gpioIds::EN_RW_CS, enRwDecoder); spiMuxGpios->addGpio(gpioIds::EN_RW_CS, enRwDecoder);
result = gpioComInterface->addGpios(spiMuxGpios); result = gpioComInterface->addGpios(spiMuxGpios);
@ -60,6 +61,7 @@ void initSpiCsDecoder(GpioIF* gpioComIF) {
void spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gpioOp, gpio::Levels value, void spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gpioOp, gpio::Levels value,
void* args) { void* args) {
using namespace gpio;
if (gpioComInterface == nullptr) { if (gpioComInterface == nullptr) {
sif::debug << "spiCsDecoderCallback: No gpioComIF specified. Call initSpiCsDecoder " sif::debug << "spiCsDecoderCallback: No gpioComIF specified. Call initSpiCsDecoder "
<< "to specify gpioComIF" << std::endl; << "to specify gpioComIF" << std::endl;
@ -71,7 +73,7 @@ void spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gpioOp, gpio::Lev
return; return;
} }
if (value == gpio::HIGH) { if (value == Levels::HIGH) {
switch (gpioId) { switch (gpioId) {
case (gpioIds::RTD_IC_3): { case (gpioIds::RTD_IC_3): {
disableDecoderTcsIc1(); disableDecoderTcsIc1();
@ -204,7 +206,7 @@ void spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gpioOp, gpio::Lev
default: default:
sif::debug << "spiCsDecoderCallback: Invalid gpio id " << gpioId << std::endl; sif::debug << "spiCsDecoderCallback: Invalid gpio id " << gpioId << std::endl;
} }
} else if (value == gpio::LOW) { } else if (value == Levels::LOW) {
switch (gpioId) { switch (gpioId) {
case (gpioIds::RTD_IC_3): { case (gpioIds::RTD_IC_3): {
selectY7(); selectY7();

View File

@ -1,5 +1,7 @@
#include "CoreController.h" #include "CoreController.h"
#include <fsfw/events/EventManager.h>
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "OBSWVersion.h" #include "OBSWVersion.h"
#include "fsfw/FSFWVersion.h" #include "fsfw/FSFWVersion.h"
@ -20,8 +22,8 @@
#include "bsp_q7s/memory/SdCardManager.h" #include "bsp_q7s/memory/SdCardManager.h"
#include "bsp_q7s/memory/scratchApi.h" #include "bsp_q7s/memory/scratchApi.h"
CoreController::Chip CoreController::CURRENT_CHIP = Chip::NO_CHIP; xsc::Chip CoreController::CURRENT_CHIP = xsc::Chip::NO_CHIP;
CoreController::Copy CoreController::CURRENT_COPY = Copy::NO_COPY; xsc::Copy CoreController::CURRENT_COPY = xsc::Copy::NO_COPY;
CoreController::CoreController(object_id_t objectId) CoreController::CoreController(object_id_t objectId)
: ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), opDivider(5) { : ExtendedControllerBase(objectId, objects::NO_OBJECT, 5), opDivider(5) {
@ -57,6 +59,7 @@ ReturnValue_t CoreController::handleCommandMessage(CommandMessage *message) {
void CoreController::performControlOperation() { void CoreController::performControlOperation() {
performWatchdogControlOperation(); performWatchdogControlOperation();
sdStateMachine(); sdStateMachine();
performMountedSdCardOperations();
} }
ReturnValue_t CoreController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap, ReturnValue_t CoreController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
@ -77,6 +80,8 @@ ReturnValue_t CoreController::initialize() {
} }
sdStateMachine(); sdStateMachine();
triggerEvent(REBOOT_SW, CURRENT_CHIP, CURRENT_COPY);
return ExtendedControllerBase::initialize(); return ExtendedControllerBase::initialize();
} }
@ -89,7 +94,7 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() {
} }
} }
sdStateMachine(); sdStateMachine();
result = initVersionFile(); performMountedSdCardOperations();
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
sif::warning << "CoreController::initialize: Version initialization failed" << std::endl; sif::warning << "CoreController::initialize: Version initialization failed" << std::endl;
} }
@ -102,6 +107,72 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() {
return result; return result;
} }
ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t *data, size_t size) {
switch (actionId) {
case (LIST_DIRECTORY_INTO_FILE): {
return actionListDirectoryIntoFile(actionId, commandedBy, data, size);
}
case (SWITCH_REBOOT_FILE_HANDLING): {
if (size < 1) {
return HasActionsIF::INVALID_PARAMETERS;
}
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE;
// Disable the reboot file mechanism
parseRebootFile(path, rebootFile);
if (data[0] == 0) {
rebootFile.enabled = false;
rewriteRebootFile(rebootFile);
} else if (data[0] == 1) {
rebootFile.enabled = true;
rewriteRebootFile(rebootFile);
} else {
return HasActionsIF::INVALID_PARAMETERS;
}
return HasActionsIF::EXECUTION_FINISHED;
}
case (RESET_REBOOT_COUNTERS): {
if (size == 0) {
resetRebootCount(xsc::ALL_CHIP, xsc::ALL_COPY);
} else if (size == 2) {
if (data[0] > 1 or data[1] > 1) {
return HasActionsIF::INVALID_PARAMETERS;
}
resetRebootCount(static_cast<xsc::Chip>(data[0]), static_cast<xsc::Copy>(data[1]));
}
return HasActionsIF::EXECUTION_FINISHED;
}
case (SWITCH_IMG_LOCK): {
if (size != 3) {
return HasActionsIF::INVALID_PARAMETERS;
}
if (data[1] > 1 or data[2] > 1) {
return HasActionsIF::INVALID_PARAMETERS;
}
setRebootMechanismLock(data[0], static_cast<xsc::Chip>(data[1]),
static_cast<xsc::Copy>(data[2]));
return HasActionsIF::EXECUTION_FINISHED;
}
case (SET_MAX_REBOOT_CNT): {
if (size < 1) {
return HasActionsIF::INVALID_PARAMETERS;
}
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE;
// Disable the reboot file mechanism
parseRebootFile(path, rebootFile);
rebootFile.maxCount = data[0];
rewriteRebootFile(rebootFile);
return HasActionsIF::EXECUTION_FINISHED;
}
case (REBOOT_OBC): {
return actionPerformReboot(data, size);
}
default: {
return HasActionsIF::INVALID_ACTION_ID;
}
}
}
ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode, ReturnValue_t CoreController::checkModeCommand(Mode_t mode, Submode_t submode,
uint32_t *msToReachTheMode) { uint32_t *msToReachTheMode) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
@ -500,21 +571,6 @@ ReturnValue_t CoreController::sdCardSetup(sd::SdCard sdCard, sd::SdState targetS
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t *data, size_t size) {
switch (actionId) {
case (LIST_DIRECTORY_INTO_FILE): {
return actionListDirectoryIntoFile(actionId, commandedBy, data, size);
}
case (REBOOT_OBC): {
return actionPerformReboot(data, size);
}
default: {
return HasActionsIF::INVALID_ACTION_ID;
}
}
}
ReturnValue_t CoreController::sdColdRedundantBlockingInit() { ReturnValue_t CoreController::sdColdRedundantBlockingInit() {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
@ -689,7 +745,7 @@ ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId,
ReturnValue_t CoreController::initBootCopy() { ReturnValue_t CoreController::initBootCopy() {
if (not std::filesystem::exists(CURR_COPY_FILE)) { if (not std::filesystem::exists(CURR_COPY_FILE)) {
// Thils file is created by the systemd service eive-early-config so this should // This file is created by the systemd service eive-early-config so this should
// not happen normally // not happen normally
std::string cmd = "xsc_boot_copy > " + std::string(CURR_COPY_FILE); std::string cmd = "xsc_boot_copy > " + std::string(CURR_COPY_FILE);
int result = std::system(cmd.c_str()); int result = std::system(cmd.c_str());
@ -697,22 +753,18 @@ ReturnValue_t CoreController::initBootCopy() {
utility::handleSystemError(result, "CoreController::initBootCopy"); utility::handleSystemError(result, "CoreController::initBootCopy");
} }
} }
std::ifstream file(CURR_COPY_FILE);
std::string line; getCurrentBootCopy(CURRENT_CHIP, CURRENT_COPY);
std::getline(file, line);
std::istringstream iss(line);
int value = 0;
iss >> value;
CURRENT_CHIP = static_cast<Chip>(value);
iss >> value;
CURRENT_COPY = static_cast<Copy>(value);
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
void CoreController::getCurrentBootCopy(Chip &chip, Copy &copy) { void CoreController::getCurrentBootCopy(xsc::Chip &chip, xsc::Copy &copy) {
xsc_libnor_chip_t xscChip;
xsc_libnor_copy_t xscCopy;
xsc_boot_get_chip_copy(&xscChip, &xscCopy);
// Not really thread-safe but it does not need to be // Not really thread-safe but it does not need to be
chip = CURRENT_CHIP; chip = static_cast<xsc::Chip>(xscChip);
copy = CURRENT_COPY; copy = static_cast<xsc::Copy>(xscCopy);
} }
ReturnValue_t CoreController::initWatchdogFifo() { ReturnValue_t CoreController::initWatchdogFifo() {
@ -759,8 +811,8 @@ ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t si
SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_0); SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_0);
SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_1); SdCardManager::instance()->switchOffSdCard(sd::SdCard::SLOT_1);
// If any boot copies are unprotected // If any boot copies are unprotected
ReturnValue_t retval = ReturnValue_t retval = setBootCopyProtection(xsc::Chip::SELF_CHIP, xsc::Copy::SELF_COPY, true,
setBootCopyProtection(Chip::SELF_CHIP, Copy::SELF_COPY, true, protOpPerformed, false); protOpPerformed, false);
if (retval == HasReturnvaluesIF::RETURN_OK and protOpPerformed) { if (retval == HasReturnvaluesIF::RETURN_OK and protOpPerformed) {
sif::info << "Running slot was writeprotected before reboot" << std::endl; sif::info << "Running slot was writeprotected before reboot" << std::endl;
} }
@ -771,7 +823,7 @@ ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t si
} }
return HasActionsIF::EXECUTION_FINISHED; return HasActionsIF::EXECUTION_FINISHED;
} }
if (size < 3) { if (size < 3 or (data[1] > 1 or data[2] > 1)) {
return HasActionsIF::INVALID_PARAMETERS; return HasActionsIF::INVALID_PARAMETERS;
} }
#if OBSW_VERBOSE_LEVEL >= 1 #if OBSW_VERBOSE_LEVEL >= 1
@ -782,21 +834,53 @@ ReturnValue_t CoreController::actionPerformReboot(const uint8_t *data, size_t si
// Check that the target chip and copy is writeprotected first // Check that the target chip and copy is writeprotected first
generateChipStateFile(); generateChipStateFile();
// If any boot copies are unprotected, protect them here // If any boot copies are unprotected, protect them here
ReturnValue_t retval = setBootCopyProtection( auto tgtChip = static_cast<xsc::Chip>(data[1]);
static_cast<Chip>(data[1]), static_cast<Copy>(data[2]), true, protOpPerformed, false); auto tgtCopy = static_cast<xsc::Copy>(data[2]);
ReturnValue_t retval =
setBootCopyProtection(static_cast<xsc::Chip>(data[1]), static_cast<xsc::Copy>(data[2]), true,
protOpPerformed, false);
if (retval == HasReturnvaluesIF::RETURN_OK and protOpPerformed) { if (retval == HasReturnvaluesIF::RETURN_OK and protOpPerformed) {
sif::info << "Target slot was writeprotected before reboot" << std::endl; sif::info << "Target slot was writeprotected before reboot" << std::endl;
} }
// The second byte in data is the target chip, the third byte is the target copy switch (tgtChip) {
std::string cmdString = case (xsc::Chip::CHIP_0): {
"xsc_boot_copy " + std::to_string(data[1]) + " " + std::to_string(data[2]); switch (tgtCopy) {
int result = std::system(cmdString.c_str()); case (xsc::Copy::COPY_0): {
if (result != 0) { xsc_boot_copy(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_NOMINAL);
utility::handleSystemError(result, "CoreController::executeAction"); break;
return HasReturnvaluesIF::RETURN_FAILED;
} }
return HasActionsIF::EXECUTION_FINISHED; case (xsc::Copy::COPY_1): {
xsc_boot_copy(XSC_LIBNOR_CHIP_0, XSC_LIBNOR_COPY_GOLD);
break;
}
default: {
break;
}
}
break;
}
case (xsc::Chip::CHIP_1): {
switch (tgtCopy) {
case (xsc::Copy::COPY_0): {
xsc_boot_copy(XSC_LIBNOR_CHIP_1, XSC_LIBNOR_COPY_NOMINAL);
break;
}
case (xsc::Copy::COPY_1): {
xsc_boot_copy(XSC_LIBNOR_CHIP_1, XSC_LIBNOR_COPY_GOLD);
break;
}
default: {
break;
}
}
break;
}
default:
break;
}
return HasReturnvaluesIF::RETURN_FAILED;
} }
CoreController::~CoreController() {} CoreController::~CoreController() {}
@ -850,8 +934,8 @@ ReturnValue_t CoreController::generateChipStateFile() {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t CoreController::setBootCopyProtection(Chip targetChip, Copy targetCopy, bool protect, ReturnValue_t CoreController::setBootCopyProtection(xsc::Chip targetChip, xsc::Copy targetCopy,
bool &protOperationPerformed, bool protect, bool &protOperationPerformed,
bool updateProtFile) { bool updateProtFile) {
bool allChips = false; bool allChips = false;
bool allCopies = false; bool allCopies = false;
@ -860,14 +944,14 @@ ReturnValue_t CoreController::setBootCopyProtection(Chip targetChip, Copy target
protOperationPerformed = false; protOperationPerformed = false;
switch (targetChip) { switch (targetChip) {
case (Chip::ALL_CHIP): { case (xsc::Chip::ALL_CHIP): {
allChips = true; allChips = true;
break; break;
} }
case (Chip::NO_CHIP): { case (xsc::Chip::NO_CHIP): {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
case (Chip::SELF_CHIP): { case (xsc::Chip::SELF_CHIP): {
selfChip = true; selfChip = true;
targetChip = CURRENT_CHIP; targetChip = CURRENT_CHIP;
break; break;
@ -877,14 +961,14 @@ ReturnValue_t CoreController::setBootCopyProtection(Chip targetChip, Copy target
} }
} }
switch (targetCopy) { switch (targetCopy) {
case (Copy::ALL_COPY): { case (xsc::Copy::ALL_COPY): {
allCopies = true; allCopies = true;
break; break;
} }
case (Copy::NO_COPY): { case (xsc::Copy::NO_COPY): {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
case (Copy::SELF_COPY): { case (xsc::Copy::SELF_COPY): {
selfCopy = true; selfCopy = true;
targetCopy = CURRENT_COPY; targetCopy = CURRENT_COPY;
break; break;
@ -907,10 +991,10 @@ ReturnValue_t CoreController::setBootCopyProtection(Chip targetChip, Copy target
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
int CoreController::handleBootCopyProtAtIndex(Chip targetChip, Copy targetCopy, bool protect, int CoreController::handleBootCopyProtAtIndex(xsc::Chip targetChip, xsc::Copy targetCopy,
bool &protOperationPerformed, bool selfChip, bool protect, bool &protOperationPerformed,
bool selfCopy, bool allChips, bool allCopies, bool selfChip, bool selfCopy, bool allChips,
uint8_t arrIdx) { bool allCopies, uint8_t arrIdx) {
bool currentProt = protArray[arrIdx]; bool currentProt = protArray[arrIdx];
std::ostringstream oss; std::ostringstream oss;
bool performOp = false; bool performOp = false;
@ -923,22 +1007,22 @@ int CoreController::handleBootCopyProtAtIndex(Chip targetChip, Copy targetCopy,
return 1; return 1;
} }
} }
Chip currentChip; xsc::Chip currentChip;
Copy currentCopy; xsc::Copy currentCopy;
oss << "writeprotect "; oss << "writeprotect ";
if (arrIdx == 0 or arrIdx == 1) { if (arrIdx == 0 or arrIdx == 1) {
oss << "0 "; oss << "0 ";
currentChip = Chip::CHIP_0; currentChip = xsc::Chip::CHIP_0;
} else { } else {
oss << "1 "; oss << "1 ";
currentChip = Chip::CHIP_1; currentChip = xsc::Chip::CHIP_1;
} }
if (arrIdx == 0 or arrIdx == 2) { if (arrIdx == 0 or arrIdx == 2) {
oss << "0 "; oss << "0 ";
currentCopy = Copy::COPY_0; currentCopy = xsc::Copy::COPY_0;
} else { } else {
oss << "1 "; oss << "1 ";
currentCopy = Copy::COPY_1; currentCopy = xsc::Copy::COPY_1;
} }
if (protect) { if (protect) {
oss << "1"; oss << "1";
@ -1033,29 +1117,29 @@ ReturnValue_t CoreController::handleProtInfoUpdateLine(std::string nextLine) {
uint8_t wordIdx = 0; uint8_t wordIdx = 0;
uint8_t arrayIdx = 0; uint8_t arrayIdx = 0;
istringstream iss(nextLine); istringstream iss(nextLine);
Chip currentChip = Chip::CHIP_0; xsc::Chip currentChip = xsc::Chip::CHIP_0;
Copy currentCopy = Copy::COPY_0; xsc::Copy currentCopy = xsc::Copy::COPY_0;
while (iss >> word) { while (iss >> word) {
if (wordIdx == 1) { if (wordIdx == 1) {
currentChip = static_cast<Chip>(stoi(word)); currentChip = static_cast<xsc::Chip>(stoi(word));
} }
if (wordIdx == 3) { if (wordIdx == 3) {
currentCopy = static_cast<Copy>(stoi(word)); currentCopy = static_cast<xsc::Copy>(stoi(word));
} }
if (wordIdx == 3) { if (wordIdx == 3) {
if (currentChip == Chip::CHIP_0) { if (currentChip == xsc::Chip::CHIP_0) {
if (currentCopy == Copy::COPY_0) { if (currentCopy == xsc::Copy::COPY_0) {
arrayIdx = 0; arrayIdx = 0;
} else if (currentCopy == Copy::COPY_1) { } else if (currentCopy == xsc::Copy::COPY_1) {
arrayIdx = 1; arrayIdx = 1;
} }
} }
else if (currentChip == Chip::CHIP_1) { else if (currentChip == xsc::Chip::CHIP_1) {
if (currentCopy == Copy::COPY_0) { if (currentCopy == xsc::Copy::COPY_0) {
arrayIdx = 2; arrayIdx = 2;
} else if (currentCopy == Copy::COPY_1) { } else if (currentCopy == xsc::Copy::COPY_1) {
arrayIdx = 3; arrayIdx = 3;
} }
} }
@ -1101,3 +1185,463 @@ void CoreController::performWatchdogControlOperation() {
} }
} }
} }
void CoreController::performMountedSdCardOperations() {
if (doPerformMountedSdCardOps) {
bool sdCardMounted = false;
sdCardMounted = sdcMan->isSdCardMounted(sdInfo.pref);
if (sdCardMounted) {
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + "/" + CONF_FOLDER;
if (not std::filesystem::exists(path)) {
std::filesystem::create_directory(path);
}
initVersionFile();
performRebootFileHandling(false);
doPerformMountedSdCardOps = false;
}
}
}
void CoreController::performRebootFileHandling(bool recreateFile) {
using namespace std;
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE;
if (not std::filesystem::exists(path) or recreateFile) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "CoreController::performRebootFileHandling: Recreating reboot file" << std::endl;
#endif
rebootFile.enabled = true;
rebootFile.img00Cnt = 0;
rebootFile.img01Cnt = 0;
rebootFile.img10Cnt = 0;
rebootFile.img11Cnt = 0;
rebootFile.lastChip = xsc::Chip::CHIP_0;
rebootFile.lastCopy = xsc::Copy::COPY_0;
rebootFile.img00Lock = false;
rebootFile.img01Lock = false;
rebootFile.img10Lock = false;
rebootFile.img11Lock = false;
rebootFile.mechanismNextChip = xsc::Chip::NO_CHIP;
rebootFile.mechanismNextCopy = xsc::Copy::NO_COPY;
rebootFile.bootFlag = false;
rewriteRebootFile(rebootFile);
} else {
if (not parseRebootFile(path, rebootFile)) {
performRebootFileHandling(true);
}
}
if (CURRENT_CHIP == xsc::CHIP_0) {
if (CURRENT_COPY == xsc::COPY_0) {
rebootFile.img00Cnt++;
} else {
rebootFile.img01Cnt++;
}
} else {
if (CURRENT_COPY == xsc::COPY_0) {
rebootFile.img10Cnt++;
} else {
rebootFile.img11Cnt++;
}
}
if (rebootFile.bootFlag) {
// Trigger event to inform ground that a reboot was triggered
uint32_t p1 = rebootFile.lastChip << 16 | rebootFile.lastCopy;
uint32_t p2 = rebootFile.img00Cnt << 24 | rebootFile.img01Cnt << 16 | rebootFile.img10Cnt << 8 |
rebootFile.img11Cnt;
triggerEvent(REBOOT_MECHANISM_TRIGGERED, p1, p2);
// Clear the boot flag
rebootFile.bootFlag = false;
}
if (rebootFile.mechanismNextChip != xsc::NO_CHIP and
rebootFile.mechanismNextCopy != xsc::NO_COPY) {
if (CURRENT_CHIP != rebootFile.mechanismNextChip or
CURRENT_COPY != rebootFile.mechanismNextCopy) {
std::string infoString = std::to_string(rebootFile.mechanismNextChip) + " " +
std::to_string(rebootFile.mechanismNextCopy);
sif::warning << "CoreController::performRebootFileHandling: Expected to be on image "
<< infoString << " but currently on other image. Locking " << infoString
<< std::endl;
// Firmware or other component might be corrupt and we are on another image then the target
// image specified by the mechanism. We can't really trust the target image anymore.
// Lock it for now
if (rebootFile.mechanismNextChip == xsc::CHIP_0) {
if (rebootFile.mechanismNextCopy == xsc::COPY_0) {
rebootFile.img00Lock = true;
} else {
rebootFile.img01Lock = true;
}
} else {
if (rebootFile.mechanismNextCopy == xsc::COPY_0) {
rebootFile.img10Lock = true;
} else {
rebootFile.img11Lock = true;
}
}
}
}
rebootFile.lastChip = CURRENT_CHIP;
rebootFile.lastCopy = CURRENT_COPY;
// Only reboot if the reboot functionality is enabled.
// The handler will still increment the boot counts
if (rebootFile.enabled and (*rebootFile.relevantBootCnt >= rebootFile.maxCount)) {
// Reboot to other image
bool doReboot = false;
xsc::Chip tgtChip = xsc::NO_CHIP;
xsc::Copy tgtCopy = xsc::NO_COPY;
determineAndExecuteReboot(rebootFile, doReboot, tgtChip, tgtCopy);
if (doReboot) {
rebootFile.bootFlag = true;
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "Boot counter for image " << CURRENT_CHIP << " " << CURRENT_COPY
<< " too high. Rebooting to " << tgtChip << " " << tgtCopy << std::endl;
#endif
rebootFile.mechanismNextChip = tgtChip;
rebootFile.mechanismNextCopy = tgtCopy;
rewriteRebootFile(rebootFile);
xsc_boot_copy(static_cast<xsc_libnor_chip_t>(tgtChip),
static_cast<xsc_libnor_copy_t>(tgtCopy));
}
} else {
rebootFile.mechanismNextChip = xsc::NO_CHIP;
rebootFile.mechanismNextCopy = xsc::NO_COPY;
}
rewriteRebootFile(rebootFile);
}
void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot,
xsc::Chip &tgtChip, xsc::Copy &tgtCopy) {
tgtChip = xsc::CHIP_0;
tgtCopy = xsc::COPY_0;
needsReboot = false;
if ((CURRENT_CHIP == xsc::CHIP_0) and (CURRENT_COPY == xsc::COPY_0) and
(rf.img00Cnt >= rf.maxCount)) {
needsReboot = true;
if (rf.img01Cnt < rf.maxCount and not rf.img01Lock) {
tgtCopy = xsc::COPY_1;
return;
}
if (rf.img10Cnt < rf.maxCount and not rf.img10Lock) {
tgtChip = xsc::CHIP_1;
return;
}
if (rf.img11Cnt < rf.maxCount and not rf.img11Lock) {
tgtChip = xsc::CHIP_1;
tgtCopy = xsc::COPY_1;
return;
}
// Can't really do much here. Stay on image
sif::warning
<< "All reboot counts too high or all fallback images locked, already on fallback image"
<< std::endl;
needsReboot = false;
return;
}
if ((CURRENT_CHIP == xsc::CHIP_0) and (CURRENT_COPY == xsc::COPY_1) and
(rf.img01Cnt >= rf.maxCount)) {
needsReboot = true;
if (rf.img00Cnt < rf.maxCount and not rf.img00Lock) {
// Reboot on fallback image
return;
}
if (rf.img10Cnt < rf.maxCount and not rf.img10Lock) {
tgtChip = xsc::CHIP_1;
return;
}
if (rf.img11Cnt < rf.maxCount and not rf.img11Lock) {
tgtChip = xsc::CHIP_1;
tgtCopy = xsc::COPY_1;
}
if (rf.img00Lock) {
needsReboot = false;
}
// Reboot to fallback image
}
if ((CURRENT_CHIP == xsc::CHIP_1) and (CURRENT_COPY == xsc::COPY_0) and
(rf.img10Cnt >= rf.maxCount)) {
needsReboot = true;
if (rf.img11Cnt < rf.maxCount and not rf.img11Lock) {
tgtChip = xsc::CHIP_1;
tgtCopy = xsc::COPY_1;
return;
}
if (rf.img00Cnt < rf.maxCount and not rf.img00Lock) {
return;
}
if (rf.img01Cnt < rf.maxCount and not rf.img01Lock) {
tgtCopy = xsc::COPY_1;
return;
}
if (rf.img00Lock) {
needsReboot = false;
}
// Reboot to fallback image
}
if ((CURRENT_CHIP == xsc::CHIP_1) and (CURRENT_COPY == xsc::COPY_1) and
(rf.img11Cnt >= rf.maxCount)) {
needsReboot = true;
if (rf.img10Cnt < rf.maxCount and not rf.img10Lock) {
tgtChip = xsc::CHIP_1;
return;
}
if (rf.img00Cnt < rf.maxCount and not rf.img00Lock) {
return;
}
if (rf.img01Cnt < rf.maxCount and not rf.img01Lock) {
tgtCopy = xsc::COPY_1;
return;
}
if (rf.img00Lock) {
needsReboot = false;
}
// Reboot to fallback image
}
}
bool CoreController::parseRebootFile(std::string path, RebootFile &rf) {
using namespace std;
std::string selfMatch;
if (CURRENT_CHIP == xsc::CHIP_0) {
if (CURRENT_COPY == xsc::COPY_0) {
selfMatch = "00";
} else {
selfMatch = "01";
}
} else {
if (CURRENT_COPY == xsc::COPY_0) {
selfMatch = "10";
} else {
selfMatch = "11";
}
}
ifstream file(path);
string word;
string line;
uint8_t lineIdx = 0;
while (std::getline(file, line)) {
istringstream iss(line);
switch (lineIdx) {
case 0: {
iss >> word;
if (word.find("on:") == string::npos) {
// invalid file
return false;
}
iss >> rf.enabled;
break;
}
case 1: {
iss >> word;
if (word.find("maxcnt:") == string::npos) {
return false;
}
iss >> rf.maxCount;
break;
}
case 2: {
iss >> word;
if (word.find("img00:") == string::npos) {
return false;
}
iss >> rf.img00Cnt;
if (word.find(selfMatch) != string::npos) {
rf.relevantBootCnt = &rf.img00Cnt;
}
break;
}
case 3: {
iss >> word;
if (word.find("img01:") == string::npos) {
return false;
}
iss >> rf.img01Cnt;
if (word.find(selfMatch) != string::npos) {
rf.relevantBootCnt = &rf.img01Cnt;
}
break;
}
case 4: {
iss >> word;
if (word.find("img10:") == string::npos) {
return false;
}
iss >> rf.img10Cnt;
if (word.find(selfMatch) != string::npos) {
rf.relevantBootCnt = &rf.img10Cnt;
}
break;
}
case 5: {
iss >> word;
if (word.find("img11:") == string::npos) {
return false;
}
iss >> rf.img11Cnt;
if (word.find(selfMatch) != string::npos) {
rf.relevantBootCnt = &rf.img11Cnt;
}
break;
}
case 6: {
iss >> word;
if (word.find("img00lock:") == string::npos) {
return false;
}
iss >> rf.img00Lock;
break;
}
case 7: {
iss >> word;
if (word.find("img01lock:") == string::npos) {
return false;
}
iss >> rf.img01Lock;
break;
}
case 8: {
iss >> word;
if (word.find("img10lock:") == string::npos) {
return false;
}
iss >> rf.img10Lock;
break;
}
case 9: {
iss >> word;
if (word.find("img11lock:") == string::npos) {
return false;
}
iss >> rf.img11Lock;
break;
}
case 10: {
iss >> word;
if (word.find("bootflag:") == string::npos) {
return false;
}
iss >> rf.bootFlag;
break;
}
case 11: {
iss >> word;
int copyRaw = 0;
int chipRaw = 0;
if (word.find("last:") == string::npos) {
return false;
}
iss >> chipRaw;
if (iss.fail()) {
return false;
}
iss >> copyRaw;
if (iss.fail()) {
return false;
}
if (chipRaw > 1 or copyRaw > 1) {
return false;
}
rf.lastChip = static_cast<xsc::Chip>(chipRaw);
rf.lastCopy = static_cast<xsc::Copy>(copyRaw);
break;
}
case 12: {
iss >> word;
int copyRaw = 0;
int chipRaw = 0;
if (word.find("next:") == string::npos) {
return false;
}
iss >> chipRaw;
if (iss.fail()) {
return false;
}
iss >> copyRaw;
if (iss.fail()) {
return false;
}
if (chipRaw > 2 or copyRaw > 2) {
return false;
}
rf.mechanismNextChip = static_cast<xsc::Chip>(chipRaw);
rf.mechanismNextCopy = static_cast<xsc::Copy>(copyRaw);
break;
}
}
if (iss.fail()) {
return false;
}
lineIdx++;
}
if (lineIdx < 12) {
return false;
}
return true;
}
void CoreController::resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy) {
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE;
// Disable the reboot file mechanism
parseRebootFile(path, rebootFile);
if (tgtChip == xsc::ALL_CHIP and tgtCopy == xsc::ALL_COPY) {
rebootFile.img00Cnt = 0;
rebootFile.img01Cnt = 0;
rebootFile.img10Cnt = 0;
rebootFile.img11Cnt = 0;
} else {
if (tgtChip == xsc::CHIP_0) {
if (tgtCopy == xsc::COPY_0) {
rebootFile.img00Cnt = 0;
} else {
rebootFile.img01Cnt = 0;
}
} else {
if (tgtCopy == xsc::COPY_0) {
rebootFile.img10Cnt = 0;
} else {
rebootFile.img11Cnt = 0;
}
}
}
rewriteRebootFile(rebootFile);
}
void CoreController::rewriteRebootFile(RebootFile file) {
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE;
std::ofstream rebootFile(path);
if (rebootFile.is_open()) {
// Initiate reboot file first. Reboot handling will be on on initialization
rebootFile << "on: " << file.enabled << "\nmaxcnt: " << file.maxCount
<< "\nimg00: " << file.img00Cnt << "\nimg01: " << file.img01Cnt
<< "\nimg10: " << file.img10Cnt << "\nimg11: " << file.img11Cnt
<< "\nimg00lock: " << file.img00Lock << "\nimg01lock: " << file.img01Lock
<< "\nimg10lock: " << file.img10Lock << "\nimg11lock: " << file.img11Lock
<< "\nbootflag: " << file.bootFlag << "\nlast: " << static_cast<int>(file.lastChip)
<< " " << static_cast<int>(file.lastCopy)
<< "\nnext: " << static_cast<int>(file.mechanismNextChip) << " "
<< static_cast<int>(file.mechanismNextCopy) << "\n";
}
}
void CoreController::setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy) {
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE;
// Disable the reboot file mechanism
parseRebootFile(path, rebootFile);
if (tgtChip == xsc::CHIP_0) {
if (tgtCopy == xsc::COPY_0) {
rebootFile.img00Lock = lock;
} else {
rebootFile.img01Lock = lock;
}
} else {
if (tgtCopy == xsc::COPY_0) {
rebootFile.img10Lock = lock;
} else {
rebootFile.img11Lock = lock;
}
}
rewriteRebootFile(rebootFile);
}

View File

@ -2,6 +2,9 @@
#define BSP_Q7S_CORE_CORECONTROLLER_H_ #define BSP_Q7S_CORE_CORECONTROLLER_H_
#include <fsfw/globalfunctions/PeriodicOperationDivider.h> #include <fsfw/globalfunctions/PeriodicOperationDivider.h>
#include <libxiphos.h>
#include <cstddef>
#include "bsp_q7s/memory/SdCardManager.h" #include "bsp_q7s/memory/SdCardManager.h"
#include "events/subsystemIdRanges.h" #include "events/subsystemIdRanges.h"
@ -10,24 +13,72 @@
class Timer; class Timer;
class SdCardManager; class SdCardManager;
namespace xsc {
enum Chip : int { CHIP_0, CHIP_1, NO_CHIP, SELF_CHIP, ALL_CHIP };
enum Copy : int { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY };
} // namespace xsc
struct RebootFile {
static constexpr uint8_t DEFAULT_MAX_BOOT_CNT = 10;
bool enabled = true;
size_t maxCount = DEFAULT_MAX_BOOT_CNT;
uint32_t img00Cnt = 0;
uint32_t img01Cnt = 0;
uint32_t img10Cnt = 0;
uint32_t img11Cnt = 0;
bool img00Lock = false;
bool img01Lock = false;
bool img10Lock = false;
bool img11Lock = false;
uint32_t* relevantBootCnt = &img00Cnt;
bool bootFlag = false;
xsc::Chip lastChip = xsc::Chip::CHIP_0;
xsc::Copy lastCopy = xsc::Copy::COPY_0;
xsc::Chip mechanismNextChip = xsc::Chip::NO_CHIP;
xsc::Copy mechanismNextCopy = xsc::Copy::NO_COPY;
};
class CoreController : public ExtendedControllerBase { class CoreController : public ExtendedControllerBase {
public: public:
enum Chip : uint8_t { CHIP_0, CHIP_1, NO_CHIP, SELF_CHIP, ALL_CHIP }; static xsc::Chip CURRENT_CHIP;
static xsc::Copy CURRENT_COPY;
enum Copy : uint8_t { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY };
static constexpr char CHIP_PROT_SCRIPT[] = "/home/root/scripts/get-chip-prot-status.sh"; static constexpr char CHIP_PROT_SCRIPT[] = "/home/root/scripts/get-chip-prot-status.sh";
static constexpr char CHIP_STATE_FILE[] = "/tmp/chip_prot_status.txt"; static constexpr char CHIP_STATE_FILE[] = "/tmp/chip_prot_status.txt";
static constexpr char CURR_COPY_FILE[] = "/tmp/curr_copy.txt"; static constexpr char CURR_COPY_FILE[] = "/tmp/curr_copy.txt";
static constexpr char VERSION_FILE[] = "/conf/sd_status"; static constexpr char CONF_FOLDER[] = "conf";
static constexpr char VERSION_FILE_NAME[] = "version.txt";
static constexpr char REBOOT_FILE_NAME[] = "reboot.txt";
const std::string VERSION_FILE =
"/" + std::string(CONF_FOLDER) + "/" + std::string(VERSION_FILE_NAME);
const std::string REBOOT_FILE =
"/" + std::string(CONF_FOLDER) + "/" + std::string(REBOOT_FILE_NAME);
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0; 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;
static constexpr ActionId_t SWITCH_IMG_LOCK = 7;
static constexpr ActionId_t SET_MAX_REBOOT_CNT = 8;
static constexpr ActionId_t REBOOT_OBC = 32; static constexpr ActionId_t REBOOT_OBC = 32;
static constexpr ActionId_t MOUNT_OTHER_COPY = 33; static constexpr ActionId_t MOUNT_OTHER_COPY = 33;
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE; static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM); static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
//! [EXPORT] : [COMMENT] Software reboot occured. Can also be a systemd reboot.
//! P1: Current Chip, P2: Current Copy
static constexpr Event REBOOT_SW = event::makeEvent(SUBSYSTEM_ID, 1, severity::MEDIUM);
//! [EXPORT] : [COMMENT] The reboot mechanism was triggered.
//! P1: First 16 bits: Last Chip, Last 16 bits: Last Copy,
//! P2: Each byte is the respective reboot count for the slots
static constexpr Event REBOOT_MECHANISM_TRIGGERED =
event::makeEvent(SUBSYSTEM_ID, 2, severity::MEDIUM);
//! Trying to find a way how to determine that the reboot came from ProASIC3 or PCDU..
static constexpr Event REBOOT_HW = event::makeEvent(SUBSYSTEM_ID, 3, severity::MEDIUM);
CoreController(object_id_t objectId); CoreController(object_id_t objectId);
virtual ~CoreController(); virtual ~CoreController();
@ -48,7 +99,7 @@ class CoreController : public ExtendedControllerBase {
*/ */
static ReturnValue_t generateChipStateFile(); static ReturnValue_t generateChipStateFile();
static ReturnValue_t incrementAllocationFailureCount(); static ReturnValue_t incrementAllocationFailureCount();
static void getCurrentBootCopy(Chip& chip, Copy& copy); static void getCurrentBootCopy(xsc::Chip& chip, xsc::Copy& copy);
ReturnValue_t updateProtInfo(bool regenerateChipStateFile = true); ReturnValue_t updateProtInfo(bool regenerateChipStateFile = true);
@ -63,15 +114,12 @@ class CoreController : public ExtendedControllerBase {
* @param updateProtFile Specify whether the protection info file is updated * @param updateProtFile Specify whether the protection info file is updated
* @return * @return
*/ */
ReturnValue_t setBootCopyProtection(Chip targetChip, Copy targetCopy, bool protect, ReturnValue_t setBootCopyProtection(xsc::Chip targetChip, xsc::Copy targetCopy, bool protect,
bool& protOperationPerformed, bool updateProtFile = true); bool& protOperationPerformed, bool updateProtFile = true);
bool sdInitFinished() const; bool sdInitFinished() const;
private: private:
static Chip CURRENT_CHIP;
static Copy CURRENT_COPY;
// Designated value for rechecking FIFO open // Designated value for rechecking FIFO open
static constexpr int RETRY_FIFO_OPEN = -2; static constexpr int RETRY_FIFO_OPEN = -2;
int watchdogFifoFd = 0; int watchdogFifoFd = 0;
@ -120,8 +168,9 @@ class CoreController : public ExtendedControllerBase {
sd::SdState currentlyCommandedState = sd::SdState::OFF; sd::SdState currentlyCommandedState = sd::SdState::OFF;
sd::SdCard commandedCard = sd::SdCard::NONE; sd::SdCard commandedCard = sd::SdCard::NONE;
sd::SdState commandedState = sd::SdState::OFF; sd::SdState commandedState = sd::SdState::OFF;
}; } sdInfo;
SdInfo sdInfo; RebootFile rebootFile = {};
bool doPerformMountedSdCardOps = true;
/** /**
* Index 0: Chip 0 Copy 0 * Index 0: Chip 0 Copy 0
@ -136,7 +185,7 @@ class CoreController : public ExtendedControllerBase {
LocalDataPoolManager& poolManager) override; LocalDataPoolManager& poolManager) override;
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override; LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t* msToReachTheMode); ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t* msToReachTheMode);
void performMountedSdCardOperations();
ReturnValue_t initVersionFile(); ReturnValue_t initVersionFile();
ReturnValue_t initBootCopy(); ReturnValue_t initBootCopy();
ReturnValue_t initWatchdogFifo(); ReturnValue_t initWatchdogFifo();
@ -148,10 +197,12 @@ class CoreController : public ExtendedControllerBase {
ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar, ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar,
bool printOutput = true); bool printOutput = true);
ReturnValue_t sdColdRedundantBlockingInit(); ReturnValue_t sdColdRedundantBlockingInit();
void currentStateSetter(sd::SdCard sdCard, sd::SdState newState); void currentStateSetter(sd::SdCard sdCard, sd::SdState newState);
void determinePreferredSdCard(); void determinePreferredSdCard();
void executeNextExternalSdCommand(); void executeNextExternalSdCommand();
void checkExternalSdCommandStatus(); void checkExternalSdCommandStatus();
void performRebootFileHandling(bool recreateFile);
ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy, ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size); const uint8_t* data, size_t size);
@ -160,9 +211,15 @@ class CoreController : public ExtendedControllerBase {
void performWatchdogControlOperation(); void performWatchdogControlOperation();
ReturnValue_t handleProtInfoUpdateLine(std::string nextLine); ReturnValue_t handleProtInfoUpdateLine(std::string nextLine);
int handleBootCopyProtAtIndex(Chip targetChip, Copy targetCopy, bool protect, int handleBootCopyProtAtIndex(xsc::Chip targetChip, xsc::Copy targetCopy, bool protect,
bool& protOperationPerformed, bool selfChip, bool selfCopy, bool& protOperationPerformed, bool selfChip, bool selfCopy,
bool allChips, bool allCopies, uint8_t arrIdx); bool allChips, bool allCopies, uint8_t arrIdx);
void determineAndExecuteReboot(RebootFile& rf, bool& needsReboot, xsc::Chip& tgtChip,
xsc::Copy& tgtCopy);
void resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy);
void setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy);
bool parseRebootFile(std::string path, RebootFile& file);
void rewriteRebootFile(RebootFile file);
}; };
#endif /* BSP_Q7S_CORE_CORECONTROLLER_H_ */ #endif /* BSP_Q7S_CORE_CORECONTROLLER_H_ */

View File

@ -86,7 +86,7 @@ void initmission::initTasks() {
"TCPIP_TMTC_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); "TCPIP_TMTC_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
result = tmtcBridgeTask->addComponent(objects::TMTC_BRIDGE); result = tmtcBridgeTask->addComponent(objects::TMTC_BRIDGE);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("UDP_BRIDGE", objects::TMTC_BRIDGE); initmission::printAddObjectError("TMTC_BRIDGE", objects::TMTC_BRIDGE);
} }
PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask( PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask(
"TMTC_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); "TMTC_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
@ -135,9 +135,9 @@ void initmission::initTasks() {
} }
#if OBSW_ADD_STAR_TRACKER == 1 #if OBSW_ADD_STAR_TRACKER == 1
PeriodicTaskIF* strImgLoaderTask = factory->createPeriodicTask( PeriodicTaskIF* strHelperTask = factory->createPeriodicTask(
"STR_HELPER", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); "STR_HELPER", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
result = strImgLoaderTask->addComponent(objects::STR_HELPER); result = strHelperTask->addComponent(objects::STR_HELPER);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("STR_HELPER", objects::STR_HELPER); initmission::printAddObjectError("STR_HELPER", objects::STR_HELPER);
} }
@ -204,7 +204,7 @@ void initmission::initTasks() {
#if BOARD_TE0720 == 0 #if BOARD_TE0720 == 0
fsTask->startTask(); fsTask->startTask();
#if OBSW_ADD_STAR_TRACKER == 1 #if OBSW_ADD_STAR_TRACKER == 1
strImgLoaderTask->startTask(); strHelperTask > startTask();
#endif /* OBSW_ADD_STAR_TRACKER == 1 */ #endif /* OBSW_ADD_STAR_TRACKER == 1 */
#endif #endif

View File

@ -16,9 +16,6 @@
#include "bsp_q7s/devices/PlocMemoryDumper.h" #include "bsp_q7s/devices/PlocMemoryDumper.h"
#include "bsp_q7s/devices/PlocSupervisorHandler.h" #include "bsp_q7s/devices/PlocSupervisorHandler.h"
#include "bsp_q7s/devices/PlocUpdater.h" #include "bsp_q7s/devices/PlocUpdater.h"
#include "bsp_q7s/devices/startracker/StarTrackerDefinitions.h"
#include "bsp_q7s/devices/startracker/StarTrackerHandler.h"
#include "bsp_q7s/devices/startracker/StrHelper.h"
#include "bsp_q7s/memory/FileSystemHandler.h" #include "bsp_q7s/memory/FileSystemHandler.h"
#include "busConf.h" #include "busConf.h"
#include "ccsdsConfig.h" #include "ccsdsConfig.h"
@ -57,13 +54,13 @@
#include "linux/boardtest/SpiTestClass.h" #include "linux/boardtest/SpiTestClass.h"
#include "linux/csp/CspComIF.h" #include "linux/csp/CspComIF.h"
#include "linux/csp/CspCookie.h" #include "linux/csp/CspCookie.h"
#include "mission/devices/SolarArrayDeploymentHandler.h" #include "linux/devices/GPSHyperionLinuxController.h"
#include "mission/devices/SusHandler.h" #include "linux/devices/devicedefinitions/StarTrackerDefinitions.h"
#include "mission/devices/devicedefinitions/SusDefinitions.h" #include "linux/devices/startracker/StarTrackerHandler.h"
#include "linux/devices/startracker/StrHelper.h"
#include "mission/core/GenericFactory.h" #include "mission/core/GenericFactory.h"
#include "mission/devices/ACUHandler.h" #include "mission/devices/ACUHandler.h"
#include "mission/devices/BpxBatteryHandler.h" #include "mission/devices/BpxBatteryHandler.h"
#include "linux/devices/GPSHyperionLinuxController.h"
#include "mission/devices/GyroADIS1650XHandler.h" #include "mission/devices/GyroADIS1650XHandler.h"
#include "mission/devices/HeaterHandler.h" #include "mission/devices/HeaterHandler.h"
#include "mission/devices/IMTQHandler.h" #include "mission/devices/IMTQHandler.h"
@ -75,6 +72,7 @@
#include "mission/devices/PlocMPSoCHandler.h" #include "mission/devices/PlocMPSoCHandler.h"
#include "mission/devices/RadiationSensorHandler.h" #include "mission/devices/RadiationSensorHandler.h"
#include "mission/devices/RwHandler.h" #include "mission/devices/RwHandler.h"
#include "mission/devices/SolarArrayDeploymentHandler.h"
#include "mission/devices/SusHandler.h" #include "mission/devices/SusHandler.h"
#include "mission/devices/SyrlinksHkHandler.h" #include "mission/devices/SyrlinksHkHandler.h"
#include "mission/devices/Tmp1075Handler.h" #include "mission/devices/Tmp1075Handler.h"
@ -290,14 +288,15 @@ void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF) {
} }
void ObjectFactory::createRadSensorComponent(LinuxLibgpioIF* gpioComIF) { void ObjectFactory::createRadSensorComponent(LinuxLibgpioIF* gpioComIF) {
using namespace gpio;
GpioCookie* gpioCookieRadSensor = new GpioCookie; GpioCookie* gpioCookieRadSensor = new GpioCookie;
std::stringstream consumer; std::stringstream consumer;
consumer << "0x" << std::hex << objects::RAD_SENSOR; consumer << "0x" << std::hex << objects::RAD_SENSOR;
GpiodRegularByLineName* gpio = new GpiodRegularByLineName( GpiodRegularByLineName* gpio = new GpiodRegularByLineName(
q7s::gpioNames::RAD_SENSOR_CHIP_SELECT, consumer.str(), gpio::DIR_OUT, gpio::HIGH); q7s::gpioNames::RAD_SENSOR_CHIP_SELECT, consumer.str(), Direction::OUT, Levels::HIGH);
gpioCookieRadSensor->addGpio(gpioIds::CS_RAD_SENSOR, gpio); gpioCookieRadSensor->addGpio(gpioIds::CS_RAD_SENSOR, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::ENABLE_RADFET, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::ENABLE_RADFET, consumer.str(), Direction::OUT,
gpio::LOW); Levels::LOW);
gpioCookieRadSensor->addGpio(gpioIds::ENABLE_RADFET, gpio); gpioCookieRadSensor->addGpio(gpioIds::ENABLE_RADFET, gpio);
gpioComIF->addGpios(gpioCookieRadSensor); gpioComIF->addGpios(gpioCookieRadSensor);
@ -314,43 +313,44 @@ void ObjectFactory::createRadSensorComponent(LinuxLibgpioIF* gpioComIF) {
} }
void ObjectFactory::createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF) { void ObjectFactory::createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF) {
using namespace gpio;
GpioCookie* gpioCookieSus = new GpioCookie(); GpioCookie* gpioCookieSus = new GpioCookie();
GpioCallback* susgpio = nullptr; GpioCallback* susgpio = nullptr;
susgpio = new GpioCallback("Chip select SUS 0", gpio::DIR_OUT, gpio::HIGH, susgpio = new GpioCallback("Chip select SUS 0", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
gpioCookieSus->addGpio(gpioIds::CS_SUS_0, susgpio); gpioCookieSus->addGpio(gpioIds::CS_SUS_0, susgpio);
susgpio = new GpioCallback("Chip select SUS 1", gpio::DIR_OUT, gpio::HIGH, susgpio = new GpioCallback("Chip select SUS 1", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
gpioCookieSus->addGpio(gpioIds::CS_SUS_1, susgpio); gpioCookieSus->addGpio(gpioIds::CS_SUS_1, susgpio);
susgpio = new GpioCallback("Chip select SUS 2", gpio::DIR_OUT, gpio::HIGH, susgpio = new GpioCallback("Chip select SUS 2", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
gpioCookieSus->addGpio(gpioIds::CS_SUS_2, susgpio); gpioCookieSus->addGpio(gpioIds::CS_SUS_2, susgpio);
susgpio = new GpioCallback("Chip select SUS 3", gpio::DIR_OUT, gpio::HIGH, susgpio = new GpioCallback("Chip select SUS 3", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
gpioCookieSus->addGpio(gpioIds::CS_SUS_3, susgpio); gpioCookieSus->addGpio(gpioIds::CS_SUS_3, susgpio);
susgpio = new GpioCallback("Chip select SUS 4", gpio::DIR_OUT, gpio::HIGH, susgpio = new GpioCallback("Chip select SUS 4", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
gpioCookieSus->addGpio(gpioIds::CS_SUS_4, susgpio); gpioCookieSus->addGpio(gpioIds::CS_SUS_4, susgpio);
susgpio = new GpioCallback("Chip select SUS 5", gpio::DIR_OUT, gpio::HIGH, susgpio = new GpioCallback("Chip select SUS 5", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
gpioCookieSus->addGpio(gpioIds::CS_SUS_5, susgpio); gpioCookieSus->addGpio(gpioIds::CS_SUS_5, susgpio);
susgpio = new GpioCallback("Chip select SUS 6", gpio::DIR_OUT, gpio::HIGH, susgpio = new GpioCallback("Chip select SUS 6", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
gpioCookieSus->addGpio(gpioIds::CS_SUS_6, susgpio); gpioCookieSus->addGpio(gpioIds::CS_SUS_6, susgpio);
susgpio = new GpioCallback("Chip select SUS 7", gpio::DIR_OUT, gpio::HIGH, susgpio = new GpioCallback("Chip select SUS 7", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
gpioCookieSus->addGpio(gpioIds::CS_SUS_7, susgpio); gpioCookieSus->addGpio(gpioIds::CS_SUS_7, susgpio);
susgpio = new GpioCallback("Chip select SUS 8", gpio::DIR_OUT, gpio::HIGH, susgpio = new GpioCallback("Chip select SUS 8", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
gpioCookieSus->addGpio(gpioIds::CS_SUS_8, susgpio); gpioCookieSus->addGpio(gpioIds::CS_SUS_8, susgpio);
susgpio = new GpioCallback("Chip select SUS 9", gpio::DIR_OUT, gpio::HIGH, susgpio = new GpioCallback("Chip select SUS 9", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
gpioCookieSus->addGpio(gpioIds::CS_SUS_9, susgpio); gpioCookieSus->addGpio(gpioIds::CS_SUS_9, susgpio);
susgpio = new GpioCallback("Chip select SUS 10", gpio::DIR_OUT, gpio::HIGH, susgpio = new GpioCallback("Chip select SUS 10", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
gpioCookieSus->addGpio(gpioIds::CS_SUS_10, susgpio); gpioCookieSus->addGpio(gpioIds::CS_SUS_10, susgpio);
susgpio = new GpioCallback("Chip select SUS 11", gpio::DIR_OUT, gpio::HIGH, susgpio = new GpioCallback("Chip select SUS 11", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
gpioCookieSus->addGpio(gpioIds::CS_SUS_11, susgpio); gpioCookieSus->addGpio(gpioIds::CS_SUS_11, susgpio);
@ -474,101 +474,102 @@ void ObjectFactory::createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComI
} }
void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF) { void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF) {
using namespace gpio;
GpioCookie* gpioCookieAcsBoard = new GpioCookie(); GpioCookie* gpioCookieAcsBoard = new GpioCookie();
std::stringstream consumer; std::stringstream consumer;
GpiodRegularByLineName* gpio = nullptr; GpiodRegularByLineName* gpio = nullptr;
consumer << "0x" << std::hex << objects::GYRO_0_ADIS_HANDLER; consumer << "0x" << std::hex << objects::GYRO_0_ADIS_HANDLER;
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ADIS_CS, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ADIS_CS, consumer.str(), Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookieAcsBoard->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio); gpioCookieAcsBoard->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio);
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::GYRO_1_L3G_HANDLER; consumer << "0x" << std::hex << objects::GYRO_1_L3G_HANDLER;
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_1_L3G_CS, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_1_L3G_CS, consumer.str(), Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookieAcsBoard->addGpio(gpioIds::GYRO_1_L3G_CS, gpio); gpioCookieAcsBoard->addGpio(gpioIds::GYRO_1_L3G_CS, gpio);
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::GYRO_2_ADIS_HANDLER; consumer << "0x" << std::hex << objects::GYRO_2_ADIS_HANDLER;
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ADIS_CS, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ADIS_CS, consumer.str(), Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookieAcsBoard->addGpio(gpioIds::GYRO_2_ADIS_CS, gpio); gpioCookieAcsBoard->addGpio(gpioIds::GYRO_2_ADIS_CS, gpio);
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::GYRO_3_L3G_HANDLER; consumer << "0x" << std::hex << objects::GYRO_3_L3G_HANDLER;
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_3_L3G_CS, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_3_L3G_CS, consumer.str(), Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookieAcsBoard->addGpio(gpioIds::GYRO_3_L3G_CS, gpio); gpioCookieAcsBoard->addGpio(gpioIds::GYRO_3_L3G_CS, gpio);
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::MGM_0_LIS3_HANDLER; consumer << "0x" << std::hex << objects::MGM_0_LIS3_HANDLER;
gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_0_CS, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_0_CS, consumer.str(), Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookieAcsBoard->addGpio(gpioIds::MGM_0_LIS3_CS, gpio); gpioCookieAcsBoard->addGpio(gpioIds::MGM_0_LIS3_CS, gpio);
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::MGM_1_RM3100_HANDLER; consumer << "0x" << std::hex << objects::MGM_1_RM3100_HANDLER;
gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, consumer.str(), Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookieAcsBoard->addGpio(gpioIds::MGM_1_RM3100_CS, gpio); gpioCookieAcsBoard->addGpio(gpioIds::MGM_1_RM3100_CS, gpio);
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::MGM_2_LIS3_HANDLER; consumer << "0x" << std::hex << objects::MGM_2_LIS3_HANDLER;
gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_2_CS, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_2_CS, consumer.str(), Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookieAcsBoard->addGpio(gpioIds::MGM_2_LIS3_CS, gpio); gpioCookieAcsBoard->addGpio(gpioIds::MGM_2_LIS3_CS, gpio);
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::MGM_3_RM3100_HANDLER; consumer << "0x" << std::hex << objects::MGM_3_RM3100_HANDLER;
gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_3_CS, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_3_CS, consumer.str(), Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookieAcsBoard->addGpio(gpioIds::MGM_3_RM3100_CS, gpio); gpioCookieAcsBoard->addGpio(gpioIds::MGM_3_RM3100_CS, gpio);
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::GPS_CONTROLLER; consumer << "0x" << std::hex << objects::GPS_CONTROLLER;
// GNSS reset pins are active low // GNSS reset pins are active low
gpio = new GpiodRegularByLineName(q7s::gpioNames::RESET_GNSS_0, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::RESET_GNSS_0, consumer.str(), Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookieAcsBoard->addGpio(gpioIds::GNSS_0_NRESET, gpio); gpioCookieAcsBoard->addGpio(gpioIds::GNSS_0_NRESET, gpio);
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::GPS_CONTROLLER; consumer << "0x" << std::hex << objects::GPS_CONTROLLER;
gpio = new GpiodRegularByLineName(q7s::gpioNames::RESET_GNSS_1, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::RESET_GNSS_1, consumer.str(), Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookieAcsBoard->addGpio(gpioIds::GNSS_1_NRESET, gpio); gpioCookieAcsBoard->addGpio(gpioIds::GNSS_1_NRESET, gpio);
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::GYRO_0_ADIS_HANDLER; consumer << "0x" << std::hex << objects::GYRO_0_ADIS_HANDLER;
// Enable pins must be pulled low for regular operations // Enable pins must be pulled low for regular operations
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ENABLE, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ENABLE, consumer.str(), Direction::OUT,
gpio::LOW); Levels::LOW);
gpioCookieAcsBoard->addGpio(gpioIds::GYRO_0_ENABLE, gpio); gpioCookieAcsBoard->addGpio(gpioIds::GYRO_0_ENABLE, gpio);
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::GYRO_2_ADIS_HANDLER; consumer << "0x" << std::hex << objects::GYRO_2_ADIS_HANDLER;
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ENABLE, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ENABLE, consumer.str(), Direction::OUT,
gpio::LOW); Levels::LOW);
gpioCookieAcsBoard->addGpio(gpioIds::GYRO_2_ENABLE, gpio); gpioCookieAcsBoard->addGpio(gpioIds::GYRO_2_ENABLE, gpio);
// Enable pins for GNSS // Enable pins for GNSS
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::GPS_CONTROLLER; consumer << "0x" << std::hex << objects::GPS_CONTROLLER;
gpio = new GpiodRegularByLineName(q7s::gpioNames::GNSS_0_ENABLE, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::GNSS_0_ENABLE, consumer.str(), Direction::OUT,
gpio::LOW); Levels::LOW);
gpioCookieAcsBoard->addGpio(gpioIds::GNSS_0_ENABLE, gpio); gpioCookieAcsBoard->addGpio(gpioIds::GNSS_0_ENABLE, gpio);
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::GPS_CONTROLLER; consumer << "0x" << std::hex << objects::GPS_CONTROLLER;
gpio = new GpiodRegularByLineName(q7s::gpioNames::GNSS_1_ENABLE, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::GNSS_1_ENABLE, consumer.str(), Direction::OUT,
gpio::LOW); Levels::LOW);
gpioCookieAcsBoard->addGpio(gpioIds::GNSS_1_ENABLE, gpio); gpioCookieAcsBoard->addGpio(gpioIds::GNSS_1_ENABLE, gpio);
// Select pin. 0 for GPS side A, 1 for GPS side B // Select pin. 0 for GPS side A, 1 for GPS side B
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::GPS_CONTROLLER; consumer << "0x" << std::hex << objects::GPS_CONTROLLER;
gpio = new GpiodRegularByLineName(q7s::gpioNames::GNSS_SELECT, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::GNSS_SELECT, consumer.str(), Direction::OUT,
gpio::LOW); Levels::LOW);
gpioCookieAcsBoard->addGpio(gpioIds::GNSS_SELECT, gpio); gpioCookieAcsBoard->addGpio(gpioIds::GNSS_SELECT, gpio);
gpioComIF->addGpios(gpioCookieAcsBoard); gpioComIF->addGpios(gpioCookieAcsBoard);
@ -695,43 +696,44 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI
} }
void ObjectFactory::createHeaterComponents() { void ObjectFactory::createHeaterComponents() {
using namespace gpio;
GpioCookie* heaterGpiosCookie = new GpioCookie; GpioCookie* heaterGpiosCookie = new GpioCookie;
GpiodRegularByLineName* gpio = nullptr; GpiodRegularByLineName* gpio = nullptr;
std::stringstream consumer; std::stringstream consumer;
consumer << "0x" << std::hex << objects::HEATER_HANDLER; consumer << "0x" << std::hex << objects::HEATER_HANDLER;
/* Pin H2-11 on stack connector */ /* Pin H2-11 on stack connector */
gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_0, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_0, consumer.str(), Direction::OUT,
gpio::LOW); Levels::LOW);
heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpio); heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpio);
/* Pin H2-12 on stack connector */ /* Pin H2-12 on stack connector */
gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_1, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_1, consumer.str(), Direction::OUT,
gpio::LOW); Levels::LOW);
heaterGpiosCookie->addGpio(gpioIds::HEATER_1, gpio); heaterGpiosCookie->addGpio(gpioIds::HEATER_1, gpio);
/* Pin H2-13 on stack connector */ /* Pin H2-13 on stack connector */
gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_2, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_2, consumer.str(), Direction::OUT,
gpio::LOW); Levels::LOW);
heaterGpiosCookie->addGpio(gpioIds::HEATER_2, gpio); heaterGpiosCookie->addGpio(gpioIds::HEATER_2, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_3, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_3, consumer.str(), Direction::OUT,
gpio::LOW); Levels::LOW);
heaterGpiosCookie->addGpio(gpioIds::HEATER_3, gpio); heaterGpiosCookie->addGpio(gpioIds::HEATER_3, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_4, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_4, consumer.str(), Direction::OUT,
gpio::LOW); Levels::LOW);
heaterGpiosCookie->addGpio(gpioIds::HEATER_4, gpio); heaterGpiosCookie->addGpio(gpioIds::HEATER_4, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_5, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_5, consumer.str(), Direction::OUT,
gpio::LOW); Levels::LOW);
heaterGpiosCookie->addGpio(gpioIds::HEATER_5, gpio); heaterGpiosCookie->addGpio(gpioIds::HEATER_5, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_6, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_6, consumer.str(), Direction::OUT,
gpio::LOW); Levels::LOW);
heaterGpiosCookie->addGpio(gpioIds::HEATER_6, gpio); heaterGpiosCookie->addGpio(gpioIds::HEATER_6, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_7, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::HEATER_7, consumer.str(), Direction::OUT,
gpio::LOW); Levels::LOW);
heaterGpiosCookie->addGpio(gpioIds::HEATER_7, gpio); heaterGpiosCookie->addGpio(gpioIds::HEATER_7, gpio);
new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie, new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie,
@ -739,16 +741,17 @@ void ObjectFactory::createHeaterComponents() {
} }
void ObjectFactory::createSolarArrayDeploymentComponents() { void ObjectFactory::createSolarArrayDeploymentComponents() {
using namespace gpio;
GpioCookie* solarArrayDeplCookie = new GpioCookie; GpioCookie* solarArrayDeplCookie = new GpioCookie;
GpiodRegularByLineName* gpio = nullptr; GpiodRegularByLineName* gpio = nullptr;
std::stringstream consumer; std::stringstream consumer;
consumer << "0x" << std::hex << objects::SOLAR_ARRAY_DEPL_HANDLER; consumer << "0x" << std::hex << objects::SOLAR_ARRAY_DEPL_HANDLER;
gpio = new GpiodRegularByLineName(q7s::gpioNames::SA_DPL_PIN_0, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::SA_DPL_PIN_0, consumer.str(), Direction::OUT,
gpio::LOW); Levels::LOW);
solarArrayDeplCookie->addGpio(gpioIds::DEPLSA1, gpio); solarArrayDeplCookie->addGpio(gpioIds::DEPLSA1, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::SA_DPL_PIN_1, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::SA_DPL_PIN_1, consumer.str(), Direction::OUT,
gpio::LOW); Levels::LOW);
solarArrayDeplCookie->addGpio(gpioIds::DEPLSA2, gpio); solarArrayDeplCookie->addGpio(gpioIds::DEPLSA2, gpio);
// TODO: Find out burn time. For now set to 1000 ms. // TODO: Find out burn time. For now set to 1000 ms.
@ -768,54 +771,55 @@ void ObjectFactory::createSyrlinksComponents() {
} }
void ObjectFactory::createRtdComponents(LinuxLibgpioIF* gpioComIF) { void ObjectFactory::createRtdComponents(LinuxLibgpioIF* gpioComIF) {
using namespace gpio;
GpioCookie* rtdGpioCookie = new GpioCookie; GpioCookie* rtdGpioCookie = new GpioCookie;
GpioCallback* gpioRtdIc0 = new GpioCallback("Chip select RTD IC0", gpio::DIR_OUT, gpio::HIGH, GpioCallback* gpioRtdIc0 = new GpioCallback("Chip select RTD IC0", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC_3, gpioRtdIc0); rtdGpioCookie->addGpio(gpioIds::RTD_IC_3, gpioRtdIc0);
GpioCallback* gpioRtdIc1 = new GpioCallback("Chip select RTD IC1", gpio::DIR_OUT, gpio::HIGH, GpioCallback* gpioRtdIc1 = new GpioCallback("Chip select RTD IC1", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC_4, gpioRtdIc1); rtdGpioCookie->addGpio(gpioIds::RTD_IC_4, gpioRtdIc1);
GpioCallback* gpioRtdIc2 = new GpioCallback("Chip select RTD IC2", gpio::DIR_OUT, gpio::HIGH, GpioCallback* gpioRtdIc2 = new GpioCallback("Chip select RTD IC2", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC_5, gpioRtdIc2); rtdGpioCookie->addGpio(gpioIds::RTD_IC_5, gpioRtdIc2);
GpioCallback* gpioRtdIc3 = new GpioCallback("Chip select RTD IC3", gpio::DIR_OUT, gpio::HIGH, GpioCallback* gpioRtdIc3 = new GpioCallback("Chip select RTD IC3", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC_6, gpioRtdIc3); rtdGpioCookie->addGpio(gpioIds::RTD_IC_6, gpioRtdIc3);
GpioCallback* gpioRtdIc4 = new GpioCallback("Chip select RTD IC4", gpio::DIR_OUT, gpio::HIGH, GpioCallback* gpioRtdIc4 = new GpioCallback("Chip select RTD IC4", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC_7, gpioRtdIc4); rtdGpioCookie->addGpio(gpioIds::RTD_IC_7, gpioRtdIc4);
GpioCallback* gpioRtdIc5 = new GpioCallback("Chip select RTD IC5", gpio::DIR_OUT, gpio::HIGH, GpioCallback* gpioRtdIc5 = new GpioCallback("Chip select RTD IC5", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC_8, gpioRtdIc5); rtdGpioCookie->addGpio(gpioIds::RTD_IC_8, gpioRtdIc5);
GpioCallback* gpioRtdIc6 = new GpioCallback("Chip select RTD IC6", gpio::DIR_OUT, gpio::HIGH, GpioCallback* gpioRtdIc6 = new GpioCallback("Chip select RTD IC6", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC_9, gpioRtdIc6); rtdGpioCookie->addGpio(gpioIds::RTD_IC_9, gpioRtdIc6);
GpioCallback* gpioRtdIc7 = new GpioCallback("Chip select RTD IC7", gpio::DIR_OUT, gpio::HIGH, GpioCallback* gpioRtdIc7 = new GpioCallback("Chip select RTD IC7", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC_10, gpioRtdIc7); rtdGpioCookie->addGpio(gpioIds::RTD_IC_10, gpioRtdIc7);
GpioCallback* gpioRtdIc8 = new GpioCallback("Chip select RTD IC8", gpio::DIR_OUT, gpio::HIGH, GpioCallback* gpioRtdIc8 = new GpioCallback("Chip select RTD IC8", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC_11, gpioRtdIc8); rtdGpioCookie->addGpio(gpioIds::RTD_IC_11, gpioRtdIc8);
GpioCallback* gpioRtdIc9 = new GpioCallback("Chip select RTD IC9", gpio::DIR_OUT, gpio::HIGH, GpioCallback* gpioRtdIc9 = new GpioCallback("Chip select RTD IC9", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC_12, gpioRtdIc9); rtdGpioCookie->addGpio(gpioIds::RTD_IC_12, gpioRtdIc9);
GpioCallback* gpioRtdIc10 = new GpioCallback("Chip select RTD IC10", gpio::DIR_OUT, gpio::HIGH, GpioCallback* gpioRtdIc10 = new GpioCallback("Chip select RTD IC10", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC_13, gpioRtdIc10); rtdGpioCookie->addGpio(gpioIds::RTD_IC_13, gpioRtdIc10);
GpioCallback* gpioRtdIc11 = new GpioCallback("Chip select RTD IC11", gpio::DIR_OUT, gpio::HIGH, GpioCallback* gpioRtdIc11 = new GpioCallback("Chip select RTD IC11", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC_14, gpioRtdIc11); rtdGpioCookie->addGpio(gpioIds::RTD_IC_14, gpioRtdIc11);
GpioCallback* gpioRtdIc12 = new GpioCallback("Chip select RTD IC12", gpio::DIR_OUT, gpio::HIGH, GpioCallback* gpioRtdIc12 = new GpioCallback("Chip select RTD IC12", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC_15, gpioRtdIc12); rtdGpioCookie->addGpio(gpioIds::RTD_IC_15, gpioRtdIc12);
GpioCallback* gpioRtdIc13 = new GpioCallback("Chip select RTD IC13", gpio::DIR_OUT, gpio::HIGH, GpioCallback* gpioRtdIc13 = new GpioCallback("Chip select RTD IC13", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC_16, gpioRtdIc13); rtdGpioCookie->addGpio(gpioIds::RTD_IC_16, gpioRtdIc13);
GpioCallback* gpioRtdIc14 = new GpioCallback("Chip select RTD IC14", gpio::DIR_OUT, gpio::HIGH, GpioCallback* gpioRtdIc14 = new GpioCallback("Chip select RTD IC14", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC_17, gpioRtdIc14); rtdGpioCookie->addGpio(gpioIds::RTD_IC_17, gpioRtdIc14);
GpioCallback* gpioRtdIc15 = new GpioCallback("Chip select RTD IC15", gpio::DIR_OUT, gpio::HIGH, GpioCallback* gpioRtdIc15 = new GpioCallback("Chip select RTD IC15", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
rtdGpioCookie->addGpio(gpioIds::RTD_IC_18, gpioRtdIc15); rtdGpioCookie->addGpio(gpioIds::RTD_IC_18, gpioRtdIc15);
@ -960,40 +964,45 @@ void ObjectFactory::createRtdComponents(LinuxLibgpioIF* gpioComIF) {
} }
void ObjectFactory::createReactionWheelComponents(LinuxLibgpioIF* gpioComIF) { void ObjectFactory::createReactionWheelComponents(LinuxLibgpioIF* gpioComIF) {
using namespace gpio;
GpioCookie* gpioCookieRw = new GpioCookie; GpioCookie* gpioCookieRw = new GpioCookie;
GpioCallback* csRw1 = new GpioCallback("Chip select reaction wheel 1", gpio::DIR_OUT, gpio::HIGH, GpioCallback* csRw1 =
new GpioCallback("Chip select reaction wheel 1", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
gpioCookieRw->addGpio(gpioIds::CS_RW1, csRw1); gpioCookieRw->addGpio(gpioIds::CS_RW1, csRw1);
GpioCallback* csRw2 = new GpioCallback("Chip select reaction wheel 2", gpio::DIR_OUT, gpio::HIGH, GpioCallback* csRw2 =
new GpioCallback("Chip select reaction wheel 2", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
gpioCookieRw->addGpio(gpioIds::CS_RW2, csRw2); gpioCookieRw->addGpio(gpioIds::CS_RW2, csRw2);
GpioCallback* csRw3 = new GpioCallback("Chip select reaction wheel 3", gpio::DIR_OUT, gpio::HIGH, GpioCallback* csRw3 =
new GpioCallback("Chip select reaction wheel 3", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
gpioCookieRw->addGpio(gpioIds::CS_RW3, csRw3); gpioCookieRw->addGpio(gpioIds::CS_RW3, csRw3);
GpioCallback* csRw4 = new GpioCallback("Chip select reaction wheel 4", gpio::DIR_OUT, gpio::HIGH, GpioCallback* csRw4 =
new GpioCallback("Chip select reaction wheel 4", Direction::OUT, Levels::HIGH,
&gpioCallbacks::spiCsDecoderCallback, gpioComIF); &gpioCallbacks::spiCsDecoderCallback, gpioComIF);
gpioCookieRw->addGpio(gpioIds::CS_RW4, csRw4); gpioCookieRw->addGpio(gpioIds::CS_RW4, csRw4);
std::stringstream consumer; std::stringstream consumer;
GpiodRegularByLineName* gpio = nullptr; GpiodRegularByLineName* gpio = nullptr;
consumer << "0x" << std::hex << objects::RW1; consumer << "0x" << std::hex << objects::RW1;
gpio = gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_1, consumer.str(), Direction::OUT,
new GpiodRegularByLineName(q7s::gpioNames::EN_RW_1, consumer.str(), gpio::DIR_OUT, gpio::LOW); Levels::LOW);
gpioCookieRw->addGpio(gpioIds::EN_RW1, gpio); gpioCookieRw->addGpio(gpioIds::EN_RW1, gpio);
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::RW2; consumer << "0x" << std::hex << objects::RW2;
gpio = gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_2, consumer.str(), Direction::OUT,
new GpiodRegularByLineName(q7s::gpioNames::EN_RW_2, consumer.str(), gpio::DIR_OUT, gpio::LOW); Levels::LOW);
gpioCookieRw->addGpio(gpioIds::EN_RW2, gpio); gpioCookieRw->addGpio(gpioIds::EN_RW2, gpio);
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::RW3; consumer << "0x" << std::hex << objects::RW3;
gpio = gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_3, consumer.str(), Direction::OUT,
new GpiodRegularByLineName(q7s::gpioNames::EN_RW_3, consumer.str(), gpio::DIR_OUT, gpio::LOW); Levels::LOW);
gpioCookieRw->addGpio(gpioIds::EN_RW3, gpio); gpioCookieRw->addGpio(gpioIds::EN_RW3, gpio);
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::RW4; consumer << "0x" << std::hex << objects::RW4;
gpio = gpio = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_4, consumer.str(), Direction::OUT,
new GpiodRegularByLineName(q7s::gpioNames::EN_RW_4, consumer.str(), gpio::DIR_OUT, gpio::LOW); Levels::LOW);
gpioCookieRw->addGpio(gpioIds::EN_RW4, gpio); gpioCookieRw->addGpio(gpioIds::EN_RW4, gpio);
gpioComIF->addGpios(gpioCookieRw); gpioComIF->addGpios(gpioCookieRw);
@ -1045,6 +1054,7 @@ void ObjectFactory::createReactionWheelComponents(LinuxLibgpioIF* gpioComIF) {
} }
void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) { void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) {
using namespace gpio;
// GPIO definitions of signals connected to the virtual channel interfaces of the PTME IP Core // GPIO definitions of signals connected to the virtual channel interfaces of the PTME IP Core
GpioCookie* gpioCookiePtmeIp = new GpioCookie; GpioCookie* gpioCookiePtmeIp = new GpioCookie;
GpiodRegularByLineName* gpio = nullptr; GpiodRegularByLineName* gpio = nullptr;
@ -1122,8 +1132,8 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) {
consumer.str(""); consumer.str("");
consumer << "0x" << std::hex << objects::PDEC_HANDLER; consumer << "0x" << std::hex << objects::PDEC_HANDLER;
// GPIO also low after linux boot (specified by device-tree) // GPIO also low after linux boot (specified by device-tree)
gpio = new GpiodRegularByLineName(q7s::gpioNames::PDEC_RESET, consumer.str(), gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::PDEC_RESET, consumer.str(), Direction::OUT,
gpio::LOW); Levels::LOW);
gpioCookiePdec->addGpio(gpioIds::PDEC_RESET, gpio); gpioCookiePdec->addGpio(gpioIds::PDEC_RESET, gpio);
gpioComIF->addGpios(gpioCookiePdec); gpioComIF->addGpios(gpioCookiePdec);
@ -1134,18 +1144,18 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) {
#if BOARD_TE0720 == 0 #if BOARD_TE0720 == 0
GpioCookie* gpioRS485Chip = new GpioCookie; GpioCookie* gpioRS485Chip = new GpioCookie;
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver", gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_CLOCK, "RS485 Transceiver",
gpio::Direction::DIR_OUT, gpio::LOW); Direction::OUT, Levels::LOW);
gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_CLOCK, gpio); gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_CLOCK, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_DATA, "RS485 Transceiver", gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_TX_DATA, "RS485 Transceiver",
gpio::Direction::DIR_OUT, gpio::LOW); Direction::OUT, Levels::LOW);
gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_DATA, gpio); gpioRS485Chip->addGpio(gpioIds::RS485_EN_TX_DATA, gpio);
// Default configuration enables RX channels (RXEN = LOW) // Default configuration enables RX channels (RXEN = LOW)
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_CLOCK, "RS485 Transceiver", gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_CLOCK, "RS485 Transceiver",
gpio::Direction::DIR_OUT, gpio::LOW); Direction::OUT, Levels::LOW);
gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_CLOCK, gpio); gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_CLOCK, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_DATA, "RS485 Transceiver", gpio = new GpiodRegularByLineName(q7s::gpioNames::RS485_EN_RX_DATA, "RS485 Transceiver",
gpio::Direction::DIR_OUT, gpio::LOW); Direction::OUT, Levels::LOW);
gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_DATA, gpio); gpioRS485Chip->addGpio(gpioIds::RS485_EN_RX_DATA, gpio);
gpioComIF->addGpios(gpioRS485Chip); gpioComIF->addGpios(gpioRS485Chip);
@ -1153,44 +1163,45 @@ void ObjectFactory::createCcsdsComponents(LinuxLibgpioIF* gpioComIF) {
} }
void ObjectFactory::createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF) { void ObjectFactory::createPlPcduComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF) {
using namespace gpio;
// Create all GPIO components first // Create all GPIO components first
GpioCookie* plPcduGpios = new GpioCookie; GpioCookie* plPcduGpios = new GpioCookie;
GpiodRegularByLineName* gpio = nullptr; GpiodRegularByLineName* gpio = nullptr;
std::string consumer; std::string consumer;
// Switch pins are active high // Switch pins are active high
consumer = "PLPCDU_ENB_VBAT_0"; consumer = "PLPCDU_ENB_VBAT_0";
gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_VBAT0, consumer, gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_VBAT0, consumer, Direction::OUT,
gpio::Levels::LOW); gpio::Levels::LOW);
plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_VBAT0, gpio); plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_VBAT0, gpio);
consumer = "PLPCDU_ENB_VBAT_1"; consumer = "PLPCDU_ENB_VBAT_1";
gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_VBAT1, consumer, gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_VBAT1, consumer, Direction::OUT,
gpio::Levels::LOW); gpio::Levels::LOW);
plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_VBAT1, gpio); plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_VBAT1, gpio);
consumer = "PLPCDU_ENB_DRO"; consumer = "PLPCDU_ENB_DRO";
gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_DRO, consumer, gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_DRO, consumer, Direction::OUT,
gpio::Levels::LOW); gpio::Levels::LOW);
plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_DRO, gpio); plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_DRO, gpio);
consumer = "PLPCDU_ENB_HPA"; consumer = "PLPCDU_ENB_HPA";
gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_HPA, consumer, gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_HPA, consumer, Direction::OUT,
gpio::Levels::LOW); gpio::Levels::LOW);
plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_HPA, gpio); plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_HPA, gpio);
consumer = "PLPCDU_ENB_MPA"; consumer = "PLPCDU_ENB_MPA";
gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_MPA, consumer, gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_MPA, consumer, Direction::OUT,
gpio::Levels::LOW); gpio::Levels::LOW);
plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_MPA, gpio); plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_MPA, gpio);
consumer = "PLPCDU_ENB_X8"; consumer = "PLPCDU_ENB_X8";
gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_X8, consumer, gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_X8, consumer, Direction::OUT,
gpio::Levels::LOW); gpio::Levels::LOW);
plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_X8, gpio); plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_X8, gpio);
consumer = "PLPCDU_ENB_TX"; consumer = "PLPCDU_ENB_TX";
gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_TX, consumer, gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ENABLE_TX, consumer, Direction::OUT,
gpio::Levels::LOW); gpio::Levels::LOW);
plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_TX, gpio); plPcduGpios->addGpio(gpioIds::PLPCDU_ENB_TX, gpio);
// Chip select pin is active low // Chip select pin is active low
consumer = "PLPCDU_ADC_CS"; consumer = "PLPCDU_ADC_CS";
gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ADC_CS, consumer, gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::PL_PCDU_ADC_CS, consumer, Direction::OUT,
gpio::Levels::HIGH); gpio::Levels::HIGH);
plPcduGpios->addGpio(gpioIds::PLPCDU_ADC_CS, gpio); plPcduGpios->addGpio(gpioIds::PLPCDU_ADC_CS, gpio);
gpioComIF->addGpios(plPcduGpios); gpioComIF->addGpios(plPcduGpios);
@ -1204,10 +1215,10 @@ void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) {
#if BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1 #if BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1
#if OBSW_TEST_GPIO_OPEN_BYLABEL == 1 #if OBSW_TEST_GPIO_OPEN_BYLABEL == 1
/* Configure MIO0 as input */ /* Configure MIO0 as input */
GpiodRegular* testGpio = new GpiodRegular("MIO0", gpio::DIR_OUT, 0, "/amba_pl/gpio@41200000", 0); GpiodRegular* testGpio = new GpiodRegular("MIO0", Direction::OUT, 0, "/amba_pl/gpio@41200000", 0);
#elif OBSW_TEST_GPIO_OPEN_BY_LINE_NAME #elif OBSW_TEST_GPIO_OPEN_BY_LINE_NAME
GpiodRegularByLineName* testGpio = GpiodRegularByLineName* testGpio =
new GpiodRegularByLineName("test-name", "gpio-test", gpio::DIR_OUT, 0); new GpiodRegularByLineName("test-name", "gpio-test", Direction::OUT, 0);
#else #else
/* Configure MIO0 as input */ /* Configure MIO0 as input */
GpiodRegular* testGpio = new GpiodRegular("gpiochip0", 0, "MIO0", gpio::IN, 0); GpiodRegular* testGpio = new GpiodRegular("gpiochip0", 0, "MIO0", gpio::IN, 0);
@ -1220,7 +1231,7 @@ void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) {
#if BOARD_TE0720 == 1 && OBSW_TEST_SUS == 1 #if BOARD_TE0720 == 1 && OBSW_TEST_SUS == 1
GpioCookie* gpioCookieSus = new GpioCookie; GpioCookie* gpioCookieSus = new GpioCookie;
GpiodRegular* chipSelectSus = new GpiodRegular( GpiodRegular* chipSelectSus = new GpiodRegular(
std::string("gpiochip1"), 9, std::string("Chip Select Sus Sensor"), gpio::DIR_OUT, 1); std::string("gpiochip1"), 9, std::string("Chip Select Sus Sensor"), Direction::OUT, 1);
gpioCookieSus->addGpio(gpioIds::CS_SUS_0, chipSelectSus); gpioCookieSus->addGpio(gpioIds::CS_SUS_0, chipSelectSus);
gpioComIF->addGpios(gpioCookieSus); gpioComIF->addGpios(gpioCookieSus);
@ -1249,7 +1260,7 @@ void ObjectFactory::createTestComponents(LinuxLibgpioIF* gpioComIF) {
#if BOARD_TE0720 == 1 && OBSW_TEST_RAD_SENSOR == 1 #if BOARD_TE0720 == 1 && OBSW_TEST_RAD_SENSOR == 1
GpioCookie* gpioCookieRadSensor = new GpioCookie; GpioCookie* gpioCookieRadSensor = new GpioCookie;
GpiodRegular* chipSelectRadSensor = new GpiodRegular( GpiodRegular* chipSelectRadSensor = new GpiodRegular(
std::string("gpiochip1"), 0, std::string("Chip select radiation sensor"), gpio::DIR_OUT, 1); std::string("gpiochip1"), 0, std::string("Chip select radiation sensor"), Direction::OUT, 1);
gpioCookieRadSensor->addGpio(gpioIds::CS_RAD_SENSOR, chipSelectRadSensor); gpioCookieRadSensor->addGpio(gpioIds::CS_RAD_SENSOR, chipSelectRadSensor);
gpioComIF->addGpios(gpioCookieRadSensor); gpioComIF->addGpios(gpioCookieRadSensor);

View File

@ -3,5 +3,3 @@ target_sources(${OBSW_NAME} PRIVATE
PlocUpdater.cpp PlocUpdater.cpp
PlocMemoryDumper.cpp PlocMemoryDumper.cpp
) )
add_subdirectory(startracker)

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@
#include <fstream> #include <fstream>
#include <memory> #include <memory>
#include "common/config/commonObjects.h"
#include "fsfw/ipc/MutexFactory.h" #include "fsfw/ipc/MutexFactory.h"
#include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/serviceinterface/ServiceInterface.h"
#include "linux/utility/utility.h" #include "linux/utility/utility.h"
@ -14,7 +15,7 @@
SdCardManager* SdCardManager::factoryInstance = nullptr; SdCardManager* SdCardManager::factoryInstance = nullptr;
SdCardManager::SdCardManager() : cmdExecutor(256) {} SdCardManager::SdCardManager() : SystemObject(objects::SDC_MANAGER), cmdExecutor(256) {}
SdCardManager::~SdCardManager() {} SdCardManager::~SdCardManager() {}

View File

@ -1,6 +1,7 @@
#ifndef BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_ #ifndef BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_
#define BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_ #define BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_
#include <fsfw/objectmanager/SystemObject.h>
#include <poll.h> #include <poll.h>
#include <array> #include <array>
@ -22,7 +23,7 @@ class MutexIF;
* @brief Manages handling of SD cards like switching them on or off or getting the current * @brief Manages handling of SD cards like switching them on or off or getting the current
* state * state
*/ */
class SdCardManager { class SdCardManager : public SystemObject {
friend class SdCardAccess; friend class SdCardAccess;
public: public:
@ -54,6 +55,7 @@ class SdCardManager {
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FILE_SYSTEM; static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FILE_SYSTEM;
static constexpr Event SANITIZATION_FAILED = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW); static constexpr Event SANITIZATION_FAILED = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW);
static constexpr Event MOUNTED_SD_CARD = event::makeEvent(SUBSYSTEM_ID, 1, severity::INFO);
// C++17 does not support constexpr std::string yet // C++17 does not support constexpr std::string yet
static constexpr char SD_0_DEV_NAME[] = "/dev/mmcblk0p1"; static constexpr char SD_0_DEV_NAME[] = "/dev/mmcblk0p1";
@ -183,7 +185,7 @@ class SdCardManager {
/** /**
* @brief Checks if an SD card is mounted * @brief Checks if an SD card is mounted
* *
* @param sdCard The SD crad to check * @param sdCard The SD card to check
* *
* @return true if mounted, otherwise false * @return true if mounted, otherwise false
*/ */

View File

@ -47,7 +47,7 @@ if(CMAKE_CROSSCOMPILING)
set_property(CACHE TGT_BSP set_property(CACHE TGT_BSP
PROPERTY STRINGS PROPERTY STRINGS
"arm/q7s" "arm/raspberrypi" "arm/q7s" "arm/raspberrypi" "arm/egse"
) )
endif() endif()
@ -57,6 +57,8 @@ if(TGT_BSP)
set(BSP_PATH "bsp_linux_board") set(BSP_PATH "bsp_linux_board")
elseif(TGT_BSP MATCHES "arm/q7s") elseif(TGT_BSP MATCHES "arm/q7s")
set(BSP_PATH "bsp_q7s") set(BSP_PATH "bsp_q7s")
elseif(TGT_BSP MATCHES "arm/egse")
set(BSP_PATH "bsp_egse")
else() else()
message(WARNING "CMake not configured for this target!") message(WARNING "CMake not configured for this target!")
message(FATAL_ERROR "Target: ${TGT_BSP}!") message(FATAL_ERROR "Target: ${TGT_BSP}!")

View File

@ -17,8 +17,7 @@ if(FSFW_OSAL MATCHES linux AND TGT_BSP)
"${CMAKE_SCRIPT_PATH}/Q7SCrossCompileConfig.cmake" "${CMAKE_SCRIPT_PATH}/Q7SCrossCompileConfig.cmake"
PARENT_SCOPE PARENT_SCOPE
) )
elseif(TGT_BSP MATCHES "arm/raspberrypi" OR TGT_BSP MATCHES "arm/egse")
elseif(TGT_BSP MATCHES "arm/raspberrypi")
if(NOT DEFINED ENV{LINUX_ROOTFS}) if(NOT DEFINED ENV{LINUX_ROOTFS})
if(NOT DEFINED LINUX_ROOTFS) if(NOT DEFINED LINUX_ROOTFS)
message(WARNING "No LINUX_ROOTFS environmental or CMake variable set!") message(WARNING "No LINUX_ROOTFS environmental or CMake variable set!")

View File

@ -81,8 +81,19 @@ set(CMAKE_PREFIX_PATH
# "${SYSROOT_PATH}/usr/lib/${CROSS_COMPILE}" # "${SYSROOT_PATH}/usr/lib/${CROSS_COMPILE}"
) )
set(C_FLAGS
-mcpu=cortex-a9
-mfpu=neon-vfpv3
-mfloat-abi=hard
${COMMON_FLAGS}
-lgpiod
-lxiphos
)
string (REPLACE ";" " " C_FLAGS "${C_FLAGS}")
set(CMAKE_C_FLAGS set(CMAKE_C_FLAGS
"-mcpu=cortex-a9 -mfpu=neon-vfpv3 -mfloat-abi=hard ${COMMON_FLAGS} -lgpiod" ${C_FLAGS}
CACHE STRING "C flags for Q7S" CACHE STRING "C flags for Q7S"
) )
set(CMAKE_CXX_FLAGS set(CMAKE_CXX_FLAGS

View File

@ -1,5 +1,49 @@
#!/bin/sh #!/bin/sh
export PATH=$PATH:"/c/Xilinx/SDK/2018.2/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin" # Run with: source q7s-env-win-sh [OPTIONS]
export CROSS_COMPILE="arm-linux-gnueabihf" function help () {
echo "source q7s-env-win-sh [options] -t|--toolchain=<toolchain path> -s|--sysroot=<sysroot path>"
}
export Q7S_SYSROOT="/c/Users/${USER}/Documents/EIVE/cortexa9hf-neon-xiphos-linux-gnueabi" TOOLCHAIN_PATH="/c/Xilinx/Vitis/2019.2/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin"
SYSROOT="/c/Users/${USER}/eive-software/cortexa9hf-neon-xiphos-linux-gnueabi"
for i in "$@"; do
case $i in
-t=*|--toolchain=*)
TOOLCHAIN_PATH="${i#*=}"
shift
;;
-s=*|--sysroot=*)
SYSROOT="${i#*=}"
shift
;;
-h|--help)
help
shift
;;
-*|--*)
echo "Unknown option $i"
help
return
;;
*)
;;
esac
done
if [ -d "$TOOLCHAIN_PATH" ]; then
export PATH=$PATH:"/c/Xilinx/Vitis/2019.2/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin"
export CROSS_COMPILE="arm-linux-gnueabihf"
echo "Set toolchain path to /c/Xilinx/Vitis/2019.2/gnu/aarch32/nt/gcc-arm-linux-gnueabi/bin"
else
echo "Toolchain path $TOOLCHAIN_PATH does not exist"
return
fi
if [ -d "$SYSROOT" ]; then
export Q7S_SYSROOT=$SYSROOT
echo "Set sysroot path to $SYSROOT"
else
echo "Sysroot path $SYSROOT does not exist"
return
fi

View File

@ -0,0 +1,13 @@
#!/bin/sh
# Script to set path to raspberry pi toolchain
# Run script with: source egse_path_helper_win.sh
TOOLCHAIN_PATH="/c/SysGCC/raspberry/bin"
if [ $# -eq 1 ];then
export PATH=$PATH:"$1"
else
export PATH=$PATH:$TOOLCHAIN_PATH
fi
echo "Path of toolchain set to $TOOLCHAIN_PATH"
export CROSS_COMPILE="arm-linux-gnueabihf"
export RASPBERRY_VERSION="4"

View File

@ -0,0 +1,34 @@
#!/bin/sh
counter=0
cfg_script_name="cmake-build-cfg.py"
while [ ${counter} -lt 5 ]
do
cd ..
if [ -f ${cfg_script_name} ];then
break
fi
counter=$((counter=counter + 1))
done
if [ "${counter}" -ge 5 ];then
echo "${cfg_script_name} not found in upper directories!"
exit 1
fi
os_fsfw="linux"
tgt_bsp="arm/egse"
build_generator="make"
build_dir="build-Debug-egse"
if [ "${OS}" = "Windows_NT" ]; then
python="py"
# Could be other OS but this works for now.
else
python="python3"
fi
echo "Running command (without the leading +):"
set -x # Print command
${python} ${cfg_script_name} -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \
-l"${build_dir}"
# set +x

View File

@ -19,6 +19,7 @@ enum: uint8_t {
PLOC_MEMORY_DUMPER = 118, PLOC_MEMORY_DUMPER = 118,
PDEC_HANDLER = 119, PDEC_HANDLER = 119,
STR_HELPER = 120, STR_HELPER = 120,
PL_PCDU_HANDLER = 121,
COMMON_SUBSYSTEM_ID_END COMMON_SUBSYSTEM_ID_END
}; };
} }

View File

@ -48,9 +48,9 @@ namespace uart {
static constexpr size_t HYPERION_GPS_REPLY_MAX_BUFFER = 1024; static constexpr size_t HYPERION_GPS_REPLY_MAX_BUFFER = 1024;
static constexpr uint32_t SYRLINKS_BAUD = 38400; static constexpr uint32_t SYRLINKS_BAUD = 38400;
static constexpr uint32_t GNSS_BAUD = 9600; static constexpr uint32_t GNSS_BAUD = 9600;
static constexpr uint32_t PLOC_MPSOC_BAUD = 115200; static constexpr uint32_t PLOC_MPSOC_BAUD = 921600;
static constexpr uint32_t PLOC_SUPERVISOR_BAUD = 115200; static constexpr uint32_t PLOC_SUPERVISOR_BAUD = 115200;
static constexpr uint32_t STAR_TRACKER_BAUD = 115200; static constexpr uint32_t STAR_TRACKER_BAUD = 921600;
} }

2
fsfw

@ -1 +1 @@
Subproject commit 123f2ff360e71228e1c0c786d80a4c93d7144a2e Subproject commit 0ccaf27fcb0e7a0f2dd1ca7175a7051a0267c8ec

View File

@ -6,9 +6,9 @@
<envs> <envs>
<env name="PYTHONUNBUFFERED" value="1" /> <env name="PYTHONUNBUFFERED" value="1" />
</envs> </envs>
<option name="SDK_HOME" value="" /> <option name="SDK_HOME" value="C:\Users\jakob\AppData\Local\Programs\Python\Python39\python.exe" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" /> <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" /> <option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" /> <option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" /> <option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" /> <EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />

View File

@ -1,140 +1,139 @@
2200;STORE_SEND_WRITE_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h 2200;STORE_SEND_WRITE_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
2201;STORE_WRITE_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h 2201;STORE_WRITE_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
2202;STORE_SEND_READ_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h 2202;STORE_SEND_READ_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
2203;STORE_READ_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h 2203;STORE_READ_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
2204;UNEXPECTED_MSG;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h 2204;UNEXPECTED_MSG;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
2205;STORING_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h 2205;STORING_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
2206;TM_DUMP_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h 2206;TM_DUMP_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
2207;STORE_INIT_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h 2207;STORE_INIT_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
2208;STORE_INIT_EMPTY;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h 2208;STORE_INIT_EMPTY;INFO;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
2209;STORE_CONTENT_CORRUPTED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h 2209;STORE_CONTENT_CORRUPTED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
2210;STORE_INITIALIZE;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h 2210;STORE_INITIALIZE;INFO;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
2211;INIT_DONE;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h 2211;INIT_DONE;INFO;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
2212;DUMP_FINISHED;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h 2212;DUMP_FINISHED;INFO;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
2213;DELETION_FINISHED;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h 2213;DELETION_FINISHED;INFO;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
2214;DELETION_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h 2214;DELETION_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
2215;AUTO_CATALOGS_SENDING_FAILED;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h 2215;AUTO_CATALOGS_SENDING_FAILED;INFO;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
2600;GET_DATA_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h 2600;GET_DATA_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h
2601;STORE_DATA_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h 2601;STORE_DATA_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h
2800;DEVICE_BUILDING_COMMAND_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h 2800;DEVICE_BUILDING_COMMAND_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
2801;DEVICE_SENDING_COMMAND_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h 2801;DEVICE_SENDING_COMMAND_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
2802;DEVICE_REQUESTING_REPLY_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h 2802;DEVICE_REQUESTING_REPLY_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
2803;DEVICE_READING_REPLY_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h 2803;DEVICE_READING_REPLY_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
2804;DEVICE_INTERPRETING_REPLY_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h 2804;DEVICE_INTERPRETING_REPLY_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
2805;DEVICE_MISSED_REPLY;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h 2805;DEVICE_MISSED_REPLY;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
2806;DEVICE_UNKNOWN_REPLY;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h 2806;DEVICE_UNKNOWN_REPLY;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
2807;DEVICE_UNREQUESTED_REPLY;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h 2807;DEVICE_UNREQUESTED_REPLY;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
2808;INVALID_DEVICE_COMMAND;LOW;Indicates a SW bug in child class.;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h 2808;INVALID_DEVICE_COMMAND;LOW;Indicates a SW bug in child class.;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
2809;MONITORING_LIMIT_EXCEEDED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h 2809;MONITORING_LIMIT_EXCEEDED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
2810;MONITORING_AMBIGUOUS;HIGH;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h 2810;MONITORING_AMBIGUOUS;HIGH;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
2811;DEVICE_WANTS_HARD_REBOOT;HIGH;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h 2811;DEVICE_WANTS_HARD_REBOOT;HIGH;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
4201;FUSE_CURRENT_HIGH;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/Fuse.h 4201;FUSE_CURRENT_HIGH;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/power/Fuse.h
4202;FUSE_WENT_OFF;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/Fuse.h 4202;FUSE_WENT_OFF;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/power/Fuse.h
4204;POWER_ABOVE_HIGH_LIMIT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/Fuse.h 4204;POWER_ABOVE_HIGH_LIMIT;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/power/Fuse.h
4205;POWER_BELOW_LOW_LIMIT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/Fuse.h 4205;POWER_BELOW_LOW_LIMIT;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/power/Fuse.h
4300;SWITCH_WENT_OFF;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitchIF.h 4300;SWITCH_WENT_OFF;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/power/PowerSwitchIF.h
5000;HEATER_ON;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h 5000;HEATER_ON;INFO;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h
5001;HEATER_OFF;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h 5001;HEATER_OFF;INFO;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h
5002;HEATER_TIMEOUT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h 5002;HEATER_TIMEOUT;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h
5003;HEATER_STAYED_ON;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h 5003;HEATER_STAYED_ON;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h
5004;HEATER_STAYED_OFF;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h 5004;HEATER_STAYED_OFF;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h
5200;TEMP_SENSOR_HIGH;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h 5200;TEMP_SENSOR_HIGH;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h
5201;TEMP_SENSOR_LOW;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h 5201;TEMP_SENSOR_LOW;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h
5202;TEMP_SENSOR_GRADIENT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h 5202;TEMP_SENSOR_GRADIENT;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h
5901;COMPONENT_TEMP_LOW;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h 5901;COMPONENT_TEMP_LOW;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h
5902;COMPONENT_TEMP_HIGH;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h 5902;COMPONENT_TEMP_HIGH;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h
5903;COMPONENT_TEMP_OOL_LOW;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h 5903;COMPONENT_TEMP_OOL_LOW;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h
5904;COMPONENT_TEMP_OOL_HIGH;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h 5904;COMPONENT_TEMP_OOL_HIGH;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h
5905;TEMP_NOT_IN_OP_RANGE;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h 5905;TEMP_NOT_IN_OP_RANGE;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h
7101;FDIR_CHANGED_STATE;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h 7101;FDIR_CHANGED_STATE;INFO;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h
7102;FDIR_STARTS_RECOVERY;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h 7102;FDIR_STARTS_RECOVERY;MEDIUM;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h
7103;FDIR_TURNS_OFF_DEVICE;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h 7103;FDIR_TURNS_OFF_DEVICE;MEDIUM;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h
7201;MONITOR_CHANGED_STATE;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h 7201;MONITOR_CHANGED_STATE;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h
7202;VALUE_BELOW_LOW_LIMIT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h 7202;VALUE_BELOW_LOW_LIMIT;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h
7203;VALUE_ABOVE_HIGH_LIMIT;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h 7203;VALUE_ABOVE_HIGH_LIMIT;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h
7204;VALUE_OUT_OF_RANGE;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h 7204;VALUE_OUT_OF_RANGE;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h
7400;CHANGING_MODE;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h 7400;CHANGING_MODE;INFO;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h
7401;MODE_INFO;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h 7401;MODE_INFO;INFO;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h
7402;FALLBACK_FAILED;HIGH;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h 7402;FALLBACK_FAILED;HIGH;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h
7403;MODE_TRANSITION_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h 7403;MODE_TRANSITION_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h
7404;CANT_KEEP_MODE;HIGH;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h 7404;CANT_KEEP_MODE;HIGH;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h
7405;OBJECT_IN_INVALID_MODE;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h 7405;OBJECT_IN_INVALID_MODE;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h
7406;FORCING_MODE;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h 7406;FORCING_MODE;MEDIUM;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h
7407;MODE_CMD_REJECTED;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h 7407;MODE_CMD_REJECTED;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h
7506;HEALTH_INFO;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h 7506;HEALTH_INFO;INFO;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h
7507;CHILD_CHANGED_HEALTH;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h 7507;CHILD_CHANGED_HEALTH;INFO;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h
7508;CHILD_PROBLEMS;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h 7508;CHILD_PROBLEMS;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h
7509;OVERWRITING_HEALTH;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h 7509;OVERWRITING_HEALTH;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h
7510;TRYING_RECOVERY;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h 7510;TRYING_RECOVERY;MEDIUM;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h
7511;RECOVERY_STEP;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h 7511;RECOVERY_STEP;MEDIUM;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h
7512;RECOVERY_DONE;MEDIUM;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h 7512;RECOVERY_DONE;MEDIUM;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h
7900;RF_AVAILABLE;INFO;A RF available signal was detected. P1: raw RFA state, P2: 0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h 7900;RF_AVAILABLE;INFO;A RF available signal was detected. P1: raw RFA state, P2: 0;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
7901;RF_LOST;INFO;A previously found RF available signal was lost. P1: raw RFA state, P2: 0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h 7901;RF_LOST;INFO;A previously found RF available signal was lost. P1: raw RFA state, P2: 0;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
7902;BIT_LOCK;INFO;A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h 7902;BIT_LOCK;INFO;A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
7903;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h 7903;BIT_LOCK_LOST;INFO;A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
7905;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h 7905;FRAME_PROCESSING_FAILED;LOW;The CCSDS Board could not interpret a TC;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
8900;CLOCK_SET;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h 8900;CLOCK_SET;INFO;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h
8901;CLOCK_SET_FAILURE;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h 8901;CLOCK_SET_FAILURE;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h
9700;TEST;INFO;;/home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/pus/Service17Test.h 9700;TEST;INFO;;C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/pus/Service17Test.h
10600;CHANGE_OF_SETUP_PARAMETER;LOW;;/home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h 10600;CHANGE_OF_SETUP_PARAMETER;LOW;;C:\Users\jakob\eive-software\eive_obsw/fsfw/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h
10900;GPIO_PULL_HIGH_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/HeaterHandler.h 10900;GPIO_PULL_HIGH_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/HeaterHandler.h
10901;GPIO_PULL_LOW_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/HeaterHandler.h 10901;GPIO_PULL_LOW_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/HeaterHandler.h
10902;SWITCH_ALREADY_ON;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/HeaterHandler.h 10902;SWITCH_ALREADY_ON;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/HeaterHandler.h
10903;SWITCH_ALREADY_OFF;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/HeaterHandler.h 10903;SWITCH_ALREADY_OFF;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/HeaterHandler.h
10904;MAIN_SWITCH_TIMEOUT;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/HeaterHandler.h 10904;MAIN_SWITCH_TIMEOUT;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/HeaterHandler.h
11000;MAIN_SWITCH_ON_TIMEOUT;LOW;;/home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h 11000;MAIN_SWITCH_ON_TIMEOUT;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/SolarArrayDeploymentHandler.h
11001;MAIN_SWITCH_OFF_TIMEOUT;LOW;;/home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h 11001;MAIN_SWITCH_OFF_TIMEOUT;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/SolarArrayDeploymentHandler.h
11002;DEPLOYMENT_FAILED;HIGH;;/home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h 11002;DEPLOYMENT_FAILED;HIGH;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/SolarArrayDeploymentHandler.h
11003;DEPL_SA1_GPIO_SWTICH_ON_FAILED;HIGH;;/home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h 11003;DEPL_SA1_GPIO_SWTICH_ON_FAILED;HIGH;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/SolarArrayDeploymentHandler.h
11004;DEPL_SA2_GPIO_SWTICH_ON_FAILED;HIGH;;/home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h 11004;DEPL_SA2_GPIO_SWTICH_ON_FAILED;HIGH;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/SolarArrayDeploymentHandler.h
11101;MEMORY_READ_RPT_CRC_FAILURE;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h 11101;MEMORY_READ_RPT_CRC_FAILURE;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/PlocMPSoCHandler.h
11102;ACK_FAILURE;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h 11102;ACK_FAILURE;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/PlocMPSoCHandler.h
11103;EXE_FAILURE;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h 11103;EXE_FAILURE;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/PlocMPSoCHandler.h
11104;CRC_FAILURE_EVENT;LOW;;/home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h 11104;CRC_FAILURE_EVENT;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/PlocMPSoCHandler.h
11201;SELF_TEST_I2C_FAILURE;LOW;Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h 11201;SELF_TEST_I2C_FAILURE;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/IMTQHandler.h
11202;SELF_TEST_SPI_FAILURE;LOW;Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h 11202;SELF_TEST_SPI_FAILURE;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/IMTQHandler.h
11203;SELF_TEST_ADC_FAILURE;LOW;Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h 11203;SELF_TEST_ADC_FAILURE;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/IMTQHandler.h
11204;SELF_TEST_PWM_FAILURE;LOW;Get self test result returns PWM failure which concerns the coil actuation. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h 11204;SELF_TEST_PWM_FAILURE;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/IMTQHandler.h
11205;SELF_TEST_TC_FAILURE;LOW;Get self test result returns TC failure (system failure) P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h 11205;SELF_TEST_TC_FAILURE;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/IMTQHandler.h
11206;SELF_TEST_MTM_RANGE_FAILURE;LOW;Get self test result returns failure that MTM values were outside of the expected range. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h 11206;SELF_TEST_MTM_RANGE_FAILURE;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/IMTQHandler.h
11207;SELF_TEST_COIL_CURRENT_FAILURE;LOW;Get self test result returns failure indicating that the coil current was outside of the expected range P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h 11207;SELF_TEST_COIL_CURRENT_FAILURE;LOW;;C:\Users\jakob\eive-software\eive_obsw/mission/devices/IMTQHandler.h
11208;INVALID_ERROR_BYTE;LOW;Received invalid error byte. This indicates an error of the communication link between IMTQ and OBC.;/home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h 11208;INVALID_ERROR_BYTE;LOW;Received invalid error byte. This indicates an error of the communication link between IMTQ and OBC.;C:\Users\jakob\eive-software\eive_obsw/mission/devices/IMTQHandler.h
11301;ERROR_STATE;HIGH;Reaction wheel signals an error state;/home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h 11301;ERROR_STATE;HIGH;Reaction wheel signals an error state;C:\Users\jakob\eive-software\eive_obsw/mission/devices/RwHandler.h
11501;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocSupervisorHandler.h 11401;BOOTING_FIRMWARE_FAILED;LOW;Failed to boot firmware;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StarTrackerHandler.h
11502;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocSupervisorHandler.h 11402;BOOTING_BOOTLOADER_FAILED;LOW;Failed to boot star tracker into bootloader mode;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StarTrackerHandler.h
11503;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocSupervisorHandler.h 11501;SUPV_MEMORY_READ_RPT_CRC_FAILURE;LOW;PLOC supervisor crc failure in telemetry packet;C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h
11504;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocSupervisorHandler.h 11502;SUPV_ACK_FAILURE;LOW;PLOC supervisor received acknowledgment failure report;C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h
11600;SANITIZATION_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h 11503;SUPV_EXE_FAILURE;LOW;PLOC received execution failure report;C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h
11700;UPDATE_FILE_NOT_EXISTS;LOW;;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocUpdater.h 11504;SUPV_CRC_FAILURE_EVENT;LOW;PLOC supervisor reply has invalid crc;C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h
11701;ACTION_COMMANDING_FAILED;LOW;Failed to send command to supervisor handler P1: Return value of CommandActionHelper::commandAction P2: Action ID of command to send;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocUpdater.h 11600;SANITIZATION_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/memory/SdCardManager.h
11702;UPDATE_AVAILABLE_FAILED;LOW;Supervisor handler replied action message indicating a command execution failure of the update available command;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocUpdater.h 11700;UPDATE_FILE_NOT_EXISTS;LOW;;C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
11703;UPDATE_TRANSFER_FAILED;LOW;Supervisor handler failed to transfer an update space packet. P1: Parameter holds the number of update packets already sent (inclusive the failed packet);/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocUpdater.h 11701;ACTION_COMMANDING_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
11704;UPDATE_VERIFY_FAILED;LOW;Supervisor failed to execute the update verify command.;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocUpdater.h 11702;UPDATE_AVAILABLE_FAILED;LOW;Supervisor handler replied action message indicating a command execution failure of the update available command;C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
11705;UPDATE_FINISHED;INFO;MPSoC update successful completed;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocUpdater.h 11703;UPDATE_TRANSFER_FAILED;LOW;Supervisor handler failed to transfer an update space packet. P1: Parameter holds the number of update packets already sent (inclusive the failed packet);C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
11800;SEND_MRAM_DUMP_FAILED;LOW;Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocMemoryDumper.h 11704;UPDATE_VERIFY_FAILED;LOW;Supervisor failed to execute the update verify command.;C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
11801;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocMemoryDumper.h 11705;UPDATE_FINISHED;INFO;MPSoC update successful completed;C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
11802;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocMemoryDumper.h 11800;SEND_MRAM_DUMP_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h
11901;INVALID_TC_FRAME;HIGH;;/home/rmueller/EIVE/eive-obsw/linux/obc/PdecHandler.h 11801;MRAM_DUMP_FAILED;LOW;Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command;C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h
11902;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;/home/rmueller/EIVE/eive-obsw/linux/obc/PdecHandler.h 11802;MRAM_DUMP_FINISHED;LOW;MRAM dump finished successfully;C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h
11903;CARRIER_LOCK;INFO;Carrier lock detected;/home/rmueller/EIVE/eive-obsw/linux/obc/PdecHandler.h 11901;INVALID_TC_FRAME;HIGH;;C:\Users\jakob\eive-software\eive_obsw/linux/obc/PdecHandler.h
11904;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);/home/rmueller/EIVE/eive-obsw/linux/obc/PdecHandler.h 11902;INVALID_FAR;HIGH;Read invalid FAR from PDEC after startup;C:\Users\jakob\eive-software\eive_obsw/linux/obc/PdecHandler.h
12000;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 11903;CARRIER_LOCK;INFO;Carrier lock detected;C:\Users\jakob\eive-software\eive_obsw/linux/obc/PdecHandler.h
12001;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 11904;BIT_LOCK_PDEC;INFO;Bit lock detected (data valid);C:\Users\jakob\eive-software\eive_obsw/linux/obc/PdecHandler.h
12002;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 12000;IMAGE_UPLOAD_FAILED;LOW;Image upload failed;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12003;IMAGE_DOWNLOAD_SUCCESSFUL;LOW;Image download was successful;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 12001;IMAGE_DOWNLOAD_FAILED;LOW;Image download failed;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12004;FLASH_WRITE_SUCCESSFUL;LOW;Finished flash write procedure successfully;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 12002;IMAGE_UPLOAD_SUCCESSFUL;LOW;Uploading image to star tracker was successfulop;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12005;FLASH_READ_SUCCESSFUL;LOW;Finished flash read procedure successfully;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 12003;IMAGE_DOWNLOAD_SUCCESSFUL;LOW;Image download was successful;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12006;FLASH_WRITE_FAILED;LOW;Flash write procedure failed;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 12004;FLASH_WRITE_SUCCESSFUL;LOW;Finished flash write procedure successfully;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12007;FLASH_READ_FAILED;LOW;Flash read procedure failed;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 12005;FLASH_READ_SUCCESSFUL;LOW;Finished flash read procedure successfully;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12008;FPGA_DOWNLOAD_SUCCESSFUL;LOW;Download of FPGA image successful;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 12006;FLASH_READ_FAILED;LOW;Flash read procedure failed;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12009;FPGA_DOWNLOAD_FAILED;LOW;Download of FPGA image failed;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 12007;FIRMWARE_UPDATE_SUCCESSFUL;LOW;Firmware update was successful;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12010;FPGA_UPLOAD_SUCCESSFUL;LOW;Upload of FPGA image successful;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 12008;FIRMWARE_UPDATE_FAILED;LOW;Firmware update failed;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12011;FPGA_UPLOAD_FAILED;LOW;Upload of FPGA image failed;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 12009;STR_HELPER_READING_REPLY_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12012;STR_HELPER_READING_REPLY_FAILED;LOW;Failed to read communication interface reply data P1: Return code of failed communication interface read call P1: Upload/download position for which the read call failed;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 12010;STR_HELPER_COM_ERROR;LOW;;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12013;STR_HELPER_COM_ERROR;LOW;Unexpected stop of decoding sequence P1: Return code of failed communication interface read call P1: Upload/download position for which the read call failed;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 12011;STR_HELPER_NO_REPLY;LOW;Star tracker did not send replies (maybe device is powered off) P1: Position of upload or download packet for which no reply was sent;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12014;STR_HELPER_NO_REPLY;LOW;Star tracker did not send replies (maybe device is powered off) P1: Position of upload or download packet for which no reply was sent;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 12012;STR_HELPER_DEC_ERROR;LOW;;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12015;STR_HELPER_DEC_ERROR;LOW;Error during decoding of received reply occurred P1: Return value of decoding function P2: Position of upload/download packet, or address of flash write/read request;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 12013;POSITION_MISMATCH;LOW;Position mismatch P1: The expected position and thus the position for which the image upload/download failed;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12016;POSITION_MISMATCH;LOW;Position mismatch P1: The expected position and thus the position for which the image upload/download failed;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 12014;STR_HELPER_FILE_NOT_EXISTS;LOW;Specified file does not exist P1: Internal state of str helper;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12017;STR_HELPER_FILE_NOT_EXISTS;LOW;Specified file does not exist P1: Internal state of str helper;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 12015;STR_HELPER_SENDING_PACKET_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12018;STR_HELPER_SENDING_PACKET_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h 12016;STR_HELPER_REQUESTING_MSG_FAILED;LOW;;C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12019;STR_HELPER_REQUESTING_MSG_FAILED;LOW;;/home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h

1 2200 STORE_SEND_WRITE_FAILED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
2 2201 STORE_WRITE_FAILED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
3 2202 STORE_SEND_READ_FAILED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
4 2203 STORE_READ_FAILED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
5 2204 UNEXPECTED_MSG LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
6 2205 STORING_FAILED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
7 2206 TM_DUMP_FAILED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
8 2207 STORE_INIT_FAILED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
9 2208 STORE_INIT_EMPTY INFO /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
10 2209 STORE_CONTENT_CORRUPTED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
11 2210 STORE_INITIALIZE INFO /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
12 2211 INIT_DONE INFO /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
13 2212 DUMP_FINISHED INFO /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
14 2213 DELETION_FINISHED INFO /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
15 2214 DELETION_FAILED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
16 2215 AUTO_CATALOGS_SENDING_FAILED INFO /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/tmstorage/TmStoreBackendIF.h
17 2600 GET_DATA_FAILED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h
18 2601 STORE_DATA_FAILED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/storagemanager/StorageManagerIF.h
19 2800 DEVICE_BUILDING_COMMAND_FAILED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
20 2801 DEVICE_SENDING_COMMAND_FAILED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
21 2802 DEVICE_REQUESTING_REPLY_FAILED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
22 2803 DEVICE_READING_REPLY_FAILED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
23 2804 DEVICE_INTERPRETING_REPLY_FAILED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
24 2805 DEVICE_MISSED_REPLY LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
25 2806 DEVICE_UNKNOWN_REPLY LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
26 2807 DEVICE_UNREQUESTED_REPLY LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
27 2808 INVALID_DEVICE_COMMAND LOW Indicates a SW bug in child class. /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
28 2809 MONITORING_LIMIT_EXCEEDED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
29 2810 MONITORING_AMBIGUOUS HIGH /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
30 2811 DEVICE_WANTS_HARD_REBOOT HIGH /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/devicehandlers/DeviceHandlerIF.h
31 4201 FUSE_CURRENT_HIGH LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/Fuse.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/power/Fuse.h
32 4202 FUSE_WENT_OFF LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/Fuse.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/power/Fuse.h
33 4204 POWER_ABOVE_HIGH_LIMIT LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/Fuse.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/power/Fuse.h
34 4205 POWER_BELOW_LOW_LIMIT LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/Fuse.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/power/Fuse.h
35 4300 SWITCH_WENT_OFF LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/power/PowerSwitchIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/power/PowerSwitchIF.h
36 5000 HEATER_ON INFO /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h
37 5001 HEATER_OFF INFO /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h
38 5002 HEATER_TIMEOUT LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h
39 5003 HEATER_STAYED_ON LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h
40 5004 HEATER_STAYED_OFF LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/Heater.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/Heater.h
41 5200 TEMP_SENSOR_HIGH LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h
42 5201 TEMP_SENSOR_LOW LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h
43 5202 TEMP_SENSOR_GRADIENT LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/AbstractTemperatureSensor.h
44 5901 COMPONENT_TEMP_LOW LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h
45 5902 COMPONENT_TEMP_HIGH LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h
46 5903 COMPONENT_TEMP_OOL_LOW LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h
47 5904 COMPONENT_TEMP_OOL_HIGH LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h
48 5905 TEMP_NOT_IN_OP_RANGE LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/thermal/ThermalComponentIF.h
49 7101 FDIR_CHANGED_STATE INFO /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h
50 7102 FDIR_STARTS_RECOVERY MEDIUM /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h
51 7103 FDIR_TURNS_OFF_DEVICE MEDIUM /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/fdir/FailureIsolationBase.h
52 7201 MONITOR_CHANGED_STATE LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h
53 7202 VALUE_BELOW_LOW_LIMIT LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h
54 7203 VALUE_ABOVE_HIGH_LIMIT LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h
55 7204 VALUE_OUT_OF_RANGE LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/monitoring/MonitoringIF.h
56 7400 CHANGING_MODE INFO /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h
57 7401 MODE_INFO INFO /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h
58 7402 FALLBACK_FAILED HIGH /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h
59 7403 MODE_TRANSITION_FAILED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h
60 7404 CANT_KEEP_MODE HIGH /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h
61 7405 OBJECT_IN_INVALID_MODE LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h
62 7406 FORCING_MODE MEDIUM /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h
63 7407 MODE_CMD_REJECTED LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/modes/HasModesIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/modes/HasModesIF.h
64 7506 HEALTH_INFO INFO /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h
65 7507 CHILD_CHANGED_HEALTH INFO /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h
66 7508 CHILD_PROBLEMS LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h
67 7509 OVERWRITING_HEALTH LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h
68 7510 TRYING_RECOVERY MEDIUM /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h
69 7511 RECOVERY_STEP MEDIUM /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h
70 7512 RECOVERY_DONE MEDIUM /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/health/HasHealthIF.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/health/HasHealthIF.h
71 7900 RF_AVAILABLE INFO A RF available signal was detected. P1: raw RFA state, P2: 0 /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
72 7901 RF_LOST INFO A previously found RF available signal was lost. P1: raw RFA state, P2: 0 /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
73 7902 BIT_LOCK INFO A Bit Lock signal. Was detected. P1: raw BLO state, P2: 0 /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
74 7903 BIT_LOCK_LOST INFO A previously found Bit Lock signal was lost. P1: raw BLO state, P2: 0 /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
75 7905 FRAME_PROCESSING_FAILED LOW The CCSDS Board could not interpret a TC /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/datalinklayer/DataLinkLayer.h
76 8900 CLOCK_SET INFO /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h
77 8901 CLOCK_SET_FAILURE LOW /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/pus/Service9TimeManagement.h
78 9700 TEST INFO /home/rmueller/EIVE/eive-obsw/fsfw/src/fsfw/pus/Service17Test.h C:\Users\jakob\eive-software\eive_obsw/fsfw/src/fsfw/pus/Service17Test.h
79 10600 CHANGE_OF_SETUP_PARAMETER LOW /home/rmueller/EIVE/eive-obsw/fsfw/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h C:\Users\jakob\eive-software\eive_obsw/fsfw/hal/src/fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h
80 10900 GPIO_PULL_HIGH_FAILED LOW /home/rmueller/EIVE/eive-obsw/mission/devices/HeaterHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/HeaterHandler.h
81 10901 GPIO_PULL_LOW_FAILED LOW /home/rmueller/EIVE/eive-obsw/mission/devices/HeaterHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/HeaterHandler.h
82 10902 SWITCH_ALREADY_ON LOW /home/rmueller/EIVE/eive-obsw/mission/devices/HeaterHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/HeaterHandler.h
83 10903 SWITCH_ALREADY_OFF LOW /home/rmueller/EIVE/eive-obsw/mission/devices/HeaterHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/HeaterHandler.h
84 10904 MAIN_SWITCH_TIMEOUT LOW /home/rmueller/EIVE/eive-obsw/mission/devices/HeaterHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/HeaterHandler.h
85 11000 MAIN_SWITCH_ON_TIMEOUT LOW /home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/SolarArrayDeploymentHandler.h
86 11001 MAIN_SWITCH_OFF_TIMEOUT LOW /home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/SolarArrayDeploymentHandler.h
87 11002 DEPLOYMENT_FAILED HIGH /home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/SolarArrayDeploymentHandler.h
88 11003 DEPL_SA1_GPIO_SWTICH_ON_FAILED HIGH /home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/SolarArrayDeploymentHandler.h
89 11004 DEPL_SA2_GPIO_SWTICH_ON_FAILED HIGH /home/rmueller/EIVE/eive-obsw/linux/devices/SolarArrayDeploymentHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/SolarArrayDeploymentHandler.h
90 11101 MEMORY_READ_RPT_CRC_FAILURE LOW /home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/PlocMPSoCHandler.h
91 11102 ACK_FAILURE LOW /home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/PlocMPSoCHandler.h
92 11103 EXE_FAILURE LOW /home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/PlocMPSoCHandler.h
93 11104 CRC_FAILURE_EVENT LOW /home/rmueller/EIVE/eive-obsw/mission/devices/PlocMPSoCHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/PlocMPSoCHandler.h
94 11201 SELF_TEST_I2C_FAILURE LOW Get self test result returns I2C failure P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA /home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/IMTQHandler.h
95 11202 SELF_TEST_SPI_FAILURE LOW Get self test result returns SPI failure. This concerns the MTM connectivity. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA /home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/IMTQHandler.h
96 11203 SELF_TEST_ADC_FAILURE LOW Get self test result returns failure in measurement of current and temperature. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA /home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/IMTQHandler.h
97 11204 SELF_TEST_PWM_FAILURE LOW Get self test result returns PWM failure which concerns the coil actuation. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA /home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/IMTQHandler.h
98 11205 SELF_TEST_TC_FAILURE LOW Get self test result returns TC failure (system failure) P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA /home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/IMTQHandler.h
99 11206 SELF_TEST_MTM_RANGE_FAILURE LOW Get self test result returns failure that MTM values were outside of the expected range. P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA /home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/IMTQHandler.h
100 11207 SELF_TEST_COIL_CURRENT_FAILURE LOW Get self test result returns failure indicating that the coil current was outside of the expected range P1: Indicates on which axis the failure occurred. 0 -> INIT, 1 -> +X, 2 -> -X, 3 -> +Y, 4 -> -Y, 5 -> +Z, 6 -> -Z, 7 -> FINA /home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/IMTQHandler.h
101 11208 INVALID_ERROR_BYTE LOW Received invalid error byte. This indicates an error of the communication link between IMTQ and OBC. /home/rmueller/EIVE/eive-obsw/mission/devices/IMTQHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/IMTQHandler.h
102 11301 ERROR_STATE HIGH Reaction wheel signals an error state /home/rmueller/EIVE/eive-obsw/mission/devices/RwHandler.h C:\Users\jakob\eive-software\eive_obsw/mission/devices/RwHandler.h
103 11501 11401 SUPV_MEMORY_READ_RPT_CRC_FAILURE BOOTING_FIRMWARE_FAILED LOW PLOC supervisor crc failure in telemetry packet Failed to boot firmware /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocSupervisorHandler.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StarTrackerHandler.h
104 11502 11402 SUPV_ACK_FAILURE BOOTING_BOOTLOADER_FAILED LOW PLOC supervisor received acknowledgment failure report Failed to boot star tracker into bootloader mode /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocSupervisorHandler.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StarTrackerHandler.h
105 11503 11501 SUPV_EXE_FAILURE SUPV_MEMORY_READ_RPT_CRC_FAILURE LOW PLOC received execution failure report PLOC supervisor crc failure in telemetry packet /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocSupervisorHandler.h C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h
106 11504 11502 SUPV_CRC_FAILURE_EVENT SUPV_ACK_FAILURE LOW PLOC supervisor reply has invalid crc PLOC supervisor received acknowledgment failure report /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocSupervisorHandler.h C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h
107 11600 11503 SANITIZATION_FAILED SUPV_EXE_FAILURE LOW PLOC received execution failure report /home/rmueller/EIVE/eive-obsw/bsp_q7s/memory/SdCardManager.h C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h
108 11700 11504 UPDATE_FILE_NOT_EXISTS SUPV_CRC_FAILURE_EVENT LOW PLOC supervisor reply has invalid crc /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocUpdater.h C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocSupervisorHandler.h
109 11701 11600 ACTION_COMMANDING_FAILED SANITIZATION_FAILED LOW Failed to send command to supervisor handler P1: Return value of CommandActionHelper::commandAction P2: Action ID of command to send /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocUpdater.h C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/memory/SdCardManager.h
110 11702 11700 UPDATE_AVAILABLE_FAILED UPDATE_FILE_NOT_EXISTS LOW Supervisor handler replied action message indicating a command execution failure of the update available command /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocUpdater.h C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
111 11703 11701 UPDATE_TRANSFER_FAILED ACTION_COMMANDING_FAILED LOW Supervisor handler failed to transfer an update space packet. P1: Parameter holds the number of update packets already sent (inclusive the failed packet) /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocUpdater.h C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
112 11704 11702 UPDATE_VERIFY_FAILED UPDATE_AVAILABLE_FAILED LOW Supervisor failed to execute the update verify command. Supervisor handler replied action message indicating a command execution failure of the update available command /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocUpdater.h C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
113 11705 11703 UPDATE_FINISHED UPDATE_TRANSFER_FAILED INFO LOW MPSoC update successful completed Supervisor handler failed to transfer an update space packet. P1: Parameter holds the number of update packets already sent (inclusive the failed packet) /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocUpdater.h C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
114 11800 11704 SEND_MRAM_DUMP_FAILED UPDATE_VERIFY_FAILED LOW Failed to send mram dump command to supervisor handler P1: Return value of commandAction function P2: Start address of MRAM to dump with this command Supervisor failed to execute the update verify command. /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocMemoryDumper.h C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
115 11801 11705 MRAM_DUMP_FAILED UPDATE_FINISHED LOW INFO Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command MPSoC update successful completed /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocMemoryDumper.h C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocUpdater.h
116 11802 11800 MRAM_DUMP_FINISHED SEND_MRAM_DUMP_FAILED LOW MRAM dump finished successfully /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/PlocMemoryDumper.h C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h
117 11901 11801 INVALID_TC_FRAME MRAM_DUMP_FAILED HIGH LOW Received completion failure report form PLOC supervisor handler P1: MRAM start address of failing dump command /home/rmueller/EIVE/eive-obsw/linux/obc/PdecHandler.h C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h
118 11902 11802 INVALID_FAR MRAM_DUMP_FINISHED HIGH LOW Read invalid FAR from PDEC after startup MRAM dump finished successfully /home/rmueller/EIVE/eive-obsw/linux/obc/PdecHandler.h C:\Users\jakob\eive-software\eive_obsw/bsp_q7s/devices/PlocMemoryDumper.h
119 11903 11901 CARRIER_LOCK INVALID_TC_FRAME INFO HIGH Carrier lock detected /home/rmueller/EIVE/eive-obsw/linux/obc/PdecHandler.h C:\Users\jakob\eive-software\eive_obsw/linux/obc/PdecHandler.h
120 11904 11902 BIT_LOCK_PDEC INVALID_FAR INFO HIGH Bit lock detected (data valid) Read invalid FAR from PDEC after startup /home/rmueller/EIVE/eive-obsw/linux/obc/PdecHandler.h C:\Users\jakob\eive-software\eive_obsw/linux/obc/PdecHandler.h
121 12000 11903 IMAGE_UPLOAD_FAILED CARRIER_LOCK LOW INFO Image upload failed Carrier lock detected /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/obc/PdecHandler.h
122 12001 11904 IMAGE_DOWNLOAD_FAILED BIT_LOCK_PDEC LOW INFO Image download failed Bit lock detected (data valid) /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/obc/PdecHandler.h
123 12002 12000 IMAGE_UPLOAD_SUCCESSFUL IMAGE_UPLOAD_FAILED LOW Uploading image to star tracker was successfulop Image upload failed /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
124 12003 12001 IMAGE_DOWNLOAD_SUCCESSFUL IMAGE_DOWNLOAD_FAILED LOW Image download was successful Image download failed /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
125 12004 12002 FLASH_WRITE_SUCCESSFUL IMAGE_UPLOAD_SUCCESSFUL LOW Finished flash write procedure successfully Uploading image to star tracker was successfulop /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
126 12005 12003 FLASH_READ_SUCCESSFUL IMAGE_DOWNLOAD_SUCCESSFUL LOW Finished flash read procedure successfully Image download was successful /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
127 12006 12004 FLASH_WRITE_FAILED FLASH_WRITE_SUCCESSFUL LOW Flash write procedure failed Finished flash write procedure successfully /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
128 12007 12005 FLASH_READ_FAILED FLASH_READ_SUCCESSFUL LOW Flash read procedure failed Finished flash read procedure successfully /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
129 12008 12006 FPGA_DOWNLOAD_SUCCESSFUL FLASH_READ_FAILED LOW Download of FPGA image successful Flash read procedure failed /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
130 12009 12007 FPGA_DOWNLOAD_FAILED FIRMWARE_UPDATE_SUCCESSFUL LOW Download of FPGA image failed Firmware update was successful /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
131 12010 12008 FPGA_UPLOAD_SUCCESSFUL FIRMWARE_UPDATE_FAILED LOW Upload of FPGA image successful Firmware update failed /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
132 12011 12009 FPGA_UPLOAD_FAILED STR_HELPER_READING_REPLY_FAILED LOW Upload of FPGA image failed /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
133 12012 12010 STR_HELPER_READING_REPLY_FAILED STR_HELPER_COM_ERROR LOW Failed to read communication interface reply data P1: Return code of failed communication interface read call P1: Upload/download position for which the read call failed /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
134 12013 12011 STR_HELPER_COM_ERROR STR_HELPER_NO_REPLY LOW Unexpected stop of decoding sequence P1: Return code of failed communication interface read call P1: Upload/download position for which the read call failed Star tracker did not send replies (maybe device is powered off) P1: Position of upload or download packet for which no reply was sent /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
135 12014 12012 STR_HELPER_NO_REPLY STR_HELPER_DEC_ERROR LOW Star tracker did not send replies (maybe device is powered off) P1: Position of upload or download packet for which no reply was sent /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
136 12015 12013 STR_HELPER_DEC_ERROR POSITION_MISMATCH LOW Error during decoding of received reply occurred P1: Return value of decoding function P2: Position of upload/download packet, or address of flash write/read request Position mismatch P1: The expected position and thus the position for which the image upload/download failed /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
137 12016 12014 POSITION_MISMATCH STR_HELPER_FILE_NOT_EXISTS LOW Position mismatch P1: The expected position and thus the position for which the image upload/download failed Specified file does not exist P1: Internal state of str helper /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
138 12017 12015 STR_HELPER_FILE_NOT_EXISTS STR_HELPER_SENDING_PACKET_FAILED LOW Specified file does not exist P1: Internal state of str helper /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
139 12018 12016 STR_HELPER_SENDING_PACKET_FAILED STR_HELPER_REQUESTING_MSG_FAILED LOW /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h C:\Users\jakob\eive-software\eive_obsw/linux/devices/startracker/StrHelper.h
12019 STR_HELPER_REQUESTING_MSG_FAILED LOW /home/rmueller/EIVE/eive-obsw/bsp_q7s/devices/startracker/StrHelper.h

View File

@ -74,6 +74,7 @@
0x50000300;TMTC_BRIDGE 0x50000300;TMTC_BRIDGE
0x50000400;TMTC_POLLING_TASK 0x50000400;TMTC_POLLING_TASK
0x50000500;FILE_SYSTEM_HANDLER 0x50000500;FILE_SYSTEM_HANDLER
0x50000550;SDC_MANAGER
0x50000600;PTME 0x50000600;PTME
0x50000700;PDEC_HANDLER 0x50000700;PDEC_HANDLER
0x50000800;CCSDS_HANDLER 0x50000800;CCSDS_HANDLER

1 0x00005060 P60DOCK_TEST_TASK
74 0x50000300 TMTC_BRIDGE
75 0x50000400 TMTC_POLLING_TASK
76 0x50000500 FILE_SYSTEM_HANDLER
77 0x50000550 SDC_MANAGER
78 0x50000600 PTME
79 0x50000700 PDEC_HANDLER
80 0x50000800 CCSDS_HANDLER

View File

@ -1,7 +1,7 @@
/** /**
* @brief Auto-generated event translation file. Contains 140 translations. * @brief Auto-generated event translation file. Contains 139 translations.
* @details * @details
* Generated on: 2022-02-03 17:30:40 * Generated on: 2022-02-27 15:36:42
*/ */
#include "translateEvents.h" #include "translateEvents.h"
@ -107,6 +107,8 @@ const char *SELF_TEST_MTM_RANGE_FAILURE_STRING = "SELF_TEST_MTM_RANGE_FAILURE";
const char *SELF_TEST_COIL_CURRENT_FAILURE_STRING = "SELF_TEST_COIL_CURRENT_FAILURE"; const char *SELF_TEST_COIL_CURRENT_FAILURE_STRING = "SELF_TEST_COIL_CURRENT_FAILURE";
const char *INVALID_ERROR_BYTE_STRING = "INVALID_ERROR_BYTE"; const char *INVALID_ERROR_BYTE_STRING = "INVALID_ERROR_BYTE";
const char *ERROR_STATE_STRING = "ERROR_STATE"; const char *ERROR_STATE_STRING = "ERROR_STATE";
const char *BOOTING_FIRMWARE_FAILED_STRING = "BOOTING_FIRMWARE_FAILED";
const char *BOOTING_BOOTLOADER_FAILED_STRING = "BOOTING_BOOTLOADER_FAILED";
const char *SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING = "SUPV_MEMORY_READ_RPT_CRC_FAILURE"; const char *SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING = "SUPV_MEMORY_READ_RPT_CRC_FAILURE";
const char *SUPV_ACK_FAILURE_STRING = "SUPV_ACK_FAILURE"; const char *SUPV_ACK_FAILURE_STRING = "SUPV_ACK_FAILURE";
const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE"; const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE";
@ -131,12 +133,9 @@ const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
const char *IMAGE_DOWNLOAD_SUCCESSFUL_STRING = "IMAGE_DOWNLOAD_SUCCESSFUL"; const char *IMAGE_DOWNLOAD_SUCCESSFUL_STRING = "IMAGE_DOWNLOAD_SUCCESSFUL";
const char *FLASH_WRITE_SUCCESSFUL_STRING = "FLASH_WRITE_SUCCESSFUL"; const char *FLASH_WRITE_SUCCESSFUL_STRING = "FLASH_WRITE_SUCCESSFUL";
const char *FLASH_READ_SUCCESSFUL_STRING = "FLASH_READ_SUCCESSFUL"; const char *FLASH_READ_SUCCESSFUL_STRING = "FLASH_READ_SUCCESSFUL";
const char *FLASH_WRITE_FAILED_STRING = "FLASH_WRITE_FAILED";
const char *FLASH_READ_FAILED_STRING = "FLASH_READ_FAILED"; const char *FLASH_READ_FAILED_STRING = "FLASH_READ_FAILED";
const char *FPGA_DOWNLOAD_SUCCESSFUL_STRING = "FPGA_DOWNLOAD_SUCCESSFUL"; const char *FIRMWARE_UPDATE_SUCCESSFUL_STRING = "FIRMWARE_UPDATE_SUCCESSFUL";
const char *FPGA_DOWNLOAD_FAILED_STRING = "FPGA_DOWNLOAD_FAILED"; const char *FIRMWARE_UPDATE_FAILED_STRING = "FIRMWARE_UPDATE_FAILED";
const char *FPGA_UPLOAD_SUCCESSFUL_STRING = "FPGA_UPLOAD_SUCCESSFUL";
const char *FPGA_UPLOAD_FAILED_STRING = "FPGA_UPLOAD_FAILED";
const char *STR_HELPER_READING_REPLY_FAILED_STRING = "STR_HELPER_READING_REPLY_FAILED"; const char *STR_HELPER_READING_REPLY_FAILED_STRING = "STR_HELPER_READING_REPLY_FAILED";
const char *STR_HELPER_COM_ERROR_STRING = "STR_HELPER_COM_ERROR"; const char *STR_HELPER_COM_ERROR_STRING = "STR_HELPER_COM_ERROR";
const char *STR_HELPER_NO_REPLY_STRING = "STR_HELPER_NO_REPLY"; const char *STR_HELPER_NO_REPLY_STRING = "STR_HELPER_NO_REPLY";
@ -352,6 +351,10 @@ const char * translateEvents(Event event) {
return INVALID_ERROR_BYTE_STRING; return INVALID_ERROR_BYTE_STRING;
case(11301): case(11301):
return ERROR_STATE_STRING; return ERROR_STATE_STRING;
case(11401):
return BOOTING_FIRMWARE_FAILED_STRING;
case(11402):
return BOOTING_BOOTLOADER_FAILED_STRING;
case(11501): case(11501):
return SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING; return SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING;
case(11502): case(11502):
@ -401,32 +404,26 @@ const char * translateEvents(Event event) {
case(12005): case(12005):
return FLASH_READ_SUCCESSFUL_STRING; return FLASH_READ_SUCCESSFUL_STRING;
case(12006): case(12006):
return FLASH_WRITE_FAILED_STRING;
case(12007):
return FLASH_READ_FAILED_STRING; return FLASH_READ_FAILED_STRING;
case(12007):
return FIRMWARE_UPDATE_SUCCESSFUL_STRING;
case(12008): case(12008):
return FPGA_DOWNLOAD_SUCCESSFUL_STRING; return FIRMWARE_UPDATE_FAILED_STRING;
case(12009): case(12009):
return FPGA_DOWNLOAD_FAILED_STRING;
case(12010):
return FPGA_UPLOAD_SUCCESSFUL_STRING;
case(12011):
return FPGA_UPLOAD_FAILED_STRING;
case(12012):
return STR_HELPER_READING_REPLY_FAILED_STRING; return STR_HELPER_READING_REPLY_FAILED_STRING;
case(12013): case(12010):
return STR_HELPER_COM_ERROR_STRING; return STR_HELPER_COM_ERROR_STRING;
case(12014): case(12011):
return STR_HELPER_NO_REPLY_STRING; return STR_HELPER_NO_REPLY_STRING;
case(12015): case(12012):
return STR_HELPER_DEC_ERROR_STRING; return STR_HELPER_DEC_ERROR_STRING;
case(12016): case(12013):
return POSITION_MISMATCH_STRING; return POSITION_MISMATCH_STRING;
case(12017): case(12014):
return STR_HELPER_FILE_NOT_EXISTS_STRING; return STR_HELPER_FILE_NOT_EXISTS_STRING;
case(12018): case(12015):
return STR_HELPER_SENDING_PACKET_FAILED_STRING; return STR_HELPER_SENDING_PACKET_FAILED_STRING;
case(12019): case(12016):
return STR_HELPER_REQUESTING_MSG_FAILED_STRING; return STR_HELPER_REQUESTING_MSG_FAILED_STRING;
default: default:
return "UNKNOWN_EVENT"; return "UNKNOWN_EVENT";

@ -1 +1 @@
Subproject commit 24fa9a3fe3f5c6157b4c48e867e22bd2d335d18a Subproject commit bd76760052482f6f8fcdd84b88da963e61c9a48c

View File

@ -1,8 +1,8 @@
/** /**
* @brief Auto-generated object translation file. * @brief Auto-generated object translation file.
* @details * @details
* Contains 111 translations. * Contains 112 translations.
* Generated on: 2022-02-21 17:31:37 * Generated on: 2022-02-27 15:36:48
*/ */
#include "translateObjects.h" #include "translateObjects.h"
@ -82,6 +82,7 @@ const char *PUS_PACKET_DISTRIBUTOR_STRING = "PUS_PACKET_DISTRIBUTOR";
const char *TMTC_BRIDGE_STRING = "TMTC_BRIDGE"; const char *TMTC_BRIDGE_STRING = "TMTC_BRIDGE";
const char *TMTC_POLLING_TASK_STRING = "TMTC_POLLING_TASK"; const char *TMTC_POLLING_TASK_STRING = "TMTC_POLLING_TASK";
const char *FILE_SYSTEM_HANDLER_STRING = "FILE_SYSTEM_HANDLER"; const char *FILE_SYSTEM_HANDLER_STRING = "FILE_SYSTEM_HANDLER";
const char *SDC_MANAGER_STRING = "SDC_MANAGER";
const char *PTME_STRING = "PTME"; const char *PTME_STRING = "PTME";
const char *PDEC_HANDLER_STRING = "PDEC_HANDLER"; const char *PDEC_HANDLER_STRING = "PDEC_HANDLER";
const char *CCSDS_HANDLER_STRING = "CCSDS_HANDLER"; const char *CCSDS_HANDLER_STRING = "CCSDS_HANDLER";
@ -272,6 +273,8 @@ const char* translateObject(object_id_t object) {
return TMTC_POLLING_TASK_STRING; return TMTC_POLLING_TASK_STRING;
case 0x50000500: case 0x50000500:
return FILE_SYSTEM_HANDLER_STRING; return FILE_SYSTEM_HANDLER_STRING;
case 0x50000550:
return SDC_MANAGER_STRING;
case 0x50000600: case 0x50000600:
return PTME_STRING; return PTME_STRING;
case 0x50000700: case 0x50000700:

View File

@ -337,6 +337,8 @@ void SpiTestClass::performMax1227Test() {
std::string deviceName = q7s::SPI_DEFAULT_DEV; std::string deviceName = q7s::SPI_DEFAULT_DEV;
#elif defined(RASPBERRY_PI) #elif defined(RASPBERRY_PI)
std::string deviceName = ""; std::string deviceName = "";
#elif defined(EGSE)
std::string deviceName = "";
#endif #endif
int fd = 0; int fd = 0;
UnixFileGuard fileHelper(deviceName, &fd, O_RDWR, "SpiComIF::initializeInterface"); UnixFileGuard fileHelper(deviceName, &fd, O_RDWR, "SpiComIF::initializeInterface");
@ -638,72 +640,73 @@ void SpiTestClass::max1227PlPcduTest(int fd) {
} }
void SpiTestClass::acsInit() { void SpiTestClass::acsInit() {
using namespace gpio;
GpioCookie *gpioCookie = new GpioCookie(); GpioCookie *gpioCookie = new GpioCookie();
#ifdef RASPBERRY_PI #ifdef RASPBERRY_PI
GpiodRegularByChip *gpio = nullptr; GpiodRegularByChip *gpio = nullptr;
std::string rpiGpioName = "gpiochip0"; std::string rpiGpioName = "gpiochip0";
gpio = new GpiodRegularByChip(rpiGpioName, mgm0Lis3mdlChipSelect, "MGM_0_LIS3", gpio::DIR_OUT, gpio = new GpiodRegularByChip(rpiGpioName, mgm0Lis3mdlChipSelect, "MGM_0_LIS3", Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookie->addGpio(gpioIds::MGM_0_LIS3_CS, gpio); gpioCookie->addGpio(gpioIds::MGM_0_LIS3_CS, gpio);
gpio = new GpiodRegularByChip(rpiGpioName, mgm1Rm3100ChipSelect, "MGM_1_RM3100", gpio::DIR_OUT, gpio = new GpiodRegularByChip(rpiGpioName, mgm1Rm3100ChipSelect, "MGM_1_RM3100", Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookie->addGpio(gpioIds::MGM_1_RM3100_CS, gpio); gpioCookie->addGpio(gpioIds::MGM_1_RM3100_CS, gpio);
gpio = new GpiodRegularByChip(rpiGpioName, gyro0AdisChipSelect, "GYRO_0_ADIS", gpio::DIR_OUT, gpio = new GpiodRegularByChip(rpiGpioName, gyro0AdisChipSelect, "GYRO_0_ADIS", Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookie->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio); gpioCookie->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio);
gpio = new GpiodRegularByChip(rpiGpioName, gyro1L3gd20ChipSelect, "GYRO_1_L3G", gpio::DIR_OUT, gpio = new GpiodRegularByChip(rpiGpioName, gyro1L3gd20ChipSelect, "GYRO_1_L3G", Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookie->addGpio(gpioIds::GYRO_1_L3G_CS, gpio); gpioCookie->addGpio(gpioIds::GYRO_1_L3G_CS, gpio);
gpio = new GpiodRegularByChip(rpiGpioName, gyro3L3gd20ChipSelect, "GYRO_2_L3G", gpio::DIR_OUT, gpio = new GpiodRegularByChip(rpiGpioName, gyro3L3gd20ChipSelect, "GYRO_2_L3G", Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookie->addGpio(gpioIds::GYRO_3_L3G_CS, gpio); gpioCookie->addGpio(gpioIds::GYRO_3_L3G_CS, gpio);
gpio = new GpiodRegularByChip(rpiGpioName, mgm2Lis3mdlChipSelect, "MGM_2_LIS3", gpio::DIR_OUT, gpio = new GpiodRegularByChip(rpiGpioName, mgm2Lis3mdlChipSelect, "MGM_2_LIS3", Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookie->addGpio(gpioIds::MGM_2_LIS3_CS, gpio); gpioCookie->addGpio(gpioIds::MGM_2_LIS3_CS, gpio);
gpio = new GpiodRegularByChip(rpiGpioName, mgm3Rm3100ChipSelect, "MGM_3_RM3100", gpio::DIR_OUT, gpio = new GpiodRegularByChip(rpiGpioName, mgm3Rm3100ChipSelect, "MGM_3_RM3100", Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookie->addGpio(gpioIds::MGM_3_RM3100_CS, gpio); gpioCookie->addGpio(gpioIds::MGM_3_RM3100_CS, gpio);
#elif defined(XIPHOS_Q7S) #elif defined(XIPHOS_Q7S)
GpiodRegularByLineName *gpio = nullptr; GpiodRegularByLineName *gpio = nullptr;
gpio = gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_0_CS, "MGM_0_LIS3", Direction::OUT,
new GpiodRegularByLineName(q7s::gpioNames::MGM_0_CS, "MGM_0_LIS3", gpio::DIR_OUT, gpio::HIGH); Levels::HIGH);
gpioCookie->addGpio(gpioIds::MGM_0_LIS3_CS, gpio); gpioCookie->addGpio(gpioIds::MGM_0_LIS3_CS, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, "MGM_1_RM3100", gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, "MGM_1_RM3100", Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookie->addGpio(gpioIds::MGM_1_RM3100_CS, gpio); gpioCookie->addGpio(gpioIds::MGM_1_RM3100_CS, gpio);
gpio = gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_2_CS, "MGM_2_LIS3", Direction::OUT,
new GpiodRegularByLineName(q7s::gpioNames::MGM_2_CS, "MGM_2_LIS3", gpio::DIR_OUT, gpio::HIGH); Levels::HIGH);
gpioCookie->addGpio(gpioIds::MGM_2_LIS3_CS, gpio); gpioCookie->addGpio(gpioIds::MGM_2_LIS3_CS, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, "MGM_3_RM3100", gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, "MGM_3_RM3100", Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookie->addGpio(gpioIds::MGM_3_RM3100_CS, gpio); gpioCookie->addGpio(gpioIds::MGM_3_RM3100_CS, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ADIS_CS, "GYRO_0_ADIS", gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ADIS_CS, "GYRO_0_ADIS", Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookie->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio); gpioCookie->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_1_L3G_CS, "GYRO_1_L3G", gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_1_L3G_CS, "GYRO_1_L3G", Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookie->addGpio(gpioIds::GYRO_1_L3G_CS, gpio); gpioCookie->addGpio(gpioIds::GYRO_1_L3G_CS, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ADIS_CS, "GYRO_2_ADIS", gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ADIS_CS, "GYRO_2_ADIS", Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookie->addGpio(gpioIds::GYRO_2_ADIS_CS, gpio); gpioCookie->addGpio(gpioIds::GYRO_2_ADIS_CS, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_3_L3G_CS, "GYRO_3_L3G", gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_3_L3G_CS, "GYRO_3_L3G", Direction::OUT,
gpio::HIGH); Levels::HIGH);
gpioCookie->addGpio(gpioIds::GYRO_3_L3G_CS, gpio); gpioCookie->addGpio(gpioIds::GYRO_3_L3G_CS, gpio);
// Enable pins must be pulled low for regular operations // Enable pins must be pulled low for regular operations
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ENABLE, "GYRO_0_ENABLE", gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ENABLE, "GYRO_0_ENABLE", Direction::OUT,
gpio::LOW); Levels::LOW);
gpioCookie->addGpio(gpioIds::GYRO_0_ENABLE, gpio); gpioCookie->addGpio(gpioIds::GYRO_0_ENABLE, gpio);
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ENABLE, "GYRO_2_ENABLE", gpio::DIR_OUT, gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ENABLE, "GYRO_2_ENABLE", Direction::OUT,
gpio::LOW); Levels::LOW);
gpioCookie->addGpio(gpioIds::GYRO_2_ENABLE, gpio); gpioCookie->addGpio(gpioIds::GYRO_2_ENABLE, gpio);
#endif #endif
if (gpioIF != nullptr) { if (gpioIF != nullptr) {

View File

@ -1,3 +1,7 @@
if(EIVE_BUILD_GPSD_GPS_HANDLER)
target_sources(${OBSW_NAME} PRIVATE target_sources(${OBSW_NAME} PRIVATE
GPSHyperionLinuxController.cpp GPSHyperionLinuxController.cpp
) )
endif()
add_subdirectory(startracker)

View File

@ -2,9 +2,9 @@
#define MISSION_DEVICES_GPSHYPERIONHANDLER_H_ #define MISSION_DEVICES_GPSHYPERIONHANDLER_H_
#include "fsfw/FSFW.h" #include "fsfw/FSFW.h"
#include "mission/devices/devicedefinitions/GPSDefinitions.h"
#include "fsfw/controller/ExtendedControllerBase.h" #include "fsfw/controller/ExtendedControllerBase.h"
#include "fsfw/devicehandlers/DeviceHandlerBase.h" #include "fsfw/devicehandlers/DeviceHandlerBase.h"
#include "mission/devices/devicedefinitions/GPSDefinitions.h"
#ifdef FSFW_OSAL_LINUX #ifdef FSFW_OSAL_LINUX
#include <gps.h> #include <gps.h>

View File

@ -6,7 +6,7 @@ ArcsecDatalinkLayer::~ArcsecDatalinkLayer() {}
void ArcsecDatalinkLayer::slipInit() { void ArcsecDatalinkLayer::slipInit() {
slipInfo.buffer = rxBuffer; slipInfo.buffer = rxBuffer;
slipInfo.maxlength = StarTracker::MAX_FRAME_SIZE; slipInfo.maxlength = startracker::MAX_FRAME_SIZE;
slipInfo.length = 0; slipInfo.length = 0;
slipInfo.unescape_next = 0; slipInfo.unescape_next = 0;
slipInfo.prev_state = SLIP_COMPLETE; slipInfo.prev_state = SLIP_COMPLETE;

View File

@ -1,8 +1,8 @@
#ifndef BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ #ifndef BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_
#define BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ #define BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_
#include "StarTrackerDefinitions.h"
#include "fsfw/returnvalues/HasReturnvaluesIF.h" #include "fsfw/returnvalues/HasReturnvaluesIF.h"
#include "linux/devices/devicedefinitions/StarTrackerDefinitions.h"
extern "C" { extern "C" {
#include "common/misc.h" #include "common/misc.h"
@ -79,12 +79,12 @@ class ArcsecDatalinkLayer : public HasReturnvaluesIF {
static const uint8_t STATUS_OFFSET = 2; static const uint8_t STATUS_OFFSET = 2;
// Used by arcsec slip decoding function process received data // Used by arcsec slip decoding function process received data
uint8_t rxBuffer[StarTracker::MAX_FRAME_SIZE]; uint8_t rxBuffer[startracker::MAX_FRAME_SIZE];
// Decoded frame will be copied to this buffer // Decoded frame will be copied to this buffer
uint8_t decodedFrame[StarTracker::MAX_FRAME_SIZE]; uint8_t decodedFrame[startracker::MAX_FRAME_SIZE];
// Buffer where encoded frames will be stored. First byte of encoded frame represents type of // Buffer where encoded frames will be stored. First byte of encoded frame represents type of
// reply // reply
uint8_t encBuffer[StarTracker::MAX_FRAME_SIZE * 2 + 2]; uint8_t encBuffer[startracker::MAX_FRAME_SIZE * 2 + 2];
// Size of decoded frame // Size of decoded frame
uint32_t decFrameSize = 0; uint32_t decFrameSize = 0;
// Size of encoded frame // Size of encoded frame

View File

@ -28,6 +28,13 @@ static const char qx[] = "qx";
static const char qy[] = "qy"; static const char qy[] = "qy";
static const char qz[] = "qz"; static const char qz[] = "qz";
static const char IMAGE_PROCESSOR[] = "imageprocessor";
static const char IMAGE_PROCESSOR_MODE[] = "mode";
static const char STORE[] = "store";
static const char SIGNAL_THRESHOLD[] = "signalThreshold";
static const char IMAGE_PROCESSOR_DARK_THRESHOLD[] = "darkThreshold";
static const char BACKGROUND_COMPENSATION[] = "backgroundcompensation";
static const char CAMERA[] = "camera"; static const char CAMERA[] = "camera";
static const char MODE[] = "mode"; static const char MODE[] = "mode";
static const char FOCALLENGTH[] = "focallength"; static const char FOCALLENGTH[] = "focallength";
@ -53,7 +60,6 @@ static const char VAL_7[] = "val7";
static const char REG_8[] = "reg8"; static const char REG_8[] = "reg8";
static const char VAL_8[] = "val8"; static const char VAL_8[] = "val8";
static const char FREQ_1[] = "freq1"; static const char FREQ_1[] = "freq1";
static const char FREQ_2[] = "freq2";
static const char BLOB[] = "blob"; static const char BLOB[] = "blob";
static const char MIN_VALUE[] = "minValue"; static const char MIN_VALUE[] = "minValue";
@ -65,8 +71,8 @@ static const char MAX_TOTAL_VALUE[] = "maxTotalValue";
static const char MIN_BRIGHT_NEIGHBOURS[] = "minBrightNeighbours"; static const char MIN_BRIGHT_NEIGHBOURS[] = "minBrightNeighbours";
static const char MAX_BRIGHT_NEIGHBOURS[] = "maxBrightNeighbours"; static const char MAX_BRIGHT_NEIGHBOURS[] = "maxBrightNeighbours";
static const char MAX_PIXEL_TO_CONSIDER[] = "maxPixelsToConsider"; static const char MAX_PIXEL_TO_CONSIDER[] = "maxPixelsToConsider";
static const char SIGNAL_THRESHOLD[] = "signalThreshold"; // static const char SIGNAL_THRESHOLD[] = "signalThreshold";
static const char DARK_THRESHOLD[] = "darkThreshold"; static const char BLOB_DARK_THRESHOLD[] = "darkThreshold";
static const char ENABLE_HISTOGRAM[] = "enableHistogram"; static const char ENABLE_HISTOGRAM[] = "enableHistogram";
static const char ENABLE_CONTRAST[] = "enableContrast"; static const char ENABLE_CONTRAST[] = "enableContrast";
static const char BIN_MODE[] = "binMode"; static const char BIN_MODE[] = "binMode";
@ -74,6 +80,7 @@ static const char BIN_MODE[] = "binMode";
static const char CENTROIDING[] = "centroiding"; static const char CENTROIDING[] = "centroiding";
static const char ENABLE_FILTER[] = "enableFilter"; static const char ENABLE_FILTER[] = "enableFilter";
static const char MAX_QUALITY[] = "maxquality"; static const char MAX_QUALITY[] = "maxquality";
static const char DARK_THRESHOLD[] = "darkthreshold";
static const char MIN_QUALITY[] = "minquality"; static const char MIN_QUALITY[] = "minquality";
static const char MAX_INTENSITY[] = "maxintensity"; static const char MAX_INTENSITY[] = "maxintensity";
static const char MIN_INTENSITY[] = "minintensity"; static const char MIN_INTENSITY[] = "minintensity";
@ -86,6 +93,7 @@ static const char TRANSMATRIX_10[] = "transmatrix10";
static const char TRANSMATRIX_11[] = "transmatrix11"; static const char TRANSMATRIX_11[] = "transmatrix11";
static const char LISA[] = "lisa"; static const char LISA[] = "lisa";
static const char LISA_MODE[] = "mode";
static const char PREFILTER_DIST_THRESHOLD[] = "prefilterDistThreshold"; static const char PREFILTER_DIST_THRESHOLD[] = "prefilterDistThreshold";
static const char PREFILTER_ANGLE_THRESHOLD[] = "prefilterAngleThreshold"; static const char PREFILTER_ANGLE_THRESHOLD[] = "prefilterAngleThreshold";
static const char FOV_WIDTH[] = "fov_width"; static const char FOV_WIDTH[] = "fov_width";
@ -118,9 +126,56 @@ static const char TRACKER_CHOICE[] = "trackerChoice";
static const char ALGO[] = "algo"; static const char ALGO[] = "algo";
static const char L2T_MIN_CONFIDENCE[] = "l2t_minConfidence"; static const char L2T_MIN_CONFIDENCE[] = "l2t_minConfidence";
static const char L2T_MIN_MATCHED[] = "l2t_minConfidence"; static const char L2T_MIN_MATCHED[] = "l2t_minMatched";
static const char T2L_MIN_CONFIDENCE[] = "t2l_minConfidence"; static const char T2L_MIN_CONFIDENCE[] = "t2l_minConfidence";
static const char T2L_MIN_MATCHED[] = "t2l_minMatched"; static const char T2L_MIN_MATCHED[] = "t2l_minMatched";
static const char LOGLEVEL[] = "loglevel";
static const char LOGLEVEL1[] = "loglevel1";
static const char LOGLEVEL2[] = "loglevel2";
static const char LOGLEVEL3[] = "loglevel3";
static const char LOGLEVEL4[] = "loglevel4";
static const char LOGLEVEL5[] = "loglevel5";
static const char LOGLEVEL6[] = "loglevel6";
static const char LOGLEVEL7[] = "loglevel7";
static const char LOGLEVEL8[] = "loglevel8";
static const char LOGLEVEL9[] = "loglevel9";
static const char LOGLEVEL10[] = "loglevel10";
static const char LOGLEVEL11[] = "loglevel11";
static const char LOGLEVEL12[] = "loglevel12";
static const char LOGLEVEL13[] = "loglevel13";
static const char LOGLEVEL14[] = "loglevel14";
static const char LOGLEVEL15[] = "loglevel15";
static const char LOGLEVEL16[] = "loglevel16";
static const char SUBSCRIPTION[] = "subscription";
static const char TELEMETRY_1[] = "telemetry1";
static const char TELEMETRY_2[] = "telemetry2";
static const char TELEMETRY_3[] = "telemetry3";
static const char TELEMETRY_4[] = "telemetry4";
static const char TELEMETRY_5[] = "telemetry5";
static const char TELEMETRY_6[] = "telemetry6";
static const char TELEMETRY_7[] = "telemetry7";
static const char TELEMETRY_8[] = "telemetry8";
static const char TELEMETRY_9[] = "telemetry9";
static const char TELEMETRY_10[] = "telemetry10";
static const char TELEMETRY_11[] = "telemetry11";
static const char TELEMETRY_12[] = "telemetry12";
static const char TELEMETRY_13[] = "telemetry13";
static const char TELEMETRY_14[] = "telemetry14";
static const char TELEMETRY_15[] = "telemetry15";
static const char TELEMETRY_16[] = "telemetry16";
static const char LOG_SUBSCRIPTION[] = "logsubscription";
static const char LEVEL1[] = "level1";
static const char MODULE1[] = "module1";
static const char LEVEL2[] = "level2";
static const char MODULE2[] = "module2";
static const char DEBUG_CAMERA[] = "debugcamera";
static const char TIMING[] = "timing";
static const char TEST[] = "test";
} // namespace arcseckeys } // namespace arcseckeys
#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_ARCSECJSONKEYS_H_ */ #endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_ARCSECJSONKEYS_H_ */

View File

@ -8,9 +8,15 @@ ReturnValue_t ArcsecJsonParamBase::create(std::string fullname, uint8_t* buffer)
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
result = init(fullname); result = init(fullname);
if (result != RETURN_OK) { if (result != RETURN_OK) {
sif::warning << "ArcsecJsonParamBase::create: Failed to init parameter command for set "
<< setName << std::endl;
return result; return result;
} }
result = createCommand(buffer); result = createCommand(buffer);
if (result != RETURN_OK) {
sif::warning << "ArcsecJsonParamBase::create: Failed to create parameter command for set "
<< setName << std::endl;
}
return result; return result;
} }
@ -91,5 +97,7 @@ ReturnValue_t ArcsecJsonParamBase::initSet() {
return RETURN_OK; return RETURN_OK;
} }
} }
sif::warning << "ArcsecJsonParamBase::initSet: Set " << setName << "not present in json file"
<< std::endl;
return SET_NOT_EXISTS; return SET_NOT_EXISTS;
} }

View File

@ -5,8 +5,8 @@
#include <fstream> #include <fstream>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include "StarTrackerDefinitions.h"
#include "fsfw/returnvalues/HasReturnvaluesIF.h" #include "fsfw/returnvalues/HasReturnvaluesIF.h"
#include "linux/devices/devicedefinitions/StarTrackerDefinitions.h"
extern "C" { extern "C" {
#include "thirdparty/arcsec_star_tracker/common/generated/tmtcstructs.h" #include "thirdparty/arcsec_star_tracker/common/generated/tmtcstructs.h"

File diff suppressed because it is too large Load Diff

View File

@ -5,11 +5,12 @@
#include "ArcsecDatalinkLayer.h" #include "ArcsecDatalinkLayer.h"
#include "ArcsecJsonParamBase.h" #include "ArcsecJsonParamBase.h"
#include "StarTrackerDefinitions.h" #include "OBSWConfig.h"
#include "StrHelper.h" #include "StrHelper.h"
#include "fsfw/devicehandlers/DeviceHandlerBase.h" #include "fsfw/devicehandlers/DeviceHandlerBase.h"
#include "fsfw/src/fsfw/serialize/SerializeAdapter.h" #include "fsfw/src/fsfw/serialize/SerializeAdapter.h"
#include "fsfw/timemanager/Countdown.h" #include "fsfw/timemanager/Countdown.h"
#include "linux/devices/devicedefinitions/StarTrackerDefinitions.h"
#include "thirdparty/arcsec_star_tracker/common/SLIP.h" #include "thirdparty/arcsec_star_tracker/common/SLIP.h"
/** /**
@ -47,6 +48,11 @@ class StarTrackerHandler : public DeviceHandlerBase {
void performOperationHook() override; void performOperationHook() override;
Submode_t getInitialSubmode() override;
static const Submode_t SUBMODE_BOOTLOADER = 1;
static const Submode_t SUBMODE_FIRMWARE = 2;
protected: protected:
void doStartUp() override; void doStartUp() override;
void doShutDown() override; void doShutDown() override;
@ -56,6 +62,7 @@ class StarTrackerHandler : public DeviceHandlerBase {
void fillCommandAndReplyMap() override; void fillCommandAndReplyMap() override;
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData, ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData,
size_t commandDataLen) override; size_t commandDataLen) override;
ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override;
ReturnValue_t scanForReply(const uint8_t* start, size_t remainingSize, DeviceCommandId_t* foundId, ReturnValue_t scanForReply(const uint8_t* start, size_t remainingSize, DeviceCommandId_t* foundId,
size_t* foundLen) override; size_t* foundLen) override;
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) override; ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) override;
@ -68,78 +75,76 @@ class StarTrackerHandler : public DeviceHandlerBase {
*/ */
virtual size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override; virtual size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override;
virtual ReturnValue_t doSendReadHook() override; virtual ReturnValue_t doSendReadHook() override;
virtual void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override;
private: private:
static const uint8_t INTERFACE_ID = CLASS_ID::STR_HANDLER; static const uint8_t INTERFACE_ID = CLASS_ID::STR_HANDLER;
//! [EXPORT] : [COMMENT] Received reply is too short
static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xB0);
//! [EXPORT] : [COMMENT] Received reply with invalid CRC
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xB1);
//! [EXPORT] : [COMMENT] Image loader executing
static const ReturnValue_t IMAGE_LOADER_EXECUTING = MAKE_RETURN_CODE(0xB2);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HANDLER;
//! [EXPORT] : [COMMENT] Status in temperature reply signals error //! [EXPORT] : [COMMENT] Status in temperature reply signals error
static const ReturnValue_t TEMPERATURE_REQ_FAILED = MAKE_RETURN_CODE(0xA0); static const ReturnValue_t TEMPERATURE_REQ_FAILED = MAKE_RETURN_CODE(0xA0);
//! [EXPORT] : [COMMENT] Ping command failed //! [EXPORT] : [COMMENT] Ping command failed
static const ReturnValue_t PING_FAILED = MAKE_RETURN_CODE(0xA1); static const ReturnValue_t PING_FAILED = MAKE_RETURN_CODE(0xA1);
//! [EXPORT] : [COMMENT] Status in version reply signals error //! [EXPORT] : [COMMENT] Status in version reply signals error
static const ReturnValue_t VERSION_REQ_FAILED = MAKE_RETURN_CODE(0xA3); static const ReturnValue_t VERSION_REQ_FAILED = MAKE_RETURN_CODE(0xA2);
//! [EXPORT] : [COMMENT] Status in interface reply signals error //! [EXPORT] : [COMMENT] Status in interface reply signals error
static const ReturnValue_t INTERFACE_REQ_FAILED = MAKE_RETURN_CODE(0xA4); static const ReturnValue_t INTERFACE_REQ_FAILED = MAKE_RETURN_CODE(0xA3);
//! [EXPORT] : [COMMENT] Status in power reply signals error //! [EXPORT] : [COMMENT] Status in power reply signals error
static const ReturnValue_t POWER_REQ_FAILED = MAKE_RETURN_CODE(0xA5); static const ReturnValue_t POWER_REQ_FAILED = MAKE_RETURN_CODE(0xA4);
//! [EXPORT] : [COMMENT] Status of reply to parameter set command signals error //! [EXPORT] : [COMMENT] Status of reply to parameter set command signals error
static const ReturnValue_t SET_PARAM_FAILED = MAKE_RETURN_CODE(0xA6); static const ReturnValue_t SET_PARAM_FAILED = MAKE_RETURN_CODE(0xA5);
//! [EXPORT] : [COMMENT] Status of reply to action command signals error //! [EXPORT] : [COMMENT] Status of reply to action command signals error
static const ReturnValue_t ACTION_FAILED = MAKE_RETURN_CODE(0xA7); static const ReturnValue_t ACTION_FAILED = MAKE_RETURN_CODE(0xA6);
//! [EXPORT] : [COMMENT] Received upload image command with invalid length
static const ReturnValue_t UPLOAD_TOO_SHORT = MAKE_RETURN_CODE(0xA8);
//! [EXPORT] : [COMMENT] Received upload image command with invalid position field
static const ReturnValue_t UPLOAD_INVALID_POSITION = MAKE_RETURN_CODE(0xA8);
//! [EXPORT] : [COMMENT] Position value in upload image reply not matching sent position
static const ReturnValue_t UPLOAD_IMAGE_FAILED = MAKE_RETURN_CODE(0xA9);
//! [EXPORT] : [COMMENT] Received upload image command with invalid length
static const ReturnValue_t INVALID_UPLOAD_COMMAND = MAKE_RETURN_CODE(0xAA);
//! [EXPORT] : [COMMENT] Received invalid path string. Exceeds allowed length //! [EXPORT] : [COMMENT] Received invalid path string. Exceeds allowed length
static const ReturnValue_t FILE_PATH_TOO_LONG = MAKE_RETURN_CODE(0xAB); static const ReturnValue_t FILE_PATH_TOO_LONG = MAKE_RETURN_CODE(0xA7);
//! [EXPORT] : [COMMENT] Name of file received with command is too long //! [EXPORT] : [COMMENT] Name of file received with command is too long
static const ReturnValue_t FILENAME_TOO_LONG = MAKE_RETURN_CODE(0xAC); static const ReturnValue_t FILENAME_TOO_LONG = MAKE_RETURN_CODE(0xA8);
//! [EXPORT] : [COMMENT] Received version reply with invalid program ID //! [EXPORT] : [COMMENT] Received version reply with invalid program ID
static const ReturnValue_t INVALID_PROGRAM = MAKE_RETURN_CODE(0xAD); static const ReturnValue_t INVALID_PROGRAM = MAKE_RETURN_CODE(0xA9);
//! [EXPORT] : [COMMENT] Status field reply signals error //! [EXPORT] : [COMMENT] Status field reply signals error
static const ReturnValue_t REPLY_ERROR = MAKE_RETURN_CODE(0xAE); static const ReturnValue_t REPLY_ERROR = MAKE_RETURN_CODE(0xAA);
//! [EXPORT] : [COMMENT] Status field of contrast reply signals error
static const ReturnValue_t CONTRAST_REQ_FAILED = MAKE_RETURN_CODE(0xAE);
//! [EXPORT] : [COMMENT] Received command which is too short (some data is missing for proper //! [EXPORT] : [COMMENT] Received command which is too short (some data is missing for proper
//! execution) //! execution)
static const ReturnValue_t COMMAND_TOO_SHORT = MAKE_RETURN_CODE(0xAF); static const ReturnValue_t COMMAND_TOO_SHORT = MAKE_RETURN_CODE(0xAB);
//! [EXPORT] : [COMMENT] Received command with invalid length (too few or too many parameters) //! [EXPORT] : [COMMENT] Received command with invalid length (too few or too many parameters)
static const ReturnValue_t INVALID_LENGTH = MAKE_RETURN_CODE(0xB0); static const ReturnValue_t INVALID_LENGTH = MAKE_RETURN_CODE(0xAC);
//! [EXPORT] : [COMMENT] Region mismatch between send and received data //! [EXPORT] : [COMMENT] Region mismatch between send and received data
static const ReturnValue_t REGION_MISMATCH = MAKE_RETURN_CODE(0xB1); static const ReturnValue_t REGION_MISMATCH = MAKE_RETURN_CODE(0xAD);
//! [EXPORT] : [COMMENT] Address mismatch between send and received data //! [EXPORT] : [COMMENT] Address mismatch between send and received data
static const ReturnValue_t ADDRESS_MISMATCH = MAKE_RETURN_CODE(0xB2); static const ReturnValue_t ADDRESS_MISMATCH = MAKE_RETURN_CODE(0xAE);
//! [EXPORT] : [COMMENT] Length field mismatch between send and received data //! [EXPORT] : [COMMENT] Length field mismatch between send and received data
static const ReturnValue_t lENGTH_MISMATCH = MAKE_RETURN_CODE(0xB3); static const ReturnValue_t lENGTH_MISMATCH = MAKE_RETURN_CODE(0xAF);
//! [EXPORT] : [COMMENT] Specified file does not exist //! [EXPORT] : [COMMENT] Specified file does not exist
static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xB4); static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xB0);
//! [EXPORT] : [COMMENT] Reply to upload centroid does not match commanded centroid id
static const ReturnValue_t UPLOAD_CENTROID_ID_MISMATCH = MAKE_RETURN_CODE(0xB5);
//! [EXPORT] : [COMMENT] Download blob pixel command has invalid type field //! [EXPORT] : [COMMENT] Download blob pixel command has invalid type field
static const ReturnValue_t INVALID_TYPE = MAKE_RETURN_CODE(0xB6); static const ReturnValue_t INVALID_TYPE = MAKE_RETURN_CODE(0xB1);
//! [EXPORT] : [COMMENT] Received FPGA action command with invalid ID //! [EXPORT] : [COMMENT] Received FPGA action command with invalid ID
static const ReturnValue_t INVALID_ID = MAKE_RETURN_CODE(0xB7); static const ReturnValue_t INVALID_ID = MAKE_RETURN_CODE(0xB2);
//! [EXPORT] : [COMMENT] Received reply is too short
static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xB3);
//! [EXPORT] : [COMMENT] Received reply with invalid CRC
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xB4);
//! [EXPORT] : [COMMENT] Star tracker handler currently executing a command and using the
//! communication interface
static const ReturnValue_t STR_HELPER_EXECUTING = MAKE_RETURN_CODE(0xB5);
//! [EXPORT] : [COMMENT] Star tracker is already in firmware mode
static const ReturnValue_t STARTRACKER_ALREADY_BOOTED = MAKE_RETURN_CODE(0xB6);
//! [EXPORT] : [COMMENT] Star tracker is in firmware mode but must be in bootloader mode to
//! execute this command
static const ReturnValue_t STARTRACKER_RUNNING_FIRMWARE = MAKE_RETURN_CODE(0xB7);
//! [EXPORT] : [COMMENT] Star tracker is in bootloader mode but must be in firmware mode to
//! execute this command
static const ReturnValue_t STARTRACKER_RUNNING_BOOTLOADER = MAKE_RETURN_CODE(0xB8);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HANDLER;
//! [EXPORT] : [COMMENT] Failed to boot firmware
static const Event BOOTING_FIRMWARE_FAILED = MAKE_EVENT(1, severity::LOW);
//! [EXPORT] : [COMMENT] Failed to boot star tracker into bootloader mode
static const Event BOOTING_BOOTLOADER_FAILED = MAKE_EVENT(2, severity::LOW);
static const size_t MAX_PATH_SIZE = 50; static const size_t MAX_PATH_SIZE = 50;
static const size_t MAX_FILE_NAME = 30; static const size_t MAX_FILE_NAME = 30;
// position (uint32) + 1024 image data
static const size_t UPLOAD_COMMAND_LEN = 1028;
// Max valid position value in upload image command
static const uint16_t MAX_POSITION = 4095;
static const uint8_t STATUS_OFFSET = 1; static const uint8_t STATUS_OFFSET = 1;
static const uint8_t PARAMS_OFFSET = 1; static const uint8_t PARAMS_OFFSET = 1;
static const uint8_t TICKS_OFFSET = 2; static const uint8_t TICKS_OFFSET = 2;
@ -154,37 +159,14 @@ class StarTrackerHandler : public DeviceHandlerBase {
static const MutexIF::TimeoutType TIMEOUT_TYPE = MutexIF::TimeoutType::WAITING; static const MutexIF::TimeoutType TIMEOUT_TYPE = MutexIF::TimeoutType::WAITING;
static const uint32_t MUTEX_TIMEOUT = 20; static const uint32_t MUTEX_TIMEOUT = 20;
static const uint32_t BOOT_TIMEOUT = 1000; static const uint32_t BOOT_TIMEOUT = 1000;
static const uint32_t DEFAULT_TRANSITION_DELAY = 15000;
class WriteCmd { class FlashReadCmd {
public: public:
static const uint8_t ADDRESS_OFFSET = 1; // Minimum length of a read command (region, length and filename)
static const uint8_t FILE_OFFSET = 5;
// Minimum length of a write command (region, address and filename)
static const size_t MIN_LENGTH = 7; static const size_t MIN_LENGTH = 7;
}; };
class ReadCmd {
public:
static const uint8_t ADDRESS_OFFSET = 1;
static const uint8_t LENGTH_OFFSET = 5;
static const uint8_t FILE_OFFSET = 9;
// Minimum length of a read command (region, address, length and filename)
static const size_t MIN_LENGTH = 11;
};
class EraseCmd {
public:
static const uint8_t LENGTH = 1;
uint8_t rememberRegion = 0;
};
EraseCmd eraseCmd;
class UnlockCmd {
public:
static const uint8_t CODE_OFFSET = 1;
};
class ChecksumCmd { class ChecksumCmd {
public: public:
static const uint8_t ADDRESS_OFFSET = 1; static const uint8_t ADDRESS_OFFSET = 1;
@ -198,94 +180,69 @@ class StarTrackerHandler : public DeviceHandlerBase {
ChecksumCmd checksumCmd; ChecksumCmd checksumCmd;
class SetTimeCmd {
public:
static const uint8_t LENGTH = 8;
};
class DownloadCentroidCmd {
public:
static const uint8_t LENGTH = 1;
};
class UploadCentroid {
public:
uint8_t rememberId = 0;
};
UploadCentroid uploadCentroid;
class DownloadMatchedStarCmd {
public:
static const uint8_t LENGTH = 1;
};
class DownloadDbImageCmd {
public:
static const uint8_t LENGTH = 1;
};
class DownloadBlobPixCmd {
public:
static const uint8_t LENGTH = 2;
static const uint8_t NORMAL = 0;
static const uint8_t FAST = 1;
};
class FpgaDownloadCmd {
public:
static const uint8_t MIN_LENGTH = 10;
};
class FpgaActionCmd {
public:
static const uint8_t LENGTH = 1;
static const uint8_t ID = 3;
};
MessageQueueIF* eventQueue = nullptr; MessageQueueIF* eventQueue = nullptr;
ArcsecDatalinkLayer dataLinkLayer; ArcsecDatalinkLayer dataLinkLayer;
StarTracker::TemperatureSet temperatureSet; startracker::TemperatureSet temperatureSet;
StarTracker::VersionSet versionSet; startracker::VersionSet versionSet;
StarTracker::PowerSet powerSet; startracker::PowerSet powerSet;
StarTracker::InterfaceSet interfaceSet; startracker::InterfaceSet interfaceSet;
StarTracker::TimeSet timeSet; startracker::TimeSet timeSet;
StarTracker::SolutionSet solutionSet; startracker::SolutionSet solutionSet;
StarTracker::HistogramSet histogramSet; startracker::HistogramSet histogramSet;
StarTracker::ContrastSet contrastSet; startracker::ChecksumSet checksumSet;
StarTracker::ChecksumSet checksumSet; startracker::CameraSet cameraSet;
StarTracker::DownloadCentroidSet downloadCentroidSet; startracker::LimitsSet limitsSet;
StarTracker::DownloadMatchedStar downloadMatchedStar; startracker::LogLevelSet loglevelSet;
StarTracker::DownloadDBImage downloadDbImage; startracker::MountingSet mountingSet;
StarTracker::DownloadBlobPixel downloadBlobPixel; startracker::ImageProcessorSet imageProcessorSet;
StarTracker::CameraSet cameraSet; startracker::CentroidingSet centroidingSet;
StarTracker::LimitsSet limitsSet; startracker::LisaSet lisaSet;
StarTracker::BlobSet blobSet; startracker::MatchingSet matchingSet;
startracker::TrackingSet trackingSet;
startracker::ValidationSet validationSet;
startracker::AlgoSet algoSet;
startracker::SubscriptionSet subscriptionSet;
startracker::LogSubscriptionSet logSubscriptionSet;
startracker::DebugCameraSet debugCameraSet;
// Pointer to object responsible for uploading and downloading images to/from the star tracker // Pointer to object responsible for uploading and downloading images to/from the star tracker
StrHelper* strHelper = nullptr; StrHelper* strHelper = nullptr;
uint8_t commandBuffer[StarTracker::MAX_FRAME_SIZE]; uint8_t commandBuffer[startracker::MAX_FRAME_SIZE];
// Countdown to insert delay for star tracker to switch from bootloader to firmware program // Countdown to insert delay for star tracker to switch from bootloader to firmware program
// Loading firmware requires some time and the command will not trigger a reply when executed
Countdown bootCountdown; Countdown bootCountdown;
std::string paramJsonFile = "/mnt/sd0/startracker/full.json"; #ifdef EGSE
std::string paramJsonFile = "/home/pi/arcsec/json/flight-config.json";
#else
#if OBSW_STAR_TRACKER_GROUND_CONFIG == 1
std::string paramJsonFile = "/mnt/sd0/startracker/ground-config.json";
#else
std::string paramJsonFile = "/mnt/sd0/startracker/flight-config.json";
#endif
#endif
enum class InternalState { TEMPERATURE_REQUEST }; enum class NormalState { TEMPERATURE_REQUEST, SOLUTION_REQUEST };
InternalState internalState = InternalState::TEMPERATURE_REQUEST; NormalState normalState = NormalState::TEMPERATURE_REQUEST;
enum class StartupState { enum class InternalState {
IDLE, IDLE,
CHECK_BOOT_STATE,
BOOT, BOOT,
REQ_VERSION,
VERIFY_BOOT,
STARTUP_CHECK,
BOOT_DELAY, BOOT_DELAY,
FIRMWARE_CHECK,
LOGLEVEL,
LIMITS, LIMITS,
TRACKING, TRACKING,
MOUNTING, MOUNTING,
IMAGE_PROCESSOR,
CAMERA, CAMERA,
BLOB, BLOB,
CENTROIDING, CENTROIDING,
@ -293,10 +250,20 @@ class StarTrackerHandler : public DeviceHandlerBase {
MATCHING, MATCHING,
VALIDATION, VALIDATION,
ALGO, ALGO,
LOG_SUBSCRIPTION,
DEBUG_CAMERA,
WAIT_FOR_EXECUTION, WAIT_FOR_EXECUTION,
DONE DONE,
FAILED_FIRMWARE_BOOT,
BOOT_BOOTLOADER,
BOOTLOADER_CHECK,
BOOTING_BOOTLOADER_FAILED
}; };
InternalState internalState = InternalState::IDLE;
enum class StartupState { IDLE, CHECK_PROGRAM, WAIT_CHECK_PROGRAM, BOOT_BOOTLOADER, DONE };
StartupState startupState = StartupState::IDLE; StartupState startupState = StartupState::IDLE;
bool strHelperExecuting = false; bool strHelperExecuting = false;
@ -338,24 +305,6 @@ class StarTrackerHandler : public DeviceHandlerBase {
*/ */
void handleEvent(EventMessage* eventMessage); void handleEvent(EventMessage* eventMessage);
/**
* @brief Executes the write command
*
* @param commandData Pointer to received command data
* @param commandDataLen Size of received command data
*
* @return RETURN_OK if start of execution was successful, otherwise error return value
*/
ReturnValue_t executeWriteCommand(const uint8_t* commandData, size_t commandDataLen);
/**
* @brief Starts the execution of the fpga download command
*
* @param commandData Pointer to buffer with command data
* @param commandDataLen Size of received command
*/
ReturnValue_t executeFpgaDownloadCommand(const uint8_t* commandData, size_t commandDataLen);
/** /**
* @brief Extracts information for flash-read-command from TC data and starts execution of * @brief Extracts information for flash-read-command from TC data and starts execution of
* flash-read-procedure * flash-read-procedure
@ -365,7 +314,7 @@ class StarTrackerHandler : public DeviceHandlerBase {
* *
* @return RETURN_OK if start of execution was successful, otherwise error return value * @return RETURN_OK if start of execution was successful, otherwise error return value
*/ */
ReturnValue_t executeReadCommand(const uint8_t* commandData, size_t commandDataLen); ReturnValue_t executeFlashReadCommand(const uint8_t* commandData, size_t commandDataLen);
/** /**
* @brief Fills command buffer with data to boot image (works only when star tracker is * @brief Fills command buffer with data to boot image (works only when star tracker is
@ -373,36 +322,11 @@ class StarTrackerHandler : public DeviceHandlerBase {
*/ */
void prepareBootCommand(); void prepareBootCommand();
/**
* @brief Fills command buffer with command to erase a flash region
*/
ReturnValue_t prepareEraseCommand(const uint8_t* commandData, size_t commandDataLen);
/**
* @brief Fills command buffer with command to unlock flash region
*/
ReturnValue_t prepareUnlockCommand(const uint8_t* commandData, size_t commandDataLen);
/** /**
* @brief Fills command buffer with command to get the checksum of a flash part * @brief Fills command buffer with command to get the checksum of a flash part
*/ */
ReturnValue_t prepareChecksumCommand(const uint8_t* commandData, size_t commandDataLen); ReturnValue_t prepareChecksumCommand(const uint8_t* commandData, size_t commandDataLen);
/**
* @brief Fills command buffer with command to set the unix time
*/
ReturnValue_t prepareSetTimeCommand(const uint8_t* commandData, size_t commandDataLen);
/**
* @brief Fills command buffer with command to request a centroid
*/
ReturnValue_t prepareDownloadCentroidCommand(const uint8_t* commandData, size_t commandDataLen);
/**
* @brief Fills command buffer with command to upload a centroid for testing purpose
*/
ReturnValue_t prepareUploadCentroidCommand(const uint8_t* commandData, size_t commandDataLen);
/** /**
* @brief Fills the command buffer with the command to take an image. * @brief Fills the command buffer with the command to take an image.
*/ */
@ -426,7 +350,7 @@ class StarTrackerHandler : public DeviceHandlerBase {
/** /**
* @brief Fills command buffer with data to reboot star tracker. * @brief Fills command buffer with data to reboot star tracker.
*/ */
void prepareRebootCommand(); void prepareSwitchToBootloaderCmd();
/** /**
* @brief Fills command buffer with data to subscribe to a telemetry packet. * @brief Fills command buffer with data to subscribe to a telemetry packet.
@ -451,13 +375,6 @@ class StarTrackerHandler : public DeviceHandlerBase {
*/ */
void prepareHistogramRequest(); void prepareHistogramRequest();
void prepareContrastRequest();
/**
* @brief Fills command buffer with command to reset the error signal of the star tracker
*/
void prepareErrorResetRequest();
/** /**
* @brief Reads parameters from json file specified by string in commandData and * @brief Reads parameters from json file specified by string in commandData and
* prepares the command to apply the parameter set to the star tracker * prepares the command to apply the parameter set to the star tracker
@ -472,40 +389,23 @@ class StarTrackerHandler : public DeviceHandlerBase {
ArcsecJsonParamBase& paramSet); ArcsecJsonParamBase& paramSet);
/** /**
* @brief Fills command buffer with data to request matched star. * @brief The following function will fill the command buffer with the command to request
*/ * a parameter set.
ReturnValue_t prepareDownloadMatchedStarCommand(const uint8_t* commandData,
size_t commandDataLen);
/**
* @brief Fills command buffer with data to request matched star coordinates.
*/
ReturnValue_t prepareDownloadDbImageCommand(const uint8_t* commandData, size_t commandDataLen);
/**
* @brief Fills command buffer with data to request output of the blob filter algorithm.
*/
ReturnValue_t prepareDownloadBlobPixelCommand(const uint8_t* commandData, size_t commandDataLen);
/**
* @brief With this command the FPGA update will be applied to the star tracker
*/
ReturnValue_t prepareFpgaActionCommand(const uint8_t* commandData, size_t commandDataLen);
/**
* @brief Will fill the command buffer with the command to request the set camera parameters.
*/ */
ReturnValue_t prepareRequestCameraParams(); ReturnValue_t prepareRequestCameraParams();
/**
* @brief Will fill the command buffer with the command to request the set limits.
*/
ReturnValue_t prepareRequestLimitsParams(); ReturnValue_t prepareRequestLimitsParams();
ReturnValue_t prepareRequestLogLevelParams();
/** ReturnValue_t prepareRequestMountingParams();
* @brief Will fill the command buffer with the command to request the set blob parameters. ReturnValue_t prepareRequestImageProcessorParams();
*/ ReturnValue_t prepareRequestCentroidingParams();
ReturnValue_t prepareRequestBlobParams(); ReturnValue_t prepareRequestLisaParams();
ReturnValue_t prepareRequestMatchingParams();
ReturnValue_t prepareRequestTrackingParams();
ReturnValue_t prepareRequestValidationParams();
ReturnValue_t prepareRequestAlgoParams();
ReturnValue_t prepareRequestSubscriptionParams();
ReturnValue_t prepareRequestLogSubscriptionParams();
ReturnValue_t prepareRequestDebugCameraParams();
/** /**
* @brief Handles action replies with datasets. * @brief Handles action replies with datasets.
@ -522,11 +422,6 @@ class StarTrackerHandler : public DeviceHandlerBase {
*/ */
ReturnValue_t handleUploadCentroidReply(); ReturnValue_t handleUploadCentroidReply();
/**
* @brief Handles reply to erase command
*/
ReturnValue_t handleEraseReply();
/** /**
* @brief Handles reply to checksum command * @brief Handles reply to checksum command
*/ */
@ -560,6 +455,20 @@ class StarTrackerHandler : public DeviceHandlerBase {
* @return RETURN_OK if successful, otherwise error return value * @return RETURN_OK if successful, otherwise error return value
*/ */
ReturnValue_t handleTm(LocalPoolDataSetBase& dataset, size_t size); ReturnValue_t handleTm(LocalPoolDataSetBase& dataset, size_t size);
/**
* @brief Checks if star tracker is in valid mode for executing the received command.
*
* @param actioId Id of received command
*
* @return RETURN_OK if star tracker is in valid mode, otherwise error return value
*/
ReturnValue_t checkCommand(ActionId_t actionId);
void doOnTransition(Submode_t subModeFrom);
void doNormalTransition(Mode_t modeFrom, Submode_t subModeFrom);
void bootFirmware(Mode_t toMode);
void bootBootloader();
}; };
#endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */ #endif /* MISSION_DEVICES_STARTRACKERHANDLER_H_ */

View File

@ -10,7 +10,7 @@ ReturnValue_t Limits::createCommand(uint8_t* buffer) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
uint8_t offset = 0; uint8_t offset = 0;
std::string param; std::string param;
addSetParamHeader(buffer, StarTracker::ID::LIMITS); addSetParamHeader(buffer, startracker::ID::LIMITS);
offset = 2; offset = 2;
result = getParam(arcseckeys::ACTION, param); result = getParam(arcseckeys::ACTION, param);
if (result != RETURN_OK) { if (result != RETURN_OK) {
@ -88,7 +88,7 @@ ReturnValue_t Tracking::createCommand(uint8_t* buffer) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
uint8_t offset = 0; uint8_t offset = 0;
std::string param; std::string param;
addSetParamHeader(buffer, StarTracker::ID::TRACKING); addSetParamHeader(buffer, startracker::ID::TRACKING);
offset = 2; offset = 2;
result = getParam(arcseckeys::THIN_LIMIT, param); result = getParam(arcseckeys::THIN_LIMIT, param);
if (result != RETURN_OK) { if (result != RETURN_OK) {
@ -124,7 +124,7 @@ ReturnValue_t Mounting::createCommand(uint8_t* buffer) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
uint8_t offset = 0; uint8_t offset = 0;
std::string param; std::string param;
addSetParamHeader(buffer, StarTracker::ID::MOUNTING); addSetParamHeader(buffer, startracker::ID::MOUNTING);
offset = 2; offset = 2;
result = getParam(arcseckeys::qw, param); result = getParam(arcseckeys::qw, param);
if (result != RETURN_OK) { if (result != RETURN_OK) {
@ -152,6 +152,48 @@ ReturnValue_t Mounting::createCommand(uint8_t* buffer) {
return RETURN_OK; return RETURN_OK;
} }
ImageProcessor::ImageProcessor() : ArcsecJsonParamBase(arcseckeys::IMAGE_PROCESSOR) {}
size_t ImageProcessor::getSize() { return COMMAND_SIZE; }
ReturnValue_t ImageProcessor::createCommand(uint8_t* buffer) {
ReturnValue_t result = RETURN_OK;
uint8_t offset = 0;
std::string param;
addSetParamHeader(buffer, startracker::ID::IMAGE_PROCESSOR);
offset = 2;
result = getParam(arcseckeys::IMAGE_PROCESSOR_MODE, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::STORE, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::SIGNAL_THRESHOLD, param);
if (result != RETURN_OK) {
return result;
}
adduint16(param, buffer + offset);
offset += sizeof(uint16_t);
result = getParam(arcseckeys::IMAGE_PROCESSOR_DARK_THRESHOLD, param);
if (result != RETURN_OK) {
return result;
}
adduint16(param, buffer + offset);
offset += sizeof(uint16_t);
result = getParam(arcseckeys::BACKGROUND_COMPENSATION, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
return RETURN_OK;
}
Camera::Camera() : ArcsecJsonParamBase(arcseckeys::CAMERA) {} Camera::Camera() : ArcsecJsonParamBase(arcseckeys::CAMERA) {}
size_t Camera::getSize() { return COMMAND_SIZE; } size_t Camera::getSize() { return COMMAND_SIZE; }
@ -160,7 +202,7 @@ ReturnValue_t Camera::createCommand(uint8_t* buffer) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
uint8_t offset = 0; uint8_t offset = 0;
std::string param; std::string param;
addSetParamHeader(buffer, StarTracker::ID::CAMERA); addSetParamHeader(buffer, startracker::ID::CAMERA);
offset = 2; offset = 2;
result = getParam(arcseckeys::MODE, param); result = getParam(arcseckeys::MODE, param);
if (result != RETURN_OK) { if (result != RETURN_OK) {
@ -304,116 +346,7 @@ ReturnValue_t Camera::createCommand(uint8_t* buffer) {
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }
addfloat(param, buffer + offset);
offset += sizeof(float);
result = getParam(arcseckeys::FREQ_2, param);
if (result != RETURN_OK) {
return result;
}
addfloat(param, buffer + offset);
return RETURN_OK;
}
Blob::Blob() : ArcsecJsonParamBase(arcseckeys::BLOB) {}
size_t Blob::getSize() { return COMMAND_SIZE; }
ReturnValue_t Blob::createCommand(uint8_t* buffer) {
ReturnValue_t result = RETURN_OK;
uint8_t offset = 0;
std::string param;
addSetParamHeader(buffer, StarTracker::ID::BLOB);
offset = 2;
result = getParam(arcseckeys::MODE, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::MIN_VALUE, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::MIN_DISTANCE, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::NEIGHBOUR_DISTANCE, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::NEIGHBOUR_BRIGHT_PIXELS, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::MIN_TOTAL_VALUE, param);
if (result != RETURN_OK) {
return result;
}
adduint16(param, buffer + offset);
offset += sizeof(uint16_t);
result = getParam(arcseckeys::MAX_TOTAL_VALUE, param);
if (result != RETURN_OK) {
return result;
}
adduint16(param, buffer + offset);
offset += sizeof(uint16_t);
result = getParam(arcseckeys::MIN_BRIGHT_NEIGHBOURS, param);
if (result != RETURN_OK) {
return result;
}
adduint16(param, buffer + offset);
offset += sizeof(uint16_t);
result = getParam(arcseckeys::MAX_BRIGHT_NEIGHBOURS, param);
if (result != RETURN_OK) {
return result;
}
adduint16(param, buffer + offset);
offset += sizeof(uint16_t);
result = getParam(arcseckeys::MAX_PIXEL_TO_CONSIDER, param);
if (result != RETURN_OK) {
return result;
}
adduint32(param, buffer + offset); adduint32(param, buffer + offset);
offset += sizeof(uint32_t);
result = getParam(arcseckeys::SIGNAL_THRESHOLD, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::DARK_THRESHOLD, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::ENABLE_HISTOGRAM, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::ENABLE_CONTRAST, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::BIN_MODE, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
return RETURN_OK; return RETURN_OK;
} }
@ -425,7 +358,7 @@ ReturnValue_t Centroiding::createCommand(uint8_t* buffer) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
uint8_t offset = 0; uint8_t offset = 0;
std::string param; std::string param;
addSetParamHeader(buffer, StarTracker::ID::CENTROIDING); addSetParamHeader(buffer, startracker::ID::CENTROIDING);
offset = 2; offset = 2;
result = getParam(arcseckeys::ENABLE_FILTER, param); result = getParam(arcseckeys::ENABLE_FILTER, param);
if (result != RETURN_OK) { if (result != RETURN_OK) {
@ -439,6 +372,12 @@ ReturnValue_t Centroiding::createCommand(uint8_t* buffer) {
} }
addfloat(param, buffer + offset); addfloat(param, buffer + offset);
offset += sizeof(float); offset += sizeof(float);
result = getParam(arcseckeys::DARK_THRESHOLD, param);
if (result != RETURN_OK) {
return result;
}
addfloat(param, buffer + offset);
offset += sizeof(float);
result = getParam(arcseckeys::MIN_QUALITY, param); result = getParam(arcseckeys::MIN_QUALITY, param);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
@ -509,8 +448,14 @@ ReturnValue_t Lisa::createCommand(uint8_t* buffer) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
uint8_t offset = 0; uint8_t offset = 0;
std::string param; std::string param;
addSetParamHeader(buffer, StarTracker::ID::LISA); addSetParamHeader(buffer, startracker::ID::LISA);
offset = 2; offset = 2;
result = getParam(arcseckeys::LISA_MODE, param);
if (result != RETURN_OK) {
return result;
}
adduint32(param, buffer + offset);
offset += sizeof(uint32_t);
result = getParam(arcseckeys::PREFILTER_DIST_THRESHOLD, param); result = getParam(arcseckeys::PREFILTER_DIST_THRESHOLD, param);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
@ -559,6 +504,12 @@ ReturnValue_t Lisa::createCommand(uint8_t* buffer) {
} }
addfloat(param, buffer + offset); addfloat(param, buffer + offset);
offset += sizeof(float); offset += sizeof(float);
result = getParam(arcseckeys::RATING_WEIGHT_MEAN_SUM, param);
if (result != RETURN_OK) {
return result;
}
addfloat(param, buffer + offset);
offset += sizeof(float);
result = getParam(arcseckeys::RATING_WEIGHT_DB_STAR_COUNT, param); result = getParam(arcseckeys::RATING_WEIGHT_DB_STAR_COUNT, param);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
@ -594,7 +545,7 @@ ReturnValue_t Matching::createCommand(uint8_t* buffer) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
uint8_t offset = 0; uint8_t offset = 0;
std::string param; std::string param;
addSetParamHeader(buffer, StarTracker::ID::MATCHING); addSetParamHeader(buffer, startracker::ID::MATCHING);
offset = 2; offset = 2;
result = getParam(arcseckeys::SQUARED_DISTANCE_LIMIT, param); result = getParam(arcseckeys::SQUARED_DISTANCE_LIMIT, param);
if (result != RETURN_OK) { if (result != RETURN_OK) {
@ -618,7 +569,7 @@ ReturnValue_t Validation::createCommand(uint8_t* buffer) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
uint8_t offset = 0; uint8_t offset = 0;
std::string param; std::string param;
addSetParamHeader(buffer, StarTracker::ID::VALIDATION); addSetParamHeader(buffer, startracker::ID::VALIDATION);
offset = 2; offset = 2;
result = getParam(arcseckeys::STABLE_COUNT, param); result = getParam(arcseckeys::STABLE_COUNT, param);
if (result != RETURN_OK) { if (result != RETURN_OK) {
@ -654,7 +605,7 @@ ReturnValue_t Algo::createCommand(uint8_t* buffer) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
uint8_t offset = 0; uint8_t offset = 0;
std::string param; std::string param;
addSetParamHeader(buffer, StarTracker::ID::ALGO); addSetParamHeader(buffer, startracker::ID::ALGO);
offset = 2; offset = 2;
result = getParam(arcseckeys::MODE, param); result = getParam(arcseckeys::MODE, param);
if (result != RETURN_OK) { if (result != RETURN_OK) {
@ -687,3 +638,280 @@ ReturnValue_t Algo::createCommand(uint8_t* buffer) {
adduint8(param, buffer + offset); adduint8(param, buffer + offset);
return RETURN_OK; return RETURN_OK;
} }
LogLevel::LogLevel() : ArcsecJsonParamBase(arcseckeys::LOGLEVEL) {}
size_t LogLevel::getSize() { return COMMAND_SIZE; }
ReturnValue_t LogLevel::createCommand(uint8_t* buffer) {
ReturnValue_t result = RETURN_OK;
uint8_t offset = 0;
std::string param;
addSetParamHeader(buffer, startracker::ID::LOG_LEVEL);
offset = 2;
result = getParam(arcseckeys::LOGLEVEL1, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::LOGLEVEL2, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::LOGLEVEL3, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::LOGLEVEL4, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::LOGLEVEL5, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::LOGLEVEL6, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::LOGLEVEL7, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::LOGLEVEL8, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::LOGLEVEL9, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::LOGLEVEL10, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::LOGLEVEL11, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::LOGLEVEL12, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::LOGLEVEL13, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::LOGLEVEL14, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::LOGLEVEL15, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::LOGLEVEL16, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
return RETURN_OK;
}
Subscription::Subscription() : ArcsecJsonParamBase(arcseckeys::SUBSCRIPTION) {}
size_t Subscription::getSize() { return COMMAND_SIZE; }
ReturnValue_t Subscription::createCommand(uint8_t* buffer) {
ReturnValue_t result = RETURN_OK;
uint8_t offset = 0;
std::string param;
addSetParamHeader(buffer, startracker::ID::SUBSCRIPTION);
offset = 2;
result = getParam(arcseckeys::TELEMETRY_1, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::TELEMETRY_2, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::TELEMETRY_3, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::TELEMETRY_4, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::TELEMETRY_5, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::TELEMETRY_6, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::TELEMETRY_7, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::TELEMETRY_8, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::TELEMETRY_9, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::TELEMETRY_10, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::TELEMETRY_11, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::TELEMETRY_12, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::TELEMETRY_13, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::TELEMETRY_14, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::TELEMETRY_15, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::TELEMETRY_16, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
return RETURN_OK;
}
LogSubscription::LogSubscription() : ArcsecJsonParamBase(arcseckeys::LOG_SUBSCRIPTION) {}
size_t LogSubscription::getSize() { return COMMAND_SIZE; }
ReturnValue_t LogSubscription::createCommand(uint8_t* buffer) {
ReturnValue_t result = RETURN_OK;
uint8_t offset = 0;
std::string param;
addSetParamHeader(buffer, startracker::ID::LOG_SUBSCRIPTION);
offset = 2;
result = getParam(arcseckeys::LEVEL1, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::MODULE1, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::LEVEL2, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
offset += sizeof(uint8_t);
result = getParam(arcseckeys::MODULE2, param);
if (result != RETURN_OK) {
return result;
}
adduint8(param, buffer + offset);
return RETURN_OK;
}
DebugCamera::DebugCamera() : ArcsecJsonParamBase(arcseckeys::DEBUG_CAMERA) {}
size_t DebugCamera::getSize() { return COMMAND_SIZE; }
ReturnValue_t DebugCamera::createCommand(uint8_t* buffer) {
ReturnValue_t result = RETURN_OK;
uint8_t offset = 0;
std::string param;
addSetParamHeader(buffer, startracker::ID::DEBUG_CAMERA);
offset = 2;
result = getParam(arcseckeys::TIMING, param);
if (result != RETURN_OK) {
return result;
}
adduint32(param, buffer + offset);
offset += sizeof(uint32_t);
result = getParam(arcseckeys::TEST, param);
if (result != RETURN_OK) {
return result;
}
adduint32(param, buffer + offset);
return RETURN_OK;
}

View File

@ -60,6 +60,22 @@ class Mounting : public ArcsecJsonParamBase {
ReturnValue_t createCommand(uint8_t* buffer) override; ReturnValue_t createCommand(uint8_t* buffer) override;
}; };
/**
* @brief Generates the command to configure the image processor
*
*/
class ImageProcessor : public ArcsecJsonParamBase {
public:
ImageProcessor();
size_t getSize();
private:
static const size_t COMMAND_SIZE = 9;
ReturnValue_t createCommand(uint8_t* buffer) override;
};
/** /**
* @brief Generates the command to set the mounting quaternion * @brief Generates the command to set the mounting quaternion
* *
@ -71,23 +87,7 @@ class Camera : public ArcsecJsonParamBase {
size_t getSize(); size_t getSize();
private: private:
static const size_t COMMAND_SIZE = 43; static const size_t COMMAND_SIZE = 39;
ReturnValue_t createCommand(uint8_t* buffer) override;
};
/**
* @brief Generates the command to configure the blob algorithm
*
*/
class Blob : public ArcsecJsonParamBase {
public:
Blob();
size_t getSize();
private:
static const size_t COMMAND_SIZE = 24;
ReturnValue_t createCommand(uint8_t* buffer) override; ReturnValue_t createCommand(uint8_t* buffer) override;
}; };
@ -103,7 +103,7 @@ class Centroiding : public ArcsecJsonParamBase {
size_t getSize(); size_t getSize();
private: private:
static const size_t COMMAND_SIZE = 47; static const size_t COMMAND_SIZE = 51;
ReturnValue_t createCommand(uint8_t* buffer) override; ReturnValue_t createCommand(uint8_t* buffer) override;
}; };
@ -119,7 +119,7 @@ class Lisa : public ArcsecJsonParamBase {
size_t getSize(); size_t getSize();
private: private:
static const size_t COMMAND_SIZE = 48; static const size_t COMMAND_SIZE = 52;
ReturnValue_t createCommand(uint8_t* buffer) override; ReturnValue_t createCommand(uint8_t* buffer) override;
}; };
@ -173,4 +173,68 @@ class Algo : public ArcsecJsonParamBase {
ReturnValue_t createCommand(uint8_t* buffer) override; ReturnValue_t createCommand(uint8_t* buffer) override;
}; };
/**
* @brief Generates command to configure the log level parameters.
*
*/
class LogLevel : public ArcsecJsonParamBase {
public:
LogLevel();
size_t getSize();
private:
static const size_t COMMAND_SIZE = 18;
ReturnValue_t createCommand(uint8_t* buffer) override;
};
/**
* @brief Generates command to set subscription parameters.
*
*/
class Subscription : public ArcsecJsonParamBase {
public:
Subscription();
size_t getSize();
private:
static const size_t COMMAND_SIZE = 18;
ReturnValue_t createCommand(uint8_t* buffer) override;
};
/**
* @brief Generates command to set log subscription parameters.
*
*/
class LogSubscription : public ArcsecJsonParamBase {
public:
LogSubscription();
size_t getSize();
private:
static const size_t COMMAND_SIZE = 6;
ReturnValue_t createCommand(uint8_t* buffer) override;
};
/**
* @brief Generates command to set debug camera parameters
*
*/
class DebugCamera : public ArcsecJsonParamBase {
public:
DebugCamera();
size_t getSize();
private:
static const size_t COMMAND_SIZE = 10;
ReturnValue_t createCommand(uint8_t* buffer) override;
};
#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ */ #endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ */

View File

@ -3,18 +3,24 @@
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
#include "OBSWConfig.h"
#include "fsfw/timemanager/Countdown.h"
#include "linux/devices/devicedefinitions/StarTrackerDefinitions.h"
#include "mission/utility/Timestamp.h" #include "mission/utility/Timestamp.h"
#include "mission/utility/ProgressPrinter.h"
StrHelper::StrHelper(object_id_t objectId) : SystemObject(objectId) {} StrHelper::StrHelper(object_id_t objectId) : SystemObject(objectId) {}
StrHelper::~StrHelper() {} StrHelper::~StrHelper() {}
ReturnValue_t StrHelper::initialize() { ReturnValue_t StrHelper::initialize() {
#ifdef XIPHOS_Q7S
sdcMan = SdCardManager::instance(); sdcMan = SdCardManager::instance();
if (sdcMan == nullptr) { if (sdcMan == nullptr) {
sif::warning << "StrHelper::initialize: Invalid SD Card Manager" << std::endl; sif::warning << "StrHelper::initialize: Invalid SD Card Manager" << std::endl;
return RETURN_FAILED; return RETURN_FAILED;
} }
#endif
return RETURN_OK; return RETURN_OK;
} }
@ -47,16 +53,6 @@ ReturnValue_t StrHelper::performOperation(uint8_t operationCode) {
internalState = InternalState::IDLE; internalState = InternalState::IDLE;
break; break;
} }
case InternalState::FLASH_WRITE: {
result = performFlashWrite();
if (result == RETURN_OK) {
triggerEvent(FLASH_WRITE_SUCCESSFUL);
} else {
triggerEvent(FLASH_WRITE_FAILED);
}
internalState = InternalState::IDLE;
break;
}
case InternalState::FLASH_READ: { case InternalState::FLASH_READ: {
result = performFlashRead(); result = performFlashRead();
if (result == RETURN_OK) { if (result == RETURN_OK) {
@ -67,22 +63,12 @@ ReturnValue_t StrHelper::performOperation(uint8_t operationCode) {
internalState = InternalState::IDLE; internalState = InternalState::IDLE;
break; break;
} }
case InternalState::DOWNLOAD_FPGA_IMAGE: { case InternalState::FIRMWARE_UPDATE: {
result = performFpgaDownload(); result = performFirmwareUpdate();
if (result == RETURN_OK) { if (result == RETURN_OK) {
triggerEvent(FPGA_DOWNLOAD_SUCCESSFUL); triggerEvent(FIRMWARE_UPDATE_SUCCESSFUL);
} else { } else {
triggerEvent(FPGA_DOWNLOAD_FAILED); triggerEvent(FIRMWARE_UPDATE_FAILED);
}
internalState = InternalState::IDLE;
break;
}
case InternalState::UPLOAD_FPGA_IMAGE: {
result = performFpgaUpload();
if (result == RETURN_OK) {
triggerEvent(FPGA_UPLOAD_SUCCESSFUL);
} else {
triggerEvent(FPGA_UPLOAD_FAILED);
} }
internalState = InternalState::IDLE; internalState = InternalState::IDLE;
break; break;
@ -106,10 +92,12 @@ ReturnValue_t StrHelper::setComIF(DeviceCommunicationIF* communicationInterface_
void StrHelper::setComCookie(CookieIF* comCookie_) { comCookie = comCookie_; } void StrHelper::setComCookie(CookieIF* comCookie_) { comCookie = comCookie_; }
ReturnValue_t StrHelper::startImageUpload(std::string fullname) { ReturnValue_t StrHelper::startImageUpload(std::string fullname) {
#ifdef XIPHOS_Q7S
ReturnValue_t result = checkPath(fullname); ReturnValue_t result = checkPath(fullname);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }
#endif
uploadImage.uploadFile = fullname; uploadImage.uploadFile = fullname;
if (not std::filesystem::exists(fullname)) { if (not std::filesystem::exists(fullname)) {
return FILE_NOT_EXISTS; return FILE_NOT_EXISTS;
@ -121,10 +109,12 @@ ReturnValue_t StrHelper::startImageUpload(std::string fullname) {
} }
ReturnValue_t StrHelper::startImageDownload(std::string path) { ReturnValue_t StrHelper::startImageDownload(std::string path) {
#ifdef XIPHOS_Q7S
ReturnValue_t result = checkPath(path); ReturnValue_t result = checkPath(path);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }
#endif
if (not std::filesystem::exists(path)) { if (not std::filesystem::exists(path)) {
return PATH_NOT_EXISTS; return PATH_NOT_EXISTS;
} }
@ -141,37 +131,37 @@ void StrHelper::setDownloadImageName(std::string filename) { downloadImage.filen
void StrHelper::setFlashReadFilename(std::string filename) { flashRead.filename = filename; } void StrHelper::setFlashReadFilename(std::string filename) { flashRead.filename = filename; }
void StrHelper::setDownloadFpgaImage(std::string filename) { fpgaDownload.fileName = filename; } ReturnValue_t StrHelper::startFirmwareUpdate(std::string fullname) {
#ifdef XIPHOS_Q7S
ReturnValue_t StrHelper::startFlashWrite(std::string fullname, uint8_t region, uint32_t address) {
ReturnValue_t result = checkPath(fullname); ReturnValue_t result = checkPath(fullname);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }
#endif
flashWrite.fullname = fullname; flashWrite.fullname = fullname;
if (not std::filesystem::exists(flashWrite.fullname)) { if (not std::filesystem::exists(flashWrite.fullname)) {
return FILE_NOT_EXISTS; return FILE_NOT_EXISTS;
} }
flashWrite.address = address; flashWrite.firstRegion = static_cast<uint8_t>(startracker::FirmwareRegions::FIRST);
flashWrite.region = region; flashWrite.lastRegion = static_cast<uint8_t>(startracker::FirmwareRegions::LAST);
internalState = InternalState::FLASH_WRITE; internalState = InternalState::FIRMWARE_UPDATE;
semaphore.release(); semaphore.release();
terminate = false; terminate = false;
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t StrHelper::startFlashRead(std::string path, uint8_t region, uint32_t address, ReturnValue_t StrHelper::startFlashRead(std::string path, uint8_t startRegion, uint32_t length) {
uint32_t length) { #ifdef XIPHOS_Q7S
ReturnValue_t result = checkPath(path); ReturnValue_t result = checkPath(path);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }
#endif
flashRead.path = path; flashRead.path = path;
if (not std::filesystem::exists(flashRead.path)) { if (not std::filesystem::exists(flashRead.path)) {
return FILE_NOT_EXISTS; return FILE_NOT_EXISTS;
} }
flashRead.address = address; flashRead.startRegion = startRegion;
flashRead.region = region;
flashRead.size = length; flashRead.size = length;
internalState = InternalState::FLASH_READ; internalState = InternalState::FLASH_READ;
semaphore.release(); semaphore.release();
@ -179,39 +169,27 @@ ReturnValue_t StrHelper::startFlashRead(std::string path, uint8_t region, uint32
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t StrHelper::startFpgaDownload(std::string path, uint32_t startPosition, void StrHelper::disableTimestamping() { timestamping = false; }
uint32_t length) {
fpgaDownload.path = path;
fpgaDownload.startPosition = startPosition;
fpgaDownload.length = length;
internalState = InternalState::DOWNLOAD_FPGA_IMAGE;
semaphore.release();
terminate = false;
return RETURN_OK;
}
ReturnValue_t StrHelper::startFpgaUpload(std::string uploadFile) { void StrHelper::enableTimestamping() { timestamping = true; }
fpgaUpload.uploadFile = uploadFile;
internalState = InternalState::UPLOAD_FPGA_IMAGE;
semaphore.release();
terminate = false;
return RETURN_OK;
}
ReturnValue_t StrHelper::performImageDownload() { ReturnValue_t StrHelper::performImageDownload() {
ReturnValue_t result; ReturnValue_t result;
#if OBSW_DEBUG_STARTRACKER == 1
ProgressPrinter progressPrinter("Image download", ImageDownload::LAST_POSITION);
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
struct DownloadActionRequest downloadReq; struct DownloadActionRequest downloadReq;
uint32_t size = 0; uint32_t size = 0;
uint32_t retries = 0; uint32_t retries = 0;
Timestamp timestamp; std::string image = makeFullFilename(downloadImage.path, downloadImage.filename);
std::string image = downloadImage.path + "/" + timestamp.str() + downloadImage.filename; std::ofstream file(image, std::ios_base::out);
std::ofstream file(image, std::ios_base::app | std::ios_base::out);
if (not std::filesystem::exists(image)) { if (not std::filesystem::exists(image)) {
return FILE_CREATION_FAILED; return FILE_CREATION_FAILED;
} }
downloadReq.position = 0; downloadReq.position = 0;
while (downloadReq.position < ImageDownload::LAST_POSITION) { while (downloadReq.position < ImageDownload::LAST_POSITION) {
if (terminate) { if (terminate) {
file.close();
return RETURN_OK; return RETURN_OK;
} }
arc_pack_download_action_req(&downloadReq, commandBuffer, &size); arc_pack_download_action_req(&downloadReq, commandBuffer, &size);
@ -246,7 +224,10 @@ ReturnValue_t StrHelper::performImageDownload() {
return result; return result;
} }
file.write(reinterpret_cast<const char*>(datalinkLayer.getReply() + IMAGE_DATA_OFFSET), file.write(reinterpret_cast<const char*>(datalinkLayer.getReply() + IMAGE_DATA_OFFSET),
IMAGE_DATA_SIZE); CHUNK_SIZE);
#if OBSW_DEBUG_STARTRACKER == 1
progressPrinter.print(downloadReq.position);
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
downloadReq.position++; downloadReq.position++;
retries = 0; retries = 0;
} }
@ -271,8 +252,12 @@ ReturnValue_t StrHelper::performImageUpload() {
file.seekg(0, file.end); file.seekg(0, file.end);
// tellg returns position of character in input stream // tellg returns position of character in input stream
imageSize = file.tellg(); imageSize = file.tellg();
#if OBSW_DEBUG_STARTRACKER == 1
ProgressPrinter progressPrinter("Image upload", imageSize);
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
while ((uploadReq.position + 1) * SIZE_IMAGE_PART < imageSize) { while ((uploadReq.position + 1) * SIZE_IMAGE_PART < imageSize) {
if (terminate) { if (terminate) {
file.close();
return RETURN_OK; return RETURN_OK;
} }
file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg); file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg);
@ -280,12 +265,17 @@ ReturnValue_t StrHelper::performImageUpload() {
arc_pack_upload_action_req(&uploadReq, commandBuffer, &size); arc_pack_upload_action_req(&uploadReq, commandBuffer, &size);
result = sendAndRead(size, uploadReq.position); result = sendAndRead(size, uploadReq.position);
if (result != RETURN_OK) { if (result != RETURN_OK) {
file.close();
return RETURN_FAILED; return RETURN_FAILED;
} }
result = checkActionReply(); result = checkActionReply();
if (result != RETURN_OK) { if (result != RETURN_OK) {
file.close();
return result; return result;
} }
#if OBSW_DEBUG_STARTRACKER == 1
progressPrinter.print((uploadReq.position + 1) * SIZE_IMAGE_PART);
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
uploadReq.position++; uploadReq.position++;
} }
std::memset(uploadReq.data, 0, sizeof(uploadReq.data)); std::memset(uploadReq.data, 0, sizeof(uploadReq.data));
@ -303,13 +293,28 @@ ReturnValue_t StrHelper::performImageUpload() {
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }
#if OBSW_DEBUG_STARTRACKER == 1
progressPrinter.print((uploadReq.position + 1) * SIZE_IMAGE_PART);
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t StrHelper::performFirmwareUpdate() {
using namespace startracker;
ReturnValue_t result = RETURN_OK;
result = unlockAndEraseRegions(static_cast<uint32_t>(startracker::FirmwareRegions::FIRST),
static_cast<uint32_t>(startracker::FirmwareRegions::LAST));
if (result != RETURN_OK) {
return result;
}
result = performFlashWrite();
return result;
}
ReturnValue_t StrHelper::performFlashWrite() { ReturnValue_t StrHelper::performFlashWrite() {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
uint32_t size = 0; uint32_t size = 0;
uint32_t remainingBytes = 0; uint32_t bytesWritten = 0;
uint32_t fileSize = 0; uint32_t fileSize = 0;
struct WriteActionRequest req; struct WriteActionRequest req;
if (not std::filesystem::exists(flashWrite.fullname)) { if (not std::filesystem::exists(flashWrite.fullname)) {
@ -320,65 +325,97 @@ ReturnValue_t StrHelper::performFlashWrite() {
std::ifstream file(flashWrite.fullname, std::ifstream::binary); std::ifstream file(flashWrite.fullname, std::ifstream::binary);
file.seekg(0, file.end); file.seekg(0, file.end);
fileSize = file.tellg(); fileSize = file.tellg();
remainingBytes = fileSize; if (fileSize > FLASH_REGION_SIZE * (flashWrite.lastRegion - flashWrite.firstRegion)) {
req.region = flashWrite.region; sif::warning << "StrHelper::performFlashWrite: Invalid file" << std::endl;
req.address = flashWrite.address; return RETURN_FAILED;
req.length = MAX_FLASH_DATA; }
while (remainingBytes >= MAX_FLASH_DATA) { #if OBSW_DEBUG_STARTRACKER == 1
ProgressPrinter progressPrinter("Flash write", fileSize);
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
uint32_t fileChunks = fileSize / CHUNK_SIZE;
bytesWritten = 0;
req.region = flashWrite.firstRegion;
req.length = CHUNK_SIZE;
for (uint32_t idx = 0; idx < fileChunks; idx++) {
if (terminate) { if (terminate) {
file.close();
return RETURN_OK; return RETURN_OK;
} }
file.seekg(fileSize - remainingBytes, file.beg); file.seekg(idx * CHUNK_SIZE, file.beg);
file.read(reinterpret_cast<char*>(req.data), MAX_FLASH_DATA); file.read(reinterpret_cast<char*>(req.data), CHUNK_SIZE);
if (bytesWritten + CHUNK_SIZE > FLASH_REGION_SIZE) {
req.region++;
bytesWritten = 0;
}
req.address = bytesWritten;
arc_pack_write_action_req(&req, commandBuffer, &size); arc_pack_write_action_req(&req, commandBuffer, &size);
result = sendAndRead(size, req.address); result = sendAndRead(size, req.address);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return RETURN_FAILED; file.close();
}
result = checkFlashActionReply(req.region, req.address, req.length);
if (result != RETURN_OK) {
return result; return result;
} }
remainingBytes = remainingBytes - MAX_FLASH_DATA; result = checkActionReply();
if (result != RETURN_OK) {
file.close();
return result;
} }
file.seekg(fileSize - remainingBytes, file.beg); bytesWritten += CHUNK_SIZE;
#if OBSW_DEBUG_STARTRACKER == 1
progressPrinter.print(idx * CHUNK_SIZE);
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
}
uint32_t remainingBytes = fileSize - fileChunks * CHUNK_SIZE;
file.seekg((fileChunks - 1) * CHUNK_SIZE, file.beg);
file.read(reinterpret_cast<char*>(req.data), remainingBytes); file.read(reinterpret_cast<char*>(req.data), remainingBytes);
file.close(); file.close();
if (bytesWritten + CHUNK_SIZE > FLASH_REGION_SIZE) {
req.region++;
bytesWritten = 0;
}
req.address = bytesWritten;
req.length = remainingBytes;
bytesWritten += remainingBytes;
arc_pack_write_action_req(&req, commandBuffer, &size); arc_pack_write_action_req(&req, commandBuffer, &size);
result = sendAndRead(size, req.address); result = sendAndRead(size, req.address);
if (result != RETURN_OK) { if (result != RETURN_OK) {
return RETURN_FAILED; return result;
} }
result = checkFlashActionReply(req.region, req.address, req.length); result = checkActionReply();
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }
#if OBSW_DEBUG_STARTRACKER == 1
progressPrinter.print(fileSize);
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t StrHelper::performFlashRead() { ReturnValue_t StrHelper::performFlashRead() {
ReturnValue_t result; ReturnValue_t result;
#if OBSW_DEBUG_STARTRACKER == 1
ProgressPrinter progressPrinter("Flash read", flashRead.size);
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
struct ReadActionRequest req; struct ReadActionRequest req;
uint32_t bytesRead = 0; uint32_t bytesRead = 0;
uint32_t size = 0; uint32_t size = 0;
uint32_t retries = 0; uint32_t retries = 0;
Timestamp timestamp; Timestamp timestamp;
std::string fullname = flashRead.path + "/" + timestamp.str() + flashRead.filename; std::string fullname = makeFullFilename(flashRead.path, flashRead.filename);
std::ofstream file(fullname, std::ios_base::app | std::ios_base::out); std::ofstream file(fullname, std::ios_base::app | std::ios_base::out);
if (not std::filesystem::exists(fullname)) { if (not std::filesystem::exists(fullname)) {
return FILE_CREATION_FAILED; return FILE_CREATION_FAILED;
} }
req.region = flashRead.region; req.region = flashRead.startRegion;
req.address = 0;
while (bytesRead < flashRead.size) { while (bytesRead < flashRead.size) {
if (terminate) { if (terminate) {
return RETURN_OK; return RETURN_OK;
} }
if ((flashRead.size - bytesRead) < MAX_FLASH_DATA) { if ((flashRead.size - bytesRead) < CHUNK_SIZE) {
req.length = flashRead.size - bytesRead; req.length = flashRead.size - bytesRead;
} else { } else {
req.length = MAX_FLASH_DATA; req.length = CHUNK_SIZE;
} }
req.address = flashRead.address + bytesRead;
arc_pack_read_action_req(&req, commandBuffer, &size); arc_pack_read_action_req(&req, commandBuffer, &size);
result = sendAndRead(size, req.address); result = sendAndRead(size, req.address);
if (result != RETURN_OK) { if (result != RETURN_OK) {
@ -400,117 +437,24 @@ ReturnValue_t StrHelper::performFlashRead() {
file.close(); file.close();
return result; return result;
} }
result = checkFlashActionReply(req.region, req.address, req.length);
if (result != RETURN_OK) {
if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) {
uartComIF->flushUartRxBuffer(comCookie);
retries++;
continue;
}
file.close();
return result;
}
file.write(reinterpret_cast<const char*>(datalinkLayer.getReply() + FLASH_READ_DATA_OFFSET), file.write(reinterpret_cast<const char*>(datalinkLayer.getReply() + FLASH_READ_DATA_OFFSET),
req.length); req.length);
bytesRead += req.length; bytesRead += req.length;
req.address += req.length;
if (req.address >= FLASH_REGION_SIZE) {
req.address = 0;
req.region++;
}
retries = 0; retries = 0;
#if OBSW_DEBUG_STARTRACKER == 1
progressPrinter.print(bytesRead);
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
} }
file.close(); file.close();
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t StrHelper::performFpgaDownload() { ReturnValue_t StrHelper::sendAndRead(size_t size, uint32_t parameter, uint32_t delayMs) {
ReturnValue_t result;
struct DownloadFPGAImageActionRequest req;
uint32_t size = 0;
uint32_t retries = 0;
Timestamp timestamp;
std::string image = fpgaDownload.path + "/" + timestamp.str() + fpgaDownload.fileName;
std::ofstream file(image, std::ios_base::app | std::ios_base::out);
if (not std::filesystem::exists(image)) {
return FILE_CREATION_FAILED;
}
req.pos = fpgaDownload.startPosition;
while (req.pos < fpgaDownload.length) {
if (terminate) {
return RETURN_OK;
}
if (fpgaDownload.length - req.pos >= FpgaDownload::MAX_DATA) {
req.length = FpgaDownload::MAX_DATA;
} else {
req.length = fpgaDownload.length - req.pos;
}
arc_pack_downloadfpgaimage_action_req(&req, commandBuffer, &size);
result = sendAndRead(size, req.pos);
if (result != RETURN_OK) {
if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) {
uartComIF->flushUartRxBuffer(comCookie);
retries++;
continue;
}
file.close();
return result;
}
result = checkFpgaActionReply(req.pos, req.length);
if (result != RETURN_OK) {
if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) {
uartComIF->flushUartRxBuffer(comCookie);
retries++;
continue;
}
file.close();
return result;
}
file.write(reinterpret_cast<const char*>(datalinkLayer.getReply() + FpgaDownload::DATA_OFFSET),
req.length);
req.pos += req.length;
retries = 0;
}
file.close();
return RETURN_OK;
}
ReturnValue_t StrHelper::performFpgaUpload() {
ReturnValue_t result = RETURN_OK;
uint32_t commandSize = 0;
uint32_t bytesUploaded = 0;
uint32_t fileSize = 0;
struct UploadFPGAImageActionRequest req;
if (not std::filesystem::exists(fpgaUpload.uploadFile)) {
triggerEvent(STR_HELPER_FILE_NOT_EXISTS, static_cast<uint32_t>(internalState));
internalState = InternalState::IDLE;
return RETURN_FAILED;
}
std::ifstream file(flashWrite.fullname, std::ifstream::binary);
file.seekg(0, file.end);
fileSize = file.tellg();
req.pos = 0;
while (bytesUploaded <= fileSize) {
if (terminate) {
return RETURN_OK;
}
if (fileSize - bytesUploaded > FpgaUpload::MAX_DATA) {
req.length = FpgaUpload::MAX_DATA;
} else {
req.length = fileSize - bytesUploaded;
}
file.seekg(bytesUploaded, file.beg);
file.read(reinterpret_cast<char*>(req.data), req.length);
arc_pack_uploadfpgaimage_action_req(&req, commandBuffer, &commandSize);
result = sendAndRead(commandSize, req.pos);
if (result != RETURN_OK) {
return RETURN_FAILED;
}
result = checkFpgaActionReply(req.pos, req.length);
if (result != RETURN_OK) {
return result;
}
bytesUploaded += req.length;
}
return RETURN_OK;
}
ReturnValue_t StrHelper::sendAndRead(size_t size, uint32_t parameter) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
ReturnValue_t decResult = RETURN_OK; ReturnValue_t decResult = RETURN_OK;
size_t receivedDataLen = 0; size_t receivedDataLen = 0;
@ -527,7 +471,11 @@ ReturnValue_t StrHelper::sendAndRead(size_t size, uint32_t parameter) {
} }
decResult = ArcsecDatalinkLayer::DEC_IN_PROGRESS; decResult = ArcsecDatalinkLayer::DEC_IN_PROGRESS;
while (decResult == ArcsecDatalinkLayer::DEC_IN_PROGRESS) { while (decResult == ArcsecDatalinkLayer::DEC_IN_PROGRESS) {
result = uartComIF->requestReceiveMessage(comCookie, StarTracker::MAX_FRAME_SIZE * 2 + 2); Countdown delay(delayMs);
delay.resetTimer();
while (delay.isBusy()) {
}
result = uartComIF->requestReceiveMessage(comCookie, startracker::MAX_FRAME_SIZE * 2 + 2);
if (result != RETURN_OK) { if (result != RETURN_OK) {
sif::warning << "StrHelper::sendAndRead: Failed to request reply" << std::endl; sif::warning << "StrHelper::sendAndRead: Failed to request reply" << std::endl;
triggerEvent(STR_HELPER_REQUESTING_MSG_FAILED, result, parameter); triggerEvent(STR_HELPER_REQUESTING_MSG_FAILED, result, parameter);
@ -588,72 +536,7 @@ ReturnValue_t StrHelper::checkReplyPosition(uint32_t expectedPosition) {
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t StrHelper::checkFlashActionReply(uint8_t region_, uint32_t address_, #ifdef XIPHOS_Q7S
uint16_t length_) {
ReturnValue_t result = RETURN_OK;
result = checkActionReply();
if (result != RETURN_OK) {
return result;
}
const uint8_t* data = datalinkLayer.getReply();
uint8_t region = *(data + REGION_OFFSET);
uint32_t address;
const uint8_t* addressData = data + ADDRESS_OFFSET;
size_t size = sizeof(address);
result =
SerializeAdapter::deSerialize(&address, &addressData, &size, SerializeIF::Endianness::LITTLE);
if (result != RETURN_OK) {
sif::warning << "StrHelper::checkFlashActionReply: Deserialization of address failed"
<< std::endl;
return result;
}
uint16_t length = 0;
size = sizeof(length);
const uint8_t* lengthData = data + LENGTH_OFFSET;
result =
SerializeAdapter::deSerialize(&length, lengthData, &size, SerializeIF::Endianness::LITTLE);
if (result != RETURN_OK) {
sif::warning << "StrHelper::checkFlashActionReply: Deserialization of length failed"
<< std::endl;
}
if (region != region_) {
return REGION_MISMATCH;
}
if (address != address_) {
return ADDRESS_MISMATCH;
}
if (length != length_) {
return LENGTH_MISMATCH;
}
return RETURN_OK;
}
ReturnValue_t StrHelper::checkFpgaActionReply(uint32_t expectedPosition, uint32_t expectedLength) {
ReturnValue_t result = RETURN_OK;
result = checkActionReply();
if (result != RETURN_OK) {
return result;
}
const uint8_t* data = datalinkLayer.getReply() + ACTION_DATA_OFFSET;
uint32_t position;
size_t size = sizeof(position);
result = SerializeAdapter::deSerialize(&position, &data, &size, SerializeIF::Endianness::LITTLE);
if (result != RETURN_OK) {
sif::warning << "StrHelper::checkFpgaActionReply: Deserialization of position failed"
<< std::endl;
return result;
}
uint32_t length;
size = sizeof(length);
result = SerializeAdapter::deSerialize(&length, &data, &size, SerializeIF::Endianness::LITTLE);
if (result != RETURN_OK) {
sif::warning << "StrHelper::checkFpgaActionReply: Deserialization of length failed"
<< std::endl;
return result;
}
return result;
}
ReturnValue_t StrHelper::checkPath(std::string name) { ReturnValue_t StrHelper::checkPath(std::string name) {
if (name.substr(0, sizeof(SdCardManager::SD_0_MOUNT_POINT)) == if (name.substr(0, sizeof(SdCardManager::SD_0_MOUNT_POINT)) ==
std::string(SdCardManager::SD_0_MOUNT_POINT)) { std::string(SdCardManager::SD_0_MOUNT_POINT)) {
@ -670,3 +553,49 @@ ReturnValue_t StrHelper::checkPath(std::string name) {
} }
return RETURN_OK; return RETURN_OK;
} }
#endif
ReturnValue_t StrHelper::unlockAndEraseRegions(uint32_t from, uint32_t to) {
ReturnValue_t result = RETURN_OK;
#if OBSW_DEBUG_STARTRACKER == 1
ProgressPrinter progressPrinter("Unlock and erase", to - from);
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
struct UnlockActionRequest unlockReq;
struct EraseActionRequest eraseReq;
uint32_t size = 0;
for (uint32_t idx = from; idx <= to; idx++) {
unlockReq.region = idx;
unlockReq.code = startracker::region_secrets::secret[idx];
arc_pack_unlock_action_req(&unlockReq, commandBuffer, &size);
sendAndRead(size, unlockReq.region);
result = checkActionReply();
if (result != RETURN_OK) {
sif::warning << "StrHelper::unlockAndEraseRegions: Failed to unlock region with id "
<< static_cast<unsigned int>(unlockReq.region) << std::endl;
return result;
}
eraseReq.region = idx;
arc_pack_erase_action_req(&eraseReq, commandBuffer, &size);
result = sendAndRead(size, eraseReq.region, FLASH_ERASE_DELAY);
if (result != RETURN_OK) {
sif::warning << "StrHelper::unlockAndEraseRegions: Failed to erase region with id "
<< static_cast<unsigned int>(eraseReq.region) << std::endl;
return result;
}
#if OBSW_DEBUG_STARTRACKER == 1
progressPrinter.print(idx - from);
#endif /* OBSW_DEBUG_STARTRACKER == 1 */
}
return result;
}
std::string StrHelper::makeFullFilename(std::string path, std::string filename) {
std::string image;
Timestamp timestamp;
if (timestamping) {
image = path + "/" + timestamp.str() + filename;
} else {
image = path + "/" + filename;
}
return image;
}

View File

@ -4,7 +4,12 @@
#include <string> #include <string>
#include "ArcsecDatalinkLayer.h" #include "ArcsecDatalinkLayer.h"
#include "OBSWConfig.h"
#ifdef XIPHOS_Q7S
#include "bsp_q7s/memory/SdCardManager.h" #include "bsp_q7s/memory/SdCardManager.h"
#endif
#include "fsfw/devicehandlers/CookieIF.h" #include "fsfw/devicehandlers/CookieIF.h"
#include "fsfw/objectmanager/SystemObject.h" #include "fsfw/objectmanager/SystemObject.h"
#include "fsfw/osal/linux/BinarySemaphore.h" #include "fsfw/osal/linux/BinarySemaphore.h"
@ -19,6 +24,8 @@ extern "C" {
/** /**
* @brief Helper class for the star tracker handler to accelerate large data transfers. * @brief Helper class for the star tracker handler to accelerate large data transfers.
*
* @author J. Meier
*/ */
class StrHelper : public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF { class StrHelper : public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF {
public: public:
@ -36,49 +43,43 @@ class StrHelper : public SystemObject, public ExecutableObjectIF, public HasRetu
static const Event FLASH_WRITE_SUCCESSFUL = MAKE_EVENT(4, severity::LOW); static const Event FLASH_WRITE_SUCCESSFUL = MAKE_EVENT(4, severity::LOW);
//! [EXPORT] : [COMMENT] Finished flash read procedure successfully //! [EXPORT] : [COMMENT] Finished flash read procedure successfully
static const Event FLASH_READ_SUCCESSFUL = MAKE_EVENT(5, severity::LOW); static const Event FLASH_READ_SUCCESSFUL = MAKE_EVENT(5, severity::LOW);
//! [EXPORT] : [COMMENT] Flash write procedure failed
static const Event FLASH_WRITE_FAILED = MAKE_EVENT(6, severity::LOW);
//! [EXPORT] : [COMMENT] Flash read procedure failed //! [EXPORT] : [COMMENT] Flash read procedure failed
static const Event FLASH_READ_FAILED = MAKE_EVENT(7, severity::LOW); static const Event FLASH_READ_FAILED = MAKE_EVENT(6, severity::LOW);
//! [EXPORT] : [COMMENT] Download of FPGA image successful //! [EXPORT] : [COMMENT] Firmware update was successful
static const Event FPGA_DOWNLOAD_SUCCESSFUL = MAKE_EVENT(8, severity::LOW); static const Event FIRMWARE_UPDATE_SUCCESSFUL = MAKE_EVENT(7, severity::LOW);
//! [EXPORT] : [COMMENT] Download of FPGA image failed //! [EXPORT] : [COMMENT] Firmware update failed
static const Event FPGA_DOWNLOAD_FAILED = MAKE_EVENT(9, severity::LOW); static const Event FIRMWARE_UPDATE_FAILED = MAKE_EVENT(8, severity::LOW);
//! [EXPORT] : [COMMENT] Upload of FPGA image successful
static const Event FPGA_UPLOAD_SUCCESSFUL = MAKE_EVENT(10, severity::LOW);
//! [EXPORT] : [COMMENT] Upload of FPGA image failed
static const Event FPGA_UPLOAD_FAILED = MAKE_EVENT(11, severity::LOW);
//! [EXPORT] : [COMMENT] Failed to read communication interface reply data //! [EXPORT] : [COMMENT] Failed to read communication interface reply data
//! P1: Return code of failed communication interface read call //! P1: Return code of failed communication interface read call
//! P1: Upload/download position for which the read call failed //! P1: Upload/download position for which the read call failed
static const Event STR_HELPER_READING_REPLY_FAILED = MAKE_EVENT(12, severity::LOW); static const Event STR_HELPER_READING_REPLY_FAILED = MAKE_EVENT(9, severity::LOW);
//! [EXPORT] : [COMMENT] Unexpected stop of decoding sequence //! [EXPORT] : [COMMENT] Unexpected stop of decoding sequence
//! P1: Return code of failed communication interface read call //! P1: Return code of failed communication interface read call
//! P1: Upload/download position for which the read call failed //! P1: Upload/download position for which the read call failed
static const Event STR_HELPER_COM_ERROR = MAKE_EVENT(13, severity::LOW); static const Event STR_HELPER_COM_ERROR = MAKE_EVENT(10, severity::LOW);
//! [EXPORT] : [COMMENT] Star tracker did not send replies (maybe device is powered off) //! [EXPORT] : [COMMENT] Star tracker did not send replies (maybe device is powered off)
//! P1: Position of upload or download packet for which no reply was sent //! P1: Position of upload or download packet for which no reply was sent
static const Event STR_HELPER_NO_REPLY = MAKE_EVENT(14, severity::LOW); static const Event STR_HELPER_NO_REPLY = MAKE_EVENT(11, severity::LOW);
//! [EXPORT] : [COMMENT] Error during decoding of received reply occurred //! [EXPORT] : [COMMENT] Error during decoding of received reply occurred
// P1: Return value of decoding function // P1: Return value of decoding function
// P2: Position of upload/download packet, or address of flash write/read request // P2: Position of upload/download packet, or address of flash write/read request
static const Event STR_HELPER_DEC_ERROR = MAKE_EVENT(15, severity::LOW); static const Event STR_HELPER_DEC_ERROR = MAKE_EVENT(12, severity::LOW);
//! [EXPORT] : [COMMENT] Position mismatch //! [EXPORT] : [COMMENT] Position mismatch
//! P1: The expected position and thus the position for which the image upload/download failed //! P1: The expected position and thus the position for which the image upload/download failed
static const Event POSITION_MISMATCH = MAKE_EVENT(16, severity::LOW); static const Event POSITION_MISMATCH = MAKE_EVENT(13, severity::LOW);
//! [EXPORT] : [COMMENT] Specified file does not exist //! [EXPORT] : [COMMENT] Specified file does not exist
//! P1: Internal state of str helper //! P1: Internal state of str helper
static const Event STR_HELPER_FILE_NOT_EXISTS = MAKE_EVENT(17, severity::LOW); static const Event STR_HELPER_FILE_NOT_EXISTS = MAKE_EVENT(14, severity::LOW);
//! [EXPORT] : [COMMENT] Sending packet to star tracker failed //! [EXPORT] : [COMMENT] Sending packet to star tracker failed
//! P1: Return code of communication interface sendMessage function //! P1: Return code of communication interface sendMessage function
//! P2: Position of upload/download packet, or address of flash write/read request for which //! P2: Position of upload/download packet, or address of flash write/read request for which
//! sending failed //! sending failed
static const Event STR_HELPER_SENDING_PACKET_FAILED = MAKE_EVENT(18, severity::LOW); static const Event STR_HELPER_SENDING_PACKET_FAILED = MAKE_EVENT(15, severity::LOW);
//! [EXPORT] : [COMMENT] Communication interface requesting reply failed //! [EXPORT] : [COMMENT] Communication interface requesting reply failed
//! P1: Return code of failed request //! P1: Return code of failed request
//! P1: Upload/download position, or address of flash write/read request for which transmission //! P1: Upload/download position, or address of flash write/read request for which transmission
//! failed //! failed
static const Event STR_HELPER_REQUESTING_MSG_FAILED = MAKE_EVENT(19, severity::LOW); static const Event STR_HELPER_REQUESTING_MSG_FAILED = MAKE_EVENT(16, severity::LOW);
StrHelper(object_id_t objectId); StrHelper(object_id_t objectId);
virtual ~StrHelper(); virtual ~StrHelper();
@ -105,40 +106,21 @@ class StrHelper : public SystemObject, public ExecutableObjectIF, public HasRetu
ReturnValue_t startImageDownload(std::string path); ReturnValue_t startImageDownload(std::string path);
/** /**
* @brief Starts the flash write procedure * @brief Will start the firmware update
* *
* @param fullname Full name including absolute path of file to write to flash * @param fullname Full name including absolute path of file containing firmware
* @param region Region ID of flash region to write to * update.
* @param address Start address of flash write procedure
*/ */
ReturnValue_t startFlashWrite(std::string fullname, uint8_t region, uint32_t address); ReturnValue_t startFirmwareUpdate(std::string fullname);
/** /**
* @brief Starts the flash read procedure * @brief Starts the flash read procedure
* *
* @param path Path where file with read flash data will be created * @param path Path where file with read flash data will be created
* @param region Region ID of flash region to read from * @param startRegion Region form where to start reading
* @param address Start address of flash section to read
* @param length Number of bytes to read from flash * @param length Number of bytes to read from flash
*/ */
ReturnValue_t startFlashRead(std::string path, uint8_t region, uint32_t address, uint32_t length); ReturnValue_t startFlashRead(std::string path, uint8_t startRegion, uint32_t length);
/**
* @brief Starts the download of the FPGA image
*
* @param path The path where the file with the downloaded data will be created
* @param startPosition Offset in fpga image to read from
* @param length Number of bytes to dwonload from the FPGA image
*
*/
ReturnValue_t startFpgaDownload(std::string path, uint32_t startPosition, uint32_t length);
/**
* @brief Starts upload of new image to FPGA
*
* @param uploadFile Full name of file containing FPGA image data
*/
ReturnValue_t startFpgaUpload(std::string uploadFile);
/** /**
* @brief Can be used to interrupt a running data transfer. * @brief Can be used to interrupt a running data transfer.
@ -156,9 +138,14 @@ class StrHelper : public SystemObject, public ExecutableObjectIF, public HasRetu
void setFlashReadFilename(std::string filename); void setFlashReadFilename(std::string filename);
/** /**
* @brief Set download FPGA image name * @brief Disables timestamp generation when new file is created
*/ */
void setDownloadFpgaImage(std::string filename); void disableTimestamping();
/**
* @brief Enables timestamp generation when new file is created
*/
void enableTimestamping();
private: private:
static const uint8_t INTERFACE_ID = CLASS_ID::STR_HELPER; static const uint8_t INTERFACE_ID = CLASS_ID::STR_HELPER;
@ -184,35 +171,13 @@ class StrHelper : public SystemObject, public ExecutableObjectIF, public HasRetu
// Size of one image part which can be sent per action request // Size of one image part which can be sent per action request
static const size_t SIZE_IMAGE_PART = 1024; static const size_t SIZE_IMAGE_PART = 1024;
static const uint32_t FLASH_REGION_SIZE = 0x20000;
class ImageDownload { class ImageDownload {
public: public:
static const uint32_t LAST_POSITION = 4095; static const uint32_t LAST_POSITION = 4095;
}; };
class FpgaDownload {
public:
static const uint16_t MAX_DATA = 1024;
static const uint8_t DATA_OFFSET = 10;
// Start position of fpga image part to download
uint32_t startPosition = 0;
// Length of image part to download
uint32_t length = 0;
// Path where downloaded FPGA image will be stored
std::string path;
// Name of file containing downloaded FPGA image
std::string fileName = "fpgaimage.bin";
};
FpgaDownload fpgaDownload;
class FpgaUpload {
public:
static const uint32_t MAX_DATA = 1024;
// Full name of file to upload
std::string uploadFile;
};
FpgaUpload fpgaUpload;
static const uint32_t MAX_POLLS = 10000; static const uint32_t MAX_POLLS = 10000;
static const uint8_t ACTION_DATA_OFFSET = 2; static const uint8_t ACTION_DATA_OFFSET = 2;
@ -222,19 +187,11 @@ class StrHelper : public SystemObject, public ExecutableObjectIF, public HasRetu
static const uint8_t REGION_OFFSET = 2; static const uint8_t REGION_OFFSET = 2;
static const uint8_t ADDRESS_OFFSET = 3; static const uint8_t ADDRESS_OFFSET = 3;
static const uint8_t LENGTH_OFFSET = 7; static const uint8_t LENGTH_OFFSET = 7;
static const size_t IMAGE_DATA_SIZE = 1024; static const size_t CHUNK_SIZE = 1024;
static const size_t MAX_FLASH_DATA = 1024;
static const size_t CONFIG_MAX_DOWNLOAD_RETRIES = 3; static const size_t CONFIG_MAX_DOWNLOAD_RETRIES = 3;
static const uint32_t FLASH_ERASE_DELAY = 500;
enum class InternalState { enum class InternalState { IDLE, UPLOAD_IMAGE, DOWNLOAD_IMAGE, FLASH_READ, FIRMWARE_UPDATE };
IDLE,
UPLOAD_IMAGE,
DOWNLOAD_IMAGE,
FLASH_WRITE,
FLASH_READ,
DOWNLOAD_FPGA_IMAGE,
UPLOAD_FPGA_IMAGE
};
InternalState internalState = InternalState::IDLE; InternalState internalState = InternalState::IDLE;
@ -262,8 +219,10 @@ class StrHelper : public SystemObject, public ExecutableObjectIF, public HasRetu
public: public:
// File which contains data to write when executing the flash write command // File which contains data to write when executing the flash write command
std::string fullname; std::string fullname;
// Will be set with the flash write command // The first region to write to
uint8_t region = 0; uint8_t firstRegion = 0;
// Maximum region the flash write command is allowed to write to
uint8_t lastRegion = 0;
// Will be set with the flash write command and specifies the start address where to write the // Will be set with the flash write command and specifies the start address where to write the
// flash data to // flash data to
uint32_t address = 0; uint32_t address = 0;
@ -277,21 +236,26 @@ class StrHelper : public SystemObject, public ExecutableObjectIF, public HasRetu
// Default name of file containing the data read from flash, can be changed via command // Default name of file containing the data read from flash, can be changed via command
std::string filename = "flashread.bin"; std::string filename = "flashread.bin";
// Will be set with the flash read command // Will be set with the flash read command
uint8_t region = 0; uint8_t startRegion = 0;
// Will be set with the flash read command and specifies the start address of the flash section
// to read
uint32_t address = 0;
// Number of bytes to read from flash // Number of bytes to read from flash
uint32_t size = 0; uint32_t size = 0;
}; };
FlashRead flashRead; FlashRead flashRead;
#ifdef XIPHOS_Q7S
SdCardManager* sdcMan = nullptr; SdCardManager* sdcMan = nullptr;
#endif
uint8_t commandBuffer[StarTracker::MAX_FRAME_SIZE]; uint8_t commandBuffer[startracker::MAX_FRAME_SIZE];
bool terminate = false; bool terminate = false;
#ifdef EGSE
bool timestamping = false;
#else
bool timestamping = true;
#endif
/** /**
* UART communication object responsible for low level access of star tracker * UART communication object responsible for low level access of star tracker
* Must be set by star tracker handler * Must be set by star tracker handler
@ -308,6 +272,13 @@ class StrHelper : public SystemObject, public ExecutableObjectIF, public HasRetu
*/ */
ReturnValue_t performImageUpload(); ReturnValue_t performImageUpload();
/**
* @brief Performs firmware update
*
* @return RETURN_OK if successful, otherwise error return value
*/
ReturnValue_t performFirmwareUpdate();
/** /**
* @brief Performs download of last taken image from the star tracker. * @brief Performs download of last taken image from the star tracker.
* *
@ -321,6 +292,8 @@ class StrHelper : public SystemObject, public ExecutableObjectIF, public HasRetu
/** /**
* @brief Handles flash write procedure * @brief Handles flash write procedure
* *
* @param ID of first region to write to
*
* @return RETURN_OK if successful, otherwise RETURN_FAILED * @return RETURN_OK if successful, otherwise RETURN_FAILED
*/ */
ReturnValue_t performFlashWrite(); ReturnValue_t performFlashWrite();
@ -331,28 +304,17 @@ class StrHelper : public SystemObject, public ExecutableObjectIF, public HasRetu
*/ */
ReturnValue_t performFlashRead(); ReturnValue_t performFlashRead();
/**
* @brief Performs the download of the FPGA image which requires to be slip over multiple
* action requests.
*/
ReturnValue_t performFpgaDownload();
/**
* @brief Performs upload of new FPGA image. Upload sequence split over multiple commands
* because one command can only transport 1024 bytes of image data.
*/
ReturnValue_t performFpgaUpload();
/** /**
* @brief Sends packet to the star tracker and reads reply by using the communication * @brief Sends packet to the star tracker and reads reply by using the communication
* interface * interface
* *
* @param size Size of data beforehand written to the commandBuffer * @param size Size of data beforehand written to the commandBuffer
* @param parameter Parameter 2 of trigger event function * @param parameter Parameter 2 of trigger event function
* @param delayMs Delay in milliseconds between send and receive call
* *
* @return RETURN_OK if successful, otherwise RETURN_FAILED * @return RETURN_OK if successful, otherwise RETURN_FAILED
*/ */
ReturnValue_t sendAndRead(size_t size, uint32_t parameter); ReturnValue_t sendAndRead(size_t size, uint32_t parameter, uint32_t delayMs = 0);
/** /**
* @brief Checks the header (type id and status fields) of the action reply * @brief Checks the header (type id and status fields) of the action reply
@ -370,28 +332,33 @@ class StrHelper : public SystemObject, public ExecutableObjectIF, public HasRetu
*/ */
ReturnValue_t checkReplyPosition(uint32_t expectedPosition); ReturnValue_t checkReplyPosition(uint32_t expectedPosition);
/** #ifdef XIPHOS_Q7S
* @brief Checks the region, address and length value of a flash write or read reply.
*
* @return RETURN_OK if values match expected values, otherwise appropriate error return
* value.
*/
ReturnValue_t checkFlashActionReply(uint8_t region_, uint32_t address_, uint16_t length_);
/**
* @brief Checks the reply to the fpga download and upload request
*
* @param expectedPosition The expected position value in the reply
* @param expectedLength The expected length field in the reply
*/
ReturnValue_t checkFpgaActionReply(uint32_t expectedPosition, uint32_t expectedLength);
/** /**
* @brief Checks if a path points to an sd card and whether the SD card is monuted. * @brief Checks if a path points to an sd card and whether the SD card is monuted.
* *
* @return SD_NOT_MOUNTED id SD card is not mounted, otherwise RETURN_OK * @return SD_NOT_MOUNTED id SD card is not mounted, otherwise RETURN_OK
*/ */
ReturnValue_t checkPath(std::string name); ReturnValue_t checkPath(std::string name);
#endif
/**
* @brief Unlocks a range of flash regions
*
* @param from First region in range to unlock
* @param to Last region in range to unlock
*
*/
ReturnValue_t unlockAndEraseRegions(uint32_t from, uint32_t to);
/**
* @brief Creates full filename either with timestamp or without
*
* @param path Path where to create the file
* @param filename Name fo the file
*
* @return Full filename
*/
std::string makeFullFilename(std::string path, std::string filename);
}; };
#endif /* BSP_Q7S_DEVICES_STRHELPER_H_ */ #endif /* BSP_Q7S_DEVICES_STRHELPER_H_ */

View File

@ -9,6 +9,7 @@
#cmakedefine RASPBERRY_PI #cmakedefine RASPBERRY_PI
#cmakedefine XIPHOS_Q7S #cmakedefine XIPHOS_Q7S
#cmakedefine BEAGLEBONEBLACK #cmakedefine BEAGLEBONEBLACK
#cmakedefine EGSE
#ifdef RASPBERRY_PI #ifdef RASPBERRY_PI
#include "rpiConfig.h" #include "rpiConfig.h"
@ -55,10 +56,16 @@ debugging. */
#define OBSW_ADD_PL_PCDU 0 #define OBSW_ADD_PL_PCDU 0
#define OBSW_ADD_SYRLINKS 0 #define OBSW_ADD_SYRLINKS 0
#define OBSW_ENABLE_SYRLINKS_TRANSMIT_TIMEOUT 0 #define OBSW_ENABLE_SYRLINKS_TRANSMIT_TIMEOUT 0
#define OBSW_SYRLINKS_SIMULATED 1
#define OBSW_STAR_TRACKER_GROUND_CONFIG 1
#define OBSW_ENABLE_PERIODIC_HK 0 #define OBSW_ENABLE_PERIODIC_HK 0
#endif #endif
#ifdef EGSE
#define OBSW_ADD_STAR_TRACKER 1
#endif
/*******************************************************************/ /*******************************************************************/
/** All of the following flags should be disabled for mission code */ /** All of the following flags should be disabled for mission code */
/*******************************************************************/ /*******************************************************************/
@ -104,11 +111,16 @@ debugging. */
#define OBSW_DEBUG_SYRLINKS 0 #define OBSW_DEBUG_SYRLINKS 0
#define OBSW_DEBUG_IMTQ 0 #define OBSW_DEBUG_IMTQ 0
#define OBSW_DEBUG_RW 0 #define OBSW_DEBUG_RW 0
#define OBSW_DEBUG_STARTRACKER 0
#define OBSW_DEBUG_PLOC_MPSOC 0 #define OBSW_DEBUG_PLOC_MPSOC 0
#define OBSW_DEBUG_PLOC_SUPERVISOR 0 #define OBSW_DEBUG_PLOC_SUPERVISOR 0
#define OBSW_DEBUG_PDEC_HANDLER 0 #define OBSW_DEBUG_PDEC_HANDLER 0
#ifdef EGSE
#define OBSW_DEBUG_STARTRACKER 1
#else
#define OBSW_DEBUG_STARTRACKER 0
#endif
#ifdef RASPBERRY_PI #ifdef RASPBERRY_PI
#define OBSW_ENABLE_TIMERS 1 #define OBSW_ENABLE_TIMERS 1

View File

@ -1,7 +1,7 @@
/** /**
* @brief Auto-generated event translation file. Contains 140 translations. * @brief Auto-generated event translation file. Contains 139 translations.
* @details * @details
* Generated on: 2022-02-03 17:30:40 * Generated on: 2022-02-27 15:36:42
*/ */
#include "translateEvents.h" #include "translateEvents.h"
@ -107,6 +107,8 @@ const char *SELF_TEST_MTM_RANGE_FAILURE_STRING = "SELF_TEST_MTM_RANGE_FAILURE";
const char *SELF_TEST_COIL_CURRENT_FAILURE_STRING = "SELF_TEST_COIL_CURRENT_FAILURE"; const char *SELF_TEST_COIL_CURRENT_FAILURE_STRING = "SELF_TEST_COIL_CURRENT_FAILURE";
const char *INVALID_ERROR_BYTE_STRING = "INVALID_ERROR_BYTE"; const char *INVALID_ERROR_BYTE_STRING = "INVALID_ERROR_BYTE";
const char *ERROR_STATE_STRING = "ERROR_STATE"; const char *ERROR_STATE_STRING = "ERROR_STATE";
const char *BOOTING_FIRMWARE_FAILED_STRING = "BOOTING_FIRMWARE_FAILED";
const char *BOOTING_BOOTLOADER_FAILED_STRING = "BOOTING_BOOTLOADER_FAILED";
const char *SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING = "SUPV_MEMORY_READ_RPT_CRC_FAILURE"; const char *SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING = "SUPV_MEMORY_READ_RPT_CRC_FAILURE";
const char *SUPV_ACK_FAILURE_STRING = "SUPV_ACK_FAILURE"; const char *SUPV_ACK_FAILURE_STRING = "SUPV_ACK_FAILURE";
const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE"; const char *SUPV_EXE_FAILURE_STRING = "SUPV_EXE_FAILURE";
@ -131,12 +133,9 @@ const char *IMAGE_UPLOAD_SUCCESSFUL_STRING = "IMAGE_UPLOAD_SUCCESSFUL";
const char *IMAGE_DOWNLOAD_SUCCESSFUL_STRING = "IMAGE_DOWNLOAD_SUCCESSFUL"; const char *IMAGE_DOWNLOAD_SUCCESSFUL_STRING = "IMAGE_DOWNLOAD_SUCCESSFUL";
const char *FLASH_WRITE_SUCCESSFUL_STRING = "FLASH_WRITE_SUCCESSFUL"; const char *FLASH_WRITE_SUCCESSFUL_STRING = "FLASH_WRITE_SUCCESSFUL";
const char *FLASH_READ_SUCCESSFUL_STRING = "FLASH_READ_SUCCESSFUL"; const char *FLASH_READ_SUCCESSFUL_STRING = "FLASH_READ_SUCCESSFUL";
const char *FLASH_WRITE_FAILED_STRING = "FLASH_WRITE_FAILED";
const char *FLASH_READ_FAILED_STRING = "FLASH_READ_FAILED"; const char *FLASH_READ_FAILED_STRING = "FLASH_READ_FAILED";
const char *FPGA_DOWNLOAD_SUCCESSFUL_STRING = "FPGA_DOWNLOAD_SUCCESSFUL"; const char *FIRMWARE_UPDATE_SUCCESSFUL_STRING = "FIRMWARE_UPDATE_SUCCESSFUL";
const char *FPGA_DOWNLOAD_FAILED_STRING = "FPGA_DOWNLOAD_FAILED"; const char *FIRMWARE_UPDATE_FAILED_STRING = "FIRMWARE_UPDATE_FAILED";
const char *FPGA_UPLOAD_SUCCESSFUL_STRING = "FPGA_UPLOAD_SUCCESSFUL";
const char *FPGA_UPLOAD_FAILED_STRING = "FPGA_UPLOAD_FAILED";
const char *STR_HELPER_READING_REPLY_FAILED_STRING = "STR_HELPER_READING_REPLY_FAILED"; const char *STR_HELPER_READING_REPLY_FAILED_STRING = "STR_HELPER_READING_REPLY_FAILED";
const char *STR_HELPER_COM_ERROR_STRING = "STR_HELPER_COM_ERROR"; const char *STR_HELPER_COM_ERROR_STRING = "STR_HELPER_COM_ERROR";
const char *STR_HELPER_NO_REPLY_STRING = "STR_HELPER_NO_REPLY"; const char *STR_HELPER_NO_REPLY_STRING = "STR_HELPER_NO_REPLY";
@ -352,6 +351,10 @@ const char *translateEvents(Event event) {
return INVALID_ERROR_BYTE_STRING; return INVALID_ERROR_BYTE_STRING;
case (11301): case (11301):
return ERROR_STATE_STRING; return ERROR_STATE_STRING;
case (11401):
return BOOTING_FIRMWARE_FAILED_STRING;
case (11402):
return BOOTING_BOOTLOADER_FAILED_STRING;
case (11501): case (11501):
return SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING; return SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING;
case (11502): case (11502):
@ -401,32 +404,26 @@ const char *translateEvents(Event event) {
case (12005): case (12005):
return FLASH_READ_SUCCESSFUL_STRING; return FLASH_READ_SUCCESSFUL_STRING;
case (12006): case (12006):
return FLASH_WRITE_FAILED_STRING;
case (12007):
return FLASH_READ_FAILED_STRING; return FLASH_READ_FAILED_STRING;
case (12007):
return FIRMWARE_UPDATE_SUCCESSFUL_STRING;
case (12008): case (12008):
return FPGA_DOWNLOAD_SUCCESSFUL_STRING; return FIRMWARE_UPDATE_FAILED_STRING;
case (12009): case (12009):
return FPGA_DOWNLOAD_FAILED_STRING;
case (12010):
return FPGA_UPLOAD_SUCCESSFUL_STRING;
case (12011):
return FPGA_UPLOAD_FAILED_STRING;
case (12012):
return STR_HELPER_READING_REPLY_FAILED_STRING; return STR_HELPER_READING_REPLY_FAILED_STRING;
case (12013): case (12010):
return STR_HELPER_COM_ERROR_STRING; return STR_HELPER_COM_ERROR_STRING;
case (12014): case (12011):
return STR_HELPER_NO_REPLY_STRING; return STR_HELPER_NO_REPLY_STRING;
case (12015): case (12012):
return STR_HELPER_DEC_ERROR_STRING; return STR_HELPER_DEC_ERROR_STRING;
case (12016): case (12013):
return POSITION_MISMATCH_STRING; return POSITION_MISMATCH_STRING;
case (12017): case (12014):
return STR_HELPER_FILE_NOT_EXISTS_STRING; return STR_HELPER_FILE_NOT_EXISTS_STRING;
case (12018): case (12015):
return STR_HELPER_SENDING_PACKET_FAILED_STRING; return STR_HELPER_SENDING_PACKET_FAILED_STRING;
case (12019): case (12016):
return STR_HELPER_REQUESTING_MSG_FAILED_STRING; return STR_HELPER_REQUESTING_MSG_FAILED_STRING;
default: default:
return "UNKNOWN_EVENT"; return "UNKNOWN_EVENT";

View File

@ -1,8 +1,8 @@
/** /**
* @brief Auto-generated object translation file. * @brief Auto-generated object translation file.
* @details * @details
* Contains 111 translations. * Contains 112 translations.
* Generated on: 2022-02-21 17:31:37 * Generated on: 2022-02-27 15:36:48
*/ */
#include "translateObjects.h" #include "translateObjects.h"
@ -82,6 +82,7 @@ const char *PUS_PACKET_DISTRIBUTOR_STRING = "PUS_PACKET_DISTRIBUTOR";
const char *TMTC_BRIDGE_STRING = "TMTC_BRIDGE"; const char *TMTC_BRIDGE_STRING = "TMTC_BRIDGE";
const char *TMTC_POLLING_TASK_STRING = "TMTC_POLLING_TASK"; const char *TMTC_POLLING_TASK_STRING = "TMTC_POLLING_TASK";
const char *FILE_SYSTEM_HANDLER_STRING = "FILE_SYSTEM_HANDLER"; const char *FILE_SYSTEM_HANDLER_STRING = "FILE_SYSTEM_HANDLER";
const char *SDC_MANAGER_STRING = "SDC_MANAGER";
const char *PTME_STRING = "PTME"; const char *PTME_STRING = "PTME";
const char *PDEC_HANDLER_STRING = "PDEC_HANDLER"; const char *PDEC_HANDLER_STRING = "PDEC_HANDLER";
const char *CCSDS_HANDLER_STRING = "CCSDS_HANDLER"; const char *CCSDS_HANDLER_STRING = "CCSDS_HANDLER";
@ -272,6 +273,8 @@ const char *translateObject(object_id_t object) {
return TMTC_POLLING_TASK_STRING; return TMTC_POLLING_TASK_STRING;
case 0x50000500: case 0x50000500:
return FILE_SYSTEM_HANDLER_STRING; return FILE_SYSTEM_HANDLER_STRING;
case 0x50000550:
return SDC_MANAGER_STRING;
case 0x50000600: case 0x50000600:
return PTME_STRING; return PTME_STRING;
case 0x50000700: case 0x50000700:

View File

@ -447,6 +447,7 @@ ReturnValue_t pst::pstI2c(FixedTimeslotTaskIF *thisSequence) {
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::BPX_BATT_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ);
#endif #endif
static_cast<void>(length);
if (thisSequence->checkSequence() != HasReturnvaluesIF::RETURN_OK) { if (thisSequence->checkSequence() != HasReturnvaluesIF::RETURN_OK) {
sif::error << "I2C PST initialization failed" << std::endl; sif::error << "I2C PST initialization failed" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
@ -469,9 +470,11 @@ ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) {
thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::PLOC_MPSOC_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ);
#endif #endif
#ifdef XIPHOS_Q7S
thisSequence->addSlot(objects::PLOC_UPDATER, length * 0, DeviceHandlerIF::PERFORM_OPERATION); thisSequence->addSlot(objects::PLOC_UPDATER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::PLOC_MEMORY_DUMPER, length * 0, thisSequence->addSlot(objects::PLOC_MEMORY_DUMPER, length * 0,
DeviceHandlerIF::PERFORM_OPERATION); DeviceHandlerIF::PERFORM_OPERATION);
#endif
#if OBSW_ADD_PLOC_SUPERVISOR == 1 #if OBSW_ADD_PLOC_SUPERVISOR == 1
thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0, thisSequence->addSlot(objects::PLOC_SUPERVISOR_HANDLER, length * 0,
DeviceHandlerIF::PERFORM_OPERATION); DeviceHandlerIF::PERFORM_OPERATION);
@ -500,7 +503,7 @@ ReturnValue_t pst::pstUart(FixedTimeslotTaskIF *thisSequence) {
thisSequence->addSlot(objects::STAR_TRACKER, length * 0.6, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::STAR_TRACKER, length * 0.6, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::STAR_TRACKER, length * 0.8, DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::STAR_TRACKER, length * 0.8, DeviceHandlerIF::GET_READ);
#endif #endif
static_cast<void>(length);
if (uartPstEmpty) { if (uartPstEmpty) {
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }

View File

@ -19,7 +19,7 @@ ReturnValue_t NVMParameterBase::readJsonFile() {
ReturnValue_t NVMParameterBase::writeJsonFile() { ReturnValue_t NVMParameterBase::writeJsonFile() {
std::ofstream o(fullName); std::ofstream o(fullName);
o << std::setw(4) << json; o << std::setw(4) << json << std::endl;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }

View File

@ -34,7 +34,7 @@ class NVMParameterBase : public HasReturnvaluesIF {
ReturnValue_t setValue(std::string key, T value); ReturnValue_t setValue(std::string key, T value);
template <typename T> template <typename T>
ReturnValue_t getValue(std::string key, T* value) const; ReturnValue_t getValue(std::string key, T& value) const;
void printKeys() const; void printKeys() const;
void print() const; void print() const;
@ -67,11 +67,11 @@ inline ReturnValue_t NVMParameterBase::setValue(std::string key, T value) {
} }
template <typename T> template <typename T>
inline ReturnValue_t NVMParameterBase::getValue(std::string key, T* value) const { inline ReturnValue_t NVMParameterBase::getValue(std::string key, T& value) const {
if (!json.contains(key)) { if (!json.contains(key)) {
return KEY_NOT_EXISTS; return KEY_NOT_EXISTS;
} }
*value = json[key]; value = json[key];
return RETURN_OK; return RETURN_OK;
} }

View File

@ -1,6 +1,7 @@
target_sources(${LIB_EIVE_MISSION} PRIVATE target_sources(${LIB_EIVE_MISSION} PRIVATE
TmFunnel.cpp TmFunnel.cpp
Timestamp.cpp Timestamp.cpp
ProgressPrinter.cpp
) )

View File

@ -0,0 +1,16 @@
#include "ProgressPrinter.h"
#include "fsfw/serviceinterface/ServiceInterfaceStream.h"
ProgressPrinter::ProgressPrinter(std::string name, uint32_t numSteps)
: name(name), numSteps(numSteps) {}
ProgressPrinter::~ProgressPrinter() {
}
void ProgressPrinter::print(uint32_t currentStep) {
float progressInPercent = static_cast<float>(currentStep) / static_cast<float>(numSteps) * 100;
if (static_cast<uint32_t>(progressInPercent) >= nextProgressPrint) {
sif::info << name << " progress: " << progressInPercent << " %" << std::endl;
nextProgressPrint += FIVE_PERCENT;
}
}

View File

@ -0,0 +1,37 @@
#ifndef MISSION_UTILITY_PROGRESSPRINTER_H_
#define MISSION_UTILITY_PROGRESSPRINTER_H_
#include <string>
/**
* @brief Class which can be used to print the progress of processes in percent.
*
* @author J. Meier
*/
class ProgressPrinter {
public:
/**
* @brief Constructor
*
* @param name Name of the process to monitor
* @param numSteps Number of steps to execute
*/
ProgressPrinter(std::string name, uint32_t numSteps);
virtual ~ProgressPrinter();
/**
* @brief Will print the progress
*
* @param currentStep Current step from which to derive progress
*/
void print(uint32_t step);
private:
static constexpr uint32_t FIVE_PERCENT = 5;
std::string name = "";
uint32_t numSteps = 0;
uint32_t nextProgressPrint = 0;
};
#endif /* MISSION_UTILITY_PROGRESSPRINTER_H_ */

View File

@ -8,4 +8,7 @@ find ./linux -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --sty
find ./bsp_q7s -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i find ./bsp_q7s -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i
find ./bsp_linux_board -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i find ./bsp_linux_board -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i
find ./bsp_hosted -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i find ./bsp_hosted -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i
find ./bsp_egse -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i
find ./test -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i find ./test -iname *.h -o -iname *.cpp -o -iname *.c | xargs clang-format --style=file -i
find ./unittest -iname *.h -o -iname *.cpp -o -iname *.c -o -type d -name build -prune | \
xargs clang-format --style=file -i

6
scripts/egse-port.sh Normal file
View File

@ -0,0 +1,6 @@
#!/bin/bash
echo "-L 1534:localhost:1534 pi@192.168.18.31 portforwarding for tcf agent"
echo "-L 1537:localhost:7301 pi@192.168.18.31 for TMTC commanding using the TCP/IP IF"
ssh -L 1534:localhost:1534 \
-L 1537:localhost:7301 pi@192.168.18.31

@ -1 +1 @@
Subproject commit 5d5e46b09bbd5208176c68d94c798493e705a2ee Subproject commit b1594df9303056456604726592635d8a1c987e75

2
tmtc

@ -1 +1 @@
Subproject commit 7e24589184bb7bbd427c66ed55b3c29bbeba927f Subproject commit 54b319a48757cdae2ed7b89f3af3e29500c31588

View File

@ -4,4 +4,3 @@
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
// fsfwtest::customMain(argc, argv); // fsfwtest::customMain(argc, argv);
} }

2
unittest/rebootLogic/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/build
c_cpp_properties.json

View File

@ -0,0 +1,51 @@
{
"editor.tabSize": 2,
"files.associations": {
"iosfwd": "cpp",
"array": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"chrono": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"concepts": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"fstream": "cpp",
"functional": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"new": "cpp",
"numbers": "cpp",
"optional": "cpp",
"ostream": "cpp",
"ratio": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"type_traits": "cpp",
"tuple": "cpp",
"typeinfo": "cpp",
"utility": "cpp",
"variant": "cpp",
"filesystem": "cpp",
"queue": "cpp"
}
}

View File

@ -0,0 +1,29 @@
cmake_minimum_required(VERSION 3.13.0)
project(reboot-logic VERSION 0.1.0)
include(CTest)
find_package(Catch2 3)
if(NOT Catch2_FOUND)
include(FetchContent)
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v3.0.0-preview4
)
FetchContent_MakeAvailable(Catch2)
#fixes regression -preview4, to be confirmed in later releases
set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "")
endif()
enable_testing()
add_executable(reboot-logic)
add_subdirectory(src)
target_link_libraries(reboot-logic PRIVATE Catch2::Catch2WithMain)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)

View File

@ -0,0 +1,16 @@
Reboot Logic Unittest
=======
These tests were written with Catch2 and VS code.
Install VS code with the C++ and CMake plugins and open this folder with VS code.
You should be able to run the tests directly.
It is also recommended to [install Catch2](https://github.com/catchorg/Catch2/blob/devel/docs/cmake-integration.md):
```sh
git clone https://github.com/catchorg/Catch2.git
cd Catch2
git checkout v3.0.0-preview4
cmake -Bbuild -H. -DBUILD_TESTING=OFF
sudo cmake --build build/ --target install
```

View File

@ -0,0 +1,14 @@
target_sources(reboot-logic PRIVATE
main.cpp
CoreController.cpp
SdCardManager.cpp
event.cpp
libxiphos.cpp
print.c
)
target_include_directories(reboot-logic PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
add_subdirectory(fsfw)

View File

@ -0,0 +1,529 @@
#include "CoreController.h"
#include <filesystem>
#include <fstream>
#include <iostream>
#include "HasActionsIF.h"
#include "SdCardManager.h"
#include "conf.h"
#include "event.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
#include "libxiphos.h"
xsc::Chip CoreController::CURRENT_CHIP = xsc::Chip::NO_CHIP;
xsc::Copy CoreController::CURRENT_COPY = xsc::Copy::NO_COPY;
CoreController::CoreController() {
sdcMan = new SdCardManager();
setCurrentBootCopy(xsc::CHIP_0, xsc::COPY_0);
}
void CoreController::performRebootFileHandling(bool recreateFile) {
using namespace std;
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE;
if (not std::filesystem::exists(path) or recreateFile) {
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "CoreController::performRebootFileHandling: Recreating reboot file" << std::endl;
#endif
rebootFile.enabled = true;
rebootFile.img00Cnt = 0;
rebootFile.img01Cnt = 0;
rebootFile.img10Cnt = 0;
rebootFile.img11Cnt = 0;
rebootFile.lastChip = xsc::Chip::CHIP_0;
rebootFile.lastCopy = xsc::Copy::COPY_0;
rebootFile.img00Lock = false;
rebootFile.img01Lock = false;
rebootFile.img10Lock = false;
rebootFile.img11Lock = false;
rebootFile.mechanismNextChip = xsc::Chip::NO_CHIP;
rebootFile.mechanismNextCopy = xsc::Copy::NO_COPY;
rebootFile.bootFlag = false;
rewriteRebootFile(rebootFile);
} else {
if (not parseRebootFile(path, rebootFile)) {
performRebootFileHandling(true);
}
}
if (CURRENT_CHIP == xsc::CHIP_0) {
if (CURRENT_COPY == xsc::COPY_0) {
rebootFile.img00Cnt++;
} else {
rebootFile.img01Cnt++;
}
} else {
if (CURRENT_COPY == xsc::COPY_0) {
rebootFile.img10Cnt++;
} else {
rebootFile.img11Cnt++;
}
}
if (rebootFile.bootFlag) {
// Trigger event to inform ground that a reboot was triggered
uint32_t p1 = rebootFile.lastChip << 16 | rebootFile.lastCopy;
uint32_t p2 = rebootFile.img00Cnt << 24 | rebootFile.img01Cnt << 16 | rebootFile.img10Cnt << 8 |
rebootFile.img11Cnt;
triggerEvent(REBOOT_MECHANISM_TRIGGERED, p1, p2);
// Clear the boot flag
rebootFile.bootFlag = false;
}
if (rebootFile.mechanismNextChip != xsc::NO_CHIP and
rebootFile.mechanismNextCopy != xsc::NO_COPY) {
if (CURRENT_CHIP != rebootFile.mechanismNextChip or
CURRENT_COPY != rebootFile.mechanismNextCopy) {
std::string infoString = std::to_string(rebootFile.mechanismNextChip) + " " +
std::to_string(rebootFile.mechanismNextCopy);
sif::warning << "CoreController::performRebootFileHandling: Expected to be on image "
<< infoString << " but currently on other image. Locking " << infoString
<< std::endl;
// Firmware or other component might be corrupt and we are on another image then the target
// image specified by the mechanism. We can't really trust the target image anymore.
// Lock it for now
if (rebootFile.mechanismNextChip == xsc::CHIP_0) {
if (rebootFile.mechanismNextCopy == xsc::COPY_0) {
rebootFile.img00Lock = true;
} else {
rebootFile.img01Lock = true;
}
} else {
if (rebootFile.mechanismNextCopy == xsc::COPY_0) {
rebootFile.img10Lock = true;
} else {
rebootFile.img11Lock = true;
}
}
}
}
rebootFile.lastChip = CURRENT_CHIP;
rebootFile.lastCopy = CURRENT_COPY;
// Only reboot if the reboot functionality is enabled.
// The handler will still increment the boot counts
if (rebootFile.enabled and (*rebootFile.relevantBootCnt >= rebootFile.maxCount)) {
// Reboot to other image
bool doReboot = false;
xsc::Chip tgtChip = xsc::NO_CHIP;
xsc::Copy tgtCopy = xsc::NO_COPY;
determineAndExecuteReboot(rebootFile, doReboot, tgtChip, tgtCopy);
if (doReboot) {
rebootFile.bootFlag = true;
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "Boot counter for image " << CURRENT_CHIP << " " << CURRENT_COPY
<< " too high. Rebooting to " << tgtChip << " " << tgtCopy << std::endl;
#endif
rebootFile.mechanismNextChip = tgtChip;
rebootFile.mechanismNextCopy = tgtCopy;
rewriteRebootFile(rebootFile);
xsc_boot_copy(static_cast<xsc_libnor_chip_t>(tgtChip),
static_cast<xsc_libnor_copy_t>(tgtCopy));
}
} else {
rebootFile.mechanismNextChip = xsc::NO_CHIP;
rebootFile.mechanismNextCopy = xsc::NO_COPY;
}
rewriteRebootFile(rebootFile);
}
void CoreController::determineAndExecuteReboot(RebootFile &rf, bool &needsReboot,
xsc::Chip &tgtChip, xsc::Copy &tgtCopy) {
tgtChip = xsc::CHIP_0;
tgtCopy = xsc::COPY_0;
needsReboot = false;
if ((CURRENT_CHIP == xsc::CHIP_0) and (CURRENT_COPY == xsc::COPY_0) and
(rf.img00Cnt >= rf.maxCount)) {
needsReboot = true;
if (rf.img01Cnt < rf.maxCount and not rf.img01Lock) {
tgtCopy = xsc::COPY_1;
return;
}
if (rf.img10Cnt < rf.maxCount and not rf.img10Lock) {
tgtChip = xsc::CHIP_1;
return;
}
if (rf.img11Cnt < rf.maxCount and not rf.img11Lock) {
tgtChip = xsc::CHIP_1;
tgtCopy = xsc::COPY_1;
return;
}
// Can't really do much here. Stay on image
sif::warning
<< "All reboot counts too high or all fallback images locked, already on fallback image"
<< std::endl;
needsReboot = false;
return;
}
if ((CURRENT_CHIP == xsc::CHIP_0) and (CURRENT_COPY == xsc::COPY_1) and
(rf.img01Cnt >= rf.maxCount)) {
needsReboot = true;
if (rf.img00Cnt < rf.maxCount and not rf.img00Lock) {
// Reboot on fallback image
return;
}
if (rf.img10Cnt < rf.maxCount and not rf.img10Lock) {
tgtChip = xsc::CHIP_1;
return;
}
if (rf.img11Cnt < rf.maxCount and not rf.img11Lock) {
tgtChip = xsc::CHIP_1;
tgtCopy = xsc::COPY_1;
}
if (rf.img00Lock) {
needsReboot = false;
}
// Reboot to fallback image
}
if ((CURRENT_CHIP == xsc::CHIP_1) and (CURRENT_COPY == xsc::COPY_0) and
(rf.img10Cnt >= rf.maxCount)) {
needsReboot = true;
if (rf.img11Cnt < rf.maxCount and not rf.img11Lock) {
tgtChip = xsc::CHIP_1;
tgtCopy = xsc::COPY_1;
return;
}
if (rf.img00Cnt < rf.maxCount and not rf.img00Lock) {
return;
}
if (rf.img01Cnt < rf.maxCount and not rf.img01Lock) {
tgtCopy = xsc::COPY_1;
return;
}
if (rf.img00Lock) {
needsReboot = false;
}
// Reboot to fallback image
}
if ((CURRENT_CHIP == xsc::CHIP_1) and (CURRENT_COPY == xsc::COPY_1) and
(rf.img11Cnt >= rf.maxCount)) {
needsReboot = true;
if (rf.img10Cnt < rf.maxCount and not rf.img10Lock) {
tgtChip = xsc::CHIP_1;
return;
}
if (rf.img00Cnt < rf.maxCount and not rf.img00Lock) {
return;
}
if (rf.img01Cnt < rf.maxCount and not rf.img01Lock) {
tgtCopy = xsc::COPY_1;
return;
}
if (rf.img00Lock) {
needsReboot = false;
}
// Reboot to fallback image
}
}
bool CoreController::parseRebootFile(std::string path, RebootFile &rf) {
using namespace std;
std::string selfMatch;
if (CURRENT_CHIP == xsc::CHIP_0) {
if (CURRENT_COPY == xsc::COPY_0) {
selfMatch = "00";
} else {
selfMatch = "01";
}
} else {
if (CURRENT_COPY == xsc::COPY_0) {
selfMatch = "10";
} else {
selfMatch = "11";
}
}
ifstream file(path);
string word;
string line;
uint8_t lineIdx = 0;
while (std::getline(file, line)) {
istringstream iss(line);
switch (lineIdx) {
case 0: {
iss >> word;
if (word.find("on:") == string::npos) {
// invalid file
return false;
}
iss >> rf.enabled;
break;
}
case 1: {
iss >> word;
if (word.find("maxcnt:") == string::npos) {
return false;
}
iss >> rf.maxCount;
break;
}
case 2: {
iss >> word;
if (word.find("img00:") == string::npos) {
return false;
}
iss >> rf.img00Cnt;
if (word.find(selfMatch) != string::npos) {
rf.relevantBootCnt = &rf.img00Cnt;
}
break;
}
case 3: {
iss >> word;
if (word.find("img01:") == string::npos) {
return false;
}
iss >> rf.img01Cnt;
if (word.find(selfMatch) != string::npos) {
rf.relevantBootCnt = &rf.img01Cnt;
}
break;
}
case 4: {
iss >> word;
if (word.find("img10:") == string::npos) {
return false;
}
iss >> rf.img10Cnt;
if (word.find(selfMatch) != string::npos) {
rf.relevantBootCnt = &rf.img10Cnt;
}
break;
}
case 5: {
iss >> word;
if (word.find("img11:") == string::npos) {
return false;
}
iss >> rf.img11Cnt;
if (word.find(selfMatch) != string::npos) {
rf.relevantBootCnt = &rf.img11Cnt;
}
break;
}
case 6: {
iss >> word;
if (word.find("img00lock:") == string::npos) {
return false;
}
iss >> rf.img00Lock;
break;
}
case 7: {
iss >> word;
if (word.find("img01lock:") == string::npos) {
return false;
}
iss >> rf.img01Lock;
break;
}
case 8: {
iss >> word;
if (word.find("img10lock:") == string::npos) {
return false;
}
iss >> rf.img10Lock;
break;
}
case 9: {
iss >> word;
if (word.find("img11lock:") == string::npos) {
return false;
}
iss >> rf.img11Lock;
break;
}
case 10: {
iss >> word;
if (word.find("bootflag:") == string::npos) {
return false;
}
iss >> rf.bootFlag;
break;
}
case 11: {
iss >> word;
int copyRaw = 0;
int chipRaw = 0;
if (word.find("last:") == string::npos) {
return false;
}
iss >> chipRaw;
if (iss.fail()) {
return false;
}
iss >> copyRaw;
if (iss.fail()) {
return false;
}
if (chipRaw > 1 or copyRaw > 1) {
return false;
}
rf.lastChip = static_cast<xsc::Chip>(chipRaw);
rf.lastCopy = static_cast<xsc::Copy>(copyRaw);
break;
}
case 12: {
iss >> word;
int copyRaw = 0;
int chipRaw = 0;
if (word.find("next:") == string::npos) {
return false;
}
iss >> chipRaw;
if (iss.fail()) {
return false;
}
iss >> copyRaw;
if (iss.fail()) {
return false;
}
if (chipRaw > 2 or copyRaw > 2) {
return false;
}
rf.mechanismNextChip = static_cast<xsc::Chip>(chipRaw);
rf.mechanismNextCopy = static_cast<xsc::Copy>(copyRaw);
break;
}
}
if (iss.fail()) {
return false;
}
lineIdx++;
}
if (lineIdx < 12) {
return false;
}
return true;
}
void CoreController::resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy) {
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE;
// Disable the reboot file mechanism
parseRebootFile(path, rebootFile);
if (tgtChip == xsc::ALL_CHIP and tgtCopy == xsc::ALL_COPY) {
rebootFile.img00Cnt = 0;
rebootFile.img01Cnt = 0;
rebootFile.img10Cnt = 0;
rebootFile.img11Cnt = 0;
} else {
if (tgtChip == xsc::CHIP_0) {
if (tgtCopy == xsc::COPY_0) {
rebootFile.img00Cnt = 0;
} else {
rebootFile.img01Cnt = 0;
}
} else {
if (tgtCopy == xsc::COPY_0) {
rebootFile.img10Cnt = 0;
} else {
rebootFile.img11Cnt = 0;
}
}
}
rewriteRebootFile(rebootFile);
}
void CoreController::rewriteRebootFile(RebootFile file) {
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE;
std::ofstream rebootFile(path);
if (rebootFile.is_open()) {
// Initiate reboot file first. Reboot handling will be on on initialization
rebootFile << "on: " << file.enabled << "\nmaxcnt: " << file.maxCount
<< "\nimg00: " << file.img00Cnt << "\nimg01: " << file.img01Cnt
<< "\nimg10: " << file.img10Cnt << "\nimg11: " << file.img11Cnt
<< "\nimg00lock: " << file.img00Lock << "\nimg01lock: " << file.img01Lock
<< "\nimg10lock: " << file.img10Lock << "\nimg11lock: " << file.img11Lock
<< "\nbootflag: " << file.bootFlag << "\nlast: " << static_cast<int>(file.lastChip)
<< " " << static_cast<int>(file.lastCopy)
<< "\nnext: " << static_cast<int>(file.mechanismNextChip) << " "
<< static_cast<int>(file.mechanismNextCopy) << "\n";
}
}
ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t *data, size_t size) {
switch (actionId) {
case (SWITCH_REBOOT_FILE_HANDLING): {
if (size < 1) {
return HasActionsIF::INVALID_PARAMETERS;
}
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE;
// Disable the reboot file mechanism
parseRebootFile(path, rebootFile);
if (data[0] == 0) {
rebootFile.enabled = false;
rewriteRebootFile(rebootFile);
} else if (data[0] == 1) {
rebootFile.enabled = true;
rewriteRebootFile(rebootFile);
} else {
return HasActionsIF::INVALID_PARAMETERS;
}
return HasActionsIF::EXECUTION_FINISHED;
}
case (RESET_REBOOT_COUNTERS): {
if (size == 0) {
resetRebootCount(xsc::ALL_CHIP, xsc::ALL_COPY);
} else if (size == 2) {
if (data[0] > 1 or data[1] > 1) {
return HasActionsIF::INVALID_PARAMETERS;
}
resetRebootCount(static_cast<xsc::Chip>(data[0]), static_cast<xsc::Copy>(data[1]));
}
return HasActionsIF::EXECUTION_FINISHED;
}
case (SWITCH_IMG_LOCK): {
if (size != 3) {
return HasActionsIF::INVALID_PARAMETERS;
}
if (data[1] > 1 or data[2] > 1) {
return HasActionsIF::INVALID_PARAMETERS;
}
setRebootMechanismLock(data[0], static_cast<xsc::Chip>(data[1]),
static_cast<xsc::Copy>(data[2]));
return HasActionsIF::EXECUTION_FINISHED;
}
case (SET_MAX_REBOOT_CNT): {
if (size < 1) {
return HasActionsIF::INVALID_PARAMETERS;
}
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE;
// Disable the reboot file mechanism
parseRebootFile(path, rebootFile);
rebootFile.maxCount = data[0];
rewriteRebootFile(rebootFile);
return HasActionsIF::EXECUTION_FINISHED;
}
default: {
return HasActionsIF::INVALID_ACTION_ID;
}
}
}
void CoreController::setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy) {
std::string path = sdcMan->getCurrentMountPrefix(sdInfo.pref) + REBOOT_FILE;
// Disable the reboot file mechanism
parseRebootFile(path, rebootFile);
if (tgtChip == xsc::CHIP_0) {
if (tgtCopy == xsc::COPY_0) {
rebootFile.img00Lock = lock;
} else {
rebootFile.img01Lock = lock;
}
} else {
if (tgtCopy == xsc::COPY_0) {
rebootFile.img10Lock = lock;
} else {
rebootFile.img11Lock = lock;
}
}
rewriteRebootFile(rebootFile);
}
void CoreController::setCurrentBootCopy(xsc::Chip chip, xsc::Copy copy) {
CURRENT_CHIP = chip;
CURRENT_COPY = copy;
}

View File

@ -0,0 +1,79 @@
#pragma once
#include <cstddef>
#include <cstdint>
#include <string>
#include "SdCardManager.h"
#include "definitions.h"
namespace xsc {
enum Chip : int { CHIP_0, CHIP_1, NO_CHIP, SELF_CHIP, ALL_CHIP };
enum Copy : int { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY };
} // namespace xsc
struct RebootFile {
static constexpr uint8_t DEFAULT_MAX_BOOT_CNT = 10;
bool enabled = true;
size_t maxCount = DEFAULT_MAX_BOOT_CNT;
uint32_t img00Cnt = 0;
uint32_t img01Cnt = 0;
uint32_t img10Cnt = 0;
uint32_t img11Cnt = 0;
bool img00Lock = false;
bool img01Lock = false;
bool img10Lock = false;
bool img11Lock = false;
uint32_t* relevantBootCnt = &img00Cnt;
bool bootFlag = false;
xsc::Chip lastChip = xsc::Chip::CHIP_0;
xsc::Copy lastCopy = xsc::Copy::COPY_0;
xsc::Chip mechanismNextChip = xsc::Chip::NO_CHIP;
xsc::Copy mechanismNextCopy = xsc::Copy::NO_COPY;
};
class SdCardManager;
class CoreController {
public:
static constexpr char REBOOT_FILE[] = "/conf/reboot.txt";
//! [EXPORT] : [COMMENT] The reboot mechanism was triggered.
//! P1: First 16 bits: Last Chip, Last 16 bits: Last Copy,
//! P2: Each byte is the respective reboot count for the slots
static constexpr Event REBOOT_MECHANISM_TRIGGERED = 1;
static xsc::Chip CURRENT_CHIP;
static xsc::Copy CURRENT_COPY;
static constexpr ActionId_t SWITCH_REBOOT_FILE_HANDLING = 5;
static constexpr ActionId_t RESET_REBOOT_COUNTERS = 6;
static constexpr ActionId_t SWITCH_IMG_LOCK = 7;
static constexpr ActionId_t SET_MAX_REBOOT_CNT = 8;
CoreController();
static void setCurrentBootCopy(xsc::Chip chip, xsc::Copy copy);
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size);
void performRebootFileHandling(bool recreateFile);
void determineAndExecuteReboot(RebootFile& rf, bool& needsReboot, xsc::Chip& tgtChip,
xsc::Copy& tgtCopy);
void setRebootMechanismLock(bool lock, xsc::Chip tgtChip, xsc::Copy tgtCopy);
void resetRebootCount(xsc::Chip tgtChip, xsc::Copy tgtCopy);
bool parseRebootFile(std::string path, RebootFile& file);
void rewriteRebootFile(RebootFile file);
private:
struct SdInfo {
sd::SdCard pref = sd::SdCard::NONE;
sd::SdState prefState = sd::SdState::OFF;
sd::SdCard other = sd::SdCard::NONE;
sd::SdState otherState = sd::SdState::OFF;
} sdInfo;
SdCardManager* sdcMan = nullptr;
RebootFile rebootFile = {};
bool doPerformRebootFileHandling = true;
};

View File

@ -0,0 +1,9 @@
#include "definitions.h"
class HasActionsIF {
public:
static const ReturnValue_t IS_BUSY = 1;
static const ReturnValue_t INVALID_PARAMETERS = 2;
static const ReturnValue_t EXECUTION_FINISHED = 3;
static const ReturnValue_t INVALID_ACTION_ID = 4;
};

View File

@ -0,0 +1,5 @@
#include "SdCardManager.h"
std::string SdCardManager::getCurrentMountPrefix(sd::SdCard prefSdCard) { return "/tmp"; }
bool SdCardManager::isSdCardMounted(sd::SdCard sdCard) { return true; }

View File

@ -0,0 +1,23 @@
#pragma once
#include <cstdint>
#include <string>
namespace sd {
enum SdState : uint8_t {
OFF = 0,
ON = 1,
// A mounted SD card is on as well
MOUNTED = 2
};
enum SdCard : uint8_t { SLOT_0 = 0, SLOT_1 = 1, BOTH, NONE };
} // namespace sd
class SdCardManager {
public:
std::string getCurrentMountPrefix(sd::SdCard prefSdCard);
bool isSdCardMounted(sd::SdCard sdCard);
};

View File

@ -0,0 +1 @@
#define OBSW_VERBOSE_LEVEL 1

View File

@ -0,0 +1,6 @@
#include <cstdint>
using Event = uint32_t;
using ActionId_t = uint32_t;
using MessageQueueId_t = uint32_t;
using ReturnValue_t = uint16_t;

View File

@ -0,0 +1,21 @@
#include "event.h"
#include <queue>
std::queue<EventInfo> EVENT_QUEUE = {};
void triggerEvent(Event event, uint32_t p1, uint32_t p2) {
EventInfo info = {};
info.event = event;
info.p1 = p1;
info.p2 = p2;
EVENT_QUEUE.push(info);
}
void eventWasCalled(EventInfo& eventInfo, uint32_t& numEvents) {
numEvents = EVENT_QUEUE.size();
if (not EVENT_QUEUE.empty()) {
eventInfo = std::move(EVENT_QUEUE.back());
EVENT_QUEUE.pop();
}
}

View File

@ -0,0 +1,41 @@
#pragma once
#include <cstdint>
#include <iostream>
#include "definitions.h"
struct EventInfo {
// That was just for testing, follow rule of 0
/*
EventInfo () {}
EventInfo (const EventInfo& other): event(other.event), p1(other.p1), p2(other.p2) {
std::cout << "Event info copy ctor called" << std::endl;
}
EventInfo &operator= (const EventInfo& other) {
std::cout << "Event info assignment ctor called" << std::endl;
this->event = other.event;
this->p1 = other.p1;
this->p2 = other.p2;
return *this;
}
EventInfo &operator= (EventInfo&& other) {
std::cout << "Event info move ctor called" << std::endl;
this->event = other.event;
this->p1 = other.p1;
this->p2 = other.p2;
return *this;
}
*/
uint32_t event = 0;
uint32_t p1 = 0;
uint32_t p2 = 0;
};
void triggerEvent(Event event, uint32_t p1, uint32_t p2);
void eventWasCalled(EventInfo& eventInfo, uint32_t& numEvents);

View File

@ -0,0 +1 @@
add_subdirectory(serviceinterface)

View File

@ -0,0 +1,9 @@
#pragma once
#include <cstddef>
#define FSFW_CPP_OSTREAM_ENABLED 1
namespace fsfwconfig {
static constexpr size_t FSFW_PRINT_BUFFER_SIZE = 256;
}

View File

@ -0,0 +1,4 @@
target_sources(reboot-logic PRIVATE
ServiceInterfaceStream.cpp
ServiceInterfaceBuffer.cpp
)

View File

@ -0,0 +1,13 @@
#ifndef FSFW_SERVICEINTERFACE_SERVICEINTERFACE_H_
#define FSFW_SERVICEINTERFACE_SERVICEINTERFACE_H_
#include "fsfw/FSFW.h"
#include "serviceInterfaceDefintions.h"
#if FSFW_CPP_OSTREAM_ENABLED == 1
#include "ServiceInterfaceStream.h"
#else
#include "ServiceInterfacePrinter.h"
#endif
#endif /* FSFW_SERVICEINTERFACE_SERVICEINTERFACE_H_ */

View File

@ -0,0 +1,252 @@
#include "ServiceInterfaceBuffer.h"
#if FSFW_CPP_OSTREAM_ENABLED == 1
#include <inttypes.h>
#include <cstring>
#include "fsfw/serviceinterface/serviceInterfaceDefintions.h"
#if defined(WIN32) && FSFW_COLORED_OUTPUT == 1
#include "Windows.h"
#endif
// to be implemented by bsp
extern "C" void printChar(const char*, bool errStream);
#ifndef UT699
ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string setMessage, bool addCrToPreamble,
bool buffered, bool errStream, uint16_t port)
: isActive(true),
logMessage(setMessage),
addCrToPreamble(addCrToPreamble),
buffered(buffered),
errStream(errStream) {
if (buffered) {
// Set pointers if the stream is buffered.
setp(buf, buf + BUF_SIZE);
}
#if FSFW_COLORED_OUTPUT == 1
if (setMessage.find("DEBUG") != std::string::npos) {
colorPrefix = sif::ANSI_COLOR_CYAN;
} else if (setMessage.find("INFO") != std::string::npos) {
colorPrefix = sif::ANSI_COLOR_GREEN;
} else if (setMessage.find("WARNING") != std::string::npos) {
colorPrefix = sif::ANSI_COLOR_MAGENTA;
} else if (setMessage.find("ERROR") != std::string::npos) {
colorPrefix = sif::ANSI_COLOR_RED;
} else {
colorPrefix = sif::ANSI_COLOR_RESET;
}
#ifdef WIN32
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD dwMode = 0;
GetConsoleMode(hOut, &dwMode);
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
SetConsoleMode(hOut, dwMode);
#endif
#endif
preamble.reserve(MAX_PREAMBLE_SIZE);
preamble.resize(MAX_PREAMBLE_SIZE);
}
void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) {
char array[BUF_SIZE];
uint32_t length = end - begin;
if (length > sizeof(array)) {
length = sizeof(array);
}
memcpy(array, begin, length);
for (; begin != end; begin++) {
if (errStream) {
printChar(begin, true);
} else {
printChar(begin, false);
}
}
}
#endif
int ServiceInterfaceBuffer::overflow(int c) {
if (not buffered and this->isActive) {
if (c != Traits::eof()) {
if (errStream) {
printChar(reinterpret_cast<const char*>(&c), true);
} else {
printChar(reinterpret_cast<const char*>(&c), false);
}
}
return 0;
}
// Handle output
putChars(pbase(), pptr());
if (c != Traits::eof()) {
char c2 = c;
// Handle the one character that didn't fit to buffer
putChars(&c2, &c2 + 1);
}
// This tells that buffer is empty again
setp(buf, buf + BUF_SIZE - 1);
// I'm not sure about this return value!
return 0;
}
int ServiceInterfaceBuffer::sync(void) {
if (not this->isActive and not buffered) {
if (not buffered) {
setp(buf, buf + BUF_SIZE - 1);
}
return 0;
}
if (not buffered) {
return 0;
}
size_t preambleSize = 0;
std::string* preamble = getPreamble(&preambleSize);
// Write logMessage and time
this->putChars(preamble->data(), preamble->data() + preambleSize);
// Handle output
this->putChars(pbase(), pptr());
// This tells that buffer is empty again
setp(buf, buf + BUF_SIZE - 1);
return 0;
}
bool ServiceInterfaceBuffer::isBuffered() const { return buffered; }
std::string* ServiceInterfaceBuffer::getPreamble(size_t* preambleSize) {
size_t currentSize = 0;
char* parsePosition = &preamble[0];
if (addCrToPreamble) {
preamble[0] = '\r';
currentSize += 1;
parsePosition += 1;
}
#if FSFW_COLORED_OUTPUT == 1
currentSize += sprintf(parsePosition, "%s", colorPrefix.c_str());
parsePosition += colorPrefix.size();
#endif
int32_t charCount =
sprintf(parsePosition, "%s%s | ", this->logMessage.c_str(), sif::ANSI_COLOR_RESET);
if (charCount < 0) {
printf("ServiceInterfaceBuffer: Failure parsing preamble\r\n");
return &preamble;
}
if (charCount > MAX_PREAMBLE_SIZE) {
printf(
"ServiceInterfaceBuffer: Char count too large for maximum "
"preamble size");
return &preamble;
}
currentSize += charCount;
if (preambleSize != nullptr) {
*preambleSize = currentSize;
}
return &preamble;
}
bool ServiceInterfaceBuffer::crAdditionEnabled() const { return addCrToPreamble; }
#if FSFW_COLORED_OUTPUT == 1
void ServiceInterfaceBuffer::setAsciiColorPrefix(std::string colorPrefix) {
this->colorPrefix = colorPrefix;
}
#endif
#ifdef UT699
#include "../osal/rtems/Interrupt.h"
ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string set_message, uint16_t port) {
this->log_message = set_message;
this->isActive = true;
setp(buf, buf + BUF_SIZE);
}
void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) {
char array[BUF_SIZE];
uint32_t length = end - begin;
if (length > sizeof(array)) {
length = sizeof(array);
}
memcpy(array, begin, length);
if (!Interrupt::isInterruptInProgress()) {
std::cout << array;
} else {
// Uncomment the following line if you need ISR debug output.
// printk(array);
}
}
#endif // UT699
#ifdef ML505
#include <bsp_flp/network/networkconfig.h>
ServiceInterfaceBuffer::ServiceInterfaceBuffer(std::string set_message, uint16_t port)
: isActive(true),
log_message(set_message),
udpSocket(0),
remoteAddressLength(sizeof(remoteAddress)) {
setp(buf, buf + BUF_SIZE);
memset((uint8_t*)&remoteAddress, 0, sizeof(remoteAddress));
remoteAddress.sin_family = AF_INET;
remoteAddress.sin_port = htons(port);
remoteAddress.sin_addr.s_addr = htonl(inet_addr("192.168.250.100"));
}
void ServiceInterfaceBuffer::putChars(char const* begin, char const* end) {
char array[BUF_SIZE];
uint32_t length = end - begin;
if (length > sizeof(array)) {
length = sizeof(array);
}
memcpy(array, begin, length);
if (udpSocket <= 0) {
initSocket();
}
if (udpSocket > 0) {
sendto(udpSocket, array, length, 0, (sockaddr*)&remoteAddress, sizeof(remoteAddress));
}
}
void ServiceInterfaceBuffer::initSocket() {
sockaddr_in address;
memset((uint8_t*)&address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_port = htons(0);
address.sin_addr.s_addr = htonl(INADDR_ANY);
udpSocket = socket(PF_INET, SOCK_DGRAM, 0);
if (socket < 0) {
printf("Error opening socket!\n");
return;
}
timeval timeout = {0, 20};
if (setsockopt(udpSocket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) {
printf("Error setting SO_RCVTIMEO socket options!\n");
return;
}
if (setsockopt(udpSocket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0) {
printf("Error setting SO_SNDTIMEO socket options!\n");
return;
}
if (bind(udpSocket, (sockaddr*)&address, sizeof(address)) < 0) {
printf("Error binding socket!\n");
}
}
#endif // ML505
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */

View File

@ -0,0 +1,159 @@
#ifndef FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_
#define FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_
#include "fsfw/FSFW.h"
#if FSFW_CPP_OSTREAM_ENABLED == 1
#include <iomanip>
#include <iostream>
#include <sstream>
#ifndef UT699
/**
* @brief This is the underlying stream buffer which implements the
* streambuf class and overloads the overflow() and sync() methods
* @details
* This class is used to modify the output of the stream, for example by adding.
* It also calls the char printing function which is implemented in the
* board supply package (BSP).
*/
class ServiceInterfaceBuffer : public std::streambuf {
friend class ServiceInterfaceStream;
public:
static constexpr uint8_t MAX_PREAMBLE_SIZE = 40;
ServiceInterfaceBuffer(std::string setMessage, bool addCrToPreamble, bool buffered,
bool errStream, uint16_t port);
protected:
bool isActive;
//! This is called when buffer becomes full. If
//! buffer is not used, then this is called every
//! time when characters are put to stream.
int overflow(int c = Traits::eof()) override;
//! This function is called when stream is flushed,
//! for example when std::endl is put to stream.
int sync(void) override;
bool isBuffered() const;
private:
//! For additional message information
std::string logMessage;
std::string preamble;
#if FSFW_COLORED_OUTPUT == 1
std::string colorPrefix;
void setAsciiColorPrefix(std::string colorPrefix);
#endif
// For EOF detection
typedef std::char_traits<char> Traits;
//! This is useful for some terminal programs which do not have
//! implicit carriage return with newline characters.
bool addCrToPreamble;
//! Specifies whether the stream operates in buffered or unbuffered mode.
bool buffered;
//! This specifies to print to stderr and work in unbuffered mode.
bool errStream;
//! Needed for buffered mode.
static size_t const BUF_SIZE = fsfwconfig::FSFW_PRINT_BUFFER_SIZE;
char buf[BUF_SIZE];
//! In this function, the characters are parsed.
void putChars(char const* begin, char const* end);
std::string* getPreamble(size_t* preambleSize = nullptr);
bool crAdditionEnabled() const;
};
#endif
#ifdef UT699
class ServiceInterfaceBuffer : public std::basic_streambuf<char, std::char_traits<char> > {
friend class ServiceInterfaceStream;
public:
ServiceInterfaceBuffer(std::string set_message, uint16_t port);
protected:
bool isActive;
// This is called when buffer becomes full. If
// buffer is not used, then this is called every
// time when characters are put to stream.
virtual int overflow(int c = Traits::eof());
// This function is called when stream is flushed,
// for example when std::endl is put to stream.
virtual int sync(void);
private:
// For additional message information
std::string log_message;
// For EOF detection
typedef std::char_traits<char> Traits;
// Work in buffer mode. It is also possible to work without buffer.
static size_t const BUF_SIZE = 128;
char buf[BUF_SIZE];
// In this function, the characters are parsed.
void putChars(char const* begin, char const* end);
};
#endif // UT699
#ifdef ML505
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <sys/socket.h>
#include <sys/types.h>
class ServiceInterfaceBuffer : public std::basic_streambuf<char, std::char_traits<char> > {
friend class ServiceInterfaceStream;
public:
ServiceInterfaceBuffer(std::string set_message, uint16_t port);
protected:
bool isActive;
// This is called when buffer becomes full. If
// buffer is not used, then this is called every
// time when characters are put to stream.
virtual int overflow(int c = Traits::eof());
// This function is called when stream is flushed,
// for example when std::endl is put to stream.
virtual int sync(void);
private:
// For additional message information
std::string log_message;
// For EOF detection
typedef std::char_traits<char> Traits;
// Work in buffer mode. It is also possible to work without buffer.
static size_t const BUF_SIZE = 128;
char buf[BUF_SIZE];
// In this function, the characters are parsed.
void putChars(char const* begin, char const* end);
int udpSocket;
sockaddr_in remoteAddress;
socklen_t remoteAddressLength;
void initSocket();
};
#endif // ML505
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
#endif /* FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACEBUFFER_H_ */

View File

@ -0,0 +1,21 @@
#include "ServiceInterfaceStream.h"
#if FSFW_CPP_OSTREAM_ENABLED == 1
ServiceInterfaceStream::ServiceInterfaceStream(std::string setMessage, bool addCrToPreamble,
bool buffered, bool errStream, uint16_t port)
: std::ostream(&streambuf), streambuf(setMessage, addCrToPreamble, buffered, errStream, port) {}
void ServiceInterfaceStream::setActive(bool myActive) { this->streambuf.isActive = myActive; }
std::string* ServiceInterfaceStream::getPreamble() { return streambuf.getPreamble(); }
bool ServiceInterfaceStream::crAdditionEnabled() const { return streambuf.crAdditionEnabled(); }
#if FSFW_COLORED_OUTPUT == 1
void ServiceInterfaceStream::setAsciiColorPrefix(std::string asciiColorCode) {
streambuf.setAsciiColorPrefix(asciiColorCode);
}
#endif
#endif

View File

@ -0,0 +1,67 @@
#ifndef FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_
#define FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_
#include "ServiceInterfaceBuffer.h"
#include "fsfw/FSFW.h"
#if FSFW_CPP_OSTREAM_ENABLED == 1
#include <cstdio>
#include <iostream>
/**
* Generic service interface stream which can be used like std::cout or
* std::cerr but has additional capability. Add preamble and timestamp
* to output. Can be run in buffered or unbuffered mode.
*/
class ServiceInterfaceStream : public std::ostream {
public:
/**
* This constructor is used by specifying the preamble message.
* Optionally, the output can be directed to stderr and a CR character
* can be prepended to the preamble.
* @param setMessage message of preamble.
* @param addCrToPreamble Useful for applications like Puttty.
* @param buffered specify whether to use buffered mode.
* @param errStream specify which output stream to use (stderr or stdout).
*/
ServiceInterfaceStream(std::string setMessage, bool addCrToPreamble = false, bool buffered = true,
bool errStream = false, uint16_t port = 1234);
//! An inactive stream will not print anything.
void setActive(bool);
/**
* This can be used to retrieve the preamble in case it should be printed in
* the unbuffered mode.
* @return Preamle consisting of log message and timestamp.
*/
std::string* getPreamble();
/**
* Can be used to determine if the stream was configured to add CR characters in addition
* to newline characters.
* @return
*/
bool crAdditionEnabled() const;
#if FSFW_COLORED_OUTPUT == 1
void setAsciiColorPrefix(std::string asciiColorCode);
#endif
protected:
ServiceInterfaceBuffer streambuf;
};
// Forward declaration of interface streams. These should be instantiated in
// main. They can then be used like std::cout or std::cerr.
namespace sif {
extern ServiceInterfaceStream debug;
extern ServiceInterfaceStream info;
extern ServiceInterfaceStream warning;
extern ServiceInterfaceStream error;
} // namespace sif
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
#endif /* FRAMEWORK_SERVICEINTERFACE_SERVICEINTERFACESTREAM_H_ */

View File

@ -0,0 +1,18 @@
#ifndef FSFW_SERVICEINTERFACE_SERVICEINTERFACEDEFINTIONS_H_
#define FSFW_SERVICEINTERFACE_SERVICEINTERFACEDEFINTIONS_H_
namespace sif {
enum class OutputTypes { OUT_INFO, OUT_DEBUG, OUT_WARNING, OUT_ERROR };
static const char* const ANSI_COLOR_RED = "\x1b[31m";
static const char* const ANSI_COLOR_GREEN = "\x1b[32m";
static const char* const ANSI_COLOR_YELLOW = "\x1b[33m";
static const char* const ANSI_COLOR_BLUE = "\x1b[34m";
static const char* const ANSI_COLOR_MAGENTA = "\x1b[35m";
static const char* const ANSI_COLOR_CYAN = "\x1b[36m";
static const char* const ANSI_COLOR_RESET = "\x1b[0m";
} // namespace sif
#endif /* FSFW_SERVICEINTERFACE_SERVICEINTERFACEDEFINTIONS_H_ */

View File

@ -0,0 +1,25 @@
#include "libxiphos.h"
#include "CoreController.h"
bool rebootWasCalled = false;
xsc_libnor_chip_t lastChip;
xsc_libnor_copy_t lastCopy;
bool getRebootWasCalled(xsc_libnor_chip_t& tgtChip, xsc_libnor_copy_t& tgtCopy) {
tgtChip = lastChip;
tgtCopy = lastCopy;
bool tmp = rebootWasCalled;
if (rebootWasCalled) {
rebootWasCalled = false;
}
return tmp;
}
void xsc_boot_copy(xsc_libnor_chip_t boot_chip, xsc_libnor_copy_t boot_copy) {
rebootWasCalled = true;
lastChip = boot_chip;
lastCopy = boot_copy;
CoreController::setCurrentBootCopy(static_cast<xsc::Chip>(boot_chip),
static_cast<xsc::Copy>(boot_copy));
}

View File

@ -0,0 +1,25 @@
#pragma once
/** Type for identifying the nominal or the gold (redundant) flash copy */
typedef enum {
XSC_LIBNOR_COPY_NOMINAL,
XSC_LIBNOR_COPY_GOLD,
XSC_LIBNOR_COPY_TOTAL_NUMBER
} xsc_libnor_copy_t;
/** Type for identifying on of the two NOR flash chips */
typedef enum {
XSC_LIBNOR_CHIP_0, /* First NOR flash chip */
XSC_LIBNOR_CHIP_1, /* Second NOR flash chip */
XSC_LIBNOR_CHIP_TOTAL_NUMBER
} xsc_libnor_chip_t;
/**
* @brief Used to verify whether reboot function was called
*
* @param tgtChip
* @param tgtCopy
*/
bool getRebootWasCalled(xsc_libnor_chip_t& tgtChip, xsc_libnor_copy_t& tgtCopy);
void xsc_boot_copy(xsc_libnor_chip_t boot_chip, xsc_libnor_copy_t boot_copy);

View File

@ -0,0 +1,413 @@
#include <catch2/catch_test_macros.hpp>
#include <filesystem>
#include <fstream>
#include <iostream>
#include "CoreController.h"
#include "HasActionsIF.h"
#include "event.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
#include "libxiphos.h"
static constexpr bool CAT_FILE_TO_CONSOLE = false;
const std::string CONF_PATH = "/tmp/conf";
const std::string REBOOT_FILE = CONF_PATH + "/reboot.txt";
void catFileToConsole();
ServiceInterfaceStream sif::debug("DEBUG");
ServiceInterfaceStream sif::info("INFO");
ServiceInterfaceStream sif::warning("WARNING");
ServiceInterfaceStream sif::error("ERROR", false, false, true);
TEST_CASE("Core Controller Reboot File Handling", "[reboot-file]") {
if (not std::filesystem::exists(CONF_PATH)) {
std::filesystem::create_directory(CONF_PATH);
}
CoreController ctrl;
std::array<uint8_t, 12> cmdData = {};
SECTION("Primary") {
xsc_libnor_chip_t chip;
xsc_libnor_copy_t copy;
RebootFile rf = {};
ctrl.rewriteRebootFile(rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.maxCount == RebootFile::DEFAULT_MAX_BOOT_CNT);
REQUIRE(rf.img00Cnt == 0);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
REQUIRE(rf.bootFlag == 0);
REQUIRE(rf.lastChip == 0);
REQUIRE(rf.lastCopy == 0);
// This recreates the file but should also increment the boot counter of the current image
REQUIRE(ctrl.CURRENT_CHIP == xsc::CHIP_0);
REQUIRE(ctrl.CURRENT_COPY == xsc::COPY_0);
ctrl.performRebootFileHandling(true);
catFileToConsole();
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.maxCount == RebootFile::DEFAULT_MAX_BOOT_CNT);
REQUIRE(rf.img00Cnt == 1);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
REQUIRE(rf.bootFlag == 0);
REQUIRE(rf.lastChip == xsc::CHIP_0);
REQUIRE(rf.lastCopy == xsc::COPY_0);
uint8_t newRebootCnt = 3;
CHECK(ctrl.executeAction(CoreController::SET_MAX_REBOOT_CNT, 0, &newRebootCnt, 1) ==
HasActionsIF::EXECUTION_FINISHED);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.maxCount == 3);
REQUIRE(not getRebootWasCalled(chip, copy));
ctrl.performRebootFileHandling(false);
ctrl.performRebootFileHandling(false);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 3);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
REQUIRE(rf.bootFlag == true);
REQUIRE(rf.lastChip == xsc::CHIP_0);
REQUIRE(rf.lastCopy == xsc::COPY_0);
REQUIRE(getRebootWasCalled(chip, copy));
REQUIRE(chip == XSC_LIBNOR_CHIP_0);
REQUIRE(copy == XSC_LIBNOR_COPY_GOLD);
EventInfo info = {};
uint32_t numEvents = 0;
// We are now on image 0 1 and an event will be triggered
ctrl.performRebootFileHandling(false);
eventWasCalled(info, numEvents);
CHECK(numEvents == 1);
CHECK(info.event == CoreController::REBOOT_MECHANISM_TRIGGERED);
CHECK(static_cast<xsc::Chip>((info.p1 >> 16) & 0xFFFF) == xsc::CHIP_0);
CHECK(static_cast<xsc::Copy>(info.p1 & 0xFFFF) == xsc::COPY_0);
CHECK(((info.p2 >> 24) & 0xFF) == 3);
CHECK(((info.p2 >> 16) & 0xFF) == 1);
CHECK(((info.p2 >> 8) & 0xFF) == 0);
CHECK((info.p2 & 0xFF) == 0);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 3);
REQUIRE(rf.img01Cnt == 1);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
// Flag was cleared when event was thrown
REQUIRE(rf.bootFlag == false);
REQUIRE(rf.lastChip == xsc::CHIP_0);
REQUIRE(rf.lastCopy == xsc::COPY_1);
ctrl.performRebootFileHandling(false);
ctrl.performRebootFileHandling(false);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 3);
REQUIRE(rf.img01Cnt == 3);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
// We are now on image 1 0 and an event will be triggered
ctrl.performRebootFileHandling(false);
eventWasCalled(info, numEvents);
CHECK(numEvents == 1);
CHECK(info.event == CoreController::REBOOT_MECHANISM_TRIGGERED);
CHECK(static_cast<xsc::Chip>((info.p1 >> 16) & 0xFFFF) == xsc::CHIP_0);
CHECK(static_cast<xsc::Copy>(info.p1 & 0xFFFF) == xsc::COPY_1);
CHECK(((info.p2 >> 24) & 0xFF) == 3);
CHECK(((info.p2 >> 16) & 0xFF) == 3);
CHECK(((info.p2 >> 8) & 0xFF) == 1);
CHECK((info.p2 & 0xFF) == 0);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 3);
REQUIRE(rf.img01Cnt == 3);
REQUIRE(rf.img10Cnt == 1);
REQUIRE(rf.img11Cnt == 0);
ctrl.performRebootFileHandling(false);
ctrl.performRebootFileHandling(false);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 3);
REQUIRE(rf.img01Cnt == 3);
REQUIRE(rf.img10Cnt == 3);
REQUIRE(rf.img11Cnt == 0);
eventWasCalled(info, numEvents);
// On image 1 1 now
ctrl.performRebootFileHandling(false);
eventWasCalled(info, numEvents);
CHECK(numEvents == 1);
CHECK(info.event == CoreController::REBOOT_MECHANISM_TRIGGERED);
CHECK(static_cast<xsc::Chip>((info.p1 >> 16) & 0xFFFF) == xsc::CHIP_1);
CHECK(static_cast<xsc::Copy>(info.p1 & 0xFFFF) == xsc::COPY_0);
CHECK(((info.p2 >> 24) & 0xFF) == 3);
CHECK(((info.p2 >> 16) & 0xFF) == 3);
CHECK(((info.p2 >> 8) & 0xFF) == 3);
CHECK((info.p2 & 0xFF) == 1);
ctrl.performRebootFileHandling(false);
ctrl.performRebootFileHandling(false);
// Now it should fall back to 0 0 because all are invalid
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 3);
REQUIRE(rf.img01Cnt == 3);
REQUIRE(rf.img10Cnt == 3);
REQUIRE(rf.img11Cnt == 3);
// Should remain on image now
ctrl.performRebootFileHandling(false);
eventWasCalled(info, numEvents);
CHECK(numEvents == 1);
CHECK(info.event == CoreController::REBOOT_MECHANISM_TRIGGERED);
CHECK(static_cast<xsc::Chip>((info.p1 >> 16) & 0xFFFF) == xsc::CHIP_1);
CHECK(static_cast<xsc::Copy>(info.p1 & 0xFFFF) == xsc::COPY_1);
CHECK(((info.p2 >> 24) & 0xFF) == 4);
CHECK(((info.p2 >> 16) & 0xFF) == 3);
CHECK(((info.p2 >> 8) & 0xFF) == 3);
CHECK((info.p2 & 0xFF) == 3);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.img00Cnt == 4);
REQUIRE(rf.img01Cnt == 3);
REQUIRE(rf.img10Cnt == 3);
REQUIRE(rf.img11Cnt == 3);
// Reset a specific reboot counter
cmdData[0] = 0;
cmdData[1] = 1;
ctrl.executeAction(CoreController::RESET_REBOOT_COUNTERS, 0, cmdData.data(), 2);
// Reboot to 0 0 again
ctrl.performRebootFileHandling(false);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 5);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 3);
REQUIRE(rf.img11Cnt == 3);
CHECK(CoreController::CURRENT_CHIP == xsc::CHIP_0);
CHECK(CoreController::CURRENT_COPY == xsc::COPY_1);
ctrl.executeAction(CoreController::RESET_REBOOT_COUNTERS, 0, nullptr, 0);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 0);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
uint8_t enable = 0;
ctrl.executeAction(CoreController::SWITCH_REBOOT_FILE_HANDLING, 0, &enable, 1);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 0);
REQUIRE(rf.img00Cnt == 0);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
// Reboot to 1 0 explicitely
CoreController::setCurrentBootCopy(xsc::CHIP_1, xsc::COPY_0);
// Reboot three times and verify that no reboot is performed
ctrl.performRebootFileHandling(false);
ctrl.performRebootFileHandling(false);
ctrl.performRebootFileHandling(false);
ctrl.performRebootFileHandling(false);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 0);
REQUIRE(rf.img00Cnt == 0);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 4);
REQUIRE(rf.img11Cnt == 0);
// Now enable the functionality again and verify it reboots to 1 1
enable = 1;
ctrl.executeAction(CoreController::SWITCH_REBOOT_FILE_HANDLING, 0, &enable, 1);
ctrl.performRebootFileHandling(false);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 0);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 5);
REQUIRE(rf.img11Cnt == 0);
ctrl.performRebootFileHandling(false);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 0);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 5);
REQUIRE(rf.img11Cnt == 1);
ctrl.performRebootFileHandling(false);
ctrl.performRebootFileHandling(false);
// Should be on 0 0 now
CHECK(CoreController::CURRENT_CHIP == xsc::CHIP_0);
CHECK(CoreController::CURRENT_COPY == xsc::COPY_0);
ctrl.performRebootFileHandling(false);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 1);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 5);
REQUIRE(rf.img11Cnt == 3);
// Now reset all reboot counters manually
cmdData[0] = 0;
cmdData[1] = 0;
ctrl.executeAction(CoreController::RESET_REBOOT_COUNTERS, 0, cmdData.data(), 2);
cmdData[0] = 1;
cmdData[1] = 0;
ctrl.executeAction(CoreController::RESET_REBOOT_COUNTERS, 0, cmdData.data(), 2);
cmdData[0] = 1;
cmdData[1] = 1;
ctrl.executeAction(CoreController::RESET_REBOOT_COUNTERS, 0, cmdData.data(), 2);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 0);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
// Reset lock on 0 1
cmdData[0] = false;
cmdData[1] = 0;
cmdData[2] = 1;
ctrl.executeAction(CoreController::SWITCH_IMG_LOCK, 0, cmdData.data(), 3);
CHECK(CoreController::CURRENT_CHIP == xsc::CHIP_0);
CHECK(CoreController::CURRENT_COPY == xsc::COPY_0);
ctrl.performRebootFileHandling(false);
ctrl.performRebootFileHandling(false);
ctrl.performRebootFileHandling(false);
// Now should be on 0 1
ctrl.parseRebootFile(REBOOT_FILE, rf);
CHECK(CoreController::CURRENT_CHIP == xsc::CHIP_0);
CHECK(CoreController::CURRENT_COPY == xsc::COPY_1);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 3);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
REQUIRE(rf.img00Lock == false);
REQUIRE(rf.img01Lock == false);
REQUIRE(rf.img10Lock == false);
REQUIRE(rf.img11Lock == false);
// Now simulate failure in kernel boot or reboot from ProASIC3
ctrl.setCurrentBootCopy(xsc::CHIP_0, xsc::COPY_0);
ctrl.performRebootFileHandling(false);
// Image 0 1 should have been marked as invalid now. Reboot will be triggered
// on 1 0 instead of 0 1 because 0 1 is marked as locked
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 4);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
REQUIRE(rf.img00Lock == false);
REQUIRE(rf.img01Lock == true);
REQUIRE(rf.img10Lock == false);
REQUIRE(rf.img11Lock == false);
ctrl.performRebootFileHandling(false);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 4);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 1);
REQUIRE(rf.img11Cnt == 0);
REQUIRE(rf.img00Lock == false);
REQUIRE(rf.img01Lock == true);
REQUIRE(rf.img10Lock == false);
REQUIRE(rf.img11Lock == false);
// Reset lock on 0 1 again
cmdData[0] = false;
cmdData[1] = 0;
cmdData[2] = 1;
ctrl.executeAction(CoreController::SWITCH_IMG_LOCK, 0, cmdData.data(), 3);
// Lock 1 1 manually
// Reset lock on 0 1 again
cmdData[0] = true;
cmdData[1] = 1;
cmdData[2] = 1;
ctrl.executeAction(CoreController::SWITCH_IMG_LOCK, 0, cmdData.data(), 3);
ctrl.performRebootFileHandling(false);
ctrl.performRebootFileHandling(false);
// Should be on 0 1 now
ctrl.performRebootFileHandling(false);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 4);
REQUIRE(rf.img01Cnt == 1);
REQUIRE(rf.img10Cnt == 3);
REQUIRE(rf.img11Cnt == 0);
REQUIRE(rf.img00Lock == false);
REQUIRE(rf.img01Lock == false);
REQUIRE(rf.img10Lock == false);
REQUIRE(rf.img11Lock == true);
// Lock everything except 0 0
cmdData[0] = true;
cmdData[1] = 0;
cmdData[2] = 1;
ctrl.executeAction(CoreController::SWITCH_IMG_LOCK, 0, cmdData.data(), 3);
cmdData[0] = true;
cmdData[1] = 1;
cmdData[2] = 0;
ctrl.executeAction(CoreController::SWITCH_IMG_LOCK, 0, cmdData.data(), 3);
ctrl.executeAction(CoreController::RESET_REBOOT_COUNTERS, 0, nullptr, 0);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 0);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
REQUIRE(rf.img00Lock == false);
REQUIRE(rf.img01Lock == true);
REQUIRE(rf.img10Lock == true);
REQUIRE(rf.img11Lock == true);
// Switch to 0 0
ctrl.setCurrentBootCopy(xsc::CHIP_0, xsc::COPY_0);
ctrl.performRebootFileHandling(false);
ctrl.performRebootFileHandling(false);
ctrl.performRebootFileHandling(false);
// Should still be on 0 0
ctrl.performRebootFileHandling(false);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 4);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
REQUIRE(rf.img00Lock == false);
REQUIRE(rf.img01Lock == true);
REQUIRE(rf.img10Lock == true);
REQUIRE(rf.img11Lock == true);
// Unlock 1 0
cmdData[0] = false;
cmdData[1] = 1;
cmdData[2] = 0;
ctrl.executeAction(CoreController::SWITCH_IMG_LOCK, 0, cmdData.data(), 3);
// Reboots to 1 0 now
ctrl.performRebootFileHandling(false);
ctrl.parseRebootFile(REBOOT_FILE, rf);
REQUIRE(rf.enabled == 1);
REQUIRE(rf.img00Cnt == 5);
REQUIRE(rf.img01Cnt == 0);
REQUIRE(rf.img10Cnt == 0);
REQUIRE(rf.img11Cnt == 0);
REQUIRE(rf.img00Lock == false);
REQUIRE(rf.img01Lock == true);
REQUIRE(rf.img10Lock == false);
REQUIRE(rf.img11Lock == true);
REQUIRE(CoreController::CURRENT_CHIP == xsc::CHIP_1);
REQUIRE(CoreController::CURRENT_COPY == xsc::COPY_0);
}
if (std::filesystem::exists(CONF_PATH)) {
std::uintmax_t n = std::filesystem::remove_all(CONF_PATH);
CHECK(n == 2);
}
}
void catFileToConsole() {
if (CAT_FILE_TO_CONSOLE) {
std::ifstream file(REBOOT_FILE);
if (file.is_open()) {
std::cout << file.rdbuf();
}
}
}

View File

@ -0,0 +1,10 @@
#include <stdbool.h>
#include <stdio.h>
void printChar(const char* character, bool errStream) {
if (errStream) {
putc(*character, stderr);
return;
}
putc(*character, stdout);
}