Merge remote-tracking branch 'origin/develop' into flipped-tmtctest-preproc-define
This commit is contained in:
commit
c88371b37a
@ -1,20 +1,19 @@
|
|||||||
#include "InitMission.h"
|
#include "InitMission.h"
|
||||||
#include "ObjectFactory.h"
|
|
||||||
|
|
||||||
#include <OBSWConfig.h>
|
#include <OBSWConfig.h>
|
||||||
|
#include <fsfw/objectmanager/ObjectManager.h>
|
||||||
#include <fsfw/objectmanager/ObjectManagerIF.h>
|
#include <fsfw/objectmanager/ObjectManagerIF.h>
|
||||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||||
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||||
#include <fsfw/objectmanager/ObjectManager.h>
|
|
||||||
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
|
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
|
||||||
#include <fsfw/tasks/PeriodicTaskIF.h>
|
#include <fsfw/tasks/PeriodicTaskIF.h>
|
||||||
#include <fsfw/tasks/TaskFactory.h>
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
|
|
||||||
#include <mission/utility/InitMission.h>
|
#include <mission/utility/InitMission.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "ObjectFactory.h"
|
||||||
|
|
||||||
#ifdef LINUX
|
#ifdef LINUX
|
||||||
ServiceInterfaceStream sif::debug("DEBUG");
|
ServiceInterfaceStream sif::debug("DEBUG");
|
||||||
ServiceInterfaceStream sif::info("INFO");
|
ServiceInterfaceStream sif::info("INFO");
|
||||||
@ -27,133 +26,132 @@ ServiceInterfaceStream sif::warning("WARNING", true);
|
|||||||
ServiceInterfaceStream sif::error("ERROR", true, false, true);
|
ServiceInterfaceStream sif::error("ERROR", true, false, true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ObjectManagerIF *objectManager = nullptr;
|
ObjectManagerIF* objectManager = nullptr;
|
||||||
|
|
||||||
void initmission::initMission() {
|
void initmission::initMission() {
|
||||||
sif::info << "Building global objects.." << std::endl;
|
sif::info << "Building global objects.." << std::endl;
|
||||||
/* Instantiate global object manager and also create all objects */
|
/* Instantiate global object manager and also create all objects */
|
||||||
ObjectManager::instance()->setObjectFactoryFunction(ObjectFactory::produce, nullptr);
|
ObjectManager::instance()->setObjectFactoryFunction(ObjectFactory::produce, nullptr);
|
||||||
sif::info << "Initializing all objects.." << std::endl;
|
sif::info << "Initializing all objects.." << std::endl;
|
||||||
ObjectManager::instance()->initialize();
|
ObjectManager::instance()->initialize();
|
||||||
|
|
||||||
/* This function creates and starts all tasks */
|
/* This function creates and starts all tasks */
|
||||||
initTasks();
|
initTasks();
|
||||||
}
|
}
|
||||||
|
|
||||||
void initmission::initTasks() {
|
void initmission::initTasks() {
|
||||||
TaskFactory* factory = TaskFactory::instance();
|
TaskFactory* factory = TaskFactory::instance();
|
||||||
if(factory == nullptr) {
|
if (factory == nullptr) {
|
||||||
/* Should never happen ! */
|
/* Should never happen ! */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if OBSW_PRINT_MISSED_DEADLINES == 1
|
#if OBSW_PRINT_MISSED_DEADLINES == 1
|
||||||
void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline;
|
void (*missedDeadlineFunc)(void) = TaskFactory::printMissedDeadline;
|
||||||
#else
|
#else
|
||||||
void (*missedDeadlineFunc) (void) = nullptr;
|
void (*missedDeadlineFunc)(void) = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* TMTC Distribution */
|
/* TMTC Distribution */
|
||||||
PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
|
PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
|
||||||
"DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
"DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
||||||
ReturnValue_t result = tmTcDistributor->addComponent(
|
ReturnValue_t result = tmTcDistributor->addComponent(objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||||
objects::CCSDS_PACKET_DISTRIBUTOR);
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
sif::error << "Object add component failed" << std::endl;
|
||||||
sif::error << "Object add component failed" << std::endl;
|
}
|
||||||
}
|
result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
|
||||||
result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
sif::error << "Object add component failed" << std::endl;
|
||||||
sif::error << "Object add component failed" << std::endl;
|
}
|
||||||
}
|
result = tmTcDistributor->addComponent(objects::TM_FUNNEL);
|
||||||
result = tmTcDistributor->addComponent(objects::TM_FUNNEL);
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
sif::error << "Object add component failed" << std::endl;
|
||||||
sif::error << "Object add component failed" << std::endl;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* UDP bridge */
|
/* UDP bridge */
|
||||||
PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask(
|
PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask(
|
||||||
"TMTC_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
"TMTC_UNIX_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) {
|
||||||
sif::error << "Add component UDP Unix Bridge failed" << std::endl;
|
sif::error << "Add component UDP Unix Bridge failed" << std::endl;
|
||||||
}
|
}
|
||||||
PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask(
|
PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask(
|
||||||
"UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
"UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
||||||
result = tmtcPollingTask->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 UDP Polling failed" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PUS Services */
|
/* PUS Services */
|
||||||
PeriodicTaskIF* pusVerification = factory->createPeriodicTask(
|
PeriodicTaskIF* pusVerification = factory->createPeriodicTask(
|
||||||
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
|
result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::error << "Object add component failed" << std::endl;
|
sif::error << "Object add component failed" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
PeriodicTaskIF* pusEvents = factory->createPeriodicTask(
|
PeriodicTaskIF* pusEvents = factory->createPeriodicTask(
|
||||||
"PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
"PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
|
result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING);
|
initmission::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask(
|
PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask(
|
||||||
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
||||||
}
|
}
|
||||||
result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
|
result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT);
|
initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT);
|
||||||
}
|
}
|
||||||
|
|
||||||
PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask(
|
PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask(
|
||||||
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
|
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
|
||||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
||||||
}
|
}
|
||||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT);
|
initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT);
|
||||||
}
|
}
|
||||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS);
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS);
|
initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask(
|
PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask(
|
||||||
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
|
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
|
||||||
result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
|
result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST);
|
initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
PeriodicTaskIF* testTask = factory->createPeriodicTask(
|
PeriodicTaskIF* testTask = factory->createPeriodicTask(
|
||||||
"TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
"TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
||||||
#if OBSW_ADD_TEST_CODE == 1
|
#if OBSW_ADD_TEST_CODE == 1
|
||||||
result = testTask->addComponent(objects::TEST_TASK);
|
result = testTask->addComponent(objects::TEST_TASK);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK);
|
initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK);
|
||||||
}
|
}
|
||||||
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
||||||
|
|
||||||
sif::info << "Starting tasks.." << std::endl;
|
sif::info << "Starting tasks.." << std::endl;
|
||||||
tmTcDistributor->startTask();
|
tmTcDistributor->startTask();
|
||||||
tmtcBridgeTask->startTask();
|
tmtcBridgeTask->startTask();
|
||||||
tmtcPollingTask->startTask();
|
tmtcPollingTask->startTask();
|
||||||
|
|
||||||
pusVerification->startTask();
|
pusVerification->startTask();
|
||||||
pusEvents->startTask();
|
pusEvents->startTask();
|
||||||
pusHighPrio->startTask();
|
pusHighPrio->startTask();
|
||||||
pusMedPrio->startTask();
|
pusMedPrio->startTask();
|
||||||
pusLowPrio->startTask();
|
pusLowPrio->startTask();
|
||||||
|
|
||||||
#if OBSW_ADD_TEST_CODE == 1
|
#if OBSW_ADD_TEST_CODE == 1
|
||||||
testTask->startTask();
|
testTask->startTask();
|
||||||
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
||||||
|
|
||||||
sif::info << "Tasks started.." << std::endl;
|
sif::info << "Tasks started.." << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,6 @@
|
|||||||
namespace initmission {
|
namespace initmission {
|
||||||
void initMission();
|
void initMission();
|
||||||
void initTasks();
|
void initTasks();
|
||||||
};
|
}; // namespace initmission
|
||||||
|
|
||||||
#endif /* BSP_LINUX_INITMISSION_H_ */
|
#endif /* BSP_LINUX_INITMISSION_H_ */
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
#include "ObjectFactory.h"
|
#include "ObjectFactory.h"
|
||||||
#include "OBSWConfig.h"
|
|
||||||
|
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
||||||
|
#include <fsfw/tmtcservices/PusServiceBase.h>
|
||||||
|
#include <mission/core/GenericFactory.h>
|
||||||
|
#include <mission/utility/TmFunnel.h>
|
||||||
#include <objects/systemObjectList.h>
|
#include <objects/systemObjectList.h>
|
||||||
#include <tmtc/apid.h>
|
#include <tmtc/apid.h>
|
||||||
#include <tmtc/pusIds.h>
|
#include <tmtc/pusIds.h>
|
||||||
|
|
||||||
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
#include "OBSWConfig.h"
|
||||||
#include <fsfw/tmtcservices/PusServiceBase.h>
|
|
||||||
|
|
||||||
#include <mission/core/GenericFactory.h>
|
|
||||||
#include <mission/utility/TmFunnel.h>
|
|
||||||
|
|
||||||
#if OBSW_USE_TMTC_TCP_BRIDGE == 0
|
#if OBSW_USE_TMTC_TCP_BRIDGE == 0
|
||||||
#include "fsfw/osal/common/UdpTcPollingTask.h"
|
#include "fsfw/osal/common/UdpTcPollingTask.h"
|
||||||
@ -20,29 +20,28 @@
|
|||||||
|
|
||||||
#include <fsfw/tmtcpacket/pus/tm.h>
|
#include <fsfw/tmtcpacket/pus/tm.h>
|
||||||
|
|
||||||
|
|
||||||
#if OBSW_ADD_TEST_CODE == 1
|
#if OBSW_ADD_TEST_CODE == 1
|
||||||
#include <test/testtasks/TestTask.h>
|
#include <test/testtasks/TestTask.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Factory::setStaticFrameworkObjectIds(){
|
void Factory::setStaticFrameworkObjectIds() {
|
||||||
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
|
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||||
PusServiceBase::packetDestination = objects::TM_FUNNEL;
|
PusServiceBase::packetDestination = objects::TM_FUNNEL;
|
||||||
|
|
||||||
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
|
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||||
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
|
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
|
||||||
|
|
||||||
TmFunnel::downlinkDestination = objects::TMTC_BRIDGE;
|
TmFunnel::downlinkDestination = objects::TMTC_BRIDGE;
|
||||||
// No storage object for now.
|
// No storage object for now.
|
||||||
TmFunnel::storageDestination = objects::NO_OBJECT;
|
TmFunnel::storageDestination = objects::NO_OBJECT;
|
||||||
|
|
||||||
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
|
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
|
||||||
TmPacketBase::timeStamperId = objects::TIME_STAMPER;
|
TmPacketBase::timeStamperId = objects::TIME_STAMPER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectFactory::produce(void* args){
|
void ObjectFactory::produce(void* args) {
|
||||||
Factory::setStaticFrameworkObjectIds();
|
Factory::setStaticFrameworkObjectIds();
|
||||||
ObjectFactory::produceGenericObjects();
|
ObjectFactory::produceGenericObjects();
|
||||||
|
|
||||||
new TestTask(objects::TEST_TASK);
|
new TestTask(objects::TEST_TASK);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
#ifndef BSP_LINUX_OBJECTFACTORY_H_
|
#ifndef BSP_LINUX_OBJECTFACTORY_H_
|
||||||
#define BSP_LINUX_OBJECTFACTORY_H_
|
#define BSP_LINUX_OBJECTFACTORY_H_
|
||||||
|
|
||||||
|
|
||||||
namespace ObjectFactory {
|
namespace ObjectFactory {
|
||||||
void setStatics();
|
void setStatics();
|
||||||
void produce(void* args);
|
void produce(void* args);
|
||||||
};
|
}; // namespace ObjectFactory
|
||||||
|
|
||||||
#endif /* BSP_LINUX_OBJECTFACTORY_H_ */
|
#endif /* BSP_LINUX_OBJECTFACTORY_H_ */
|
||||||
|
@ -32,7 +32,7 @@ SOFTWARE.
|
|||||||
|
|
||||||
#define ETL_CHECK_PUSH_POP
|
#define ETL_CHECK_PUSH_POP
|
||||||
|
|
||||||
#define ETL_CPP11_SUPPORTED 1
|
#define ETL_CPP11_SUPPORTED 1
|
||||||
#define ETL_NO_NULLPTR_SUPPORT 0
|
#define ETL_NO_NULLPTR_SUPPORT 0
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6,8 +6,9 @@
|
|||||||
extern "C" void __gcov_flush();
|
extern "C" void __gcov_flush();
|
||||||
#else
|
#else
|
||||||
void __gcov_flush() {
|
void __gcov_flush() {
|
||||||
sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if "
|
sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if "
|
||||||
"coverage information is desired.\n" << std::flush;
|
"coverage information is desired.\n"
|
||||||
|
<< std::flush;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3,13 +3,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
void printChar(const char* character, bool errStream) {
|
void printChar(const char* character, bool errStream) {
|
||||||
if(errStream) {
|
if (errStream) {
|
||||||
putc(*character, stderr);
|
putc(*character, stderr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
putc(*character, stdout);
|
putc(*character, stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,376 +1,351 @@
|
|||||||
#include "ArduinoComIF.h"
|
#include "ArduinoComIF.h"
|
||||||
#include "ArduinoCookie.h"
|
|
||||||
|
|
||||||
#include <fsfw/globalfunctions/DleEncoder.h>
|
|
||||||
#include <fsfw/globalfunctions/CRC.h>
|
#include <fsfw/globalfunctions/CRC.h>
|
||||||
|
#include <fsfw/globalfunctions/DleEncoder.h>
|
||||||
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||||
|
|
||||||
|
#include "ArduinoCookie.h"
|
||||||
|
|
||||||
// This only works on Linux
|
// This only works on Linux
|
||||||
#ifdef LINUX
|
#ifdef LINUX
|
||||||
#include <termios.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#elif WIN32
|
#elif WIN32
|
||||||
#include <windows.h>
|
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
ArduinoComIF::ArduinoComIF(object_id_t setObjectId, bool promptComIF,
|
ArduinoComIF::ArduinoComIF(object_id_t setObjectId, bool promptComIF, const char *serialDevice)
|
||||||
const char *serialDevice):
|
: rxBuffer(MAX_PACKET_SIZE * MAX_NUMBER_OF_SPI_DEVICES * 10, true), SystemObject(setObjectId) {
|
||||||
rxBuffer(MAX_PACKET_SIZE * MAX_NUMBER_OF_SPI_DEVICES*10, true),
|
|
||||||
SystemObject(setObjectId) {
|
|
||||||
#ifdef LINUX
|
#ifdef LINUX
|
||||||
initialized = false;
|
initialized = false;
|
||||||
serialPort = ::open("/dev/ttyUSB0", O_RDWR);
|
serialPort = ::open("/dev/ttyUSB0", O_RDWR);
|
||||||
|
|
||||||
if (serialPort < 0) {
|
if (serialPort < 0) {
|
||||||
//configuration error
|
// configuration error
|
||||||
printf("Error %i from open: %s\n", errno, strerror(errno));
|
printf("Error %i from open: %s\n", errno, strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct termios tty;
|
struct termios tty;
|
||||||
memset(&tty, 0, sizeof tty);
|
memset(&tty, 0, sizeof tty);
|
||||||
|
|
||||||
// Read in existing settings, and handle any error
|
// Read in existing settings, and handle any error
|
||||||
if (tcgetattr(serialPort, &tty) != 0) {
|
if (tcgetattr(serialPort, &tty) != 0) {
|
||||||
printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
|
printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity
|
tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity
|
||||||
tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication
|
tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication
|
||||||
tty.c_cflag |= CS8; // 8 bits per byte
|
tty.c_cflag |= CS8; // 8 bits per byte
|
||||||
tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control
|
tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control
|
||||||
tty.c_lflag &= ~ICANON; //Disable Canonical Mode
|
tty.c_lflag &= ~ICANON; // Disable Canonical Mode
|
||||||
tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
|
tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
|
||||||
tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
|
tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
|
||||||
tty.c_cc[VTIME] = 0; // Non Blocking
|
tty.c_cc[VTIME] = 0; // Non Blocking
|
||||||
tty.c_cc[VMIN] = 0;
|
tty.c_cc[VMIN] = 0;
|
||||||
|
|
||||||
cfsetispeed(&tty, B9600); //Baudrate
|
cfsetispeed(&tty, B9600); // Baudrate
|
||||||
|
|
||||||
if (tcsetattr(serialPort, TCSANOW, &tty) != 0) {
|
if (tcsetattr(serialPort, TCSANOW, &tty) != 0) {
|
||||||
//printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
|
// printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
#elif WIN32
|
#elif WIN32
|
||||||
DCB serialParams = { 0 };
|
DCB serialParams = {0};
|
||||||
|
|
||||||
// we need to ask the COM port from the user.
|
// we need to ask the COM port from the user.
|
||||||
if(promptComIF) {
|
if (promptComIF) {
|
||||||
sif::info << "Please enter the COM port (c to cancel): " << std::flush;
|
sif::info << "Please enter the COM port (c to cancel): " << std::flush;
|
||||||
std::string comPort;
|
std::string comPort;
|
||||||
while(hCom == INVALID_HANDLE_VALUE) {
|
while (hCom == INVALID_HANDLE_VALUE) {
|
||||||
|
std::getline(std::cin, comPort);
|
||||||
|
if (comPort[0] == 'c') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const TCHAR *pcCommPort = comPort.c_str();
|
||||||
|
hCom = CreateFileA(pcCommPort, // port name
|
||||||
|
GENERIC_READ | GENERIC_WRITE, // Read/Write
|
||||||
|
0, // No Sharing
|
||||||
|
NULL, // No Security
|
||||||
|
OPEN_EXISTING, // Open existing port only
|
||||||
|
0, // Non Overlapped I/O
|
||||||
|
NULL); // Null for Comm Devices
|
||||||
|
|
||||||
std::getline(std::cin, comPort);
|
if (hCom == INVALID_HANDLE_VALUE) {
|
||||||
if(comPort[0] == 'c') {
|
if (GetLastError() == 2) {
|
||||||
break;
|
sif::error << "COM Port does not found!" << std::endl;
|
||||||
}
|
} else {
|
||||||
const TCHAR *pcCommPort = comPort.c_str();
|
TCHAR err[128];
|
||||||
hCom = CreateFileA(pcCommPort, //port name
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
|
||||||
GENERIC_READ | GENERIC_WRITE, //Read/Write
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err, sizeof(err), NULL);
|
||||||
0, // No Sharing
|
// Handle the error.
|
||||||
NULL, // No Security
|
sif::info << "CreateFileA Error code: " << GetLastError() << std::endl;
|
||||||
OPEN_EXISTING,// Open existing port only
|
sif::error << err << std::flush;
|
||||||
0, // Non Overlapped I/O
|
}
|
||||||
NULL); // Null for Comm Devices
|
sif::info << "Please enter a valid COM port: " << std::flush;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (hCom == INVALID_HANDLE_VALUE)
|
serialParams.DCBlength = sizeof(serialParams);
|
||||||
{
|
if (baudRate == 9600) {
|
||||||
if(GetLastError() == 2) {
|
serialParams.BaudRate = CBR_9600;
|
||||||
sif::error << "COM Port does not found!" << std::endl;
|
}
|
||||||
}
|
if (baudRate == 115200) {
|
||||||
else {
|
serialParams.BaudRate = CBR_115200;
|
||||||
TCHAR err[128];
|
} else {
|
||||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
|
serialParams.BaudRate = baudRate;
|
||||||
GetLastError(),
|
}
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
||||||
err, sizeof(err), NULL);
|
|
||||||
// Handle the error.
|
|
||||||
sif::info << "CreateFileA Error code: " << GetLastError()
|
|
||||||
<< std::endl;
|
|
||||||
sif::error << err << std::flush;
|
|
||||||
}
|
|
||||||
sif::info << "Please enter a valid COM port: " << std::flush;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
serialParams.ByteSize = 8;
|
||||||
|
serialParams.Parity = NOPARITY;
|
||||||
|
serialParams.StopBits = ONESTOPBIT;
|
||||||
|
SetCommState(hCom, &serialParams);
|
||||||
|
|
||||||
|
COMMTIMEOUTS timeout = {0};
|
||||||
serialParams.DCBlength = sizeof(serialParams);
|
// This will set the read operation to be blocking until data is received
|
||||||
if(baudRate == 9600) {
|
// and then read continuously until there is a gap of one millisecond.
|
||||||
serialParams.BaudRate = CBR_9600;
|
timeout.ReadIntervalTimeout = 1;
|
||||||
}
|
timeout.ReadTotalTimeoutConstant = 0;
|
||||||
if(baudRate == 115200) {
|
timeout.ReadTotalTimeoutMultiplier = 0;
|
||||||
serialParams.BaudRate = CBR_115200;
|
timeout.WriteTotalTimeoutConstant = 0;
|
||||||
}
|
timeout.WriteTotalTimeoutMultiplier = 0;
|
||||||
else {
|
SetCommTimeouts(hCom, &timeout);
|
||||||
serialParams.BaudRate = baudRate;
|
// Serial port should now be read for operations.
|
||||||
}
|
|
||||||
|
|
||||||
serialParams.ByteSize = 8;
|
|
||||||
serialParams.Parity = NOPARITY;
|
|
||||||
serialParams.StopBits = ONESTOPBIT;
|
|
||||||
SetCommState(hCom, &serialParams);
|
|
||||||
|
|
||||||
COMMTIMEOUTS timeout = { 0 };
|
|
||||||
// This will set the read operation to be blocking until data is received
|
|
||||||
// and then read continuously until there is a gap of one millisecond.
|
|
||||||
timeout.ReadIntervalTimeout = 1;
|
|
||||||
timeout.ReadTotalTimeoutConstant = 0;
|
|
||||||
timeout.ReadTotalTimeoutMultiplier = 0;
|
|
||||||
timeout.WriteTotalTimeoutConstant = 0;
|
|
||||||
timeout.WriteTotalTimeoutMultiplier = 0;
|
|
||||||
SetCommTimeouts(hCom, &timeout);
|
|
||||||
// Serial port should now be read for operations.
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ArduinoComIF::~ArduinoComIF() {
|
ArduinoComIF::~ArduinoComIF() {
|
||||||
#ifdef LINUX
|
#ifdef LINUX
|
||||||
::close(serialPort);
|
::close(serialPort);
|
||||||
#elif WIN32
|
#elif WIN32
|
||||||
CloseHandle(hCom);
|
CloseHandle(hCom);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
ReturnValue_t ArduinoComIF::initializeInterface(CookieIF * cookie) {
|
ReturnValue_t ArduinoComIF::initializeInterface(CookieIF *cookie) {
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ArduinoComIF::sendMessage(CookieIF *cookie, const uint8_t *data,
|
ReturnValue_t ArduinoComIF::sendMessage(CookieIF *cookie, const uint8_t *data, size_t len) {
|
||||||
size_t len) {
|
ArduinoCookie *arduinoCookie = dynamic_cast<ArduinoCookie *>(cookie);
|
||||||
ArduinoCookie *arduinoCookie = dynamic_cast<ArduinoCookie*>(cookie);
|
if (arduinoCookie == nullptr) {
|
||||||
if (arduinoCookie == nullptr) {
|
return INVALID_COOKIE_TYPE;
|
||||||
return INVALID_COOKIE_TYPE;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return sendMessage(arduinoCookie->command, arduinoCookie->address, data,
|
return sendMessage(arduinoCookie->command, arduinoCookie->address, data, len);
|
||||||
len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ArduinoComIF::getSendSuccess(CookieIF *cookie) {
|
ReturnValue_t ArduinoComIF::getSendSuccess(CookieIF *cookie) { return RETURN_OK; }
|
||||||
return RETURN_OK;
|
|
||||||
|
ReturnValue_t ArduinoComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLen) {
|
||||||
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ArduinoComIF::requestReceiveMessage(CookieIF *cookie,
|
ReturnValue_t ArduinoComIF::readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t *size) {
|
||||||
size_t requestLen) {
|
handleSerialPortRx();
|
||||||
return RETURN_OK;
|
|
||||||
|
ArduinoCookie *arduinoCookie = dynamic_cast<ArduinoCookie *>(cookie);
|
||||||
|
if (arduinoCookie == nullptr) {
|
||||||
|
return INVALID_COOKIE_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*buffer = arduinoCookie->replyBuffer.data();
|
||||||
|
*size = arduinoCookie->receivedDataLen;
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ArduinoComIF::readReceivedMessage(CookieIF *cookie,
|
ReturnValue_t ArduinoComIF::sendMessage(uint8_t command, uint8_t address, const uint8_t *data,
|
||||||
uint8_t **buffer, size_t *size) {
|
size_t dataLen) {
|
||||||
|
if (dataLen > UINT16_MAX) {
|
||||||
|
return TOO_MUCH_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
handleSerialPortRx();
|
// being conservative here
|
||||||
|
uint8_t sendBuffer[(dataLen + 6) * 2 + 2];
|
||||||
|
|
||||||
ArduinoCookie *arduinoCookie = dynamic_cast<ArduinoCookie*>(cookie);
|
sendBuffer[0] = DleEncoder::STX_CHAR;
|
||||||
if (arduinoCookie == nullptr) {
|
|
||||||
return INVALID_COOKIE_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*buffer = arduinoCookie->replyBuffer.data();
|
uint8_t *currentPosition = sendBuffer + 1;
|
||||||
*size = arduinoCookie->receivedDataLen;
|
size_t remainingLen = sizeof(sendBuffer) - 1;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
size_t encodedLen = 0;
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t ArduinoComIF::sendMessage(uint8_t command,
|
ReturnValue_t result =
|
||||||
uint8_t address, const uint8_t *data, size_t dataLen) {
|
DleEncoder::encode(&command, 1, currentPosition, remainingLen, &encodedLen, false);
|
||||||
if (dataLen > UINT16_MAX) {
|
if (result != RETURN_OK) {
|
||||||
return TOO_MUCH_DATA;
|
return result;
|
||||||
}
|
}
|
||||||
|
currentPosition += encodedLen;
|
||||||
|
remainingLen -= encodedLen; // DleEncoder will never return encodedLen > remainingLen
|
||||||
|
|
||||||
//being conservative here
|
result = DleEncoder::encode(&address, 1, currentPosition, remainingLen, &encodedLen, false);
|
||||||
uint8_t sendBuffer[(dataLen + 6) * 2 + 2];
|
if (result != RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
currentPosition += encodedLen;
|
||||||
|
remainingLen -= encodedLen; // DleEncoder will never return encodedLen > remainingLen
|
||||||
|
|
||||||
sendBuffer[0] = DleEncoder::STX_CHAR;
|
uint8_t temporaryBuffer[2];
|
||||||
|
|
||||||
uint8_t *currentPosition = sendBuffer + 1;
|
// note to Lukas: yes we _could_ use Serialize here, but for 16 bit it is a bit too much...
|
||||||
size_t remainingLen = sizeof(sendBuffer) - 1;
|
temporaryBuffer[0] = dataLen >> 8; // we checked dataLen above
|
||||||
size_t encodedLen = 0;
|
temporaryBuffer[1] = dataLen;
|
||||||
|
|
||||||
ReturnValue_t result = DleEncoder::encode(&command, 1, currentPosition,
|
result =
|
||||||
remainingLen, &encodedLen, false);
|
DleEncoder::encode(temporaryBuffer, 2, currentPosition, remainingLen, &encodedLen, false);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
currentPosition += encodedLen;
|
currentPosition += encodedLen;
|
||||||
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
|
remainingLen -= encodedLen; // DleEncoder will never return encodedLen > remainingLen
|
||||||
|
|
||||||
result = DleEncoder::encode(&address, 1, currentPosition, remainingLen,
|
// encoding the actual data
|
||||||
&encodedLen, false);
|
result = DleEncoder::encode(data, dataLen, currentPosition, remainingLen, &encodedLen, false);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
currentPosition += encodedLen;
|
currentPosition += encodedLen;
|
||||||
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
|
remainingLen -= encodedLen; // DleEncoder will never return encodedLen > remainingLen
|
||||||
|
|
||||||
uint8_t temporaryBuffer[2];
|
uint16_t crc = CRC::crc16ccitt(&command, 1);
|
||||||
|
crc = CRC::crc16ccitt(&address, 1, crc);
|
||||||
|
// fortunately the length is still there
|
||||||
|
crc = CRC::crc16ccitt(temporaryBuffer, 2, crc);
|
||||||
|
crc = CRC::crc16ccitt(data, dataLen, crc);
|
||||||
|
|
||||||
//note to Lukas: yes we _could_ use Serialize here, but for 16 bit it is a bit too much...
|
temporaryBuffer[0] = crc >> 8;
|
||||||
temporaryBuffer[0] = dataLen >> 8; //we checked dataLen above
|
temporaryBuffer[1] = crc;
|
||||||
temporaryBuffer[1] = dataLen;
|
|
||||||
|
|
||||||
result = DleEncoder::encode(temporaryBuffer, 2, currentPosition,
|
result =
|
||||||
remainingLen, &encodedLen, false);
|
DleEncoder::encode(temporaryBuffer, 2, currentPosition, remainingLen, &encodedLen, false);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
currentPosition += encodedLen;
|
currentPosition += encodedLen;
|
||||||
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
|
remainingLen -= encodedLen; // DleEncoder will never return encodedLen > remainingLen
|
||||||
|
|
||||||
//encoding the actual data
|
if (remainingLen > 0) {
|
||||||
result = DleEncoder::encode(data, dataLen, currentPosition, remainingLen,
|
*currentPosition = DleEncoder::ETX_CHAR;
|
||||||
&encodedLen, false);
|
}
|
||||||
if (result != RETURN_OK) {
|
remainingLen -= 1;
|
||||||
return result;
|
|
||||||
}
|
|
||||||
currentPosition += encodedLen;
|
|
||||||
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
|
|
||||||
|
|
||||||
uint16_t crc = CRC::crc16ccitt(&command, 1);
|
encodedLen = sizeof(sendBuffer) - remainingLen;
|
||||||
crc = CRC::crc16ccitt(&address, 1, crc);
|
|
||||||
//fortunately the length is still there
|
|
||||||
crc = CRC::crc16ccitt(temporaryBuffer, 2, crc);
|
|
||||||
crc = CRC::crc16ccitt(data, dataLen, crc);
|
|
||||||
|
|
||||||
temporaryBuffer[0] = crc >> 8;
|
|
||||||
temporaryBuffer[1] = crc;
|
|
||||||
|
|
||||||
result = DleEncoder::encode(temporaryBuffer, 2, currentPosition,
|
|
||||||
remainingLen, &encodedLen, false);
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
currentPosition += encodedLen;
|
|
||||||
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
|
|
||||||
|
|
||||||
if (remainingLen > 0) {
|
|
||||||
*currentPosition = DleEncoder::ETX_CHAR;
|
|
||||||
}
|
|
||||||
remainingLen -= 1;
|
|
||||||
|
|
||||||
encodedLen = sizeof(sendBuffer) - remainingLen;
|
|
||||||
|
|
||||||
#ifdef LINUX
|
#ifdef LINUX
|
||||||
ssize_t writtenlen = ::write(serialPort, sendBuffer, encodedLen);
|
ssize_t writtenlen = ::write(serialPort, sendBuffer, encodedLen);
|
||||||
if (writtenlen < 0) {
|
if (writtenlen < 0) {
|
||||||
//we could try to find out what happened...
|
// we could try to find out what happened...
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
if (writtenlen != encodedLen) {
|
if (writtenlen != encodedLen) {
|
||||||
//the OS failed us, we do not try to block until everything is written, as
|
// the OS failed us, we do not try to block until everything is written, as
|
||||||
//we can not block the whole system here
|
// we can not block the whole system here
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
#elif WIN32
|
#elif WIN32
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArduinoComIF::handleSerialPortRx() {
|
void ArduinoComIF::handleSerialPortRx() {
|
||||||
#ifdef LINUX
|
#ifdef LINUX
|
||||||
uint32_t availableSpace = rxBuffer.availableWriteSpace();
|
uint32_t availableSpace = rxBuffer.availableWriteSpace();
|
||||||
|
|
||||||
uint8_t dataFromSerial[availableSpace];
|
uint8_t dataFromSerial[availableSpace];
|
||||||
|
|
||||||
ssize_t bytesRead = read(serialPort, dataFromSerial,
|
ssize_t bytesRead = read(serialPort, dataFromSerial, sizeof(dataFromSerial));
|
||||||
sizeof(dataFromSerial));
|
|
||||||
|
|
||||||
if (bytesRead < 0) {
|
if (bytesRead < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rxBuffer.writeData(dataFromSerial, bytesRead);
|
rxBuffer.writeData(dataFromSerial, bytesRead);
|
||||||
|
|
||||||
uint8_t dataReceivedSoFar[rxBuffer.getMaxSize()];
|
uint8_t dataReceivedSoFar[rxBuffer.getMaxSize()];
|
||||||
|
|
||||||
uint32_t dataLenReceivedSoFar = 0;
|
uint32_t dataLenReceivedSoFar = 0;
|
||||||
|
|
||||||
rxBuffer.readData(dataReceivedSoFar, sizeof(dataReceivedSoFar), true,
|
rxBuffer.readData(dataReceivedSoFar, sizeof(dataReceivedSoFar), true, &dataLenReceivedSoFar);
|
||||||
&dataLenReceivedSoFar);
|
|
||||||
|
|
||||||
//look for STX
|
// look for STX
|
||||||
size_t firstSTXinRawData = 0;
|
size_t firstSTXinRawData = 0;
|
||||||
while ((firstSTXinRawData < dataLenReceivedSoFar)
|
while ((firstSTXinRawData < dataLenReceivedSoFar) &&
|
||||||
&& (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX_CHAR)) {
|
(dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX_CHAR)) {
|
||||||
firstSTXinRawData++;
|
firstSTXinRawData++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX_CHAR) {
|
if (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX_CHAR) {
|
||||||
//there is no STX in our data, throw it away...
|
// there is no STX in our data, throw it away...
|
||||||
rxBuffer.deleteData(dataLenReceivedSoFar);
|
rxBuffer.deleteData(dataLenReceivedSoFar);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t packet[MAX_PACKET_SIZE];
|
uint8_t packet[MAX_PACKET_SIZE];
|
||||||
size_t packetLen = 0;
|
size_t packetLen = 0;
|
||||||
|
|
||||||
size_t readSize = 0;
|
size_t readSize = 0;
|
||||||
|
|
||||||
ReturnValue_t result = DleEncoder::decode(
|
ReturnValue_t result = DleEncoder::decode(dataReceivedSoFar + firstSTXinRawData,
|
||||||
dataReceivedSoFar + firstSTXinRawData,
|
dataLenReceivedSoFar - firstSTXinRawData, &readSize,
|
||||||
dataLenReceivedSoFar - firstSTXinRawData, &readSize, packet,
|
packet, sizeof(packet), &packetLen);
|
||||||
sizeof(packet), &packetLen);
|
|
||||||
|
|
||||||
size_t toDelete = firstSTXinRawData;
|
size_t toDelete = firstSTXinRawData;
|
||||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
handlePacket(packet, packetLen);
|
handlePacket(packet, packetLen);
|
||||||
|
|
||||||
// after handling the packet, we can delete it from the raw stream,
|
// after handling the packet, we can delete it from the raw stream,
|
||||||
// it has been copied to packet
|
// it has been copied to packet
|
||||||
toDelete += readSize;
|
toDelete += readSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
//remove Data which was processed
|
// remove Data which was processed
|
||||||
rxBuffer.deleteData(toDelete);
|
rxBuffer.deleteData(toDelete);
|
||||||
#elif WIN32
|
#elif WIN32
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArduinoComIF::setBaudrate(uint32_t baudRate) {
|
void ArduinoComIF::setBaudrate(uint32_t baudRate) { this->baudRate = baudRate; }
|
||||||
this->baudRate = baudRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArduinoComIF::handlePacket(uint8_t *packet, size_t packetLen) {
|
void ArduinoComIF::handlePacket(uint8_t *packet, size_t packetLen) {
|
||||||
uint16_t crc = CRC::crc16ccitt(packet, packetLen);
|
uint16_t crc = CRC::crc16ccitt(packet, packetLen);
|
||||||
if (crc != 0) {
|
if (crc != 0) {
|
||||||
//CRC error
|
// CRC error
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t command = packet[0];
|
uint8_t command = packet[0];
|
||||||
uint8_t address = packet[1];
|
uint8_t address = packet[1];
|
||||||
|
|
||||||
uint16_t size = (packet[2] << 8) + packet[3];
|
uint16_t size = (packet[2] << 8) + packet[3];
|
||||||
|
|
||||||
if (size != packetLen - 6) {
|
if (size != packetLen - 6) {
|
||||||
//Invalid Length
|
// Invalid Length
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case ArduinoCookie::SPI: {
|
case ArduinoCookie::SPI: {
|
||||||
//ArduinoCookie **itsComplicated;
|
// ArduinoCookie **itsComplicated;
|
||||||
auto findIter = spiMap.find(address);
|
auto findIter = spiMap.find(address);
|
||||||
if (findIter == spiMap.end()) {
|
if (findIter == spiMap.end()) {
|
||||||
//we do no know this address
|
// we do no know this address
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ArduinoCookie& cookie = findIter->second;
|
ArduinoCookie &cookie = findIter->second;
|
||||||
if (packetLen > cookie.maxReplySize + 6) {
|
if (packetLen > cookie.maxReplySize + 6) {
|
||||||
packetLen = cookie.maxReplySize + 6;
|
packetLen = cookie.maxReplySize + 6;
|
||||||
}
|
}
|
||||||
std::memcpy(cookie.replyBuffer.data(), packet + 4, packetLen - 6);
|
std::memcpy(cookie.replyBuffer.data(), packet + 4, packetLen - 6);
|
||||||
cookie.receivedDataLen = packetLen - 6;
|
cookie.receivedDataLen = packetLen - 6;
|
||||||
}
|
} break;
|
||||||
break;
|
default:
|
||||||
default:
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
#include <fsfw/container/FixedMap.h>
|
#include <fsfw/container/FixedMap.h>
|
||||||
#include <fsfw/container/SimpleRingBuffer.h>
|
#include <fsfw/container/SimpleRingBuffer.h>
|
||||||
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
|
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
|
||||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
|
||||||
#include <fsfw/objectmanager/SystemObject.h>
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
|
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -14,56 +14,53 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Forward declaration, so users don't peek
|
// Forward declaration, so users don't peek
|
||||||
class ArduinoCookie;
|
class ArduinoCookie;
|
||||||
|
|
||||||
class ArduinoComIF: public SystemObject,
|
class ArduinoComIF : public SystemObject, public DeviceCommunicationIF {
|
||||||
public DeviceCommunicationIF {
|
public:
|
||||||
public:
|
static const uint8_t MAX_NUMBER_OF_SPI_DEVICES = 8;
|
||||||
static const uint8_t MAX_NUMBER_OF_SPI_DEVICES = 8;
|
static const uint8_t MAX_PACKET_SIZE = 64;
|
||||||
static const uint8_t MAX_PACKET_SIZE = 64;
|
|
||||||
|
|
||||||
static const uint8_t COMMAND_INVALID = -1;
|
static const uint8_t COMMAND_INVALID = -1;
|
||||||
static const uint8_t COMMAND_SPI = 1;
|
static const uint8_t COMMAND_SPI = 1;
|
||||||
|
|
||||||
ArduinoComIF(object_id_t setObjectId, bool promptComIF = false,
|
ArduinoComIF(object_id_t setObjectId, bool promptComIF = false,
|
||||||
const char *serialDevice = nullptr);
|
const char *serialDevice = nullptr);
|
||||||
void setBaudrate(uint32_t baudRate);
|
void setBaudrate(uint32_t baudRate);
|
||||||
|
|
||||||
virtual ~ArduinoComIF();
|
virtual ~ArduinoComIF();
|
||||||
|
|
||||||
/** DeviceCommunicationIF overrides */
|
/** DeviceCommunicationIF overrides */
|
||||||
virtual ReturnValue_t initializeInterface(CookieIF * cookie) override;
|
virtual ReturnValue_t initializeInterface(CookieIF *cookie) override;
|
||||||
virtual ReturnValue_t sendMessage(CookieIF *cookie,
|
virtual ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t *sendData,
|
||||||
const uint8_t * sendData, size_t sendLen) override;
|
size_t sendLen) override;
|
||||||
virtual ReturnValue_t getSendSuccess(CookieIF *cookie) override;
|
virtual ReturnValue_t getSendSuccess(CookieIF *cookie) override;
|
||||||
virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie,
|
virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie, size_t requestLen) override;
|
||||||
size_t requestLen) override;
|
virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer,
|
||||||
virtual ReturnValue_t readReceivedMessage(CookieIF *cookie,
|
size_t *size) override;
|
||||||
uint8_t **buffer, size_t *size) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef LINUX
|
#ifdef LINUX
|
||||||
#elif WIN32
|
#elif WIN32
|
||||||
HANDLE hCom = INVALID_HANDLE_VALUE;
|
HANDLE hCom = INVALID_HANDLE_VALUE;
|
||||||
#endif
|
#endif
|
||||||
// remembering if the initialization in the ctor worked
|
// remembering if the initialization in the ctor worked
|
||||||
// if not, all calls are disabled
|
// if not, all calls are disabled
|
||||||
bool initialized = false;
|
bool initialized = false;
|
||||||
int serialPort = 0;
|
int serialPort = 0;
|
||||||
// Default baud rate is 9600 for now.
|
// Default baud rate is 9600 for now.
|
||||||
uint32_t baudRate = 9600;
|
uint32_t baudRate = 9600;
|
||||||
|
|
||||||
//used to know where to put the data if a reply is received
|
// used to know where to put the data if a reply is received
|
||||||
std::map<uint8_t, ArduinoCookie> spiMap;
|
std::map<uint8_t, ArduinoCookie> spiMap;
|
||||||
|
|
||||||
SimpleRingBuffer rxBuffer;
|
SimpleRingBuffer rxBuffer;
|
||||||
|
|
||||||
ReturnValue_t sendMessage(uint8_t command, uint8_t address,
|
ReturnValue_t sendMessage(uint8_t command, uint8_t address, const uint8_t *data, size_t dataLen);
|
||||||
const uint8_t *data, size_t dataLen);
|
void handleSerialPortRx();
|
||||||
void handleSerialPortRx();
|
|
||||||
|
|
||||||
void handlePacket(uint8_t *packet, size_t packetLen);
|
void handlePacket(uint8_t *packet, size_t packetLen);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_ARDUINOCOMMINTERFACE_H_ */
|
#endif /* MISSION_ARDUINOCOMMINTERFACE_H_ */
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#include <bsp_hosted/comIF/ArduinoCookie.h>
|
#include <bsp_hosted/comIF/ArduinoCookie.h>
|
||||||
|
|
||||||
ArduinoCookie::ArduinoCookie(Protocol_t protocol, uint8_t address,
|
ArduinoCookie::ArduinoCookie(Protocol_t protocol, uint8_t address, const size_t maxReplySize)
|
||||||
const size_t maxReplySize) :
|
: protocol(protocol),
|
||||||
protocol(protocol), command(protocol), address(address),
|
command(protocol),
|
||||||
maxReplySize(maxReplySize), replyBuffer(maxReplySize) {
|
address(address),
|
||||||
}
|
maxReplySize(maxReplySize),
|
||||||
|
replyBuffer(maxReplySize) {}
|
||||||
|
@ -2,26 +2,21 @@
|
|||||||
#define MISSION_ARDUINO_ARDUINOCOOKIE_H_
|
#define MISSION_ARDUINO_ARDUINOCOOKIE_H_
|
||||||
|
|
||||||
#include <fsfw/devicehandlers/CookieIF.h>
|
#include <fsfw/devicehandlers/CookieIF.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class ArduinoCookie: public CookieIF {
|
class ArduinoCookie : public CookieIF {
|
||||||
public:
|
public:
|
||||||
enum Protocol_t: uint8_t {
|
enum Protocol_t : uint8_t { INVALID, SPI, I2C };
|
||||||
INVALID,
|
|
||||||
SPI,
|
|
||||||
I2C
|
|
||||||
};
|
|
||||||
|
|
||||||
ArduinoCookie(Protocol_t protocol, uint8_t address,
|
ArduinoCookie(Protocol_t protocol, uint8_t address, const size_t maxReplySize);
|
||||||
const size_t maxReplySize);
|
|
||||||
|
|
||||||
Protocol_t protocol;
|
|
||||||
uint8_t command;
|
|
||||||
uint8_t address;
|
|
||||||
std::vector<uint8_t> replyBuffer;
|
|
||||||
size_t receivedDataLen = 0;
|
|
||||||
size_t maxReplySize;
|
|
||||||
|
|
||||||
|
Protocol_t protocol;
|
||||||
|
uint8_t command;
|
||||||
|
uint8_t address;
|
||||||
|
std::vector<uint8_t> replyBuffer;
|
||||||
|
size_t receivedDataLen = 0;
|
||||||
|
size_t maxReplySize;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_ARDUINO_ARDUINOCOOKIE_H_ */
|
#endif /* MISSION_ARDUINO_ARDUINOCOOKIE_H_ */
|
||||||
|
@ -2,56 +2,53 @@
|
|||||||
#define FSFWCONFIG_DEVICES_GPIOIDS_H_
|
#define FSFWCONFIG_DEVICES_GPIOIDS_H_
|
||||||
|
|
||||||
namespace gpioIds {
|
namespace gpioIds {
|
||||||
enum gpioId_t {
|
enum gpioId_t {
|
||||||
HEATER_0,
|
HEATER_0,
|
||||||
HEATER_1,
|
HEATER_1,
|
||||||
HEATER_2,
|
HEATER_2,
|
||||||
HEATER_3,
|
HEATER_3,
|
||||||
HEATER_4,
|
HEATER_4,
|
||||||
HEATER_5,
|
HEATER_5,
|
||||||
HEATER_6,
|
HEATER_6,
|
||||||
HEATER_7,
|
HEATER_7,
|
||||||
DEPLSA1,
|
DEPLSA1,
|
||||||
DEPLSA2,
|
DEPLSA2,
|
||||||
|
|
||||||
MGM_0_LIS3_CS,
|
MGM_0_LIS3_CS,
|
||||||
MGM_1_RM3100_CS,
|
MGM_1_RM3100_CS,
|
||||||
GYRO_0_ADIS_CS,
|
GYRO_0_ADIS_CS,
|
||||||
GYRO_1_L3G_CS,
|
GYRO_1_L3G_CS,
|
||||||
GYRO_2_L3G_CS,
|
GYRO_2_L3G_CS,
|
||||||
MGM_2_LIS3_CS,
|
MGM_2_LIS3_CS,
|
||||||
MGM_3_RM3100_CS,
|
MGM_3_RM3100_CS,
|
||||||
|
|
||||||
TEST_ID_0,
|
TEST_ID_0,
|
||||||
TEST_ID_1,
|
TEST_ID_1,
|
||||||
|
|
||||||
RTD_IC_3,
|
RTD_IC_3,
|
||||||
RTD_IC_4,
|
RTD_IC_4,
|
||||||
RTD_IC_5,
|
RTD_IC_5,
|
||||||
RTD_IC_6,
|
RTD_IC_6,
|
||||||
RTD_IC_7,
|
RTD_IC_7,
|
||||||
RTD_IC_8,
|
RTD_IC_8,
|
||||||
RTD_IC_9,
|
RTD_IC_9,
|
||||||
RTD_IC_10,
|
RTD_IC_10,
|
||||||
RTD_IC_11,
|
RTD_IC_11,
|
||||||
RTD_IC_12,
|
RTD_IC_12,
|
||||||
RTD_IC_13,
|
RTD_IC_13,
|
||||||
RTD_IC_14,
|
RTD_IC_14,
|
||||||
RTD_IC_15,
|
RTD_IC_15,
|
||||||
RTD_IC_16,
|
RTD_IC_16,
|
||||||
RTD_IC_17,
|
RTD_IC_17,
|
||||||
RTD_IC_18,
|
RTD_IC_18,
|
||||||
|
|
||||||
SPI_MUX_BIT_1,
|
SPI_MUX_BIT_1,
|
||||||
SPI_MUX_BIT_2,
|
SPI_MUX_BIT_2,
|
||||||
SPI_MUX_BIT_3,
|
SPI_MUX_BIT_3,
|
||||||
SPI_MUX_BIT_4,
|
SPI_MUX_BIT_4,
|
||||||
SPI_MUX_BIT_5,
|
SPI_MUX_BIT_5,
|
||||||
SPI_MUX_BIT_6
|
SPI_MUX_BIT_6
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* FSFWCONFIG_DEVICES_GPIOIDS_H_ */
|
#endif /* FSFWCONFIG_DEVICES_GPIOIDS_H_ */
|
||||||
|
@ -4,55 +4,54 @@
|
|||||||
#include <OBSWConfig.h>
|
#include <OBSWConfig.h>
|
||||||
|
|
||||||
namespace pcduSwitches {
|
namespace pcduSwitches {
|
||||||
/* Switches are uint8_t datatype and go from 0 to 255 */
|
/* Switches are uint8_t datatype and go from 0 to 255 */
|
||||||
enum SwitcherList {
|
enum SwitcherList {
|
||||||
Q7S,
|
Q7S,
|
||||||
PAYLOAD_PCDU_CH1,
|
PAYLOAD_PCDU_CH1,
|
||||||
RW,
|
RW,
|
||||||
TCS_BOARD_8V_HEATER_IN,
|
TCS_BOARD_8V_HEATER_IN,
|
||||||
SUS_REDUNDANT,
|
SUS_REDUNDANT,
|
||||||
DEPLOYMENT_MECHANISM,
|
DEPLOYMENT_MECHANISM,
|
||||||
PAYLOAD_PCDU_CH6,
|
PAYLOAD_PCDU_CH6,
|
||||||
ACS_BOARD_SIDE_B,
|
ACS_BOARD_SIDE_B,
|
||||||
PAYLOAD_CAMERA,
|
PAYLOAD_CAMERA,
|
||||||
TCS_BOARD_3V3,
|
TCS_BOARD_3V3,
|
||||||
SYRLINKS,
|
SYRLINKS,
|
||||||
STAR_TRACKER,
|
STAR_TRACKER,
|
||||||
MGT,
|
MGT,
|
||||||
SUS_NOMINAL,
|
SUS_NOMINAL,
|
||||||
SOLAR_CELL_EXP,
|
SOLAR_CELL_EXP,
|
||||||
PLOC,
|
PLOC,
|
||||||
ACS_BOARD_SIDE_A,
|
ACS_BOARD_SIDE_A,
|
||||||
NUMBER_OF_SWITCHES
|
NUMBER_OF_SWITCHES
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t ON = 1;
|
static const uint8_t ON = 1;
|
||||||
static const uint8_t OFF = 0;
|
static const uint8_t OFF = 0;
|
||||||
|
|
||||||
/* Output states after reboot of the PDUs */
|
/* Output states after reboot of the PDUs */
|
||||||
static const uint8_t INIT_STATE_Q7S = ON;
|
static const uint8_t INIT_STATE_Q7S = ON;
|
||||||
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF;
|
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF;
|
||||||
static const uint8_t INIT_STATE_RW = OFF;
|
static const uint8_t INIT_STATE_RW = OFF;
|
||||||
#if BOARD_TE0720 == 1
|
#if BOARD_TE0720 == 1
|
||||||
/* Because the TE0720 is not connected to the PCDU, this switch is always on */
|
/* Because the TE0720 is not connected to the PCDU, this switch is always on */
|
||||||
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON;
|
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON;
|
||||||
#else
|
#else
|
||||||
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF;
|
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF;
|
||||||
#endif
|
#endif
|
||||||
static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF;
|
static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF;
|
||||||
static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF;
|
static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF;
|
||||||
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF;
|
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF;
|
||||||
static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF;
|
static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF;
|
||||||
static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF;
|
static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF;
|
||||||
static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF;
|
static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF;
|
||||||
static const uint8_t INIT_STATE_SYRLINKS = OFF;
|
static const uint8_t INIT_STATE_SYRLINKS = OFF;
|
||||||
static const uint8_t INIT_STATE_STAR_TRACKER = OFF;
|
static const uint8_t INIT_STATE_STAR_TRACKER = OFF;
|
||||||
static const uint8_t INIT_STATE_MGT = OFF;
|
static const uint8_t INIT_STATE_MGT = OFF;
|
||||||
static const uint8_t INIT_STATE_SUS_NOMINAL = OFF;
|
static const uint8_t INIT_STATE_SUS_NOMINAL = OFF;
|
||||||
static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF;
|
static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF;
|
||||||
static const uint8_t INIT_STATE_PLOC = OFF;
|
static const uint8_t INIT_STATE_PLOC = OFF;
|
||||||
static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF;
|
static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF;
|
||||||
}
|
} // namespace pcduSwitches
|
||||||
|
|
||||||
|
|
||||||
#endif /* FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ */
|
#endif /* FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ */
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_
|
#define CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_
|
||||||
|
|
||||||
#include <common/config/commonSubsystemIds.h>
|
#include <common/config/commonSubsystemIds.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9,9 +10,7 @@
|
|||||||
* Numbers 0-80 are reserved for FSFW Subsystem IDs (framework/events/)
|
* Numbers 0-80 are reserved for FSFW Subsystem IDs (framework/events/)
|
||||||
*/
|
*/
|
||||||
namespace SUBSYSTEM_ID {
|
namespace SUBSYSTEM_ID {
|
||||||
enum: uint8_t {
|
enum : uint8_t { SUBSYSTEM_ID_START = COMMON_SUBSYSTEM_ID_END };
|
||||||
SUBSYSTEM_ID_START = COMMON_SUBSYSTEM_ID_END
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_ */
|
#endif /* CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_ */
|
||||||
|
@ -89,176 +89,176 @@ const char *ACK_FAILURE_STRING = "ACK_FAILURE";
|
|||||||
const char *EXE_FAILURE_STRING = "EXE_FAILURE";
|
const char *EXE_FAILURE_STRING = "EXE_FAILURE";
|
||||||
const char *CRC_FAILURE_EVENT_STRING = "CRC_FAILURE_EVENT";
|
const char *CRC_FAILURE_EVENT_STRING = "CRC_FAILURE_EVENT";
|
||||||
|
|
||||||
const char * translateEvents(Event event) {
|
const char *translateEvents(Event event) {
|
||||||
switch( (event & 0xffff) ) {
|
switch ((event & 0xffff)) {
|
||||||
case(2200):
|
case (2200):
|
||||||
return STORE_SEND_WRITE_FAILED_STRING;
|
return STORE_SEND_WRITE_FAILED_STRING;
|
||||||
case(2201):
|
case (2201):
|
||||||
return STORE_WRITE_FAILED_STRING;
|
return STORE_WRITE_FAILED_STRING;
|
||||||
case(2202):
|
case (2202):
|
||||||
return STORE_SEND_READ_FAILED_STRING;
|
return STORE_SEND_READ_FAILED_STRING;
|
||||||
case(2203):
|
case (2203):
|
||||||
return STORE_READ_FAILED_STRING;
|
return STORE_READ_FAILED_STRING;
|
||||||
case(2204):
|
case (2204):
|
||||||
return UNEXPECTED_MSG_STRING;
|
return UNEXPECTED_MSG_STRING;
|
||||||
case(2205):
|
case (2205):
|
||||||
return STORING_FAILED_STRING;
|
return STORING_FAILED_STRING;
|
||||||
case(2206):
|
case (2206):
|
||||||
return TM_DUMP_FAILED_STRING;
|
return TM_DUMP_FAILED_STRING;
|
||||||
case(2207):
|
case (2207):
|
||||||
return STORE_INIT_FAILED_STRING;
|
return STORE_INIT_FAILED_STRING;
|
||||||
case(2208):
|
case (2208):
|
||||||
return STORE_INIT_EMPTY_STRING;
|
return STORE_INIT_EMPTY_STRING;
|
||||||
case(2209):
|
case (2209):
|
||||||
return STORE_CONTENT_CORRUPTED_STRING;
|
return STORE_CONTENT_CORRUPTED_STRING;
|
||||||
case(2210):
|
case (2210):
|
||||||
return STORE_INITIALIZE_STRING;
|
return STORE_INITIALIZE_STRING;
|
||||||
case(2211):
|
case (2211):
|
||||||
return INIT_DONE_STRING;
|
return INIT_DONE_STRING;
|
||||||
case(2212):
|
case (2212):
|
||||||
return DUMP_FINISHED_STRING;
|
return DUMP_FINISHED_STRING;
|
||||||
case(2213):
|
case (2213):
|
||||||
return DELETION_FINISHED_STRING;
|
return DELETION_FINISHED_STRING;
|
||||||
case(2214):
|
case (2214):
|
||||||
return DELETION_FAILED_STRING;
|
return DELETION_FAILED_STRING;
|
||||||
case(2215):
|
case (2215):
|
||||||
return AUTO_CATALOGS_SENDING_FAILED_STRING;
|
return AUTO_CATALOGS_SENDING_FAILED_STRING;
|
||||||
case(2600):
|
case (2600):
|
||||||
return GET_DATA_FAILED_STRING;
|
return GET_DATA_FAILED_STRING;
|
||||||
case(2601):
|
case (2601):
|
||||||
return STORE_DATA_FAILED_STRING;
|
return STORE_DATA_FAILED_STRING;
|
||||||
case(2800):
|
case (2800):
|
||||||
return DEVICE_BUILDING_COMMAND_FAILED_STRING;
|
return DEVICE_BUILDING_COMMAND_FAILED_STRING;
|
||||||
case(2801):
|
case (2801):
|
||||||
return DEVICE_SENDING_COMMAND_FAILED_STRING;
|
return DEVICE_SENDING_COMMAND_FAILED_STRING;
|
||||||
case(2802):
|
case (2802):
|
||||||
return DEVICE_REQUESTING_REPLY_FAILED_STRING;
|
return DEVICE_REQUESTING_REPLY_FAILED_STRING;
|
||||||
case(2803):
|
case (2803):
|
||||||
return DEVICE_READING_REPLY_FAILED_STRING;
|
return DEVICE_READING_REPLY_FAILED_STRING;
|
||||||
case(2804):
|
case (2804):
|
||||||
return DEVICE_INTERPRETING_REPLY_FAILED_STRING;
|
return DEVICE_INTERPRETING_REPLY_FAILED_STRING;
|
||||||
case(2805):
|
case (2805):
|
||||||
return DEVICE_MISSED_REPLY_STRING;
|
return DEVICE_MISSED_REPLY_STRING;
|
||||||
case(2806):
|
case (2806):
|
||||||
return DEVICE_UNKNOWN_REPLY_STRING;
|
return DEVICE_UNKNOWN_REPLY_STRING;
|
||||||
case(2807):
|
case (2807):
|
||||||
return DEVICE_UNREQUESTED_REPLY_STRING;
|
return DEVICE_UNREQUESTED_REPLY_STRING;
|
||||||
case(2808):
|
case (2808):
|
||||||
return INVALID_DEVICE_COMMAND_STRING;
|
return INVALID_DEVICE_COMMAND_STRING;
|
||||||
case(2809):
|
case (2809):
|
||||||
return MONITORING_LIMIT_EXCEEDED_STRING;
|
return MONITORING_LIMIT_EXCEEDED_STRING;
|
||||||
case(2810):
|
case (2810):
|
||||||
return MONITORING_AMBIGUOUS_STRING;
|
return MONITORING_AMBIGUOUS_STRING;
|
||||||
case(4201):
|
case (4201):
|
||||||
return FUSE_CURRENT_HIGH_STRING;
|
return FUSE_CURRENT_HIGH_STRING;
|
||||||
case(4202):
|
case (4202):
|
||||||
return FUSE_WENT_OFF_STRING;
|
return FUSE_WENT_OFF_STRING;
|
||||||
case(4204):
|
case (4204):
|
||||||
return POWER_ABOVE_HIGH_LIMIT_STRING;
|
return POWER_ABOVE_HIGH_LIMIT_STRING;
|
||||||
case(4205):
|
case (4205):
|
||||||
return POWER_BELOW_LOW_LIMIT_STRING;
|
return POWER_BELOW_LOW_LIMIT_STRING;
|
||||||
case(4300):
|
case (4300):
|
||||||
return SWITCH_WENT_OFF_STRING;
|
return SWITCH_WENT_OFF_STRING;
|
||||||
case(5000):
|
case (5000):
|
||||||
return HEATER_ON_STRING;
|
return HEATER_ON_STRING;
|
||||||
case(5001):
|
case (5001):
|
||||||
return HEATER_OFF_STRING;
|
return HEATER_OFF_STRING;
|
||||||
case(5002):
|
case (5002):
|
||||||
return HEATER_TIMEOUT_STRING;
|
return HEATER_TIMEOUT_STRING;
|
||||||
case(5003):
|
case (5003):
|
||||||
return HEATER_STAYED_ON_STRING;
|
return HEATER_STAYED_ON_STRING;
|
||||||
case(5004):
|
case (5004):
|
||||||
return HEATER_STAYED_OFF_STRING;
|
return HEATER_STAYED_OFF_STRING;
|
||||||
case(5200):
|
case (5200):
|
||||||
return TEMP_SENSOR_HIGH_STRING;
|
return TEMP_SENSOR_HIGH_STRING;
|
||||||
case(5201):
|
case (5201):
|
||||||
return TEMP_SENSOR_LOW_STRING;
|
return TEMP_SENSOR_LOW_STRING;
|
||||||
case(5202):
|
case (5202):
|
||||||
return TEMP_SENSOR_GRADIENT_STRING;
|
return TEMP_SENSOR_GRADIENT_STRING;
|
||||||
case(5901):
|
case (5901):
|
||||||
return COMPONENT_TEMP_LOW_STRING;
|
return COMPONENT_TEMP_LOW_STRING;
|
||||||
case(5902):
|
case (5902):
|
||||||
return COMPONENT_TEMP_HIGH_STRING;
|
return COMPONENT_TEMP_HIGH_STRING;
|
||||||
case(5903):
|
case (5903):
|
||||||
return COMPONENT_TEMP_OOL_LOW_STRING;
|
return COMPONENT_TEMP_OOL_LOW_STRING;
|
||||||
case(5904):
|
case (5904):
|
||||||
return COMPONENT_TEMP_OOL_HIGH_STRING;
|
return COMPONENT_TEMP_OOL_HIGH_STRING;
|
||||||
case(5905):
|
case (5905):
|
||||||
return TEMP_NOT_IN_OP_RANGE_STRING;
|
return TEMP_NOT_IN_OP_RANGE_STRING;
|
||||||
case(7101):
|
case (7101):
|
||||||
return FDIR_CHANGED_STATE_STRING;
|
return FDIR_CHANGED_STATE_STRING;
|
||||||
case(7102):
|
case (7102):
|
||||||
return FDIR_STARTS_RECOVERY_STRING;
|
return FDIR_STARTS_RECOVERY_STRING;
|
||||||
case(7103):
|
case (7103):
|
||||||
return FDIR_TURNS_OFF_DEVICE_STRING;
|
return FDIR_TURNS_OFF_DEVICE_STRING;
|
||||||
case(7201):
|
case (7201):
|
||||||
return MONITOR_CHANGED_STATE_STRING;
|
return MONITOR_CHANGED_STATE_STRING;
|
||||||
case(7202):
|
case (7202):
|
||||||
return VALUE_BELOW_LOW_LIMIT_STRING;
|
return VALUE_BELOW_LOW_LIMIT_STRING;
|
||||||
case(7203):
|
case (7203):
|
||||||
return VALUE_ABOVE_HIGH_LIMIT_STRING;
|
return VALUE_ABOVE_HIGH_LIMIT_STRING;
|
||||||
case(7204):
|
case (7204):
|
||||||
return VALUE_OUT_OF_RANGE_STRING;
|
return VALUE_OUT_OF_RANGE_STRING;
|
||||||
case(7301):
|
case (7301):
|
||||||
return SWITCHING_TM_FAILED_STRING;
|
return SWITCHING_TM_FAILED_STRING;
|
||||||
case(7400):
|
case (7400):
|
||||||
return CHANGING_MODE_STRING;
|
return CHANGING_MODE_STRING;
|
||||||
case(7401):
|
case (7401):
|
||||||
return MODE_INFO_STRING;
|
return MODE_INFO_STRING;
|
||||||
case(7402):
|
case (7402):
|
||||||
return FALLBACK_FAILED_STRING;
|
return FALLBACK_FAILED_STRING;
|
||||||
case(7403):
|
case (7403):
|
||||||
return MODE_TRANSITION_FAILED_STRING;
|
return MODE_TRANSITION_FAILED_STRING;
|
||||||
case(7404):
|
case (7404):
|
||||||
return CANT_KEEP_MODE_STRING;
|
return CANT_KEEP_MODE_STRING;
|
||||||
case(7405):
|
case (7405):
|
||||||
return OBJECT_IN_INVALID_MODE_STRING;
|
return OBJECT_IN_INVALID_MODE_STRING;
|
||||||
case(7406):
|
case (7406):
|
||||||
return FORCING_MODE_STRING;
|
return FORCING_MODE_STRING;
|
||||||
case(7407):
|
case (7407):
|
||||||
return MODE_CMD_REJECTED_STRING;
|
return MODE_CMD_REJECTED_STRING;
|
||||||
case(7506):
|
case (7506):
|
||||||
return HEALTH_INFO_STRING;
|
return HEALTH_INFO_STRING;
|
||||||
case(7507):
|
case (7507):
|
||||||
return CHILD_CHANGED_HEALTH_STRING;
|
return CHILD_CHANGED_HEALTH_STRING;
|
||||||
case(7508):
|
case (7508):
|
||||||
return CHILD_PROBLEMS_STRING;
|
return CHILD_PROBLEMS_STRING;
|
||||||
case(7509):
|
case (7509):
|
||||||
return OVERWRITING_HEALTH_STRING;
|
return OVERWRITING_HEALTH_STRING;
|
||||||
case(7510):
|
case (7510):
|
||||||
return TRYING_RECOVERY_STRING;
|
return TRYING_RECOVERY_STRING;
|
||||||
case(7511):
|
case (7511):
|
||||||
return RECOVERY_STEP_STRING;
|
return RECOVERY_STEP_STRING;
|
||||||
case(7512):
|
case (7512):
|
||||||
return RECOVERY_DONE_STRING;
|
return RECOVERY_DONE_STRING;
|
||||||
case(7900):
|
case (7900):
|
||||||
return RF_AVAILABLE_STRING;
|
return RF_AVAILABLE_STRING;
|
||||||
case(7901):
|
case (7901):
|
||||||
return RF_LOST_STRING;
|
return RF_LOST_STRING;
|
||||||
case(7902):
|
case (7902):
|
||||||
return BIT_LOCK_STRING;
|
return BIT_LOCK_STRING;
|
||||||
case(7903):
|
case (7903):
|
||||||
return BIT_LOCK_LOST_STRING;
|
return BIT_LOCK_LOST_STRING;
|
||||||
case(7905):
|
case (7905):
|
||||||
return FRAME_PROCESSING_FAILED_STRING;
|
return FRAME_PROCESSING_FAILED_STRING;
|
||||||
case(8900):
|
case (8900):
|
||||||
return CLOCK_SET_STRING;
|
return CLOCK_SET_STRING;
|
||||||
case(8901):
|
case (8901):
|
||||||
return CLOCK_SET_FAILURE_STRING;
|
return CLOCK_SET_FAILURE_STRING;
|
||||||
case(9700):
|
case (9700):
|
||||||
return TEST_STRING;
|
return TEST_STRING;
|
||||||
case(10600):
|
case (10600):
|
||||||
return CHANGE_OF_SETUP_PARAMETER_STRING;
|
return CHANGE_OF_SETUP_PARAMETER_STRING;
|
||||||
case(11101):
|
case (11101):
|
||||||
return MEMORY_READ_RPT_CRC_FAILURE_STRING;
|
return MEMORY_READ_RPT_CRC_FAILURE_STRING;
|
||||||
case(11102):
|
case (11102):
|
||||||
return ACK_FAILURE_STRING;
|
return ACK_FAILURE_STRING;
|
||||||
case(11103):
|
case (11103):
|
||||||
return EXE_FAILURE_STRING;
|
return EXE_FAILURE_STRING;
|
||||||
case(11104):
|
case (11104):
|
||||||
return CRC_FAILURE_EVENT_STRING;
|
return CRC_FAILURE_EVENT_STRING;
|
||||||
default:
|
default:
|
||||||
return "UNKNOWN_EVENT";
|
return "UNKNOWN_EVENT";
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
|
|
||||||
#include <fsfw/events/Event.h>
|
#include <fsfw/events/Event.h>
|
||||||
|
|
||||||
const char * translateEvents(Event event);
|
const char* translateEvents(Event event);
|
||||||
|
|
||||||
#endif /* FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_ */
|
#endif /* FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_ */
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
#include "MissionMessageTypes.h"
|
#include "MissionMessageTypes.h"
|
||||||
|
|
||||||
#include <fsfw/ipc/CommandMessage.h>
|
#include <fsfw/ipc/CommandMessage.h>
|
||||||
|
|
||||||
void messagetypes::clearMissionMessage(CommandMessage* message) {
|
void messagetypes::clearMissionMessage(CommandMessage* message) {
|
||||||
switch(message->getMessageType()) {
|
switch (message->getMessageType()) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,10 +13,10 @@ class CommandMessage;
|
|||||||
*/
|
*/
|
||||||
namespace messagetypes {
|
namespace messagetypes {
|
||||||
enum MESSAGE_TYPE {
|
enum MESSAGE_TYPE {
|
||||||
MISSION_MESSAGE_TYPE_START = FW_MESSAGES_COUNT,
|
MISSION_MESSAGE_TYPE_START = FW_MESSAGES_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
void clearMissionMessage(CommandMessage* message);
|
void clearMissionMessage(CommandMessage* message);
|
||||||
}
|
} // namespace messagetypes
|
||||||
|
|
||||||
#endif /* CONFIG_IPC_MISSIONMESSAGETYPES_H_ */
|
#endif /* CONFIG_IPC_MISSIONMESSAGETYPES_H_ */
|
||||||
|
@ -1,31 +1,32 @@
|
|||||||
#ifndef HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
|
#ifndef HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
|
||||||
#define HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
|
#define HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <commonObjects.h>
|
#include <commonObjects.h>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
// The objects will be instantiated in the ID order
|
// The objects will be instantiated in the ID order
|
||||||
namespace objects {
|
namespace objects {
|
||||||
enum sourceObjects: uint32_t {
|
enum sourceObjects : uint32_t {
|
||||||
|
|
||||||
PUS_SERVICE_3 = 0x51000300,
|
PUS_SERVICE_3 = 0x51000300,
|
||||||
PUS_SERVICE_5 = 0x51000400,
|
PUS_SERVICE_5 = 0x51000400,
|
||||||
PUS_SERVICE_6 = 0x51000500,
|
PUS_SERVICE_6 = 0x51000500,
|
||||||
PUS_SERVICE_8 = 0x51000800,
|
PUS_SERVICE_8 = 0x51000800,
|
||||||
PUS_SERVICE_23 = 0x51002300,
|
PUS_SERVICE_23 = 0x51002300,
|
||||||
PUS_SERVICE_201 = 0x51020100,
|
PUS_SERVICE_201 = 0x51020100,
|
||||||
|
|
||||||
TM_FUNNEL = 0x52000002,
|
TM_FUNNEL = 0x52000002,
|
||||||
|
|
||||||
/* Test Task */
|
/* Test Task */
|
||||||
|
|
||||||
TEST_TASK = 0x42694269,
|
TEST_TASK = 0x42694269,
|
||||||
DUMMY_INTERFACE = 0xCAFECAFE,
|
DUMMY_INTERFACE = 0xCAFECAFE,
|
||||||
DUMMY_HANDLER = 0x4400AFFE,
|
DUMMY_HANDLER = 0x4400AFFE,
|
||||||
|
|
||||||
/* 0x49 ('I') for Communication Interfaces **/
|
/* 0x49 ('I') for Communication Interfaces **/
|
||||||
ARDUINO_COM_IF = 0x49000001
|
ARDUINO_COM_IF = 0x49000001
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* BSP_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ */
|
#endif /* BSP_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ */
|
||||||
|
@ -38,72 +38,72 @@ const char *FSFW_OBJECTS_END_STRING = "FSFW_OBJECTS_END";
|
|||||||
const char *DUMMY_INTERFACE_STRING = "DUMMY_INTERFACE";
|
const char *DUMMY_INTERFACE_STRING = "DUMMY_INTERFACE";
|
||||||
const char *NO_OBJECT_STRING = "NO_OBJECT";
|
const char *NO_OBJECT_STRING = "NO_OBJECT";
|
||||||
|
|
||||||
const char* translateObject(object_id_t object) {
|
const char *translateObject(object_id_t object) {
|
||||||
switch( (object & 0xFFFFFFFF) ) {
|
switch ((object & 0xFFFFFFFF)) {
|
||||||
case 0x42694269:
|
case 0x42694269:
|
||||||
return TEST_TASK_STRING;
|
return TEST_TASK_STRING;
|
||||||
case 0x4400AFFE:
|
case 0x4400AFFE:
|
||||||
return DUMMY_HANDLER_STRING;
|
return DUMMY_HANDLER_STRING;
|
||||||
case 0x49000001:
|
case 0x49000001:
|
||||||
return ARDUINO_COM_IF_STRING;
|
return ARDUINO_COM_IF_STRING;
|
||||||
case 0x51000300:
|
case 0x51000300:
|
||||||
return PUS_SERVICE_3_STRING;
|
return PUS_SERVICE_3_STRING;
|
||||||
case 0x51000400:
|
case 0x51000400:
|
||||||
return PUS_SERVICE_5_STRING;
|
return PUS_SERVICE_5_STRING;
|
||||||
case 0x51000500:
|
case 0x51000500:
|
||||||
return PUS_SERVICE_6_STRING;
|
return PUS_SERVICE_6_STRING;
|
||||||
case 0x51000800:
|
case 0x51000800:
|
||||||
return PUS_SERVICE_8_STRING;
|
return PUS_SERVICE_8_STRING;
|
||||||
case 0x51002300:
|
case 0x51002300:
|
||||||
return PUS_SERVICE_23_STRING;
|
return PUS_SERVICE_23_STRING;
|
||||||
case 0x51020100:
|
case 0x51020100:
|
||||||
return PUS_SERVICE_201_STRING;
|
return PUS_SERVICE_201_STRING;
|
||||||
case 0x52000002:
|
case 0x52000002:
|
||||||
return TM_FUNNEL_STRING;
|
return TM_FUNNEL_STRING;
|
||||||
case 0x53000000:
|
case 0x53000000:
|
||||||
return FSFW_OBJECTS_START_STRING;
|
return FSFW_OBJECTS_START_STRING;
|
||||||
case 0x53000001:
|
case 0x53000001:
|
||||||
return PUS_SERVICE_1_VERIFICATION_STRING;
|
return PUS_SERVICE_1_VERIFICATION_STRING;
|
||||||
case 0x53000002:
|
case 0x53000002:
|
||||||
return PUS_SERVICE_2_DEVICE_ACCESS_STRING;
|
return PUS_SERVICE_2_DEVICE_ACCESS_STRING;
|
||||||
case 0x53000003:
|
case 0x53000003:
|
||||||
return PUS_SERVICE_3_HOUSEKEEPING_STRING;
|
return PUS_SERVICE_3_HOUSEKEEPING_STRING;
|
||||||
case 0x53000005:
|
case 0x53000005:
|
||||||
return PUS_SERVICE_5_EVENT_REPORTING_STRING;
|
return PUS_SERVICE_5_EVENT_REPORTING_STRING;
|
||||||
case 0x53000008:
|
case 0x53000008:
|
||||||
return PUS_SERVICE_8_FUNCTION_MGMT_STRING;
|
return PUS_SERVICE_8_FUNCTION_MGMT_STRING;
|
||||||
case 0x53000009:
|
case 0x53000009:
|
||||||
return PUS_SERVICE_9_TIME_MGMT_STRING;
|
return PUS_SERVICE_9_TIME_MGMT_STRING;
|
||||||
case 0x53000017:
|
case 0x53000017:
|
||||||
return PUS_SERVICE_17_TEST_STRING;
|
return PUS_SERVICE_17_TEST_STRING;
|
||||||
case 0x53000020:
|
case 0x53000020:
|
||||||
return PUS_SERVICE_20_PARAMETERS_STRING;
|
return PUS_SERVICE_20_PARAMETERS_STRING;
|
||||||
case 0x53000200:
|
case 0x53000200:
|
||||||
return PUS_SERVICE_200_MODE_MGMT_STRING;
|
return PUS_SERVICE_200_MODE_MGMT_STRING;
|
||||||
case 0x53010000:
|
case 0x53010000:
|
||||||
return HEALTH_TABLE_STRING;
|
return HEALTH_TABLE_STRING;
|
||||||
case 0x53010100:
|
case 0x53010100:
|
||||||
return MODE_STORE_STRING;
|
return MODE_STORE_STRING;
|
||||||
case 0x53030000:
|
case 0x53030000:
|
||||||
return EVENT_MANAGER_STRING;
|
return EVENT_MANAGER_STRING;
|
||||||
case 0x53040000:
|
case 0x53040000:
|
||||||
return INTERNAL_ERROR_REPORTER_STRING;
|
return INTERNAL_ERROR_REPORTER_STRING;
|
||||||
case 0x534f0100:
|
case 0x534f0100:
|
||||||
return TC_STORE_STRING;
|
return TC_STORE_STRING;
|
||||||
case 0x534f0200:
|
case 0x534f0200:
|
||||||
return TM_STORE_STRING;
|
return TM_STORE_STRING;
|
||||||
case 0x534f0300:
|
case 0x534f0300:
|
||||||
return IPC_STORE_STRING;
|
return IPC_STORE_STRING;
|
||||||
case 0x53500010:
|
case 0x53500010:
|
||||||
return TIME_STAMPER_STRING;
|
return TIME_STAMPER_STRING;
|
||||||
case 0x53ffffff:
|
case 0x53ffffff:
|
||||||
return FSFW_OBJECTS_END_STRING;
|
return FSFW_OBJECTS_END_STRING;
|
||||||
case 0xCAFECAFE:
|
case 0xCAFECAFE:
|
||||||
return DUMMY_INTERFACE_STRING;
|
return DUMMY_INTERFACE_STRING;
|
||||||
case 0xFFFFFFFF:
|
case 0xFFFFFFFF:
|
||||||
return NO_OBJECT_STRING;
|
return NO_OBJECT_STRING;
|
||||||
default:
|
default:
|
||||||
return "UNKNOWN_OBJECT";
|
return "UNKNOWN_OBJECT";
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
#ifndef CONFIG_RETURNVALUES_CLASSIDS_H_
|
#ifndef CONFIG_RETURNVALUES_CLASSIDS_H_
|
||||||
#define CONFIG_RETURNVALUES_CLASSIDS_H_
|
#define CONFIG_RETURNVALUES_CLASSIDS_H_
|
||||||
|
|
||||||
#include "commonClassIds.h"
|
|
||||||
#include <fsfw/returnvalues/FwClassIds.h>
|
#include <fsfw/returnvalues/FwClassIds.h>
|
||||||
|
|
||||||
|
#include "commonClassIds.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Source IDs starts at 73 for now
|
* Source IDs starts at 73 for now
|
||||||
* Framework IDs for ReturnValues run from 0 to 56
|
* Framework IDs for ReturnValues run from 0 to 56
|
||||||
@ -11,9 +12,8 @@
|
|||||||
*/
|
*/
|
||||||
namespace CLASS_ID {
|
namespace CLASS_ID {
|
||||||
enum {
|
enum {
|
||||||
CLASS_ID_START = COMMON_CLASS_ID_END,
|
CLASS_ID_START = COMMON_CLASS_ID_END,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* CONFIG_RETURNVALUES_CLASSIDS_H_ */
|
#endif /* CONFIG_RETURNVALUES_CLASSIDS_H_ */
|
||||||
|
@ -12,8 +12,7 @@
|
|||||||
* APID is a 11 bit number
|
* APID is a 11 bit number
|
||||||
*/
|
*/
|
||||||
namespace apid {
|
namespace apid {
|
||||||
static const uint16_t EIVE_OBSW = 0x65;
|
static const uint16_t EIVE_OBSW = 0x65;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* FSFWCONFIG_TMTC_APID_H_ */
|
#endif /* FSFWCONFIG_TMTC_APID_H_ */
|
||||||
|
@ -2,21 +2,21 @@
|
|||||||
#define CONFIG_TMTC_PUSIDS_HPP_
|
#define CONFIG_TMTC_PUSIDS_HPP_
|
||||||
|
|
||||||
namespace pus {
|
namespace pus {
|
||||||
enum Ids{
|
enum Ids {
|
||||||
PUS_SERVICE_1 = 1,
|
PUS_SERVICE_1 = 1,
|
||||||
PUS_SERVICE_2 = 2,
|
PUS_SERVICE_2 = 2,
|
||||||
PUS_SERVICE_3 = 3,
|
PUS_SERVICE_3 = 3,
|
||||||
PUS_SERVICE_3_PSB = 3,
|
PUS_SERVICE_3_PSB = 3,
|
||||||
PUS_SERVICE_5 = 5,
|
PUS_SERVICE_5 = 5,
|
||||||
PUS_SERVICE_6 = 6,
|
PUS_SERVICE_6 = 6,
|
||||||
PUS_SERVICE_8 = 8,
|
PUS_SERVICE_8 = 8,
|
||||||
PUS_SERVICE_9 = 9,
|
PUS_SERVICE_9 = 9,
|
||||||
PUS_SERVICE_17 = 17,
|
PUS_SERVICE_17 = 17,
|
||||||
PUS_SERVICE_19 = 19,
|
PUS_SERVICE_19 = 19,
|
||||||
PUS_SERVICE_20 = 20,
|
PUS_SERVICE_20 = 20,
|
||||||
PUS_SERVICE_23 = 23,
|
PUS_SERVICE_23 = 23,
|
||||||
PUS_SERVICE_200 = 200,
|
PUS_SERVICE_200 = 200,
|
||||||
PUS_SERVICE_201 = 201,
|
PUS_SERVICE_201 = 201,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "InitMission.h"
|
#include "InitMission.h"
|
||||||
#include "OBSWVersion.h"
|
#include "OBSWVersion.h"
|
||||||
|
|
||||||
#include "fsfw/FSFWVersion.h"
|
#include "fsfw/FSFWVersion.h"
|
||||||
#include "fsfw/tasks/TaskFactory.h"
|
#include "fsfw/tasks/TaskFactory.h"
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
static const char* COMPILE_PRINTOUT = "Windows";
|
static const char* COMPILE_PRINTOUT = "Windows";
|
||||||
#elif LINUX
|
#elif LINUX
|
||||||
@ -17,21 +16,18 @@ static const char* COMPILE_PRINTOUT = "unknown OS";
|
|||||||
* Linux and Windows.
|
* Linux and Windows.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int main(void)
|
int main(void) {
|
||||||
{
|
std::cout << "-- EIVE OBSW --" << std::endl;
|
||||||
std::cout << "-- EIVE OBSW --" << std::endl;
|
std::cout << "-- Compiled for " << COMPILE_PRINTOUT << " --" << std::endl;
|
||||||
std::cout << "-- Compiled for " << COMPILE_PRINTOUT << " --" << std::endl;
|
std::cout << "-- OBSW " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION << "."
|
||||||
std::cout << "-- OBSW " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION <<
|
<< SW_REVISION << ", FSFW v" << FSFW_VERSION << "." << FSFW_SUBVERSION << "."
|
||||||
"." << SW_REVISION << ", FSFW v" << FSFW_VERSION << "." << FSFW_SUBVERSION << "." <<
|
<< FSFW_REVISION << "--" << std::endl;
|
||||||
FSFW_REVISION << "--" << std::endl;
|
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
|
||||||
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
|
|
||||||
|
|
||||||
initmission::initMission();
|
initmission::initMission();
|
||||||
|
|
||||||
for(;;) {
|
for (;;) {
|
||||||
// suspend main thread by sleeping it.
|
// suspend main thread by sleeping it.
|
||||||
TaskFactory::delayTask(5000);
|
TaskFactory::delayTask(5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,247 +1,244 @@
|
|||||||
#include "InitMission.h"
|
#include "InitMission.h"
|
||||||
#include "ObjectFactory.h"
|
|
||||||
|
|
||||||
#include "objects/systemObjectList.h"
|
#include <fsfw/objectmanager/ObjectManager.h>
|
||||||
#include "OBSWConfig.h"
|
|
||||||
#include "pollingsequence/pollingSequenceFactory.h"
|
|
||||||
|
|
||||||
#include <mission/utility/InitMission.h>
|
|
||||||
#include <fsfw/objectmanager/ObjectManagerIF.h>
|
#include <fsfw/objectmanager/ObjectManagerIF.h>
|
||||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||||
#include <fsfw/objectmanager/ObjectManager.h>
|
|
||||||
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
|
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
|
||||||
#include <fsfw/tasks/PeriodicTaskIF.h>
|
#include <fsfw/tasks/PeriodicTaskIF.h>
|
||||||
#include <fsfw/tasks/TaskFactory.h>
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
|
#include <mission/utility/InitMission.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "OBSWConfig.h"
|
||||||
|
#include "ObjectFactory.h"
|
||||||
|
#include "objects/systemObjectList.h"
|
||||||
|
#include "pollingsequence/pollingSequenceFactory.h"
|
||||||
|
|
||||||
ServiceInterfaceStream sif::debug("DEBUG");
|
ServiceInterfaceStream sif::debug("DEBUG");
|
||||||
ServiceInterfaceStream sif::info("INFO");
|
ServiceInterfaceStream sif::info("INFO");
|
||||||
ServiceInterfaceStream sif::warning("WARNING");
|
ServiceInterfaceStream sif::warning("WARNING");
|
||||||
ServiceInterfaceStream sif::error("ERROR");
|
ServiceInterfaceStream sif::error("ERROR");
|
||||||
|
|
||||||
ObjectManagerIF *objectManager = nullptr;
|
ObjectManagerIF* objectManager = nullptr;
|
||||||
|
|
||||||
void initmission::initMission() {
|
void initmission::initMission() {
|
||||||
sif::info << "Building global objects.." << std::endl;
|
sif::info << "Building global objects.." << std::endl;
|
||||||
/* Instantiate global object manager and also create all objects */
|
/* Instantiate global object manager and also create all objects */
|
||||||
ObjectManager::instance()->setObjectFactoryFunction(ObjectFactory::produce, nullptr);
|
ObjectManager::instance()->setObjectFactoryFunction(ObjectFactory::produce, nullptr);
|
||||||
sif::info << "Initializing all objects.." << std::endl;
|
sif::info << "Initializing all objects.." << std::endl;
|
||||||
ObjectManager::instance()->initialize();
|
ObjectManager::instance()->initialize();
|
||||||
|
|
||||||
/* This function creates and starts all tasks */
|
/* This function creates and starts all tasks */
|
||||||
initTasks();
|
initTasks();
|
||||||
}
|
}
|
||||||
|
|
||||||
void initmission::initTasks() {
|
void initmission::initTasks() {
|
||||||
TaskFactory* factory = TaskFactory::instance();
|
TaskFactory* factory = TaskFactory::instance();
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
if(factory == nullptr) {
|
if (factory == nullptr) {
|
||||||
/* Should never happen ! */
|
/* Should never happen ! */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if OBSW_PRINT_MISSED_DEADLINES == 1
|
#if OBSW_PRINT_MISSED_DEADLINES == 1
|
||||||
void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline;
|
void (*missedDeadlineFunc)(void) = TaskFactory::printMissedDeadline;
|
||||||
#else
|
#else
|
||||||
void (*missedDeadlineFunc) (void) = nullptr;
|
void (*missedDeadlineFunc)(void) = nullptr;
|
||||||
#endif
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
/* TMTC Distribution */
|
/* UDP bridge */
|
||||||
PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
|
PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask(
|
||||||
"DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
"UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
||||||
result = tmTcDistributor->addComponent(objects::CCSDS_PACKET_DISTRIBUTOR);
|
result = udpBridgeTask->addComponent(objects::TMTC_BRIDGE);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::error << "Object add component failed" << std::endl;
|
sif::error << "Add component UDP Unix Bridge failed" << std::endl;
|
||||||
}
|
}
|
||||||
result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
|
PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask(
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
"UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
||||||
sif::error << "Object add component failed" << std::endl;
|
result = udpPollingTask->addComponent(objects::TMTC_POLLING_TASK);
|
||||||
}
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
result = tmTcDistributor->addComponent(objects::TM_FUNNEL);
|
sif::error << "Add component UDP Polling failed" << std::endl;
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
}
|
||||||
sif::error << "Object add component failed" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UDP bridge */
|
/* PUS Services */
|
||||||
PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask(
|
std::vector<PeriodicTaskIF*> pusTasks;
|
||||||
"UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
createPusTasks(*factory, missedDeadlineFunc, pusTasks);
|
||||||
result = udpBridgeTask->addComponent(objects::TMTC_BRIDGE);
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
sif::error << "Add component UDP Unix Bridge failed" << std::endl;
|
|
||||||
}
|
|
||||||
PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask(
|
|
||||||
"UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
|
||||||
result = udpPollingTask->addComponent(objects::TMTC_POLLING_TASK);
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
sif::error << "Add component UDP Polling failed" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* PUS Services */
|
std::vector<PeriodicTaskIF*> pstTasks;
|
||||||
std::vector<PeriodicTaskIF*> pusTasks;
|
createPstTasks(*factory, missedDeadlineFunc, pstTasks);
|
||||||
createPusTasks(*factory, missedDeadlineFunc, pusTasks);
|
|
||||||
|
|
||||||
std::vector<PeriodicTaskIF*> pstTasks;
|
|
||||||
createPstTasks(*factory, missedDeadlineFunc, pstTasks);
|
|
||||||
#if OBSW_ADD_TEST_CODE == 1
|
#if OBSW_ADD_TEST_CODE == 1
|
||||||
std::vector<PeriodicTaskIF*> testTasks;
|
std::vector<PeriodicTaskIF*> testTasks;
|
||||||
createTestTasks(*factory, missedDeadlineFunc, pstTasks);
|
createTestTasks(*factory, missedDeadlineFunc, pstTasks);
|
||||||
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
||||||
|
|
||||||
auto taskStarter = [](std::vector<PeriodicTaskIF*>& taskVector, std::string name) {
|
auto taskStarter = [](std::vector<PeriodicTaskIF*>& taskVector, std::string name) {
|
||||||
for(const auto& task: taskVector) {
|
for (const auto& task : taskVector) {
|
||||||
if(task != nullptr) {
|
if (task != nullptr) {
|
||||||
task->startTask();
|
task->startTask();
|
||||||
}
|
} else {
|
||||||
else {
|
sif::error << "Task in vector " << name << " is invalid!" << std::endl;
|
||||||
sif::error << "Task in vector " << name << " is invalid!" << std::endl;
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
sif::info << "Starting tasks.." << std::endl;
|
sif::info << "Starting tasks.." << std::endl;
|
||||||
tmTcDistributor->startTask();
|
tmTcDistributor->startTask();
|
||||||
udpBridgeTask->startTask();
|
udpBridgeTask->startTask();
|
||||||
udpPollingTask->startTask();
|
udpPollingTask->startTask();
|
||||||
|
|
||||||
taskStarter(pusTasks, "PUS Tasks");
|
taskStarter(pusTasks, "PUS Tasks");
|
||||||
#if OBSW_ADD_TEST_CODE == 1
|
#if OBSW_ADD_TEST_CODE == 1
|
||||||
taskStarter(testTasks, "Test Tasks");
|
taskStarter(testTasks, "Test Tasks");
|
||||||
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
||||||
taskStarter(pstTasks, "PST Tasks");
|
taskStarter(pstTasks, "PST Tasks");
|
||||||
|
|
||||||
#if OBSW_ADD_TEST_PST == 1
|
#if OBSW_ADD_TEST_PST == 1
|
||||||
if(startTestPst) {
|
if (startTestPst) {
|
||||||
pstTestTask->startTask();
|
pstTestTask->startTask();
|
||||||
}
|
}
|
||||||
#endif /* RPI_TEST_ACS_BOARD == 1 */
|
#endif /* RPI_TEST_ACS_BOARD == 1 */
|
||||||
sif::info << "Tasks started.." << std::endl;
|
sif::info << "Tasks started.." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initmission::createPusTasks(TaskFactory& factory,
|
void initmission::createPusTasks(TaskFactory& factory,
|
||||||
TaskDeadlineMissedFunction missedDeadlineFunc, std::vector<PeriodicTaskIF*>& taskVec) {
|
TaskDeadlineMissedFunction missedDeadlineFunc,
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
std::vector<PeriodicTaskIF*>& taskVec) {
|
||||||
PeriodicTaskIF* pusVerification = factory.createPeriodicTask(
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
PeriodicTaskIF* pusVerification = factory.createPeriodicTask(
|
||||||
result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
|
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
|
||||||
sif::error << "Object add component failed" << std::endl;
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
}
|
sif::error << "Object add component failed" << std::endl;
|
||||||
taskVec.push_back(pusVerification);
|
}
|
||||||
|
taskVec.push_back(pusVerification);
|
||||||
|
|
||||||
PeriodicTaskIF* pusEvents = factory.createPeriodicTask(
|
PeriodicTaskIF* pusEvents = factory.createPeriodicTask(
|
||||||
"PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
"PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
result = pusEvents->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
|
result = pusEvents->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING);
|
initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING);
|
||||||
}
|
}
|
||||||
result = pusEvents->addComponent(objects::EVENT_MANAGER);
|
result = pusEvents->addComponent(objects::EVENT_MANAGER);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS_MGMT", objects::EVENT_MANAGER);
|
initmission::printAddObjectError("PUS_MGMT", objects::EVENT_MANAGER);
|
||||||
}
|
}
|
||||||
taskVec.push_back(pusEvents);
|
taskVec.push_back(pusEvents);
|
||||||
|
|
||||||
PeriodicTaskIF* pusHighPrio = factory.createPeriodicTask(
|
PeriodicTaskIF* pusHighPrio = factory.createPeriodicTask(
|
||||||
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
||||||
}
|
}
|
||||||
result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
|
result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT);
|
initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT);
|
||||||
}
|
}
|
||||||
taskVec.push_back(pusHighPrio);
|
taskVec.push_back(pusHighPrio);
|
||||||
|
|
||||||
PeriodicTaskIF* pusMedPrio = factory.createPeriodicTask(
|
PeriodicTaskIF* pusMedPrio = factory.createPeriodicTask(
|
||||||
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
|
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
|
||||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
||||||
}
|
}
|
||||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT);
|
initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT);
|
||||||
}
|
}
|
||||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS);
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS);
|
initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS);
|
||||||
}
|
}
|
||||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_3_HOUSEKEEPING);
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_3_HOUSEKEEPING);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS3", objects::PUS_SERVICE_3_HOUSEKEEPING);
|
initmission::printAddObjectError("PUS3", objects::PUS_SERVICE_3_HOUSEKEEPING);
|
||||||
}
|
}
|
||||||
taskVec.push_back(pusMedPrio);
|
taskVec.push_back(pusMedPrio);
|
||||||
|
|
||||||
PeriodicTaskIF* pusLowPrio = factory.createPeriodicTask(
|
PeriodicTaskIF* pusLowPrio = factory.createPeriodicTask(
|
||||||
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
|
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
|
||||||
result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
|
result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST);
|
initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST);
|
||||||
}
|
}
|
||||||
result = pusLowPrio->addComponent(objects::INTERNAL_ERROR_REPORTER);
|
result = pusLowPrio->addComponent(objects::INTERNAL_ERROR_REPORTER);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("INT_ERR_RPRT",
|
initmission::printAddObjectError("INT_ERR_RPRT", objects::INTERNAL_ERROR_REPORTER);
|
||||||
objects::INTERNAL_ERROR_REPORTER);
|
}
|
||||||
}
|
taskVec.push_back(pusLowPrio);
|
||||||
taskVec.push_back(pusLowPrio);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void initmission::createPstTasks(TaskFactory& factory,
|
void initmission::createPstTasks(TaskFactory& factory,
|
||||||
TaskDeadlineMissedFunction missedDeadlineFunc, std::vector<PeriodicTaskIF*> &taskVec) {
|
TaskDeadlineMissedFunction missedDeadlineFunc,
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
std::vector<PeriodicTaskIF*>& taskVec) {
|
||||||
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
#if OBSW_ADD_SPI_TEST_CODE == 0
|
#if OBSW_ADD_SPI_TEST_CODE == 0
|
||||||
FixedTimeslotTaskIF* spiPst = factory.createFixedTimeslotTask(
|
FixedTimeslotTaskIF* spiPst = factory.createFixedTimeslotTask(
|
||||||
"SPI_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0,
|
"SPI_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, missedDeadlineFunc);
|
||||||
missedDeadlineFunc);
|
result = pst::pstSpi(spiPst);
|
||||||
result = pst::pstSpi(spiPst);
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
|
||||||
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
|
}
|
||||||
}
|
taskVec.push_back(spiPst);
|
||||||
taskVec.push_back(spiPst);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void initmission::createTestTasks(TaskFactory& factory,
|
void initmission::createTestTasks(TaskFactory& factory,
|
||||||
TaskDeadlineMissedFunction missedDeadlineFunc,
|
TaskDeadlineMissedFunction missedDeadlineFunc,
|
||||||
std::vector<PeriodicTaskIF*> &taskVec) {
|
std::vector<PeriodicTaskIF*>& taskVec) {
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
PeriodicTaskIF* testTask = factory.createPeriodicTask(
|
PeriodicTaskIF* testTask = factory.createPeriodicTask(
|
||||||
"TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
"TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
||||||
result = testTask->addComponent(objects::TEST_TASK);
|
result = testTask->addComponent(objects::TEST_TASK);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK);
|
initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK);
|
||||||
}
|
}
|
||||||
#if RPI_ADD_SPI_TEST == 1
|
#if RPI_ADD_SPI_TEST == 1
|
||||||
result = testTask->addComponent(objects::SPI_TEST);
|
result = testTask->addComponent(objects::SPI_TEST);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("SPI_TEST", objects::SPI_TEST);
|
initmission::printAddObjectError("SPI_TEST", objects::SPI_TEST);
|
||||||
}
|
}
|
||||||
#endif /* RPI_ADD_SPI_TEST == 1 */
|
#endif /* RPI_ADD_SPI_TEST == 1 */
|
||||||
#if RPI_ADD_GPIO_TEST == 1
|
#if RPI_ADD_GPIO_TEST == 1
|
||||||
result = testTask->addComponent(objects::LIBGPIOD_TEST);
|
result = testTask->addComponent(objects::LIBGPIOD_TEST);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST);
|
initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST);
|
||||||
}
|
}
|
||||||
#endif /* RPI_ADD_GPIO_TEST == 1 */
|
#endif /* RPI_ADD_GPIO_TEST == 1 */
|
||||||
#if RPI_ADD_UART_TEST == 1
|
#if RPI_ADD_UART_TEST == 1
|
||||||
result = testTask->addComponent(objects::UART_TEST);
|
result = testTask->addComponent(objects::UART_TEST);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("UART_TEST", objects::UART_TEST);
|
initmission::printAddObjectError("UART_TEST", objects::UART_TEST);
|
||||||
}
|
}
|
||||||
#endif /* RPI_ADD_GPIO_TEST == 1 */
|
#endif /* RPI_ADD_GPIO_TEST == 1 */
|
||||||
|
|
||||||
bool startTestPst = true;
|
bool startTestPst = true;
|
||||||
static_cast<void>(startTestPst);
|
static_cast<void>(startTestPst);
|
||||||
#if OBSW_ADD_TEST_PST == 1
|
#if OBSW_ADD_TEST_PST == 1
|
||||||
FixedTimeslotTaskIF* pstTestTask = factory->createFixedTimeslotTask("TEST_PST", 50,
|
FixedTimeslotTaskIF* pstTestTask = factory->createFixedTimeslotTask(
|
||||||
PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 2.0, missedDeadlineFunc);
|
"TEST_PST", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 2.0, missedDeadlineFunc);
|
||||||
result = pst::pstTest(pstTestTask);
|
result = pst::pstTest(pstTestTask);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::info << "initmission::initTasks: ACS PST empty or invalid" << std::endl;
|
sif::info << "initmission::initTasks: ACS PST empty or invalid" << std::endl;
|
||||||
startTestPst = false;
|
startTestPst = false;
|
||||||
}
|
}
|
||||||
#endif /* RPI_TEST_ACS_BOARD == 1 */
|
#endif /* RPI_TEST_ACS_BOARD == 1 */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
#ifndef BSP_LINUX_INITMISSION_H_
|
#ifndef BSP_LINUX_INITMISSION_H_
|
||||||
#define BSP_LINUX_INITMISSION_H_
|
#define BSP_LINUX_INITMISSION_H_
|
||||||
|
|
||||||
#include "fsfw/tasks/Typedef.h"
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "fsfw/tasks/Typedef.h"
|
||||||
|
|
||||||
class PeriodicTaskIF;
|
class PeriodicTaskIF;
|
||||||
class TaskFactory;
|
class TaskFactory;
|
||||||
|
|
||||||
@ -11,14 +12,12 @@ namespace initmission {
|
|||||||
void initMission();
|
void initMission();
|
||||||
void initTasks();
|
void initTasks();
|
||||||
|
|
||||||
void createPstTasks(TaskFactory& factory,
|
void createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc,
|
||||||
TaskDeadlineMissedFunction missedDeadlineFunc,
|
std::vector<PeriodicTaskIF*>& taskVec);
|
||||||
std::vector<PeriodicTaskIF*> &taskVec);
|
void createTestTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc,
|
||||||
void createTestTasks(TaskFactory& factory,
|
std::vector<PeriodicTaskIF*>& taskVec);
|
||||||
TaskDeadlineMissedFunction missedDeadlineFunc,
|
|
||||||
std::vector<PeriodicTaskIF*> &taskVec);
|
|
||||||
void createPusTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc,
|
void createPusTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc,
|
||||||
std::vector<PeriodicTaskIF*>& taskVec);
|
std::vector<PeriodicTaskIF*>& taskVec);
|
||||||
};
|
}; // namespace initmission
|
||||||
|
|
||||||
#endif /* BSP_LINUX_INITMISSION_H_ */
|
#endif /* BSP_LINUX_INITMISSION_H_ */
|
||||||
|
@ -1,236 +1,241 @@
|
|||||||
#include <devConf.h>
|
|
||||||
#include "ObjectFactory.h"
|
#include "ObjectFactory.h"
|
||||||
|
|
||||||
#include "objects/systemObjectList.h"
|
#include <devConf.h>
|
||||||
|
#include <mission/devices/GPSHyperionHandler.h>
|
||||||
|
|
||||||
|
#include "OBSWConfig.h"
|
||||||
#include "devices/addresses.h"
|
#include "devices/addresses.h"
|
||||||
#include "devices/gpioIds.h"
|
#include "devices/gpioIds.h"
|
||||||
#include "OBSWConfig.h"
|
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
||||||
#include "tmtc/apid.h"
|
#include "fsfw/tasks/TaskFactory.h"
|
||||||
#include "tmtc/pusIds.h"
|
#include "fsfw/tmtcpacket/pus/tm.h"
|
||||||
|
#include "fsfw/tmtcservices/CommandingServiceBase.h"
|
||||||
|
#include "fsfw/tmtcservices/PusServiceBase.h"
|
||||||
#include "linux/boardtest/LibgpiodTest.h"
|
#include "linux/boardtest/LibgpiodTest.h"
|
||||||
#include "linux/boardtest/SpiTestClass.h"
|
#include "linux/boardtest/SpiTestClass.h"
|
||||||
#include "linux/boardtest/UartTestClass.h"
|
#include "linux/boardtest/UartTestClass.h"
|
||||||
|
|
||||||
#include "mission/core/GenericFactory.h"
|
#include "mission/core/GenericFactory.h"
|
||||||
#include "mission/utility/TmFunnel.h"
|
|
||||||
#include <mission/devices/GPSHyperionHandler.h>
|
|
||||||
#include "mission/devices/GyroADIS1650XHandler.h"
|
#include "mission/devices/GyroADIS1650XHandler.h"
|
||||||
|
#include "mission/utility/TmFunnel.h"
|
||||||
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
#include "objects/systemObjectList.h"
|
||||||
#include "fsfw/tmtcservices/CommandingServiceBase.h"
|
#include "tmtc/apid.h"
|
||||||
#include "fsfw/tmtcservices/PusServiceBase.h"
|
#include "tmtc/pusIds.h"
|
||||||
#include "fsfw/tmtcpacket/pus/tm.h"
|
|
||||||
#include "fsfw/tasks/TaskFactory.h"
|
|
||||||
|
|
||||||
/* UDP server includes */
|
/* UDP server includes */
|
||||||
#if OBSW_USE_TMTC_TCP_BRIDGE == 1
|
#if OBSW_USE_TMTC_TCP_BRIDGE == 1
|
||||||
#include <fsfw/src/fsfw/osal/common/TcpTmTcBridge.h>
|
#include <fsfw/src/fsfw/osal/common/TcpTmTcBridge.h>
|
||||||
#include <fsfw/src/fsfw/osal/common/TcpTmTcServer.h>
|
#include <fsfw/src/fsfw/osal/common/TcpTmTcServer.h>
|
||||||
#else
|
#else
|
||||||
#include "fsfw/osal/common/UdpTmTcBridge.h"
|
|
||||||
#include "fsfw/osal/common/UdpTcPollingTask.h"
|
#include "fsfw/osal/common/UdpTcPollingTask.h"
|
||||||
|
#include "fsfw/osal/common/UdpTmTcBridge.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h"
|
|
||||||
#include "fsfw_hal/devicehandlers/MgmRM3100Handler.h"
|
|
||||||
#include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h"
|
|
||||||
#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h"
|
|
||||||
#include "fsfw_hal/linux/rpi/GpioRPi.h"
|
|
||||||
#include "fsfw_hal/common/gpio/GpioCookie.h"
|
|
||||||
#include "fsfw_hal/linux/spi/SpiCookie.h"
|
|
||||||
#include "fsfw_hal/linux/spi/SpiComIF.h"
|
|
||||||
#include <fsfw_hal/linux/uart/UartComIF.h>
|
#include <fsfw_hal/linux/uart/UartComIF.h>
|
||||||
#include <fsfw_hal/linux/uart/UartCookie.h>
|
#include <fsfw_hal/linux/uart/UartCookie.h>
|
||||||
|
|
||||||
|
#include "fsfw_hal/common/gpio/GpioCookie.h"
|
||||||
|
#include "fsfw_hal/devicehandlers/GyroL3GD20Handler.h"
|
||||||
|
#include "fsfw_hal/devicehandlers/MgmLIS3MDLHandler.h"
|
||||||
|
#include "fsfw_hal/devicehandlers/MgmRM3100Handler.h"
|
||||||
|
#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h"
|
||||||
|
#include "fsfw_hal/linux/rpi/GpioRPi.h"
|
||||||
|
#include "fsfw_hal/linux/spi/SpiComIF.h"
|
||||||
|
#include "fsfw_hal/linux/spi/SpiCookie.h"
|
||||||
|
|
||||||
void Factory::setStaticFrameworkObjectIds() {
|
void Factory::setStaticFrameworkObjectIds() {
|
||||||
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
|
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||||
PusServiceBase::packetDestination = objects::TM_FUNNEL;
|
PusServiceBase::packetDestination = objects::TM_FUNNEL;
|
||||||
|
|
||||||
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
|
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||||
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
|
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
|
||||||
|
|
||||||
TmFunnel::downlinkDestination = objects::TMTC_BRIDGE;
|
TmFunnel::downlinkDestination = objects::TMTC_BRIDGE;
|
||||||
// No storage object for now.
|
// No storage object for now.
|
||||||
TmFunnel::storageDestination = objects::NO_OBJECT;
|
TmFunnel::storageDestination = objects::NO_OBJECT;
|
||||||
|
|
||||||
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
|
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
|
||||||
TmPacketBase::timeStamperId = objects::TIME_STAMPER;
|
TmPacketBase::timeStamperId = objects::TIME_STAMPER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectFactory::produce(void* args) {
|
||||||
|
Factory::setStaticFrameworkObjectIds();
|
||||||
void ObjectFactory::produce(void* args){
|
ObjectFactory::produceGenericObjects();
|
||||||
Factory::setStaticFrameworkObjectIds();
|
|
||||||
ObjectFactory::produceGenericObjects();
|
|
||||||
|
|
||||||
#if OBSW_USE_TMTC_TCP_BRIDGE == 1
|
#if OBSW_USE_TMTC_TCP_BRIDGE == 1
|
||||||
auto tmtcBridge = new TcpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
|
auto tmtcBridge = new TcpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||||
tmtcBridge->setMaxNumberOfPacketsStored(50);
|
tmtcBridge->setMaxNumberOfPacketsStored(50);
|
||||||
new TcpTmTcServer(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE);
|
new TcpTmTcServer(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE);
|
||||||
#else
|
#else
|
||||||
auto tmtcBridge = new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
|
auto tmtcBridge = new UdpTmTcBridge(objects::TMTC_BRIDGE, objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||||
tmtcBridge->setMaxNumberOfPacketsStored(50);
|
tmtcBridge->setMaxNumberOfPacketsStored(50);
|
||||||
new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE);
|
new UdpTcPollingTask(objects::TMTC_POLLING_TASK, objects::TMTC_BRIDGE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GpioIF* gpioIF = new LinuxLibgpioIF(objects::GPIO_IF);
|
GpioIF* gpioIF = new LinuxLibgpioIF(objects::GPIO_IF);
|
||||||
GpioCookie* gpioCookie = nullptr;
|
GpioCookie* gpioCookie = nullptr;
|
||||||
static_cast<void>(gpioCookie);
|
static_cast<void>(gpioCookie);
|
||||||
|
|
||||||
new SpiComIF(objects::SPI_COM_IF, gpioIF);
|
new SpiComIF(objects::SPI_COM_IF, gpioIF);
|
||||||
|
|
||||||
std::string spiDev;
|
std::string spiDev;
|
||||||
SpiCookie* spiCookie = nullptr;
|
SpiCookie* spiCookie = nullptr;
|
||||||
static_cast<void>(spiCookie);
|
static_cast<void>(spiCookie);
|
||||||
|
|
||||||
#if OBSW_ADD_ACS_BOARD == 1
|
#if OBSW_ADD_ACS_BOARD == 1
|
||||||
if(gpioCookie == nullptr) {
|
if (gpioCookie == nullptr) {
|
||||||
gpioCookie = new GpioCookie();
|
gpioCookie = new GpioCookie();
|
||||||
}
|
}
|
||||||
// TODO: Missing pin for Gyro 2
|
// TODO: Missing pin for Gyro 2
|
||||||
gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_0_LIS3_CS, gpio::MGM_0_BCM_PIN,
|
gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_0_LIS3_CS, gpio::MGM_0_BCM_PIN, "MGM_0_LIS3",
|
||||||
"MGM_0_LIS3", gpio::Direction::OUT, 1);
|
gpio::Direction::OUT, 1);
|
||||||
gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_1_RM3100_CS, gpio::MGM_1_BCM_PIN,
|
gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_1_RM3100_CS, gpio::MGM_1_BCM_PIN,
|
||||||
"MGM_1_RM3100", gpio::Direction::OUT, 1);
|
"MGM_1_RM3100", gpio::Direction::OUT, 1);
|
||||||
gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_2_LIS3_CS, gpio::MGM_2_BCM_PIN,
|
gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_2_LIS3_CS, gpio::MGM_2_BCM_PIN, "MGM_2_LIS3",
|
||||||
"MGM_2_LIS3", gpio::Direction::OUT, 1);
|
gpio::Direction::OUT, 1);
|
||||||
gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_3_RM3100_CS, gpio::MGM_3_BCM_PIN,
|
gpio::createRpiGpioConfig(gpioCookie, gpioIds::MGM_3_RM3100_CS, gpio::MGM_3_BCM_PIN,
|
||||||
"MGM_3_RM3100", gpio::Direction::OUT, 1);
|
"MGM_3_RM3100", gpio::Direction::OUT, 1);
|
||||||
gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_0_ADIS_CS, gpio::GYRO_0_BCM_PIN,
|
gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_0_ADIS_CS, gpio::GYRO_0_BCM_PIN,
|
||||||
"GYRO_0_ADIS", gpio::Direction::OUT, 1);
|
"GYRO_0_ADIS", gpio::Direction::OUT, 1);
|
||||||
gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_1_L3G_CS, gpio::GYRO_1_BCM_PIN,
|
gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_1_L3G_CS, gpio::GYRO_1_BCM_PIN, "GYRO_1_L3G",
|
||||||
"GYRO_1_L3G", gpio::Direction::OUT, 1);
|
gpio::Direction::OUT, 1);
|
||||||
gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_2_ADIS_CS, gpio::GYRO_2_BCM_PIN,
|
gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_2_ADIS_CS, gpio::GYRO_2_BCM_PIN,
|
||||||
"GYRO_2_ADIS", gpio::Direction::OUT, 1);
|
"GYRO_2_ADIS", gpio::Direction::OUT, 1);
|
||||||
gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_3_L3G_CS, gpio::GYRO_3_BCM_PIN,
|
gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_3_L3G_CS, gpio::GYRO_3_BCM_PIN, "GYRO_3_L3G",
|
||||||
"GYRO_3_L3G", gpio::Direction::OUT, 1);
|
gpio::Direction::OUT, 1);
|
||||||
gpioIF->addGpios(gpioCookie);
|
gpioIF->addGpios(gpioCookie);
|
||||||
|
|
||||||
spiDev = "/dev/spidev0.1";
|
spiDev = "/dev/spidev0.1";
|
||||||
spiCookie = new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev,
|
spiCookie =
|
||||||
MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED);
|
new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev,
|
||||||
auto mgmLis3Handler = new MgmLIS3MDLHandler(objects::MGM_0_LIS3_HANDLER,
|
MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED);
|
||||||
objects::SPI_COM_IF, spiCookie, 0);
|
auto mgmLis3Handler =
|
||||||
mgmLis3Handler->setStartUpImmediately();
|
new MgmLIS3MDLHandler(objects::MGM_0_LIS3_HANDLER, objects::SPI_COM_IF, spiCookie, 0);
|
||||||
|
mgmLis3Handler->setStartUpImmediately();
|
||||||
#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1
|
#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1
|
||||||
mgmLis3Handler->setToGoToNormalMode(true);
|
mgmLis3Handler->setToGoToNormalMode(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
spiCookie = new SpiCookie(addresses::MGM_1_RM3100, gpioIds::MGM_1_RM3100_CS, spiDev,
|
spiCookie =
|
||||||
RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED);
|
new SpiCookie(addresses::MGM_1_RM3100, gpioIds::MGM_1_RM3100_CS, spiDev,
|
||||||
auto mgmRm3100Handler = new MgmRM3100Handler(objects::MGM_1_RM3100_HANDLER,
|
RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED);
|
||||||
objects::SPI_COM_IF, spiCookie, 0);
|
auto mgmRm3100Handler =
|
||||||
mgmRm3100Handler->setStartUpImmediately();
|
new MgmRM3100Handler(objects::MGM_1_RM3100_HANDLER, objects::SPI_COM_IF, spiCookie, 0);
|
||||||
|
mgmRm3100Handler->setStartUpImmediately();
|
||||||
#if FSFW_HAL_RM3100_MGM_DEBUG == 1
|
#if FSFW_HAL_RM3100_MGM_DEBUG == 1
|
||||||
mgmRm3100Handler->setToGoToNormalMode(true);
|
mgmRm3100Handler->setToGoToNormalMode(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
spiCookie = new SpiCookie(addresses::MGM_2_LIS3, gpioIds::MGM_2_LIS3_CS, spiDev,
|
spiCookie =
|
||||||
MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED);
|
new SpiCookie(addresses::MGM_2_LIS3, gpioIds::MGM_2_LIS3_CS, spiDev,
|
||||||
mgmLis3Handler = new MgmLIS3MDLHandler(objects::MGM_2_LIS3_HANDLER,
|
MGMLIS3MDL::MAX_BUFFER_SIZE, spi::DEFAULT_LIS3_MODE, spi::DEFAULT_LIS3_SPEED);
|
||||||
objects::SPI_COM_IF, spiCookie, 0);
|
mgmLis3Handler =
|
||||||
mgmLis3Handler->setStartUpImmediately();
|
new MgmLIS3MDLHandler(objects::MGM_2_LIS3_HANDLER, objects::SPI_COM_IF, spiCookie, 0);
|
||||||
|
mgmLis3Handler->setStartUpImmediately();
|
||||||
#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1
|
#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1
|
||||||
mgmLis3Handler->setToGoToNormalMode(true);
|
mgmLis3Handler->setToGoToNormalMode(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
spiCookie = new SpiCookie(addresses::MGM_3_RM3100, gpioIds::MGM_3_RM3100_CS, spiDev,
|
spiCookie =
|
||||||
RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED);
|
new SpiCookie(addresses::MGM_3_RM3100, gpioIds::MGM_3_RM3100_CS, spiDev,
|
||||||
mgmRm3100Handler = new MgmRM3100Handler(objects::MGM_3_RM3100_HANDLER,
|
RM3100::MAX_BUFFER_SIZE, spi::DEFAULT_RM3100_MODE, spi::DEFAULT_RM3100_SPEED);
|
||||||
objects::SPI_COM_IF, spiCookie, 0);
|
mgmRm3100Handler =
|
||||||
mgmRm3100Handler->setStartUpImmediately();
|
new MgmRM3100Handler(objects::MGM_3_RM3100_HANDLER, objects::SPI_COM_IF, spiCookie, 0);
|
||||||
|
mgmRm3100Handler->setStartUpImmediately();
|
||||||
#if FSFW_HAL_RM3100_MGM_DEBUG == 1
|
#if FSFW_HAL_RM3100_MGM_DEBUG == 1
|
||||||
mgmRm3100Handler->setToGoToNormalMode(true);
|
mgmRm3100Handler->setToGoToNormalMode(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
spiCookie = new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, spiDev,
|
spiCookie =
|
||||||
ADIS16507::MAXIMUM_REPLY_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
|
new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, spiDev,
|
||||||
auto adisHandler = new GyroADIS16507Handler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_COM_IF,
|
ADIS16507::MAXIMUM_REPLY_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
|
||||||
spiCookie);
|
auto adisHandler =
|
||||||
adisHandler->setStartUpImmediately();
|
new GyroADIS16507Handler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_COM_IF, spiCookie);
|
||||||
spiCookie = new SpiCookie(addresses::GYRO_1_L3G, gpioIds::GYRO_1_L3G_CS, spiDev,
|
adisHandler->setStartUpImmediately();
|
||||||
L3GD20H::MAX_BUFFER_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
|
spiCookie =
|
||||||
auto gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_COM_IF,
|
new SpiCookie(addresses::GYRO_1_L3G, gpioIds::GYRO_1_L3G_CS, spiDev, L3GD20H::MAX_BUFFER_SIZE,
|
||||||
spiCookie, 0);
|
spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
|
||||||
gyroL3gHandler->setStartUpImmediately();
|
auto gyroL3gHandler =
|
||||||
#if FSFW_HAL_L3GD20_GYRO_DEBUG== 1
|
new GyroHandlerL3GD20H(objects::GYRO_1_L3G_HANDLER, objects::SPI_COM_IF, spiCookie, 0);
|
||||||
gyroL3gHandler->setToGoToNormalMode(true);
|
gyroL3gHandler->setStartUpImmediately();
|
||||||
|
#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1
|
||||||
|
gyroL3gHandler->setToGoToNormalMode(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
spiCookie = new SpiCookie(addresses::GYRO_2_ADIS, gpioIds::GYRO_2_ADIS_CS, spiDev,
|
spiCookie =
|
||||||
ADIS16507::MAXIMUM_REPLY_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
|
new SpiCookie(addresses::GYRO_2_ADIS, gpioIds::GYRO_2_ADIS_CS, spiDev,
|
||||||
adisHandler = new GyroADIS16507Handler(objects::GYRO_2_ADIS_HANDLER, objects::SPI_COM_IF,
|
ADIS16507::MAXIMUM_REPLY_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
|
||||||
spiCookie);
|
adisHandler =
|
||||||
adisHandler->setStartUpImmediately();
|
new GyroADIS16507Handler(objects::GYRO_2_ADIS_HANDLER, objects::SPI_COM_IF, spiCookie);
|
||||||
|
adisHandler->setStartUpImmediately();
|
||||||
|
|
||||||
spiCookie = new SpiCookie(addresses::GYRO_3_L3G, gpioIds::GYRO_3_L3G_CS, spiDev,
|
spiCookie =
|
||||||
L3GD20H::MAX_BUFFER_SIZE, spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
|
new SpiCookie(addresses::GYRO_3_L3G, gpioIds::GYRO_3_L3G_CS, spiDev, L3GD20H::MAX_BUFFER_SIZE,
|
||||||
gyroL3gHandler = new GyroHandlerL3GD20H(objects::GYRO_3_L3G_HANDLER, objects::SPI_COM_IF,
|
spi::DEFAULT_L3G_MODE, spi::DEFAULT_L3G_SPEED);
|
||||||
spiCookie, 0);
|
gyroL3gHandler =
|
||||||
gyroL3gHandler->setStartUpImmediately();
|
new GyroHandlerL3GD20H(objects::GYRO_3_L3G_HANDLER, objects::SPI_COM_IF, spiCookie, 0);
|
||||||
#if FSFW_HAL_L3GD20_GYRO_DEBUG== 1
|
gyroL3gHandler->setStartUpImmediately();
|
||||||
gyroL3gHandler->setToGoToNormalMode(true);
|
#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1
|
||||||
|
gyroL3gHandler->setToGoToNormalMode(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* RPI_TEST_ACS_BOARD == 1 */
|
#endif /* RPI_TEST_ACS_BOARD == 1 */
|
||||||
|
|
||||||
#if OBSW_ADD_TEST_CODE == 1
|
#if OBSW_ADD_TEST_CODE == 1
|
||||||
createTestTasks();
|
createTestTasks();
|
||||||
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectFactory::createTestTasks() {
|
void ObjectFactory::createTestTasks() {
|
||||||
|
new TestTask(objects::TEST_TASK);
|
||||||
new TestTask(objects::TEST_TASK);
|
|
||||||
|
|
||||||
#if RPI_ADD_SPI_TEST == 1
|
#if RPI_ADD_SPI_TEST == 1
|
||||||
new SpiTestClass(objects::SPI_TEST, gpioIF);
|
new SpiTestClass(objects::SPI_TEST, gpioIF);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if RPI_ADD_UART_TEST == 1
|
#if RPI_ADD_UART_TEST == 1
|
||||||
new UartTestClass(objects::UART_TEST);
|
new UartTestClass(objects::UART_TEST);
|
||||||
#else
|
#else
|
||||||
new UartComIF(objects::UART_COM_IF);
|
new UartComIF(objects::UART_COM_IF);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if RPI_LOOPBACK_TEST_GPIO == 1
|
#if RPI_LOOPBACK_TEST_GPIO == 1
|
||||||
GpioCookie* gpioCookieLoopback = new GpioCookie();
|
GpioCookie* gpioCookieLoopback = new GpioCookie();
|
||||||
/* Loopback pins. Adapt according to setup */
|
/* Loopback pins. Adapt according to setup */
|
||||||
gpioId_t gpioIdSender = gpioIds::TEST_ID_0;
|
gpioId_t gpioIdSender = gpioIds::TEST_ID_0;
|
||||||
int bcmPinSender = 26;
|
int bcmPinSender = 26;
|
||||||
gpioId_t gpioIdReader = gpioIds::TEST_ID_1;
|
gpioId_t gpioIdReader = gpioIds::TEST_ID_1;
|
||||||
int bcmPinReader = 16;
|
int bcmPinReader = 16;
|
||||||
gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdSender, bcmPinSender, "GPIO_LB_SENDER",
|
gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdSender, bcmPinSender, "GPIO_LB_SENDER",
|
||||||
gpio::Direction::OUT, 0);
|
gpio::Direction::OUT, 0);
|
||||||
gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdReader, bcmPinReader, "GPIO_LB_READER",
|
gpio::createRpiGpioConfig(gpioCookieLoopback, gpioIdReader, bcmPinReader, "GPIO_LB_READER",
|
||||||
gpio::Direction::IN, 0);
|
gpio::Direction::IN, 0);
|
||||||
new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookieLoopback);
|
new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookieLoopback);
|
||||||
#endif /* RPI_LOOPBACK_TEST_GPIO == 1 */
|
#endif /* RPI_LOOPBACK_TEST_GPIO == 1 */
|
||||||
|
|
||||||
#if RPI_TEST_ADIS16507 == 1
|
#if RPI_TEST_ADIS16507 == 1
|
||||||
if(gpioCookie == nullptr) {
|
if (gpioCookie == nullptr) {
|
||||||
gpioCookie = new GpioCookie();
|
gpioCookie = new GpioCookie();
|
||||||
}
|
}
|
||||||
gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_0_ADIS_CS, gpio::GYRO_0_BCM_PIN,
|
gpio::createRpiGpioConfig(gpioCookie, gpioIds::GYRO_0_ADIS_CS, gpio::GYRO_0_BCM_PIN,
|
||||||
"GYRO_0_ADIS", gpio::Direction::OUT, 1);
|
"GYRO_0_ADIS", gpio::Direction::OUT, 1);
|
||||||
gpioIF->addGpios(gpioCookie);
|
gpioIF->addGpios(gpioCookie);
|
||||||
|
|
||||||
spiDev = "/dev/spidev0.1";
|
spiDev = "/dev/spidev0.1";
|
||||||
spiCookie = new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, spiDev,
|
spiCookie = new SpiCookie(addresses::GYRO_0_ADIS, gpioIds::GYRO_0_ADIS_CS, spiDev,
|
||||||
ADIS16507::MAXIMUM_REPLY_SIZE, spi::DEFAULT_ADIS16507_MODE, spi::DEFAULT_ADIS16507_SPEED,
|
ADIS16507::MAXIMUM_REPLY_SIZE, spi::DEFAULT_ADIS16507_MODE,
|
||||||
nullptr, nullptr);
|
spi::DEFAULT_ADIS16507_SPEED, nullptr, nullptr);
|
||||||
auto adisGyroHandler = new GyroADIS16507Handler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_COM_IF, spiCookie);
|
auto adisGyroHandler =
|
||||||
adisGyroHandler->setStartUpImmediately();
|
new GyroADIS16507Handler(objects::GYRO_0_ADIS_HANDLER, objects::SPI_COM_IF, spiCookie);
|
||||||
|
adisGyroHandler->setStartUpImmediately();
|
||||||
#endif /* RPI_TEST_ADIS16507 == 1 */
|
#endif /* RPI_TEST_ADIS16507 == 1 */
|
||||||
|
|
||||||
#if RPI_TEST_GPS_HANDLER == 1
|
#if RPI_TEST_GPS_HANDLER == 1
|
||||||
UartCookie* uartCookie = new UartCookie(objects::GPS0_HANDLER, "/dev/serial0",
|
UartCookie* uartCookie =
|
||||||
UartModes::CANONICAL, 9600, 1024);
|
new UartCookie(objects::GPS0_HANDLER, "/dev/serial0", UartModes::CANONICAL, 9600, 1024);
|
||||||
uartCookie->setToFlushInput(true);
|
uartCookie->setToFlushInput(true);
|
||||||
uartCookie->setReadCycles(6);
|
uartCookie->setReadCycles(6);
|
||||||
GPSHyperionHandler* gpsHandler = new GPSHyperionHandler(objects::GPS0_HANDLER,
|
GPSHyperionHandler* gpsHandler =
|
||||||
objects::UART_COM_IF, uartCookie, false);
|
new GPSHyperionHandler(objects::GPS0_HANDLER, objects::UART_COM_IF, uartCookie, false);
|
||||||
gpsHandler->setStartUpImmediately();
|
gpsHandler->setStartUpImmediately();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
#ifndef BSP_LINUX_OBJECTFACTORY_H_
|
#ifndef BSP_LINUX_OBJECTFACTORY_H_
|
||||||
#define BSP_LINUX_OBJECTFACTORY_H_
|
#define BSP_LINUX_OBJECTFACTORY_H_
|
||||||
|
|
||||||
|
|
||||||
namespace ObjectFactory {
|
namespace ObjectFactory {
|
||||||
void setStatics();
|
void setStatics();
|
||||||
void produce(void* args);
|
void produce(void* args);
|
||||||
|
|
||||||
void createTestTasks();
|
void createTestTasks();
|
||||||
};
|
}; // namespace ObjectFactory
|
||||||
|
|
||||||
#endif /* BSP_LINUX_OBJECTFACTORY_H_ */
|
#endif /* BSP_LINUX_OBJECTFACTORY_H_ */
|
||||||
|
@ -32,7 +32,7 @@ SOFTWARE.
|
|||||||
|
|
||||||
#define ETL_CHECK_PUSH_POP
|
#define ETL_CHECK_PUSH_POP
|
||||||
|
|
||||||
#define ETL_CPP11_SUPPORTED 1
|
#define ETL_CPP11_SUPPORTED 1
|
||||||
#define ETL_NO_NULLPTR_SUPPORT 0
|
#define ETL_NO_NULLPTR_SUPPORT 0
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6,8 +6,9 @@
|
|||||||
extern "C" void __gcov_flush();
|
extern "C" void __gcov_flush();
|
||||||
#else
|
#else
|
||||||
void __gcov_flush() {
|
void __gcov_flush() {
|
||||||
sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if "
|
sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if "
|
||||||
"coverage information is desired.\n" << std::flush;
|
"coverage information is desired.\n"
|
||||||
|
<< std::flush;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2,13 +2,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
void printChar(const char* character, bool errStream) {
|
void printChar(const char* character, bool errStream) {
|
||||||
if(errStream) {
|
if (errStream) {
|
||||||
putc(*character, stderr);
|
putc(*character, stderr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
putc(*character, stdout);
|
putc(*character, stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "InitMission.h"
|
#include "InitMission.h"
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "OBSWVersion.h"
|
#include "OBSWVersion.h"
|
||||||
|
|
||||||
#include "fsfw/FSFWVersion.h"
|
#include "fsfw/FSFWVersion.h"
|
||||||
#include "fsfw/tasks/TaskFactory.h"
|
#include "fsfw/tasks/TaskFactory.h"
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#ifdef RASPBERRY_PI
|
#ifdef RASPBERRY_PI
|
||||||
static const char* const BOARD_NAME = "Raspberry Pi";
|
static const char* const BOARD_NAME = "Raspberry Pi";
|
||||||
#elif defined(BEAGLEBONEBLACK)
|
#elif defined(BEAGLEBONEBLACK)
|
||||||
@ -19,21 +18,18 @@ static const char* const BOARD_NAME = "Unknown Board";
|
|||||||
* @brief This is the main program and entry point for the Raspberry Pi.
|
* @brief This is the main program and entry point for the Raspberry Pi.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int main(void)
|
int main(void) {
|
||||||
{
|
std::cout << "-- EIVE OBSW --" << std::endl;
|
||||||
std::cout << "-- EIVE OBSW --" << std::endl;
|
std::cout << "-- Compiled for Linux board " << BOARD_NAME << " --" << std::endl;
|
||||||
std::cout << "-- Compiled for Linux board " << BOARD_NAME << " --" << std::endl;
|
std::cout << "-- OBSW " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION << "."
|
||||||
std::cout << "-- OBSW " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION <<
|
<< SW_REVISION << ", FSFW v" << FSFW_VERSION << "." << FSFW_SUBVERSION << FSFW_REVISION
|
||||||
"." << SW_REVISION << ", FSFW v" << FSFW_VERSION << "." << FSFW_SUBVERSION <<
|
<< "--" << std::endl;
|
||||||
FSFW_REVISION << "--" << std::endl;
|
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
|
||||||
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
|
|
||||||
|
|
||||||
initmission::initMission();
|
initmission::initMission();
|
||||||
|
|
||||||
for(;;) {
|
for (;;) {
|
||||||
/* Suspend main thread by sleeping it. */
|
/* Suspend main thread by sleeping it. */
|
||||||
TaskFactory::delayTask(5000);
|
TaskFactory::delayTask(5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,58 +19,58 @@ static constexpr char UIO_PDEC_CONFIG_MEMORY[] = "/dev/uio2";
|
|||||||
static constexpr char UIO_PDEC_RAM[] = "/dev/uio3";
|
static constexpr char UIO_PDEC_RAM[] = "/dev/uio3";
|
||||||
|
|
||||||
namespace gpioNames {
|
namespace gpioNames {
|
||||||
static constexpr char GYRO_0_ADIS_CS[] = "gyro_0_adis_chip_select";
|
static constexpr char GYRO_0_ADIS_CS[] = "gyro_0_adis_chip_select";
|
||||||
static constexpr char GYRO_1_L3G_CS[] = "gyro_1_l3g_chip_select";
|
static constexpr char GYRO_1_L3G_CS[] = "gyro_1_l3g_chip_select";
|
||||||
static constexpr char GYRO_2_ADIS_CS[] = "gyro_2_adis_chip_select";
|
static constexpr char GYRO_2_ADIS_CS[] = "gyro_2_adis_chip_select";
|
||||||
static constexpr char GYRO_3_L3G_CS[] = "gyro_3_l3g_chip_select";
|
static constexpr char GYRO_3_L3G_CS[] = "gyro_3_l3g_chip_select";
|
||||||
static constexpr char MGM_0_CS[] = "mgm_0_lis3_chip_select";
|
static constexpr char MGM_0_CS[] = "mgm_0_lis3_chip_select";
|
||||||
static constexpr char MGM_1_CS[] = "mgm_1_rm3100_chip_select";
|
static constexpr char MGM_1_CS[] = "mgm_1_rm3100_chip_select";
|
||||||
static constexpr char MGM_2_CS[] = "mgm_2_lis3_chip_select";
|
static constexpr char MGM_2_CS[] = "mgm_2_lis3_chip_select";
|
||||||
static constexpr char MGM_3_CS[] = "mgm_3_rm3100_chip_select";
|
static constexpr char MGM_3_CS[] = "mgm_3_rm3100_chip_select";
|
||||||
static constexpr char RESET_GNSS_0[] = "reset_gnss_0";
|
static constexpr char RESET_GNSS_0[] = "reset_gnss_0";
|
||||||
static constexpr char RESET_GNSS_1[] = "reset_gnss_1";
|
static constexpr char RESET_GNSS_1[] = "reset_gnss_1";
|
||||||
static constexpr char GNSS_0_ENABLE[] = "enable_gnss_0";
|
static constexpr char GNSS_0_ENABLE[] = "enable_gnss_0";
|
||||||
static constexpr char GNSS_1_ENABLE[] = "enable_gnss_1";
|
static constexpr char GNSS_1_ENABLE[] = "enable_gnss_1";
|
||||||
static constexpr char GYRO_0_ENABLE[] = "enable_gyro_0";
|
static constexpr char GYRO_0_ENABLE[] = "enable_gyro_0";
|
||||||
static constexpr char GYRO_2_ENABLE[] = "enable_gyro_2";
|
static constexpr char GYRO_2_ENABLE[] = "enable_gyro_2";
|
||||||
static constexpr char HEATER_0[] = "heater0";
|
static constexpr char HEATER_0[] = "heater0";
|
||||||
static constexpr char HEATER_1[] = "heater1";
|
static constexpr char HEATER_1[] = "heater1";
|
||||||
static constexpr char HEATER_2[] = "heater2";
|
static constexpr char HEATER_2[] = "heater2";
|
||||||
static constexpr char HEATER_3[] = "heater3";
|
static constexpr char HEATER_3[] = "heater3";
|
||||||
static constexpr char HEATER_4[] = "heater4";
|
static constexpr char HEATER_4[] = "heater4";
|
||||||
static constexpr char HEATER_5[] = "heater5";
|
static constexpr char HEATER_5[] = "heater5";
|
||||||
static constexpr char HEATER_6[] = "heater6";
|
static constexpr char HEATER_6[] = "heater6";
|
||||||
static constexpr char HEATER_7[] = "heater7";
|
static constexpr char HEATER_7[] = "heater7";
|
||||||
static constexpr char SA_DPL_PIN_0[] = "sa_dpl_0";
|
static constexpr char SA_DPL_PIN_0[] = "sa_dpl_0";
|
||||||
static constexpr char SA_DPL_PIN_1[] = "sa_dpl_1";
|
static constexpr char SA_DPL_PIN_1[] = "sa_dpl_1";
|
||||||
static constexpr char SPI_MUX_BIT_1_PIN[] = "spi_mux_bit_1";
|
static constexpr char SPI_MUX_BIT_1_PIN[] = "spi_mux_bit_1";
|
||||||
static constexpr char SPI_MUX_BIT_2_PIN[] = "spi_mux_bit_2";
|
static constexpr char SPI_MUX_BIT_2_PIN[] = "spi_mux_bit_2";
|
||||||
static constexpr char SPI_MUX_BIT_3_PIN[] = "spi_mux_bit_3";
|
static constexpr char SPI_MUX_BIT_3_PIN[] = "spi_mux_bit_3";
|
||||||
static constexpr char SPI_MUX_BIT_4_PIN[] = "spi_mux_bit_4";
|
static constexpr char SPI_MUX_BIT_4_PIN[] = "spi_mux_bit_4";
|
||||||
static constexpr char SPI_MUX_BIT_5_PIN[] = "spi_mux_bit_5";
|
static constexpr char SPI_MUX_BIT_5_PIN[] = "spi_mux_bit_5";
|
||||||
static constexpr char SPI_MUX_BIT_6_PIN[] = "spi_mux_bit_6";
|
static constexpr char SPI_MUX_BIT_6_PIN[] = "spi_mux_bit_6";
|
||||||
static constexpr char EN_RW_CS[] = "en_rw_cs";
|
static constexpr char EN_RW_CS[] = "en_rw_cs";
|
||||||
static constexpr char EN_RW_1[] = "enable_rw_1";
|
static constexpr char EN_RW_1[] = "enable_rw_1";
|
||||||
static constexpr char EN_RW_2[] = "enable_rw_2";
|
static constexpr char EN_RW_2[] = "enable_rw_2";
|
||||||
static constexpr char EN_RW_3[] = "enable_rw_3";
|
static constexpr char EN_RW_3[] = "enable_rw_3";
|
||||||
static constexpr char EN_RW_4[] = "enable_rw_4";
|
static constexpr char EN_RW_4[] = "enable_rw_4";
|
||||||
static constexpr char GNSS_MUX_SELECT[] = "gnss_mux_select";
|
static constexpr char GNSS_MUX_SELECT[] = "gnss_mux_select";
|
||||||
static constexpr char RAD_SENSOR_CHIP_SELECT[] = "rad_sensor_chip_select";
|
static constexpr char RAD_SENSOR_CHIP_SELECT[] = "rad_sensor_chip_select";
|
||||||
static constexpr char PAPB_BUSY_SIGNAL_VC0[] = "papb_busy_signal_vc0";
|
static constexpr char PAPB_BUSY_SIGNAL_VC0[] = "papb_busy_signal_vc0";
|
||||||
static constexpr char PAPB_EMPTY_SIGNAL_VC0[] = "papb_empty_signal_vc0";
|
static constexpr char PAPB_EMPTY_SIGNAL_VC0[] = "papb_empty_signal_vc0";
|
||||||
static constexpr char PAPB_BUSY_SIGNAL_VC1[] = "papb_busy_signal_vc1";
|
static constexpr char PAPB_BUSY_SIGNAL_VC1[] = "papb_busy_signal_vc1";
|
||||||
static constexpr char PAPB_EMPTY_SIGNAL_VC1[] = "papb_empty_signal_vc1";
|
static constexpr char PAPB_EMPTY_SIGNAL_VC1[] = "papb_empty_signal_vc1";
|
||||||
static constexpr char PAPB_BUSY_SIGNAL_VC2[] = "papb_busy_signal_vc2";
|
static constexpr char PAPB_BUSY_SIGNAL_VC2[] = "papb_busy_signal_vc2";
|
||||||
static constexpr char PAPB_EMPTY_SIGNAL_VC2[] = "papb_empty_signal_vc2";
|
static constexpr char PAPB_EMPTY_SIGNAL_VC2[] = "papb_empty_signal_vc2";
|
||||||
static constexpr char PAPB_BUSY_SIGNAL_VC3[] = "papb_busy_signal_vc3";
|
static constexpr char PAPB_BUSY_SIGNAL_VC3[] = "papb_busy_signal_vc3";
|
||||||
static constexpr char PAPB_EMPTY_SIGNAL_VC3[] = "papb_empty_signal_vc3";
|
static constexpr char PAPB_EMPTY_SIGNAL_VC3[] = "papb_empty_signal_vc3";
|
||||||
static constexpr char RS485_EN_TX_CLOCK[] = "tx_clock_enable_ltc2872";
|
static constexpr char RS485_EN_TX_CLOCK[] = "tx_clock_enable_ltc2872";
|
||||||
static constexpr char RS485_EN_TX_DATA[] = "tx_data_enable_ltc2872";
|
static constexpr char RS485_EN_TX_DATA[] = "tx_data_enable_ltc2872";
|
||||||
static constexpr char RS485_EN_RX_CLOCK[] = "rx_clock_enable_ltc2872";
|
static constexpr char RS485_EN_RX_CLOCK[] = "rx_clock_enable_ltc2872";
|
||||||
static constexpr char RS485_EN_RX_DATA[] = "rx_data_enable_ltc2872";
|
static constexpr char RS485_EN_RX_DATA[] = "rx_data_enable_ltc2872";
|
||||||
static constexpr char PDEC_RESET[] = "pdec_reset";
|
static constexpr char PDEC_RESET[] = "pdec_reset";
|
||||||
static constexpr char BIT_RATE_SEL[] = "bit_rate_sel";
|
static constexpr char BIT_RATE_SEL[] = "bit_rate_sel";
|
||||||
}
|
} // namespace gpioNames
|
||||||
}
|
} // namespace q7s
|
||||||
|
|
||||||
#endif /* BSP_Q7S_BOARDCONFIG_BUSCONF_H_ */
|
#endif /* BSP_Q7S_BOARDCONFIG_BUSCONF_H_ */
|
||||||
|
@ -32,7 +32,7 @@ SOFTWARE.
|
|||||||
|
|
||||||
#define ETL_CHECK_PUSH_POP
|
#define ETL_CHECK_PUSH_POP
|
||||||
|
|
||||||
#define ETL_CPP11_SUPPORTED 1
|
#define ETL_CPP11_SUPPORTED 1
|
||||||
#define ETL_NO_NULLPTR_SUPPORT 0
|
#define ETL_NO_NULLPTR_SUPPORT 0
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6,8 +6,9 @@
|
|||||||
extern "C" void __gcov_flush();
|
extern "C" void __gcov_flush();
|
||||||
#else
|
#else
|
||||||
void __gcov_flush() {
|
void __gcov_flush() {
|
||||||
sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if "
|
sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if "
|
||||||
"coverage information is desired.\n" << std::flush;
|
"coverage information is desired.\n"
|
||||||
|
<< std::flush;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2,13 +2,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
void printChar(const char* character, bool errStream) {
|
void printChar(const char* character, bool errStream) {
|
||||||
if(errStream) {
|
if (errStream) {
|
||||||
putc(*character, stderr);
|
putc(*character, stderr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
putc(*character, stdout);
|
putc(*character, stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,26 +1,23 @@
|
|||||||
#include "FileSystemTest.h"
|
#include "FileSystemTest.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "fsfw/timemanager/Stopwatch.h"
|
#include "fsfw/timemanager/Stopwatch.h"
|
||||||
|
|
||||||
#include <iostream>
|
enum SdCard { SDC0, SDC1 };
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
enum SdCard {
|
|
||||||
SDC0,
|
|
||||||
SDC1
|
|
||||||
};
|
|
||||||
|
|
||||||
FileSystemTest::FileSystemTest() {
|
FileSystemTest::FileSystemTest() {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
SdCard sdCard = SdCard::SDC0;
|
SdCard sdCard = SdCard::SDC0;
|
||||||
cout << "SD Card Test for SD card " << static_cast<int>(sdCard) << std::endl;
|
cout << "SD Card Test for SD card " << static_cast<int>(sdCard) << std::endl;
|
||||||
//Stopwatch stopwatch;
|
// Stopwatch stopwatch;
|
||||||
std::system("q7hw sd info all > /tmp/sd_status.txt");
|
std::system("q7hw sd info all > /tmp/sd_status.txt");
|
||||||
//stopwatch.stop(true);
|
// stopwatch.stop(true);
|
||||||
std::system("q7hw sd set 0 on > /tmp/sd_set.txt");
|
std::system("q7hw sd set 0 on > /tmp/sd_set.txt");
|
||||||
//stopwatch.stop(true);
|
// stopwatch.stop(true);
|
||||||
std::system("q7hw sd set 0 off > /tmp/sd_set.txt");
|
std::system("q7hw sd set 0 off > /tmp/sd_set.txt");
|
||||||
//stopwatch.stop(true);
|
// stopwatch.stop(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystemTest::~FileSystemTest() {
|
FileSystemTest::~FileSystemTest() {}
|
||||||
}
|
|
||||||
|
@ -2,12 +2,11 @@
|
|||||||
#define BSP_Q7S_BOARDTEST_FILESYSTEMTEST_H_
|
#define BSP_Q7S_BOARDTEST_FILESYSTEMTEST_H_
|
||||||
|
|
||||||
class FileSystemTest {
|
class FileSystemTest {
|
||||||
public:
|
public:
|
||||||
FileSystemTest();
|
FileSystemTest();
|
||||||
virtual~ FileSystemTest();
|
virtual ~FileSystemTest();
|
||||||
private:
|
|
||||||
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BSP_Q7S_BOARDTEST_FILESYSTEMTEST_H_ */
|
#endif /* BSP_Q7S_BOARDTEST_FILESYSTEMTEST_H_ */
|
||||||
|
@ -1,414 +1,397 @@
|
|||||||
|
#include "Q7STestTask.h"
|
||||||
|
|
||||||
#include <bsp_q7s/core/CoreController.h>
|
#include <bsp_q7s/core/CoreController.h>
|
||||||
#include <bsp_q7s/memory/FileSystemHandler.h>
|
#include <bsp_q7s/memory/FileSystemHandler.h>
|
||||||
#include <fsfw/objectmanager/ObjectManager.h>
|
#include <fsfw/objectmanager/ObjectManager.h>
|
||||||
#include "Q7STestTask.h"
|
|
||||||
|
|
||||||
#include "bsp_q7s/memory/SdCardManager.h"
|
|
||||||
#include "bsp_q7s/memory/scratchApi.h"
|
|
||||||
|
|
||||||
#include "fsfw/timemanager/Stopwatch.h"
|
|
||||||
#include "fsfw/tasks/TaskFactory.h"
|
|
||||||
|
|
||||||
#include "test/DummyParameter.h"
|
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
#include <gps.h>
|
#include <gps.h>
|
||||||
#include <libgpsmm.h>
|
#include <libgpsmm.h>
|
||||||
|
|
||||||
#include <ctime>
|
|
||||||
#include <iostream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <fstream>
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <ctime>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
Q7STestTask::Q7STestTask(object_id_t objectId): TestTask(objectId) {
|
#include "bsp_q7s/memory/SdCardManager.h"
|
||||||
doTestSdCard = false;
|
#include "bsp_q7s/memory/scratchApi.h"
|
||||||
doTestScratchApi = false;
|
#include "fsfw/tasks/TaskFactory.h"
|
||||||
doTestGps = false;
|
#include "fsfw/timemanager/Stopwatch.h"
|
||||||
|
#include "test/DummyParameter.h"
|
||||||
|
|
||||||
|
Q7STestTask::Q7STestTask(object_id_t objectId) : TestTask(objectId) {
|
||||||
|
doTestSdCard = false;
|
||||||
|
doTestScratchApi = false;
|
||||||
|
doTestGps = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Q7STestTask::performOneShotAction() {
|
ReturnValue_t Q7STestTask::performOneShotAction() {
|
||||||
if (doTestSdCard) {
|
if (doTestSdCard) {
|
||||||
testSdCard();
|
testSdCard();
|
||||||
}
|
}
|
||||||
if (doTestScratchApi) {
|
if (doTestScratchApi) {
|
||||||
testScratchApi();
|
testScratchApi();
|
||||||
}
|
}
|
||||||
//testJsonLibDirect();
|
// testJsonLibDirect();
|
||||||
//testDummyParams();
|
// testDummyParams();
|
||||||
//testProtHandler();
|
// testProtHandler();
|
||||||
FsOpCodes opCode = FsOpCodes::APPEND_TO_FILE;
|
FsOpCodes opCode = FsOpCodes::APPEND_TO_FILE;
|
||||||
testFileSystemHandlerDirect(opCode);
|
testFileSystemHandlerDirect(opCode);
|
||||||
return TestTask::performOneShotAction();
|
return TestTask::performOneShotAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Q7STestTask::performPeriodicAction() {
|
ReturnValue_t Q7STestTask::performPeriodicAction() {
|
||||||
if(doTestGps) {
|
if (doTestGps) {
|
||||||
testGpsDaemon();
|
testGpsDaemon();
|
||||||
}
|
}
|
||||||
return TestTask::performPeriodicAction();
|
return TestTask::performPeriodicAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Q7STestTask::testSdCard() {
|
void Q7STestTask::testSdCard() {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
Stopwatch stopwatch;
|
Stopwatch stopwatch;
|
||||||
int result = std::system("q7hw sd info all > /tmp/sd_status.txt");
|
int result = std::system("q7hw sd info all > /tmp/sd_status.txt");
|
||||||
if(result != 0) {
|
if (result != 0) {
|
||||||
sif::debug << "system call failed with " << result << endl;
|
sif::debug << "system call failed with " << result << endl;
|
||||||
|
}
|
||||||
|
ifstream sdStatus("/tmp/sd_status.txt");
|
||||||
|
string line;
|
||||||
|
uint8_t idx = 0;
|
||||||
|
while (std::getline(sdStatus, line)) {
|
||||||
|
std::istringstream iss(line);
|
||||||
|
string word;
|
||||||
|
while (iss >> word) {
|
||||||
|
if (word == "on") {
|
||||||
|
sif::info << "SD card " << static_cast<int>(idx) << " is on" << endl;
|
||||||
|
} else if (word == "off") {
|
||||||
|
sif::info << "SD card " << static_cast<int>(idx) << " is off" << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ifstream sdStatus("/tmp/sd_status.txt");
|
idx++;
|
||||||
string line;
|
}
|
||||||
uint8_t idx = 0;
|
std::remove("/tmp/sd_status.txt");
|
||||||
while (std::getline(sdStatus, line)) {
|
|
||||||
std::istringstream iss(line);
|
|
||||||
string word;
|
|
||||||
while(iss >> word) {
|
|
||||||
if(word == "on") {
|
|
||||||
sif::info << "SD card " << static_cast<int>(idx) << " is on" << endl;
|
|
||||||
}
|
|
||||||
else if(word == "off") {
|
|
||||||
sif::info << "SD card " << static_cast<int>(idx) << " is off" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
idx++;
|
|
||||||
}
|
|
||||||
std::remove("/tmp/sd_status.txt");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Q7STestTask::fileTests() {
|
void Q7STestTask::fileTests() {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
ofstream testFile("/tmp/test.txt");
|
ofstream testFile("/tmp/test.txt");
|
||||||
testFile << "Hallo Welt" << endl;
|
testFile << "Hallo Welt" << endl;
|
||||||
testFile.close();
|
testFile.close();
|
||||||
|
|
||||||
system("echo \"Hallo Welt\" > /tmp/test2.txt");
|
system("echo \"Hallo Welt\" > /tmp/test2.txt");
|
||||||
system("echo \"Hallo Welt\"");
|
system("echo \"Hallo Welt\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Q7STestTask::testScratchApi() {
|
void Q7STestTask::testScratchApi() {
|
||||||
ReturnValue_t result = scratch::writeNumber("TEST", 1);
|
ReturnValue_t result = scratch::writeNumber("TEST", 1);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::debug << "Q7STestTask::scratchApiTest: Writing number failed" << std::endl;
|
sif::debug << "Q7STestTask::scratchApiTest: Writing number failed" << std::endl;
|
||||||
}
|
}
|
||||||
int number = 0;
|
int number = 0;
|
||||||
result = scratch::readNumber("TEST", number);
|
result = scratch::readNumber("TEST", number);
|
||||||
sif::info << "Q7STestTask::testScratchApi: Value for key \"TEST\": " << number << std::endl;
|
sif::info << "Q7STestTask::testScratchApi: Value for key \"TEST\": " << number << std::endl;
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::debug << "Q7STestTask::scratchApiTest: Reading number failed" << std::endl;
|
sif::debug << "Q7STestTask::scratchApiTest: Reading number failed" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = scratch::writeString("TEST2", "halloWelt");
|
result = scratch::writeString("TEST2", "halloWelt");
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::debug << "Q7STestTask::scratchApiTest: Writing string failed" << std::endl;
|
sif::debug << "Q7STestTask::scratchApiTest: Writing string failed" << std::endl;
|
||||||
}
|
}
|
||||||
std::string string;
|
std::string string;
|
||||||
result = scratch::readString("TEST2", string);
|
result = scratch::readString("TEST2", string);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::debug << "Q7STestTask::scratchApiTest: Reading number failed" << std::endl;
|
sif::debug << "Q7STestTask::scratchApiTest: Reading number failed" << std::endl;
|
||||||
}
|
}
|
||||||
sif::info << "Q7STestTask::testScratchApi: Value for key \"TEST2\": " << string << std::endl;
|
sif::info << "Q7STestTask::testScratchApi: Value for key \"TEST2\": " << string << std::endl;
|
||||||
|
|
||||||
result = scratch::clearValue("TEST");
|
result = scratch::clearValue("TEST");
|
||||||
result = scratch::clearValue("TEST2");
|
result = scratch::clearValue("TEST2");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Q7STestTask::testJsonLibDirect() {
|
void Q7STestTask::testJsonLibDirect() {
|
||||||
Stopwatch stopwatch;
|
Stopwatch stopwatch;
|
||||||
// for convenience
|
// for convenience
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
json helloTest;
|
json helloTest;
|
||||||
// add a number that is stored as double (note the implicit conversion of j to an object)
|
// add a number that is stored as double (note the implicit conversion of j to an object)
|
||||||
helloTest["pi"] = 3.141;
|
helloTest["pi"] = 3.141;
|
||||||
std::string mntPrefix = SdCardManager::instance()->getCurrentMountPrefix();
|
std::string mntPrefix = SdCardManager::instance()->getCurrentMountPrefix();
|
||||||
std::string fileName = mntPrefix + "/pretty.json";
|
std::string fileName = mntPrefix + "/pretty.json";
|
||||||
std::ofstream o(fileName);
|
std::ofstream o(fileName);
|
||||||
o << std::setw(4) << helloTest << std::endl;
|
o << std::setw(4) << helloTest << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Q7STestTask::testDummyParams() {
|
void Q7STestTask::testDummyParams() {
|
||||||
std::string mntPrefix = SdCardManager::instance()->getCurrentMountPrefix();
|
std::string mntPrefix = SdCardManager::instance()->getCurrentMountPrefix();
|
||||||
DummyParameter param(mntPrefix, "dummy_json.txt");
|
DummyParameter param(mntPrefix, "dummy_json.txt");
|
||||||
param.printKeys();
|
param.printKeys();
|
||||||
param.print();
|
param.print();
|
||||||
if(not param.getJsonFileExists()) {
|
if (not param.getJsonFileExists()) {
|
||||||
param.writeJsonFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t result = param.readJsonFile();
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
param.setValue(DummyParameter::DUMMY_KEY_PARAM_1, 3);
|
|
||||||
param.setValue(DummyParameter::DUMMY_KEY_PARAM_2, "blirb");
|
|
||||||
|
|
||||||
param.writeJsonFile();
|
param.writeJsonFile();
|
||||||
param.print();
|
}
|
||||||
|
|
||||||
int test = 0;
|
ReturnValue_t result = param.readJsonFile();
|
||||||
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
|
|
||||||
<< " does not exist" << std::endl;
|
param.setValue(DummyParameter::DUMMY_KEY_PARAM_1, 3);
|
||||||
}
|
param.setValue(DummyParameter::DUMMY_KEY_PARAM_2, "blirb");
|
||||||
std::string test2;
|
|
||||||
result = param.getValue<std::string>(DummyParameter::DUMMY_KEY_PARAM_2, &test2);
|
param.writeJsonFile();
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
param.print();
|
||||||
sif::warning << "Q7STestTask::testDummyParams: Key " << DummyParameter::DUMMY_KEY_PARAM_1
|
|
||||||
<< " does not exist" << std::endl;
|
int test = 0;
|
||||||
}
|
result = param.getValue<int>(DummyParameter::DUMMY_KEY_PARAM_1, &test);
|
||||||
sif::info << "Test value (3 expected): " << test << std::endl;
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::info << "Test value 2 (\"blirb\" expected): " << test2 << std::endl;
|
sif::warning << "Q7STestTask::testDummyParams: Key " << DummyParameter::DUMMY_KEY_PARAM_1
|
||||||
|
<< " does not exist" << std::endl;
|
||||||
|
}
|
||||||
|
std::string test2;
|
||||||
|
result = param.getValue<std::string>(DummyParameter::DUMMY_KEY_PARAM_2, &test2);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::warning << "Q7STestTask::testDummyParams: Key " << DummyParameter::DUMMY_KEY_PARAM_1
|
||||||
|
<< " does not exist" << std::endl;
|
||||||
|
}
|
||||||
|
sif::info << "Test value (3 expected): " << test << std::endl;
|
||||||
|
sif::info << "Test value 2 (\"blirb\" expected): " << test2 << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Q7STestTask::initialize() {
|
ReturnValue_t Q7STestTask::initialize() {
|
||||||
coreController = ObjectManager::instance()->get<CoreController>(objects::CORE_CONTROLLER);
|
coreController = ObjectManager::instance()->get<CoreController>(objects::CORE_CONTROLLER);
|
||||||
if(coreController == nullptr) {
|
if (coreController == nullptr) {
|
||||||
sif::warning << "Q7STestTask::initialize: Could not retrieve CORE_CONTROLLER object" <<
|
sif::warning << "Q7STestTask::initialize: Could not retrieve CORE_CONTROLLER object"
|
||||||
std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
return TestTask::initialize();
|
return TestTask::initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Q7STestTask::testProtHandler() {
|
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(
|
||||||
CoreController::Chip::ALL_CHIP, CoreController::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(
|
||||||
CoreController::Chip::SELF_CHIP, CoreController::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;
|
}
|
||||||
}
|
if (not opPerformed) {
|
||||||
if(not opPerformed) {
|
sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl;
|
||||||
sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl;
|
}
|
||||||
}
|
int retval = std::system("print-chip-prot-status.sh");
|
||||||
int retval = std::system("print-chip-prot-status.sh");
|
if (retval != 0) {
|
||||||
if(retval != 0) {
|
utility::handleSystemError(retval, "Q7STestTask::testProtHandler");
|
||||||
utility::handleSystemError(retval, "Q7STestTask::testProtHandler");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// lock own copy
|
// lock own copy
|
||||||
result = coreController->setBootCopyProtection(
|
result = coreController->setBootCopyProtection(
|
||||||
CoreController::Chip::SELF_CHIP, CoreController::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;
|
}
|
||||||
}
|
if (not opPerformed) {
|
||||||
if(not opPerformed) {
|
sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl;
|
||||||
sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl;
|
}
|
||||||
}
|
retval = std::system("print-chip-prot-status.sh");
|
||||||
retval = std::system("print-chip-prot-status.sh");
|
if (retval != 0) {
|
||||||
if(retval != 0) {
|
utility::handleSystemError(retval, "Q7STestTask::testProtHandler");
|
||||||
utility::handleSystemError(retval, "Q7STestTask::testProtHandler");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// unlock specific copy
|
// unlock specific copy
|
||||||
result = coreController->setBootCopyProtection(
|
result = coreController->setBootCopyProtection(
|
||||||
CoreController::Chip::CHIP_1, CoreController::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;
|
}
|
||||||
}
|
if (not opPerformed) {
|
||||||
if(not opPerformed) {
|
sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl;
|
||||||
sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl;
|
}
|
||||||
}
|
retval = std::system("print-chip-prot-status.sh");
|
||||||
retval = std::system("print-chip-prot-status.sh");
|
if (retval != 0) {
|
||||||
if(retval != 0) {
|
utility::handleSystemError(retval, "Q7STestTask::testProtHandler");
|
||||||
utility::handleSystemError(retval, "Q7STestTask::testProtHandler");
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// lock specific copy
|
// lock specific copy
|
||||||
result = coreController->setBootCopyProtection(
|
result = coreController->setBootCopyProtection(
|
||||||
CoreController::Chip::CHIP_1, CoreController::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;
|
}
|
||||||
}
|
if (not opPerformed) {
|
||||||
if(not opPerformed) {
|
sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl;
|
||||||
sif::warning << "Q7STestTask::testProtHandler: No op performed" << std::endl;
|
}
|
||||||
}
|
retval = std::system("print-chip-prot-status.sh");
|
||||||
retval = std::system("print-chip-prot-status.sh");
|
if (retval != 0) {
|
||||||
if(retval != 0) {
|
utility::handleSystemError(retval, "Q7STestTask::testProtHandler");
|
||||||
utility::handleSystemError(retval, "Q7STestTask::testProtHandler");
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Q7STestTask::testGpsDaemon() {
|
void Q7STestTask::testGpsDaemon() {
|
||||||
gpsmm gpsmm(GPSD_SHARED_MEMORY, 0);
|
gpsmm gpsmm(GPSD_SHARED_MEMORY, 0);
|
||||||
gps_data_t* gps;
|
gps_data_t* gps;
|
||||||
gps = gpsmm.read();
|
gps = gpsmm.read();
|
||||||
if(gps == nullptr) {
|
if (gps == nullptr) {
|
||||||
sif::warning << "Q7STestTask: Reading GPS data failed" << std::endl;
|
sif::warning << "Q7STestTask: Reading GPS data failed" << std::endl;
|
||||||
}
|
}
|
||||||
sif::info << "-- Q7STestTask: GPS shared memory read test --" << std::endl;
|
sif::info << "-- Q7STestTask: GPS shared memory read test --" << std::endl;
|
||||||
time_t timeRaw = gps->fix.time.tv_sec;
|
time_t timeRaw = gps->fix.time.tv_sec;
|
||||||
std::tm* time = gmtime(&timeRaw);
|
std::tm* time = gmtime(&timeRaw);
|
||||||
sif::info << "Time: " << std::put_time(time, "%c %Z") << std::endl;
|
sif::info << "Time: " << std::put_time(time, "%c %Z") << std::endl;
|
||||||
sif::info << "Visible satellites: " << gps->satellites_visible << std::endl;
|
sif::info << "Visible satellites: " << gps->satellites_visible << std::endl;
|
||||||
sif::info << "Satellites used: " << gps->satellites_used << std::endl;
|
sif::info << "Satellites used: " << gps->satellites_used << std::endl;
|
||||||
sif::info << "Fix (0:Not Seen|1:No Fix|2:2D|3:3D): " << gps->fix.mode << std::endl;
|
sif::info << "Fix (0:Not Seen|1:No Fix|2:2D|3:3D): " << gps->fix.mode << std::endl;
|
||||||
sif::info << "Latitude: " << gps->fix.latitude << std::endl;
|
sif::info << "Latitude: " << gps->fix.latitude << std::endl;
|
||||||
sif::info << "Longitude: " << gps->fix.longitude << std::endl;
|
sif::info << "Longitude: " << gps->fix.longitude << std::endl;
|
||||||
sif::info << "Altitude(MSL): " << gps->fix.altMSL << std::endl;
|
sif::info << "Altitude(MSL): " << gps->fix.altMSL << std::endl;
|
||||||
sif::info << "Speed(m/s): " << gps->fix.speed << std::endl;
|
sif::info << "Speed(m/s): " << gps->fix.speed << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Q7STestTask::testFileSystemHandlerDirect(FsOpCodes opCode) {
|
void Q7STestTask::testFileSystemHandlerDirect(FsOpCodes opCode) {
|
||||||
auto fsHandler = ObjectManager::instance()->
|
auto fsHandler = ObjectManager::instance()->get<FileSystemHandler>(objects::FILE_SYSTEM_HANDLER);
|
||||||
get<FileSystemHandler>(objects::FILE_SYSTEM_HANDLER);
|
if (fsHandler == nullptr) {
|
||||||
if(fsHandler == nullptr) {
|
sif::warning << "Q7STestTask::testFileSystemHandlerDirect: No FS handler running.."
|
||||||
sif::warning << "Q7STestTask::testFileSystemHandlerDirect: No FS handler running.."
|
<< std::endl;
|
||||||
<< std::endl;
|
}
|
||||||
}
|
FileSystemHandler::FsCommandCfg cfg = {};
|
||||||
FileSystemHandler::FsCommandCfg cfg = {};
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
|
||||||
|
|
||||||
// Lambda for common code
|
// Lambda for common code
|
||||||
auto createNonEmptyTmpDir = [&]() {
|
auto createNonEmptyTmpDir = [&]() {
|
||||||
if(not std::filesystem::exists("/tmp/test")) {
|
if (not std::filesystem::exists("/tmp/test")) {
|
||||||
result = fsHandler->createDirectory("/tmp", "test", false, &cfg);
|
result = fsHandler->createDirectory("/tmp", "test", false, &cfg);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Creating sample files
|
|
||||||
sif::info << "Creating sample files in directory" << std::endl;
|
|
||||||
result = fsHandler->createFile("/tmp/test", "test1.txt", nullptr, 0, &cfg);
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = fsHandler->createFile("/tmp/test", "test2.txt", nullptr, 0, &cfg);
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
// Creating sample files
|
||||||
|
sif::info << "Creating sample files in directory" << std::endl;
|
||||||
|
result = fsHandler->createFile("/tmp/test", "test1.txt", nullptr, 0, &cfg);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = fsHandler->createFile("/tmp/test", "test2.txt", nullptr, 0, &cfg);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (opCode) {
|
||||||
switch(opCode) {
|
case (FsOpCodes::CREATE_EMPTY_FILE_IN_TMP): {
|
||||||
case(FsOpCodes::CREATE_EMPTY_FILE_IN_TMP): {
|
// No mount prefix, cause file is created in tmp
|
||||||
// No mount prefix, cause file is created in tmp
|
cfg.useMountPrefix = false;
|
||||||
cfg.useMountPrefix = false;
|
sif::info << "Creating empty file in /tmp folder" << std::endl;
|
||||||
sif::info << "Creating empty file in /tmp folder" << std::endl;
|
// Do not delete file, user can check existence in shell
|
||||||
// Do not delete file, user can check existence in shell
|
fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (FsOpCodes::REMOVE_TMP_FILE): {
|
||||||
|
sif::info << "Deleting /tmp/test.txt sample file" << std::endl;
|
||||||
|
// No mount prefix, cause file is created in tmp
|
||||||
|
cfg.useMountPrefix = false;
|
||||||
|
if (not std::filesystem::exists("/tmp/test.txt")) {
|
||||||
|
// Creating sample file
|
||||||
|
sif::info << "Creating sample file /tmp/test.txt to delete" << std::endl;
|
||||||
fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg);
|
fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg);
|
||||||
break;
|
}
|
||||||
|
result = fsHandler->removeFile("/tmp", "test.txt", &cfg);
|
||||||
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::info << "File removed successfully" << std::endl;
|
||||||
|
} else {
|
||||||
|
sif::warning << "File removal failed!" << std::endl;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case(FsOpCodes::REMOVE_TMP_FILE): {
|
case (FsOpCodes::CREATE_DIR_IN_TMP): {
|
||||||
sif::info << "Deleting /tmp/test.txt sample file" << std::endl;
|
// No mount prefix, cause file is created in tmp
|
||||||
// No mount prefix, cause file is created in tmp
|
cfg.useMountPrefix = false;
|
||||||
cfg.useMountPrefix = false;
|
sif::info << "Creating empty file in /tmp folder" << std::endl;
|
||||||
if(not std::filesystem::exists("/tmp/test.txt")) {
|
// Do not delete file, user can check existence in shell
|
||||||
// Creating sample file
|
ReturnValue_t result = fsHandler->createDirectory("/tmp/", "test", false, &cfg);
|
||||||
sif::info << "Creating sample file /tmp/test.txt to delete" << std::endl;
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg);
|
sif::info << "Directory created successfully" << std::endl;
|
||||||
}
|
} else {
|
||||||
result = fsHandler->removeFile("/tmp", "test.txt", &cfg);
|
sif::warning << "Directory creation failed!" << std::endl;
|
||||||
if(result == HasReturnvaluesIF::RETURN_OK) {
|
}
|
||||||
sif::info << "File removed successfully" << std::endl;
|
break;
|
||||||
}
|
|
||||||
else {
|
|
||||||
sif::warning << "File removal failed!" << std::endl;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case(FsOpCodes::CREATE_DIR_IN_TMP): {
|
case (FsOpCodes::REMOVE_EMPTY_DIR_IN_TMP): {
|
||||||
// No mount prefix, cause file is created in tmp
|
// No mount prefix, cause file is created in tmp
|
||||||
cfg.useMountPrefix = false;
|
cfg.useMountPrefix = false;
|
||||||
sif::info << "Creating empty file in /tmp folder" << std::endl;
|
if (not std::filesystem::exists("/tmp/test")) {
|
||||||
// Do not delete file, user can check existence in shell
|
result = fsHandler->createDirectory("/tmp", "test", false, &cfg);
|
||||||
ReturnValue_t result = fsHandler->createDirectory("/tmp/", "test", false, &cfg);
|
} else {
|
||||||
if(result == HasReturnvaluesIF::RETURN_OK) {
|
// Delete any leftover files to regular dir removal works
|
||||||
sif::info << "Directory created successfully" << std::endl;
|
std::remove("/tmp/test/*");
|
||||||
}
|
}
|
||||||
else {
|
result = fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
|
||||||
sif::warning << "Directory creation failed!" << std::endl;
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
}
|
sif::info << "Directory removed successfully" << std::endl;
|
||||||
break;
|
} else {
|
||||||
|
sif::warning << "Directory removal failed!" << std::endl;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case(FsOpCodes::REMOVE_EMPTY_DIR_IN_TMP): {
|
case (FsOpCodes::REMOVE_FILLED_DIR_IN_TMP): {
|
||||||
// No mount prefix, cause file is created in tmp
|
result = createNonEmptyTmpDir();
|
||||||
cfg.useMountPrefix = false;
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
if(not std::filesystem::exists("/tmp/test")) {
|
return;
|
||||||
result = fsHandler->createDirectory("/tmp", "test", false, &cfg);
|
}
|
||||||
}
|
result = fsHandler->removeDirectory("/tmp/", "test", true, &cfg);
|
||||||
else {
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
// Delete any leftover files to regular dir removal works
|
sif::info << "Directory removed recursively successfully" << std::endl;
|
||||||
std::remove("/tmp/test/*");
|
} else {
|
||||||
}
|
sif::warning << "Recursive directory removal failed!" << std::endl;
|
||||||
result = fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
|
}
|
||||||
if(result == HasReturnvaluesIF::RETURN_OK) {
|
break;
|
||||||
sif::info << "Directory removed successfully" << std::endl;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sif::warning << "Directory removal failed!" << std::endl;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case(FsOpCodes::REMOVE_FILLED_DIR_IN_TMP): {
|
case (FsOpCodes::ATTEMPT_DIR_REMOVAL_NON_EMPTY): {
|
||||||
result = createNonEmptyTmpDir();
|
result = createNonEmptyTmpDir();
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
result = fsHandler->removeDirectory("/tmp/", "test", true, &cfg);
|
result = fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
|
||||||
if(result == HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::info << "Directory removed recursively successfully" << std::endl;
|
sif::info << "Directory removal attempt failed as expected" << std::endl;
|
||||||
}
|
} else {
|
||||||
else {
|
sif::warning << "Directory removal worked when it should not have!" << std::endl;
|
||||||
sif::warning << "Recursive directory removal failed!" << std::endl;
|
}
|
||||||
}
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case(FsOpCodes::ATTEMPT_DIR_REMOVAL_NON_EMPTY): {
|
case (FsOpCodes::RENAME_FILE): {
|
||||||
result = createNonEmptyTmpDir();
|
// No mount prefix, cause file is created in tmp
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
cfg.useMountPrefix = false;
|
||||||
return;
|
if (std::filesystem::exists("/tmp/test.txt")) {
|
||||||
}
|
fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
|
||||||
result = fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
|
}
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
sif::info << "Creating empty file /tmp/test.txt and rename to /tmp/test2.txt" << std::endl;
|
||||||
sif::info << "Directory removal attempt failed as expected" << std::endl;
|
// Do not delete file, user can check existence in shell
|
||||||
}
|
fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg);
|
||||||
else {
|
fsHandler->renameFile("/tmp/", "test.txt", "test2.txt", &cfg);
|
||||||
sif::warning << "Directory removal worked when it should not have!" << std::endl;
|
break;
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(FsOpCodes::RENAME_FILE): {
|
|
||||||
// No mount prefix, cause file is created in tmp
|
|
||||||
cfg.useMountPrefix = false;
|
|
||||||
if(std::filesystem::exists("/tmp/test.txt")) {
|
|
||||||
fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
|
|
||||||
}
|
|
||||||
sif::info << "Creating empty file /tmp/test.txt and rename to /tmp/test2.txt" << std::endl;
|
|
||||||
// Do not delete file, user can check existence in shell
|
|
||||||
fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg);
|
|
||||||
fsHandler->renameFile("/tmp/", "test.txt", "test2.txt", &cfg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(FsOpCodes::APPEND_TO_FILE): {
|
|
||||||
// No mount prefix, cause file is created in tmp
|
|
||||||
cfg.useMountPrefix = false;
|
|
||||||
if(std::filesystem::exists("/tmp/test.txt")) {
|
|
||||||
fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
|
|
||||||
}
|
|
||||||
if(std::filesystem::exists("/tmp/test.txt")) {
|
|
||||||
fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
|
|
||||||
}
|
|
||||||
sif::info << "Creating empty file /tmp/test.txt and adding content" << std::endl;
|
|
||||||
std::string content = "Hello World\n";
|
|
||||||
// Do not delete file, user can check existence in shell
|
|
||||||
fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg);
|
|
||||||
fsHandler->appendToFile("/tmp/", "test.txt", reinterpret_cast<const uint8_t*>(
|
|
||||||
content.data()), content.size(), 0, &cfg);
|
|
||||||
}
|
}
|
||||||
|
case (FsOpCodes::APPEND_TO_FILE): {
|
||||||
|
// No mount prefix, cause file is created in tmp
|
||||||
|
cfg.useMountPrefix = false;
|
||||||
|
if (std::filesystem::exists("/tmp/test.txt")) {
|
||||||
|
fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
|
||||||
|
}
|
||||||
|
if (std::filesystem::exists("/tmp/test.txt")) {
|
||||||
|
fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
|
||||||
|
}
|
||||||
|
sif::info << "Creating empty file /tmp/test.txt and adding content" << std::endl;
|
||||||
|
std::string content = "Hello World\n";
|
||||||
|
// Do not delete file, user can check existence in shell
|
||||||
|
fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg);
|
||||||
|
fsHandler->appendToFile("/tmp/", "test.txt", reinterpret_cast<const uint8_t*>(content.data()),
|
||||||
|
content.size(), 0, &cfg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,42 +5,42 @@
|
|||||||
|
|
||||||
class CoreController;
|
class CoreController;
|
||||||
|
|
||||||
class Q7STestTask: public TestTask {
|
class Q7STestTask : public TestTask {
|
||||||
public:
|
public:
|
||||||
Q7STestTask(object_id_t objectId);
|
Q7STestTask(object_id_t objectId);
|
||||||
|
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
private:
|
|
||||||
bool doTestSdCard = false;
|
|
||||||
bool doTestScratchApi = false;
|
|
||||||
bool doTestGps = false;
|
|
||||||
|
|
||||||
CoreController* coreController = nullptr;
|
private:
|
||||||
ReturnValue_t performOneShotAction() override;
|
bool doTestSdCard = false;
|
||||||
ReturnValue_t performPeriodicAction() override;
|
bool doTestScratchApi = false;
|
||||||
|
bool doTestGps = false;
|
||||||
|
|
||||||
void testGpsDaemon();
|
CoreController* coreController = nullptr;
|
||||||
|
ReturnValue_t performOneShotAction() override;
|
||||||
|
ReturnValue_t performPeriodicAction() override;
|
||||||
|
|
||||||
void testSdCard();
|
void testGpsDaemon();
|
||||||
void fileTests();
|
|
||||||
|
|
||||||
void testScratchApi();
|
void testSdCard();
|
||||||
void testJsonLibDirect();
|
void fileTests();
|
||||||
void testDummyParams();
|
|
||||||
void testProtHandler();
|
|
||||||
|
|
||||||
enum FsOpCodes {
|
void testScratchApi();
|
||||||
CREATE_EMPTY_FILE_IN_TMP,
|
void testJsonLibDirect();
|
||||||
REMOVE_TMP_FILE,
|
void testDummyParams();
|
||||||
CREATE_DIR_IN_TMP,
|
void testProtHandler();
|
||||||
REMOVE_EMPTY_DIR_IN_TMP,
|
|
||||||
ATTEMPT_DIR_REMOVAL_NON_EMPTY,
|
enum FsOpCodes {
|
||||||
REMOVE_FILLED_DIR_IN_TMP,
|
CREATE_EMPTY_FILE_IN_TMP,
|
||||||
RENAME_FILE,
|
REMOVE_TMP_FILE,
|
||||||
APPEND_TO_FILE,
|
CREATE_DIR_IN_TMP,
|
||||||
};
|
REMOVE_EMPTY_DIR_IN_TMP,
|
||||||
void testFileSystemHandlerDirect(FsOpCodes opCode);
|
ATTEMPT_DIR_REMOVAL_NON_EMPTY,
|
||||||
|
REMOVE_FILLED_DIR_IN_TMP,
|
||||||
|
RENAME_FILE,
|
||||||
|
APPEND_TO_FILE,
|
||||||
|
};
|
||||||
|
void testFileSystemHandlerDirect(FsOpCodes opCode);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* BSP_Q7S_BOARDTEST_Q7STESTTASK_H_ */
|
#endif /* BSP_Q7S_BOARDTEST_Q7STESTTASK_H_ */
|
||||||
|
@ -1,26 +1,25 @@
|
|||||||
#include "gnssCallback.h"
|
#include "gnssCallback.h"
|
||||||
#include "devices/gpioIds.h"
|
|
||||||
|
|
||||||
|
#include "devices/gpioIds.h"
|
||||||
#include "fsfw/tasks/TaskFactory.h"
|
#include "fsfw/tasks/TaskFactory.h"
|
||||||
|
|
||||||
ReturnValue_t gps::triggerGpioResetPin(void *args) {
|
ReturnValue_t gps::triggerGpioResetPin(void* args) {
|
||||||
ResetArgs* resetArgs = reinterpret_cast<ResetArgs*>(args);
|
ResetArgs* resetArgs = reinterpret_cast<ResetArgs*>(args);
|
||||||
if(args == nullptr) {
|
if (args == nullptr) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
if (resetArgs->gpioComIF == nullptr) {
|
if (resetArgs->gpioComIF == nullptr) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
gpioId_t gpioId;
|
gpioId_t gpioId;
|
||||||
if(resetArgs->gnss1) {
|
if (resetArgs->gnss1) {
|
||||||
gpioId = gpioIds::GNSS_1_NRESET;
|
gpioId = gpioIds::GNSS_1_NRESET;
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else {
|
gpioId = gpioIds::GNSS_0_NRESET;
|
||||||
gpioId = gpioIds::GNSS_0_NRESET;
|
}
|
||||||
}
|
resetArgs->gpioComIF->pullLow(gpioId);
|
||||||
resetArgs->gpioComIF->pullLow(gpioId);
|
TaskFactory::delayTask(resetArgs->waitPeriodMs);
|
||||||
TaskFactory::delayTask(resetArgs->waitPeriodMs);
|
resetArgs->gpioComIF->pullHigh(gpioId);
|
||||||
resetArgs->gpioComIF->pullHigh(gpioId);
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
#ifndef BSP_Q7S_CALLBACKS_GNSSCALLBACK_H_
|
#ifndef BSP_Q7S_CALLBACKS_GNSSCALLBACK_H_
|
||||||
#define BSP_Q7S_CALLBACKS_GNSSCALLBACK_H_
|
#define BSP_Q7S_CALLBACKS_GNSSCALLBACK_H_
|
||||||
|
|
||||||
#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h"
|
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
|
#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h"
|
||||||
|
|
||||||
struct ResetArgs {
|
struct ResetArgs {
|
||||||
bool gnss1 = false;
|
bool gnss1 = false;
|
||||||
LinuxLibgpioIF* gpioComIF = nullptr;
|
LinuxLibgpioIF* gpioComIF = nullptr;
|
||||||
uint32_t waitPeriodMs = 100;
|
uint32_t waitPeriodMs = 100;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace gps {
|
namespace gps {
|
||||||
|
@ -1,238 +1,232 @@
|
|||||||
#include "rwSpiCallback.h"
|
#include "rwSpiCallback.h"
|
||||||
#include "devices/gpioIds.h"
|
|
||||||
#include "mission/devices/RwHandler.h"
|
|
||||||
|
|
||||||
#include "fsfw_hal/linux/spi/SpiCookie.h"
|
#include "devices/gpioIds.h"
|
||||||
#include "fsfw_hal/linux/UnixFileGuard.h"
|
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
#include "fsfw_hal/linux/UnixFileGuard.h"
|
||||||
|
#include "fsfw_hal/linux/spi/SpiCookie.h"
|
||||||
|
#include "mission/devices/RwHandler.h"
|
||||||
|
|
||||||
namespace rwSpiCallback {
|
namespace rwSpiCallback {
|
||||||
|
|
||||||
ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie *cookie, const uint8_t *sendData,
|
ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sendData,
|
||||||
size_t sendLen, void* args) {
|
size_t sendLen, void* args) {
|
||||||
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
|
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
RwHandler* handler = reinterpret_cast<RwHandler*>(args);
|
||||||
|
if (handler == nullptr) {
|
||||||
|
sif::error << "rwSpiCallback::spiCallback: Pointer to handler is invalid" << std::endl;
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
RwHandler* handler = reinterpret_cast<RwHandler*>(args);
|
uint8_t writeBuffer[2];
|
||||||
if(handler == nullptr) {
|
uint8_t writeSize = 0;
|
||||||
sif::error << "rwSpiCallback::spiCallback: Pointer to handler is invalid"
|
|
||||||
<< std::endl;
|
gpioId_t gpioId = cookie->getChipSelectPin();
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
GpioIF* gpioIF = comIf->getGpioInterface();
|
||||||
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
||||||
|
uint32_t timeoutMs = 0;
|
||||||
|
MutexIF* mutex = comIf->getMutex(&timeoutType, &timeoutMs);
|
||||||
|
if (mutex == nullptr or gpioIF == nullptr) {
|
||||||
|
sif::debug << "rwSpiCallback::spiCallback: Mutex or GPIO interface invalid" << std::endl;
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fileDescriptor = 0;
|
||||||
|
std::string device = cookie->getSpiDevice();
|
||||||
|
UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "rwSpiCallback::spiCallback");
|
||||||
|
if (fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::error << "rwSpiCallback::spiCallback: Failed to open device file" << std::endl;
|
||||||
|
return SpiComIF::OPENING_FILE_FAILED;
|
||||||
|
}
|
||||||
|
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
|
||||||
|
uint32_t spiSpeed = 0;
|
||||||
|
cookie->getSpiParameters(spiMode, spiSpeed, nullptr);
|
||||||
|
comIf->setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
|
||||||
|
|
||||||
|
result = mutex->lockMutex(timeoutType, timeoutMs);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::debug << "rwSpiCallback::spiCallback: Failed to lock mutex" << std::endl;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sending frame start sign */
|
||||||
|
writeBuffer[0] = 0x7E;
|
||||||
|
writeSize = 1;
|
||||||
|
|
||||||
|
// Pull SPI CS low. For now, no support for active high given
|
||||||
|
if (gpioId != gpio::NO_GPIO) {
|
||||||
|
if (gpioIF->pullLow(gpioId) != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::error << "rwSpiCallback::spiCallback: Failed to pull chip select low" << std::endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t writeBuffer[2];
|
if (write(fileDescriptor, writeBuffer, writeSize) != static_cast<ssize_t>(writeSize)) {
|
||||||
uint8_t writeSize = 0;
|
sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl;
|
||||||
|
closeSpi(gpioId, gpioIF, mutex);
|
||||||
|
return RwHandler::SPI_WRITE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
gpioId_t gpioId = cookie->getChipSelectPin();
|
/** Encoding and sending command */
|
||||||
GpioIF* gpioIF = comIf->getGpioInterface();
|
size_t idx = 0;
|
||||||
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
while (idx < sendLen) {
|
||||||
uint32_t timeoutMs = 0;
|
switch (*(sendData + idx)) {
|
||||||
MutexIF* mutex = comIf->getMutex(&timeoutType, &timeoutMs);
|
case 0x7E:
|
||||||
if(mutex == nullptr or gpioIF == nullptr) {
|
writeBuffer[0] = 0x7D;
|
||||||
sif::debug << "rwSpiCallback::spiCallback: Mutex or GPIO interface invalid" << std::endl;
|
writeBuffer[1] = 0x5E;
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
writeSize = 2;
|
||||||
}
|
break;
|
||||||
|
case 0x7D:
|
||||||
int fileDescriptor = 0;
|
writeBuffer[0] = 0x7D;
|
||||||
std::string device = cookie->getSpiDevice();
|
writeBuffer[1] = 0x5D;
|
||||||
UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "rwSpiCallback::spiCallback");
|
writeSize = 2;
|
||||||
if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) {
|
break;
|
||||||
sif::error << "rwSpiCallback::spiCallback: Failed to open device file" << std::endl;
|
default:
|
||||||
return SpiComIF::OPENING_FILE_FAILED;
|
writeBuffer[0] = *(sendData + idx);
|
||||||
|
writeSize = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
|
|
||||||
uint32_t spiSpeed = 0;
|
|
||||||
cookie->getSpiParameters(spiMode, spiSpeed, nullptr);
|
|
||||||
comIf->setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
|
|
||||||
|
|
||||||
result = mutex->lockMutex(timeoutType, timeoutMs);
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
sif::debug << "rwSpiCallback::spiCallback: Failed to lock mutex" << std::endl;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sending frame start sign */
|
|
||||||
writeBuffer[0] = 0x7E;
|
|
||||||
writeSize = 1;
|
|
||||||
|
|
||||||
// Pull SPI CS low. For now, no support for active high given
|
|
||||||
if(gpioId != gpio::NO_GPIO) {
|
|
||||||
if(gpioIF->pullLow(gpioId) != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
sif::error << "rwSpiCallback::spiCallback: Failed to pull chip select low" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (write(fileDescriptor, writeBuffer, writeSize) != static_cast<ssize_t>(writeSize)) {
|
if (write(fileDescriptor, writeBuffer, writeSize) != static_cast<ssize_t>(writeSize)) {
|
||||||
sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl;
|
sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl;
|
||||||
|
closeSpi(gpioId, gpioIF, mutex);
|
||||||
|
return RwHandler::SPI_WRITE_FAILURE;
|
||||||
|
}
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sending frame end sign */
|
||||||
|
writeBuffer[0] = 0x7E;
|
||||||
|
writeSize = 1;
|
||||||
|
|
||||||
|
if (write(fileDescriptor, writeBuffer, writeSize) != static_cast<ssize_t>(writeSize)) {
|
||||||
|
sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl;
|
||||||
|
closeSpi(gpioId, gpioIF, mutex);
|
||||||
|
return RwHandler::SPI_WRITE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* rxBuf = nullptr;
|
||||||
|
result = comIf->getReadBuffer(cookie->getSpiAddress(), &rxBuf);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
closeSpi(gpioId, gpioIF, mutex);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t replyBufferSize = cookie->getMaxBufferSize();
|
||||||
|
|
||||||
|
/** There must be a delay of at least 20 ms after sending the command */
|
||||||
|
usleep(RwDefinitions::SPI_REPLY_DELAY);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The reaction wheel responds with empty frames while preparing the reply data.
|
||||||
|
* However, receiving more than 5 empty frames will be interpreted as an error.
|
||||||
|
*/
|
||||||
|
uint8_t byteRead = 0;
|
||||||
|
for (int idx = 0; idx < 10; idx++) {
|
||||||
|
if (read(fileDescriptor, &byteRead, 1) != 1) {
|
||||||
|
sif::error << "rwSpiCallback::spiCallback: Read failed" << std::endl;
|
||||||
|
closeSpi(gpioId, gpioIF, mutex);
|
||||||
|
return RwHandler::SPI_READ_FAILURE;
|
||||||
|
}
|
||||||
|
if (idx == 0) {
|
||||||
|
if (byteRead != FLAG_BYTE) {
|
||||||
|
sif::error << "Invalid data, expected start marker" << std::endl;
|
||||||
closeSpi(gpioId, gpioIF, mutex);
|
closeSpi(gpioId, gpioIF, mutex);
|
||||||
return RwHandler::SPI_WRITE_FAILURE;
|
return RwHandler::NO_START_MARKER;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Encoding and sending command */
|
if (byteRead != FLAG_BYTE) {
|
||||||
size_t idx = 0;
|
break;
|
||||||
while(idx < sendLen) {
|
|
||||||
switch(*(sendData + idx)) {
|
|
||||||
case 0x7E:
|
|
||||||
writeBuffer[0] = 0x7D;
|
|
||||||
writeBuffer[1] = 0x5E;
|
|
||||||
writeSize = 2;
|
|
||||||
break;
|
|
||||||
case 0x7D:
|
|
||||||
writeBuffer[0] = 0x7D;
|
|
||||||
writeBuffer[1] = 0x5D;
|
|
||||||
writeSize = 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
writeBuffer[0] = *(sendData + idx);
|
|
||||||
writeSize = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (write(fileDescriptor, writeBuffer, writeSize) != static_cast<ssize_t>(writeSize)) {
|
|
||||||
sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl;
|
|
||||||
closeSpi(gpioId, gpioIF, mutex);
|
|
||||||
return RwHandler::SPI_WRITE_FAILURE;
|
|
||||||
}
|
|
||||||
idx++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sending frame end sign */
|
if (idx == 9) {
|
||||||
writeBuffer[0] = 0x7E;
|
sif::error << "rwSpiCallback::spiCallback: Empty frame timeout" << std::endl;
|
||||||
writeSize = 1;
|
closeSpi(gpioId, gpioIF, mutex);
|
||||||
|
return RwHandler::NO_REPLY;
|
||||||
if (write(fileDescriptor, writeBuffer, writeSize) != static_cast<ssize_t>(writeSize)) {
|
|
||||||
sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl;
|
|
||||||
closeSpi(gpioId, gpioIF, mutex);
|
|
||||||
return RwHandler::SPI_WRITE_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* rxBuf = nullptr;
|
|
||||||
result = comIf->getReadBuffer(cookie->getSpiAddress(), &rxBuf);
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
closeSpi(gpioId, gpioIF, mutex);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t replyBufferSize = cookie->getMaxBufferSize();
|
|
||||||
|
|
||||||
/** There must be a delay of at least 20 ms after sending the command */
|
|
||||||
usleep(RwDefinitions::SPI_REPLY_DELAY);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The reaction wheel responds with empty frames while preparing the reply data.
|
|
||||||
* However, receiving more than 5 empty frames will be interpreted as an error.
|
|
||||||
*/
|
|
||||||
uint8_t byteRead = 0;
|
|
||||||
for (int idx = 0; idx < 10; idx++) {
|
|
||||||
if(read(fileDescriptor, &byteRead, 1) != 1) {
|
|
||||||
sif::error << "rwSpiCallback::spiCallback: Read failed" << std::endl;
|
|
||||||
closeSpi(gpioId, gpioIF, mutex);
|
|
||||||
return RwHandler::SPI_READ_FAILURE;
|
|
||||||
}
|
|
||||||
if(idx == 0) {
|
|
||||||
if(byteRead != FLAG_BYTE) {
|
|
||||||
sif::error << "Invalid data, expected start marker" << std::endl;
|
|
||||||
closeSpi(gpioId, gpioIF, mutex);
|
|
||||||
return RwHandler::NO_START_MARKER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (byteRead != FLAG_BYTE) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (idx == 9) {
|
|
||||||
sif::error << "rwSpiCallback::spiCallback: Empty frame timeout" << std::endl;
|
|
||||||
closeSpi(gpioId, gpioIF, mutex);
|
|
||||||
return RwHandler::NO_REPLY;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if FSFW_HAL_SPI_WIRETAPPING == 1
|
#if FSFW_HAL_SPI_WIRETAPPING == 1
|
||||||
sif::info << "RW start marker detected" << std::endl;
|
sif::info << "RW start marker detected" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t decodedFrameLen = 0;
|
size_t decodedFrameLen = 0;
|
||||||
while(decodedFrameLen < replyBufferSize) {
|
while (decodedFrameLen < replyBufferSize) {
|
||||||
|
/** First byte already read in */
|
||||||
/** First byte already read in */
|
if (decodedFrameLen != 0) {
|
||||||
if (decodedFrameLen != 0) {
|
byteRead = 0;
|
||||||
byteRead = 0;
|
if (read(fileDescriptor, &byteRead, 1) != 1) {
|
||||||
if(read(fileDescriptor, &byteRead, 1) != 1) {
|
sif::error << "rwSpiCallback::spiCallback: Read failed" << std::endl;
|
||||||
sif::error << "rwSpiCallback::spiCallback: Read failed" << std::endl;
|
result = RwHandler::SPI_READ_FAILURE;
|
||||||
result = RwHandler::SPI_READ_FAILURE;
|
break;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (byteRead == FLAG_BYTE) {
|
|
||||||
/** Reached end of frame */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (byteRead == 0x7D) {
|
|
||||||
if(read(fileDescriptor, &byteRead, 1) != 1) {
|
|
||||||
sif::error << "rwSpiCallback::spiCallback: Read failed" << std::endl;
|
|
||||||
result = RwHandler::SPI_READ_FAILURE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (byteRead == 0x5E) {
|
|
||||||
*(rxBuf + decodedFrameLen) = 0x7E;
|
|
||||||
decodedFrameLen++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (byteRead == 0x5D) {
|
|
||||||
*(rxBuf + decodedFrameLen) = 0x7D;
|
|
||||||
decodedFrameLen++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sif::error << "rwSpiCallback::spiCallback: Invalid substitute" << std::endl;
|
|
||||||
closeSpi(gpioId, gpioIF, mutex);
|
|
||||||
result = RwHandler::INVALID_SUBSTITUTE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*(rxBuf + decodedFrameLen) = byteRead;
|
|
||||||
decodedFrameLen++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* There might be the unlikely case that each byte in a get-telemetry reply has been
|
|
||||||
* replaced by its substitute. Than the next byte must correspond to the end sign 0x7E.
|
|
||||||
* Otherwise there might be something wrong.
|
|
||||||
*/
|
|
||||||
if (decodedFrameLen == replyBufferSize) {
|
|
||||||
if(read(fileDescriptor, &byteRead, 1) != 1) {
|
|
||||||
sif::error << "rwSpiCallback::spiCallback: Failed to read last byte" << std::endl;
|
|
||||||
result = RwHandler::SPI_READ_FAILURE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (byteRead != 0x7E) {
|
|
||||||
sif::error << "rwSpiCallback::spiCallback: Missing end sign 0x7E" << std::endl;
|
|
||||||
decodedFrameLen--;
|
|
||||||
result = RwHandler::MISSING_END_SIGN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result = HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cookie->setTransferSize(decodedFrameLen);
|
if (byteRead == FLAG_BYTE) {
|
||||||
|
/** Reached end of frame */
|
||||||
closeSpi(gpioId, gpioIF, mutex);
|
break;
|
||||||
|
} else if (byteRead == 0x7D) {
|
||||||
return result;
|
if (read(fileDescriptor, &byteRead, 1) != 1) {
|
||||||
}
|
sif::error << "rwSpiCallback::spiCallback: Read failed" << std::endl;
|
||||||
|
result = RwHandler::SPI_READ_FAILURE;
|
||||||
void closeSpi (gpioId_t gpioId, GpioIF* gpioIF, MutexIF* mutex) {
|
break;
|
||||||
if(gpioId != gpio::NO_GPIO) {
|
}
|
||||||
if (gpioIF->pullHigh(gpioId) != HasReturnvaluesIF::RETURN_OK) {
|
if (byteRead == 0x5E) {
|
||||||
sif::error << "closeSpi: Failed to pull chip select high" << std::endl;
|
*(rxBuf + decodedFrameLen) = 0x7E;
|
||||||
}
|
decodedFrameLen++;
|
||||||
|
continue;
|
||||||
|
} else if (byteRead == 0x5D) {
|
||||||
|
*(rxBuf + decodedFrameLen) = 0x7D;
|
||||||
|
decodedFrameLen++;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
sif::error << "rwSpiCallback::spiCallback: Invalid substitute" << std::endl;
|
||||||
|
closeSpi(gpioId, gpioIF, mutex);
|
||||||
|
result = RwHandler::INVALID_SUBSTITUTE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*(rxBuf + decodedFrameLen) = byteRead;
|
||||||
|
decodedFrameLen++;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
if(mutex->unlockMutex() != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
sif::error << "rwSpiCallback::closeSpi: Failed to unlock mutex" << std::endl;;
|
/**
|
||||||
|
* There might be the unlikely case that each byte in a get-telemetry reply has been
|
||||||
|
* replaced by its substitute. Than the next byte must correspond to the end sign 0x7E.
|
||||||
|
* Otherwise there might be something wrong.
|
||||||
|
*/
|
||||||
|
if (decodedFrameLen == replyBufferSize) {
|
||||||
|
if (read(fileDescriptor, &byteRead, 1) != 1) {
|
||||||
|
sif::error << "rwSpiCallback::spiCallback: Failed to read last byte" << std::endl;
|
||||||
|
result = RwHandler::SPI_READ_FAILURE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (byteRead != 0x7E) {
|
||||||
|
sif::error << "rwSpiCallback::spiCallback: Missing end sign 0x7E" << std::endl;
|
||||||
|
decodedFrameLen--;
|
||||||
|
result = RwHandler::MISSING_END_SIGN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
result = HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
cookie->setTransferSize(decodedFrameLen);
|
||||||
|
|
||||||
|
closeSpi(gpioId, gpioIF, mutex);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void closeSpi(gpioId_t gpioId, GpioIF* gpioIF, MutexIF* mutex) {
|
||||||
|
if (gpioId != gpio::NO_GPIO) {
|
||||||
|
if (gpioIF->pullHigh(gpioId) != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::error << "closeSpi: Failed to pull chip select high" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mutex->unlockMutex() != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::error << "rwSpiCallback::closeSpi: Failed to unlock mutex" << std::endl;
|
||||||
|
;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} // namespace rwSpiCallback
|
||||||
|
@ -2,9 +2,8 @@
|
|||||||
#define BSP_Q7S_RW_SPI_CALLBACK_H_
|
#define BSP_Q7S_RW_SPI_CALLBACK_H_
|
||||||
|
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "fsfw_hal/linux/spi/SpiComIF.h"
|
|
||||||
#include "fsfw_hal/common/gpio/GpioCookie.h"
|
#include "fsfw_hal/common/gpio/GpioCookie.h"
|
||||||
|
#include "fsfw_hal/linux/spi/SpiComIF.h"
|
||||||
|
|
||||||
namespace rwSpiCallback {
|
namespace rwSpiCallback {
|
||||||
|
|
||||||
@ -31,8 +30,8 @@ static constexpr uint8_t FLAG_BYTE = 0x7E;
|
|||||||
* To switch between the to SPI peripherals, an EMIO is used which will also be controlled
|
* To switch between the to SPI peripherals, an EMIO is used which will also be controlled
|
||||||
* by this function.
|
* by this function.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie *cookie, const uint8_t *sendData,
|
ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sendData,
|
||||||
size_t sendLen, void* args);
|
size_t sendLen, void* args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function closes a spi session. Pulls the chip select to high an releases the
|
* @brief This function closes a spi session. Pulls the chip select to high an releases the
|
||||||
@ -43,5 +42,5 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie *cookie, const uint8_t *sen
|
|||||||
*/
|
*/
|
||||||
void closeSpi(gpioId_t gpioId, GpioIF* gpioIF, MutexIF* mutex);
|
void closeSpi(gpioId_t gpioId, GpioIF* gpioIF, MutexIF* mutex);
|
||||||
|
|
||||||
}
|
} // namespace rwSpiCallback
|
||||||
#endif /* BSP_Q7S_RW_SPI_CALLBACK_H_ */
|
#endif /* BSP_Q7S_RW_SPI_CALLBACK_H_ */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2,183 +2,167 @@
|
|||||||
#define BSP_Q7S_CORE_CORECONTROLLER_H_
|
#define BSP_Q7S_CORE_CORECONTROLLER_H_
|
||||||
|
|
||||||
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
||||||
#include "fsfw/controller/ExtendedControllerBase.h"
|
|
||||||
#include "bsp_q7s/memory/SdCardManager.h"
|
#include "bsp_q7s/memory/SdCardManager.h"
|
||||||
|
|
||||||
#include "events/subsystemIdRanges.h"
|
#include "events/subsystemIdRanges.h"
|
||||||
|
#include "fsfw/controller/ExtendedControllerBase.h"
|
||||||
|
|
||||||
class Timer;
|
class Timer;
|
||||||
class SdCardManager;
|
class SdCardManager;
|
||||||
|
|
||||||
class CoreController: public ExtendedControllerBase {
|
class CoreController : public ExtendedControllerBase {
|
||||||
public:
|
public:
|
||||||
enum Chip: uint8_t {
|
enum Chip : uint8_t { CHIP_0, CHIP_1, NO_CHIP, SELF_CHIP, ALL_CHIP };
|
||||||
CHIP_0,
|
|
||||||
CHIP_1,
|
|
||||||
NO_CHIP,
|
|
||||||
SELF_CHIP,
|
|
||||||
ALL_CHIP
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Copy: uint8_t {
|
enum Copy : uint8_t { COPY_0, COPY_1, NO_COPY, SELF_COPY, ALL_COPY };
|
||||||
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 VERSION_FILE[] = "/conf/sd_status";
|
||||||
|
|
||||||
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
|
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
|
||||||
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);
|
CoreController(object_id_t objectId);
|
||||||
|
virtual ~CoreController();
|
||||||
|
|
||||||
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
CoreController(object_id_t objectId);
|
ReturnValue_t initializeAfterTaskCreation() override;
|
||||||
virtual~ CoreController();
|
|
||||||
|
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
|
const uint8_t* data, size_t size) override;
|
||||||
|
|
||||||
ReturnValue_t initializeAfterTaskCreation() override;
|
ReturnValue_t handleCommandMessage(CommandMessage* message) override;
|
||||||
|
void performControlOperation() override;
|
||||||
|
|
||||||
ReturnValue_t executeAction(ActionId_t actionId,
|
/**
|
||||||
MessageQueueId_t commandedBy, const uint8_t *data, size_t size) override;
|
* Generate a file containing the chip lock/unlock states inside /tmp/chip_prot_status.txt
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static ReturnValue_t generateChipStateFile();
|
||||||
|
static ReturnValue_t incrementAllocationFailureCount();
|
||||||
|
static void getCurrentBootCopy(Chip& chip, Copy& copy);
|
||||||
|
|
||||||
ReturnValue_t handleCommandMessage(CommandMessage *message) override;
|
ReturnValue_t updateProtInfo(bool regenerateChipStateFile = true);
|
||||||
void performControlOperation() override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a file containing the chip lock/unlock states inside /tmp/chip_prot_status.txt
|
* Checks whether the target chip and copy are write protected and protect set them to a target
|
||||||
* @return
|
* state where applicable.
|
||||||
*/
|
* @param targetChip
|
||||||
static ReturnValue_t generateChipStateFile();
|
* @param targetCopy
|
||||||
static ReturnValue_t incrementAllocationFailureCount();
|
* @param protect Target state
|
||||||
static void getCurrentBootCopy(Chip& chip, Copy& copy);
|
* @param protOperationPerformed [out] Can be used to determine whether any operation
|
||||||
|
* was performed
|
||||||
|
* @param updateProtFile Specify whether the protection info file is updated
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ReturnValue_t setBootCopyProtection(Chip targetChip, Copy targetCopy, bool protect,
|
||||||
|
bool& protOperationPerformed, bool updateProtFile = true);
|
||||||
|
|
||||||
ReturnValue_t updateProtInfo(bool regenerateChipStateFile = true);
|
bool sdInitFinished() const;
|
||||||
|
|
||||||
/**
|
private:
|
||||||
* Checks whether the target chip and copy are write protected and protect set them to a target
|
static Chip CURRENT_CHIP;
|
||||||
* state where applicable.
|
static Copy CURRENT_COPY;
|
||||||
* @param targetChip
|
|
||||||
* @param targetCopy
|
|
||||||
* @param protect Target state
|
|
||||||
* @param protOperationPerformed [out] Can be used to determine whether any operation
|
|
||||||
* was performed
|
|
||||||
* @param updateProtFile Specify whether the protection info file is updated
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ReturnValue_t setBootCopyProtection(Chip targetChip, Copy targetCopy,
|
|
||||||
bool protect, bool& protOperationPerformed, bool updateProtFile = true);
|
|
||||||
|
|
||||||
bool sdInitFinished() const;
|
// Designated value for rechecking FIFO open
|
||||||
|
static constexpr int RETRY_FIFO_OPEN = -2;
|
||||||
|
int watchdogFifoFd = 0;
|
||||||
|
|
||||||
private:
|
// States for SD state machine, which is used in non-blocking mode
|
||||||
static Chip CURRENT_CHIP;
|
enum class SdStates {
|
||||||
static Copy CURRENT_COPY;
|
NONE,
|
||||||
|
START,
|
||||||
|
GET_INFO,
|
||||||
|
SET_STATE_SELF,
|
||||||
|
MOUNT_SELF,
|
||||||
|
// Determine operations for other SD card, depending on redundancy configuration
|
||||||
|
DETERMINE_OTHER,
|
||||||
|
SET_STATE_OTHER,
|
||||||
|
// Mount or unmount other
|
||||||
|
MOUNT_UNMOUNT_OTHER,
|
||||||
|
// Skip period because the shell command used to generate the info file sometimes is
|
||||||
|
// missing the last performed operation if executed too early
|
||||||
|
SKIP_CYCLE_BEFORE_INFO_UPDATE,
|
||||||
|
UPDATE_INFO,
|
||||||
|
// SD initialization done
|
||||||
|
IDLE,
|
||||||
|
// Used if SD switches or mount commands are issued via telecommand
|
||||||
|
SET_STATE_FROM_COMMAND,
|
||||||
|
};
|
||||||
|
static constexpr bool BLOCKING_SD_INIT = false;
|
||||||
|
|
||||||
// Designated value for rechecking FIFO open
|
SdCardManager* sdcMan = nullptr;
|
||||||
static constexpr int RETRY_FIFO_OPEN = -2;
|
|
||||||
int watchdogFifoFd = 0;
|
|
||||||
|
|
||||||
// States for SD state machine, which is used in non-blocking mode
|
struct SdInfo {
|
||||||
enum class SdStates {
|
sd::SdCard pref = sd::SdCard::NONE;
|
||||||
NONE,
|
sd::SdState prefState = sd::SdState::OFF;
|
||||||
START,
|
sd::SdCard other = sd::SdCard::NONE;
|
||||||
GET_INFO,
|
sd::SdState otherState = sd::SdState::OFF;
|
||||||
SET_STATE_SELF,
|
std::string prefChar = "0";
|
||||||
MOUNT_SELF,
|
std::string otherChar = "1";
|
||||||
// Determine operations for other SD card, depending on redundancy configuration
|
SdStates state = SdStates::START;
|
||||||
DETERMINE_OTHER,
|
// Used to track whether a command was executed
|
||||||
SET_STATE_OTHER,
|
bool commandExecuted = true;
|
||||||
// Mount or unmount other
|
bool initFinished = false;
|
||||||
MOUNT_UNMOUNT_OTHER,
|
SdCardManager::SdStatePair currentState;
|
||||||
// Skip period because the shell command used to generate the info file sometimes is
|
uint16_t cycleCount = 0;
|
||||||
// missing the last performed operation if executed too early
|
// These two flags are related to external commanding
|
||||||
SKIP_CYCLE_BEFORE_INFO_UPDATE,
|
bool commandIssued = false;
|
||||||
UPDATE_INFO,
|
bool commandFinished = false;
|
||||||
// SD initialization done
|
sd::SdState currentlyCommandedState = sd::SdState::OFF;
|
||||||
IDLE,
|
sd::SdCard commandedCard = sd::SdCard::NONE;
|
||||||
// Used if SD switches or mount commands are issued via telecommand
|
sd::SdState commandedState = sd::SdState::OFF;
|
||||||
SET_STATE_FROM_COMMAND,
|
};
|
||||||
};
|
SdInfo sdInfo;
|
||||||
static constexpr bool BLOCKING_SD_INIT = false;
|
|
||||||
|
|
||||||
SdCardManager* sdcMan = nullptr;
|
/**
|
||||||
|
* Index 0: Chip 0 Copy 0
|
||||||
|
* Index 1: Chip 0 Copy 1
|
||||||
|
* Index 2: Chip 1 Copy 0
|
||||||
|
* Index 3: Chip 1 Copy 1
|
||||||
|
*/
|
||||||
|
std::array<bool, 4> protArray;
|
||||||
|
PeriodicOperationDivider opDivider;
|
||||||
|
|
||||||
struct SdInfo {
|
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
sd::SdCard pref = sd::SdCard::NONE;
|
LocalDataPoolManager& poolManager) override;
|
||||||
sd::SdState prefState = sd::SdState::OFF;
|
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
||||||
sd::SdCard other = sd::SdCard::NONE;
|
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode, uint32_t* msToReachTheMode);
|
||||||
sd::SdState otherState = sd::SdState::OFF;
|
|
||||||
std::string prefChar = "0";
|
|
||||||
std::string otherChar = "1";
|
|
||||||
SdStates state = SdStates::START;
|
|
||||||
// Used to track whether a command was executed
|
|
||||||
bool commandExecuted = true;
|
|
||||||
bool initFinished = false;
|
|
||||||
SdCardManager::SdStatePair currentState;
|
|
||||||
uint16_t cycleCount = 0;
|
|
||||||
// These two flags are related to external commanding
|
|
||||||
bool commandIssued = false;
|
|
||||||
bool commandFinished = false;
|
|
||||||
sd::SdState currentlyCommandedState = sd::SdState::OFF;
|
|
||||||
sd::SdCard commandedCard = sd::SdCard::NONE;
|
|
||||||
sd::SdState commandedState = sd::SdState::OFF;
|
|
||||||
};
|
|
||||||
SdInfo sdInfo;
|
|
||||||
|
|
||||||
/**
|
ReturnValue_t initVersionFile();
|
||||||
* Index 0: Chip 0 Copy 0
|
ReturnValue_t initBootCopy();
|
||||||
* Index 1: Chip 0 Copy 1
|
ReturnValue_t initWatchdogFifo();
|
||||||
* Index 2: Chip 1 Copy 0
|
ReturnValue_t initSdCardBlocking();
|
||||||
* Index 3: Chip 1 Copy 1
|
void initPrint();
|
||||||
*/
|
|
||||||
std::array<bool, 4> protArray;
|
|
||||||
PeriodicOperationDivider opDivider;
|
|
||||||
|
|
||||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
ReturnValue_t sdStateMachine();
|
||||||
LocalDataPoolManager& poolManager) override;
|
void updateSdInfoOther();
|
||||||
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar,
|
||||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
bool printOutput = true);
|
||||||
uint32_t *msToReachTheMode);
|
ReturnValue_t sdColdRedundantBlockingInit();
|
||||||
|
void currentStateSetter(sd::SdCard sdCard, sd::SdState newState);
|
||||||
|
void determinePreferredSdCard();
|
||||||
|
void executeNextExternalSdCommand();
|
||||||
|
void checkExternalSdCommandStatus();
|
||||||
|
|
||||||
ReturnValue_t initVersionFile();
|
ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
ReturnValue_t initBootCopy();
|
const uint8_t* data, size_t size);
|
||||||
ReturnValue_t initWatchdogFifo();
|
ReturnValue_t actionPerformReboot(const uint8_t* data, size_t size);
|
||||||
ReturnValue_t initSdCardBlocking();
|
|
||||||
void initPrint();
|
|
||||||
|
|
||||||
ReturnValue_t sdStateMachine();
|
void performWatchdogControlOperation();
|
||||||
void updateSdInfoOther();
|
|
||||||
ReturnValue_t sdCardSetup(sd::SdCard sdCard, sd::SdState targetState, std::string sdChar,
|
|
||||||
bool printOutput = true);
|
|
||||||
ReturnValue_t sdColdRedundantBlockingInit();
|
|
||||||
void currentStateSetter(sd::SdCard sdCard, sd::SdState newState);
|
|
||||||
void determinePreferredSdCard();
|
|
||||||
void executeNextExternalSdCommand();
|
|
||||||
void checkExternalSdCommandStatus();
|
|
||||||
|
|
||||||
ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy,
|
ReturnValue_t handleProtInfoUpdateLine(std::string nextLine);
|
||||||
const uint8_t *data, size_t size);
|
int handleBootCopyProtAtIndex(Chip targetChip, Copy targetCopy, bool protect,
|
||||||
ReturnValue_t actionPerformReboot(const uint8_t *data, size_t size);
|
bool& protOperationPerformed, bool selfChip, bool selfCopy,
|
||||||
|
bool allChips, bool allCopies, uint8_t arrIdx);
|
||||||
void performWatchdogControlOperation();
|
|
||||||
|
|
||||||
ReturnValue_t handleProtInfoUpdateLine(std::string nextLine);
|
|
||||||
int handleBootCopyProtAtIndex(Chip targetChip, Copy targetCopy, bool protect,
|
|
||||||
bool &protOperationPerformed, bool selfChip, bool selfCopy, bool allChips,
|
|
||||||
bool allCopies, uint8_t arrIdx);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* BSP_Q7S_CORE_CORECONTROLLER_H_ */
|
#endif /* BSP_Q7S_CORE_CORECONTROLLER_H_ */
|
||||||
|
@ -1,22 +1,21 @@
|
|||||||
#include "InitMission.h"
|
#include "InitMission.h"
|
||||||
#include "ObjectFactory.h"
|
|
||||||
#include "OBSWConfig.h"
|
|
||||||
#include "pollingsequence/pollingSequenceFactory.h"
|
|
||||||
|
|
||||||
#include "mission/utility/InitMission.h"
|
|
||||||
|
|
||||||
#include "fsfw/platform.h"
|
|
||||||
#include "fsfw/objectmanager/ObjectManagerIF.h"
|
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
|
||||||
#include "fsfw/serviceinterface/ServiceInterfaceStream.h"
|
|
||||||
#include "fsfw/objectmanager/ObjectManager.h"
|
|
||||||
#include "fsfw/tasks/FixedTimeslotTaskIF.h"
|
|
||||||
#include "fsfw/tasks/PeriodicTaskIF.h"
|
|
||||||
#include "fsfw/tasks/TaskFactory.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "OBSWConfig.h"
|
||||||
|
#include "ObjectFactory.h"
|
||||||
|
#include "fsfw/objectmanager/ObjectManager.h"
|
||||||
|
#include "fsfw/objectmanager/ObjectManagerIF.h"
|
||||||
|
#include "fsfw/platform.h"
|
||||||
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
|
#include "fsfw/serviceinterface/ServiceInterfaceStream.h"
|
||||||
|
#include "fsfw/tasks/FixedTimeslotTaskIF.h"
|
||||||
|
#include "fsfw/tasks/PeriodicTaskIF.h"
|
||||||
|
#include "fsfw/tasks/TaskFactory.h"
|
||||||
|
#include "mission/utility/InitMission.h"
|
||||||
|
#include "pollingsequence/pollingSequenceFactory.h"
|
||||||
|
|
||||||
/* This is configured for linux without CR */
|
/* This is configured for linux without CR */
|
||||||
#ifdef PLATFORM_UNIX
|
#ifdef PLATFORM_UNIX
|
||||||
ServiceInterfaceStream sif::debug("DEBUG");
|
ServiceInterfaceStream sif::debug("DEBUG");
|
||||||
@ -30,344 +29,343 @@ ServiceInterfaceStream sif::warning("WARNING", true);
|
|||||||
ServiceInterfaceStream sif::error("ERROR", true, false, true);
|
ServiceInterfaceStream sif::error("ERROR", true, false, true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ObjectManagerIF *objectManager = nullptr;
|
ObjectManagerIF* objectManager = nullptr;
|
||||||
|
|
||||||
void initmission::initMission() {
|
void initmission::initMission() {
|
||||||
|
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();
|
||||||
|
|
||||||
sif::info << "Building global objects.." << std::endl;
|
/* This function creates and starts all tasks */
|
||||||
/* Instantiate global object manager and also create all objects */
|
initTasks();
|
||||||
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() {
|
void initmission::initTasks() {
|
||||||
TaskFactory* factory = TaskFactory::instance();
|
TaskFactory* factory = TaskFactory::instance();
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
if(factory == nullptr) {
|
if (factory == nullptr) {
|
||||||
/* Should never happen ! */
|
/* Should never happen ! */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if OBSW_PRINT_MISSED_DEADLINES == 1
|
#if OBSW_PRINT_MISSED_DEADLINES == 1
|
||||||
void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline;
|
void (*missedDeadlineFunc)(void) = TaskFactory::printMissedDeadline;
|
||||||
#else
|
#else
|
||||||
void (*missedDeadlineFunc) (void) = nullptr;
|
void (*missedDeadlineFunc)(void) = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BOARD_TE0720 == 0
|
#if BOARD_TE0720 == 0
|
||||||
PeriodicTaskIF* coreController = factory->createPeriodicTask(
|
PeriodicTaskIF* coreController = factory->createPeriodicTask(
|
||||||
"CORE_CTRL", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc);
|
"CORE_CTRL", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc);
|
||||||
result = coreController->addComponent(objects::CORE_CONTROLLER);
|
result = coreController->addComponent(objects::CORE_CONTROLLER);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("CORE_CTRL", objects::CORE_CONTROLLER);
|
initmission::printAddObjectError("CORE_CTRL", objects::CORE_CONTROLLER);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* TMTC Distribution */
|
/* TMTC Distribution */
|
||||||
PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
|
PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
|
||||||
"DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
"DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
||||||
result = tmTcDistributor->addComponent(objects::CCSDS_PACKET_DISTRIBUTOR);
|
result = tmTcDistributor->addComponent(objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("CCSDS_DISTRIB", objects::CCSDS_PACKET_DISTRIBUTOR);
|
initmission::printAddObjectError("CCSDS_DISTRIB", objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||||
}
|
}
|
||||||
result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
|
result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS_PACKET_DISTRIB", objects::PUS_PACKET_DISTRIBUTOR);
|
initmission::printAddObjectError("PUS_PACKET_DISTRIB", objects::PUS_PACKET_DISTRIBUTOR);
|
||||||
}
|
}
|
||||||
result = tmTcDistributor->addComponent(objects::TM_FUNNEL);
|
result = tmTcDistributor->addComponent(objects::TM_FUNNEL);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("TM_FUNNEL", objects::TM_FUNNEL);
|
initmission::printAddObjectError("TM_FUNNEL", objects::TM_FUNNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OBSW_ADD_TCPIP_BRIDGE == 1
|
#if OBSW_ADD_TCPIP_BRIDGE == 1
|
||||||
// TMTC bridge
|
// TMTC bridge
|
||||||
PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask(
|
PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask(
|
||||||
"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("UDP_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);
|
||||||
result = tmtcPollingTask->addComponent(objects::TMTC_POLLING_TASK);
|
result = tmtcPollingTask->addComponent(objects::TMTC_POLLING_TASK);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("UDP_POLLING", objects::TMTC_POLLING_TASK);
|
initmission::printAddObjectError("UDP_POLLING", objects::TMTC_POLLING_TASK);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if OBSW_USE_CCSDS_IP_CORE == 1
|
#if OBSW_USE_CCSDS_IP_CORE == 1
|
||||||
PeriodicTaskIF* ccsdsHandlerTask = factory->createPeriodicTask(
|
PeriodicTaskIF* ccsdsHandlerTask = factory->createPeriodicTask(
|
||||||
"CCSDS_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
"CCSDS_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
||||||
result = ccsdsHandlerTask->addComponent(objects::CCSDS_HANDLER);
|
result = ccsdsHandlerTask->addComponent(objects::CCSDS_HANDLER);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("CCSDS Handler", objects::CCSDS_HANDLER);
|
initmission::printAddObjectError("CCSDS Handler", objects::CCSDS_HANDLER);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Minimal distance between two received TCs amounts to 0.6 seconds
|
// Minimal distance between two received TCs amounts to 0.6 seconds
|
||||||
// If a command has not been read before the next one arrives, the old command will be
|
// If a command has not been read before the next one arrives, the old command will be
|
||||||
// overwritten by the PDEC.
|
// overwritten by the PDEC.
|
||||||
PeriodicTaskIF* pdecHandlerTask = factory->createPeriodicTask(
|
PeriodicTaskIF* pdecHandlerTask = factory->createPeriodicTask(
|
||||||
"PDEC_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, missedDeadlineFunc);
|
"PDEC_HANDLER", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, missedDeadlineFunc);
|
||||||
result = pdecHandlerTask->addComponent(objects::PDEC_HANDLER);
|
result = pdecHandlerTask->addComponent(objects::PDEC_HANDLER);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PDEC Handler", objects::PDEC_HANDLER);
|
initmission::printAddObjectError("PDEC Handler", objects::PDEC_HANDLER);
|
||||||
}
|
}
|
||||||
#endif /* OBSW_USE_CCSDS_IP_CORE == 1 */
|
#endif /* OBSW_USE_CCSDS_IP_CORE == 1 */
|
||||||
|
|
||||||
PeriodicTaskIF* acsCtrl = factory->createPeriodicTask(
|
PeriodicTaskIF* acsCtrl = factory->createPeriodicTask(
|
||||||
"ACS_CTRL", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc);
|
"ACS_CTRL", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc);
|
||||||
result = acsCtrl->addComponent(objects::GPS_CONTROLLER);
|
result = acsCtrl->addComponent(objects::GPS_CONTROLLER);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("ACS_CTRL", objects::GPS_CONTROLLER);
|
initmission::printAddObjectError("ACS_CTRL", objects::GPS_CONTROLLER);
|
||||||
}
|
}
|
||||||
|
|
||||||
# if BOARD_TE0720 == 0
|
#if BOARD_TE0720 == 0
|
||||||
// FS task, task interval does not matter because it runs in permanent loop, priority low
|
// FS task, task interval does not matter because it runs in permanent loop, priority low
|
||||||
// because it is a non-essential background task
|
// because it is a non-essential background task
|
||||||
PeriodicTaskIF* fsTask = factory->createPeriodicTask(
|
PeriodicTaskIF* fsTask = factory->createPeriodicTask(
|
||||||
"FILE_SYSTEM_TASK", 25, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc);
|
"FILE_SYSTEM_TASK", 25, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.4, missedDeadlineFunc);
|
||||||
result = fsTask->addComponent(objects::FILE_SYSTEM_HANDLER);
|
result = fsTask->addComponent(objects::FILE_SYSTEM_HANDLER);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("FILE_SYSTEM_TASK", objects::FILE_SYSTEM_HANDLER);
|
initmission::printAddObjectError("FILE_SYSTEM_TASK", objects::FILE_SYSTEM_HANDLER);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OBSW_ADD_STAR_TRACKER == 1
|
#if OBSW_ADD_STAR_TRACKER == 1
|
||||||
PeriodicTaskIF* strImgLoaderTask = factory->createPeriodicTask(
|
PeriodicTaskIF* strImgLoaderTask = factory->createPeriodicTask(
|
||||||
"FILE_SYSTEM_TASK", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
"FILE_SYSTEM_TASK", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
||||||
result = strImgLoaderTask->addComponent(objects::STR_HELPER);
|
result = strImgLoaderTask->addComponent(objects::STR_HELPER);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("FILE_SYSTEM_TASK", objects::STR_HELPER);
|
initmission::printAddObjectError("FILE_SYSTEM_TASK", objects::STR_HELPER);
|
||||||
}
|
}
|
||||||
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
||||||
|
|
||||||
#endif /* BOARD_TE0720 */
|
#endif /* BOARD_TE0720 */
|
||||||
|
|
||||||
#if OBSW_TEST_CCSDS_BRIDGE == 1
|
#if OBSW_TEST_CCSDS_BRIDGE == 1
|
||||||
PeriodicTaskIF* ptmeTestTask = factory->createPeriodicTask(
|
PeriodicTaskIF* ptmeTestTask = factory->createPeriodicTask(
|
||||||
"PTME_TEST", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
"PTME_TEST", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
||||||
result = ptmeTestTask->addComponent(objects::CCSDS_IP_CORE_BRIDGE);
|
result = ptmeTestTask->addComponent(objects::CCSDS_IP_CORE_BRIDGE);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PTME_TEST", objects::CCSDS_IP_CORE_BRIDGE);
|
initmission::printAddObjectError("PTME_TEST", objects::CCSDS_IP_CORE_BRIDGE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::vector<PeriodicTaskIF*> pusTasks;
|
std::vector<PeriodicTaskIF*> pusTasks;
|
||||||
createPusTasks(*factory, missedDeadlineFunc, pusTasks);
|
createPusTasks(*factory, missedDeadlineFunc, pusTasks);
|
||||||
std::vector<PeriodicTaskIF*> pstTasks;
|
std::vector<PeriodicTaskIF*> pstTasks;
|
||||||
createPstTasks(*factory, missedDeadlineFunc, pstTasks);
|
createPstTasks(*factory, missedDeadlineFunc, pstTasks);
|
||||||
|
|
||||||
#if OBSW_ADD_TEST_CODE == 1
|
#if OBSW_ADD_TEST_CODE == 1
|
||||||
std::vector<PeriodicTaskIF*> testTasks;
|
std::vector<PeriodicTaskIF*> testTasks;
|
||||||
createTestTasks(*factory, missedDeadlineFunc, testTasks);
|
createTestTasks(*factory, missedDeadlineFunc, testTasks);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto taskStarter = [](std::vector<PeriodicTaskIF*>& taskVector, std::string name) {
|
auto taskStarter = [](std::vector<PeriodicTaskIF*>& taskVector, std::string name) {
|
||||||
for(const auto& task: taskVector) {
|
for (const auto& task : taskVector) {
|
||||||
if(task != nullptr) {
|
if (task != nullptr) {
|
||||||
task->startTask();
|
task->startTask();
|
||||||
}
|
} else {
|
||||||
else {
|
sif::error << "Task in vector " << name << " is invalid!" << std::endl;
|
||||||
sif::error << "Task in vector " << name << " is invalid!" << std::endl;
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
|
|
||||||
sif::info << "Starting tasks.." << std::endl;
|
sif::info << "Starting tasks.." << std::endl;
|
||||||
tmTcDistributor->startTask();
|
tmTcDistributor->startTask();
|
||||||
|
|
||||||
#if OBSW_ADD_TCPIP_BRIDGE == 1
|
#if OBSW_ADD_TCPIP_BRIDGE == 1
|
||||||
tmtcBridgeTask->startTask();
|
tmtcBridgeTask->startTask();
|
||||||
tmtcPollingTask->startTask();
|
tmtcPollingTask->startTask();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if OBSW_USE_CCSDS_IP_CORE == 1
|
#if OBSW_USE_CCSDS_IP_CORE == 1
|
||||||
ccsdsHandlerTask->startTask();
|
ccsdsHandlerTask->startTask();
|
||||||
pdecHandlerTask->startTask();
|
pdecHandlerTask->startTask();
|
||||||
#endif /* OBSW_USE_CCSDS_IP_CORE == 1 */
|
#endif /* OBSW_USE_CCSDS_IP_CORE == 1 */
|
||||||
|
|
||||||
#if BOARD_TE0720 == 0
|
#if BOARD_TE0720 == 0
|
||||||
coreController->startTask();
|
coreController->startTask();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
taskStarter(pstTasks, "PST task vector");
|
taskStarter(pstTasks, "PST task vector");
|
||||||
taskStarter(pusTasks, "PUS task vector");
|
taskStarter(pusTasks, "PUS task vector");
|
||||||
#if OBSW_ADD_TEST_CODE == 1
|
#if OBSW_ADD_TEST_CODE == 1
|
||||||
taskStarter(testTasks, "Test task vector");
|
taskStarter(testTasks, "Test task vector");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if OBSW_TEST_CCSDS_BRIDGE == 1
|
#if OBSW_TEST_CCSDS_BRIDGE == 1
|
||||||
ptmeTestTask->startTask();
|
ptmeTestTask->startTask();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#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();
|
strImgLoaderTask->startTask();
|
||||||
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
acsCtrl->startTask();
|
acsCtrl->startTask();
|
||||||
|
|
||||||
sif::info << "Tasks started.." << std::endl;
|
sif::info << "Tasks started.." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initmission::createPstTasks(TaskFactory& factory,
|
void initmission::createPstTasks(TaskFactory& factory,
|
||||||
TaskDeadlineMissedFunction missedDeadlineFunc, std::vector<PeriodicTaskIF*> &taskVec) {
|
TaskDeadlineMissedFunction missedDeadlineFunc,
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
std::vector<PeriodicTaskIF*>& taskVec) {
|
||||||
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
#if BOARD_TE0720 == 0
|
#if BOARD_TE0720 == 0
|
||||||
/* Polling Sequence Table Default */
|
/* Polling Sequence Table Default */
|
||||||
#if OBSW_ADD_SPI_TEST_CODE == 0
|
#if OBSW_ADD_SPI_TEST_CODE == 0
|
||||||
FixedTimeslotTaskIF* spiPst = factory.createFixedTimeslotTask(
|
FixedTimeslotTaskIF* spiPst = factory.createFixedTimeslotTask(
|
||||||
"PST_TASK_DEFAULT", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.5,
|
"PST_TASK_DEFAULT", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.5, missedDeadlineFunc);
|
||||||
missedDeadlineFunc);
|
result = pst::pstSpi(spiPst);
|
||||||
result = pst::pstSpi(spiPst);
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != FixedTimeslotTaskIF::SLOT_LIST_EMPTY) {
|
||||||
if(result != FixedTimeslotTaskIF::SLOT_LIST_EMPTY) {
|
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
|
||||||
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
taskVec.push_back(spiPst);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
taskVec.push_back(spiPst);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FixedTimeslotTaskIF* uartPst = factory.createFixedTimeslotTask(
|
FixedTimeslotTaskIF* uartPst = factory.createFixedTimeslotTask(
|
||||||
"UART_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc);
|
"UART_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc);
|
||||||
result = pst::pstUart(uartPst);
|
result = pst::pstUart(uartPst);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
|
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
|
||||||
}
|
}
|
||||||
taskVec.push_back(uartPst);
|
taskVec.push_back(uartPst);
|
||||||
FixedTimeslotTaskIF* gpioPst = factory.createFixedTimeslotTask(
|
FixedTimeslotTaskIF* gpioPst = factory.createFixedTimeslotTask(
|
||||||
"GPIO_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc);
|
"GPIO_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc);
|
||||||
result = pst::pstGpio(gpioPst);
|
result = pst::pstGpio(gpioPst);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
|
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
|
||||||
}
|
}
|
||||||
taskVec.push_back(gpioPst);
|
taskVec.push_back(gpioPst);
|
||||||
FixedTimeslotTaskIF* i2cPst = factory.createFixedTimeslotTask(
|
FixedTimeslotTaskIF* i2cPst = factory.createFixedTimeslotTask(
|
||||||
"I2C_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc);
|
"I2C_PST", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 0.2, missedDeadlineFunc);
|
||||||
result = pst::pstI2c(i2cPst);
|
result = pst::pstI2c(i2cPst);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
|
sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
FixedTimeslotTaskIF* gomSpacePstTask = factory.createFixedTimeslotTask(
|
FixedTimeslotTaskIF* gomSpacePstTask = factory.createFixedTimeslotTask(
|
||||||
"GS_PST_TASK", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 1.0, missedDeadlineFunc);
|
"GS_PST_TASK", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 1.0, missedDeadlineFunc);
|
||||||
result = pst::pstGompaceCan(gomSpacePstTask);
|
result = pst::pstGompaceCan(gomSpacePstTask);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::error << "InitMission::initTasks: GomSpace PST initialization failed!" << std::endl;
|
sif::error << "InitMission::initTasks: GomSpace PST initialization failed!" << std::endl;
|
||||||
}
|
}
|
||||||
taskVec.push_back(gomSpacePstTask);
|
taskVec.push_back(gomSpacePstTask);
|
||||||
#else /* BOARD_TE7020 == 0 */
|
#else /* BOARD_TE7020 == 0 */
|
||||||
FixedTimeslotTaskIF * pollingSequenceTaskTE0720 = factory.createFixedTimeslotTask(
|
FixedTimeslotTaskIF* pollingSequenceTaskTE0720 = factory.createFixedTimeslotTask(
|
||||||
"PST_TASK_TE0720", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE * 8, 3.0,
|
"PST_TASK_TE0720", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE * 8, 3.0, missedDeadlineFunc);
|
||||||
missedDeadlineFunc);
|
result = pst::pollingSequenceTE0720(pollingSequenceTaskTE0720);
|
||||||
result = pst::pollingSequenceTE0720(pollingSequenceTaskTE0720);
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
sif::error << "InitMission::initTasks: Creating TE0720 PST failed!" << std::endl;
|
||||||
sif::error << "InitMission::initTasks: Creating TE0720 PST failed!" << std::endl;
|
}
|
||||||
}
|
taskVec.push_back(pollingSequenceTaskTE0720);
|
||||||
taskVec.push_back(pollingSequenceTaskTE0720);
|
|
||||||
#endif /* BOARD_TE7020 == 1 */
|
#endif /* BOARD_TE7020 == 1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
void initmission::createPusTasks(TaskFactory &factory,
|
void initmission::createPusTasks(TaskFactory& factory,
|
||||||
TaskDeadlineMissedFunction missedDeadlineFunc, std::vector<PeriodicTaskIF*> &taskVec) {
|
TaskDeadlineMissedFunction missedDeadlineFunc,
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
std::vector<PeriodicTaskIF*>& taskVec) {
|
||||||
/* PUS Services */
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
PeriodicTaskIF* pusVerification = factory.createPeriodicTask(
|
/* PUS Services */
|
||||||
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
PeriodicTaskIF* pusVerification = factory.createPeriodicTask(
|
||||||
result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
|
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
|
||||||
initmission::printAddObjectError("PUS_VERIF", objects::PUS_SERVICE_1_VERIFICATION);
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
}
|
initmission::printAddObjectError("PUS_VERIF", objects::PUS_SERVICE_1_VERIFICATION);
|
||||||
taskVec.push_back(pusVerification);
|
}
|
||||||
|
taskVec.push_back(pusVerification);
|
||||||
|
|
||||||
PeriodicTaskIF* pusEvents = factory.createPeriodicTask(
|
PeriodicTaskIF* pusEvents = factory.createPeriodicTask(
|
||||||
"PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
"PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
result = pusEvents->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
|
result = pusEvents->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING);
|
initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING);
|
||||||
}
|
}
|
||||||
result = pusEvents->addComponent(objects::EVENT_MANAGER);
|
result = pusEvents->addComponent(objects::EVENT_MANAGER);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS_MGMT", objects::EVENT_MANAGER);
|
initmission::printAddObjectError("PUS_MGMT", objects::EVENT_MANAGER);
|
||||||
}
|
}
|
||||||
taskVec.push_back(pusEvents);
|
taskVec.push_back(pusEvents);
|
||||||
|
|
||||||
PeriodicTaskIF* pusHighPrio = factory.createPeriodicTask(
|
PeriodicTaskIF* pusHighPrio = factory.createPeriodicTask(
|
||||||
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||||
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS_2", objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
initmission::printAddObjectError("PUS_2", objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
||||||
}
|
}
|
||||||
result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
|
result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS_9", objects::PUS_SERVICE_9_TIME_MGMT);
|
initmission::printAddObjectError("PUS_9", objects::PUS_SERVICE_9_TIME_MGMT);
|
||||||
}
|
}
|
||||||
taskVec.push_back(pusHighPrio);
|
taskVec.push_back(pusHighPrio);
|
||||||
|
|
||||||
PeriodicTaskIF* pusMedPrio = factory.createPeriodicTask(
|
PeriodicTaskIF* pusMedPrio = factory.createPeriodicTask(
|
||||||
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
|
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
|
||||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS_8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
initmission::printAddObjectError("PUS_8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
||||||
}
|
}
|
||||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_3_HOUSEKEEPING);
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_3_HOUSEKEEPING);
|
||||||
if(result!=HasReturnvaluesIF::RETURN_OK){
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::error << "Object add component failed" << std::endl;
|
sif::error << "Object add component failed" << std::endl;
|
||||||
}
|
}
|
||||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS_200", objects::PUS_SERVICE_200_MODE_MGMT);
|
initmission::printAddObjectError("PUS_200", objects::PUS_SERVICE_200_MODE_MGMT);
|
||||||
}
|
}
|
||||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS);
|
result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS_20", objects::PUS_SERVICE_20_PARAMETERS);
|
initmission::printAddObjectError("PUS_20", objects::PUS_SERVICE_20_PARAMETERS);
|
||||||
}
|
}
|
||||||
taskVec.push_back(pusMedPrio);
|
taskVec.push_back(pusMedPrio);
|
||||||
|
|
||||||
PeriodicTaskIF* pusLowPrio = factory.createPeriodicTask(
|
PeriodicTaskIF* pusLowPrio = factory.createPeriodicTask(
|
||||||
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
|
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
|
||||||
result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
|
result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PUS_17", objects::PUS_SERVICE_17_TEST);
|
initmission::printAddObjectError("PUS_17", objects::PUS_SERVICE_17_TEST);
|
||||||
}
|
}
|
||||||
result = pusLowPrio->addComponent(objects::INTERNAL_ERROR_REPORTER);
|
result = pusLowPrio->addComponent(objects::INTERNAL_ERROR_REPORTER);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("ERROR_REPORTER", objects::INTERNAL_ERROR_REPORTER);
|
initmission::printAddObjectError("ERROR_REPORTER", objects::INTERNAL_ERROR_REPORTER);
|
||||||
}
|
}
|
||||||
taskVec.push_back(pusLowPrio);
|
taskVec.push_back(pusLowPrio);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initmission::createTestTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc,
|
void initmission::createTestTasks(TaskFactory& factory,
|
||||||
std::vector<PeriodicTaskIF*>& taskVec) {
|
TaskDeadlineMissedFunction missedDeadlineFunc,
|
||||||
#if OBSW_ADD_TEST_TASK == 1 || OBSW_ADD_SPI_TEST_CODE == 1 || (BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1)
|
std::vector<PeriodicTaskIF*>& taskVec) {
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
#if OBSW_ADD_TEST_TASK == 1 || OBSW_ADD_SPI_TEST_CODE == 1 || \
|
||||||
|
(BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1)
|
||||||
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
#endif
|
#endif
|
||||||
PeriodicTaskIF* testTask = factory.createPeriodicTask(
|
PeriodicTaskIF* testTask = factory.createPeriodicTask(
|
||||||
"TEST_TASK", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, missedDeadlineFunc);
|
"TEST_TASK", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, missedDeadlineFunc);
|
||||||
#if OBSW_ADD_TEST_TASK == 1
|
#if OBSW_ADD_TEST_TASK == 1
|
||||||
result = testTask->addComponent(objects::TEST_TASK);
|
result = testTask->addComponent(objects::TEST_TASK);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK);
|
initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK);
|
||||||
}
|
}
|
||||||
#endif /* OBSW_ADD_TEST_TASK == 1 */
|
#endif /* OBSW_ADD_TEST_TASK == 1 */
|
||||||
|
|
||||||
#if OBSW_ADD_SPI_TEST_CODE == 1
|
#if OBSW_ADD_SPI_TEST_CODE == 1
|
||||||
result = testTask->addComponent(objects::SPI_TEST);
|
result = testTask->addComponent(objects::SPI_TEST);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("SPI_TEST", objects::SPI_TEST);
|
initmission::printAddObjectError("SPI_TEST", objects::SPI_TEST);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1
|
#if BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1
|
||||||
result = testTask->addComponent(objects::LIBGPIOD_TEST);
|
result = testTask->addComponent(objects::LIBGPIOD_TEST);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST);
|
initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST);
|
||||||
}
|
}
|
||||||
#endif /* BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1 */
|
#endif /* BOARD_TE0720 == 1 && OBSW_TEST_LIBGPIOD == 1 */
|
||||||
taskVec.push_back(testTask);
|
taskVec.push_back(testTask);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
#ifndef BSP_Q7S_INITMISSION_H_
|
#ifndef BSP_Q7S_INITMISSION_H_
|
||||||
#define BSP_Q7S_INITMISSION_H_
|
#define BSP_Q7S_INITMISSION_H_
|
||||||
|
|
||||||
#include "fsfw/tasks/Typedef.h"
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "fsfw/tasks/Typedef.h"
|
||||||
|
|
||||||
class PeriodicTaskIF;
|
class PeriodicTaskIF;
|
||||||
class TaskFactory;
|
class TaskFactory;
|
||||||
|
|
||||||
@ -12,11 +13,11 @@ void initMission();
|
|||||||
void initTasks();
|
void initTasks();
|
||||||
|
|
||||||
void createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc,
|
void createPstTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc,
|
||||||
std::vector<PeriodicTaskIF*>& taskVec);
|
std::vector<PeriodicTaskIF*>& taskVec);
|
||||||
void createPusTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc,
|
void createPusTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc,
|
||||||
std::vector<PeriodicTaskIF*>& taskVec);
|
std::vector<PeriodicTaskIF*>& taskVec);
|
||||||
void createTestTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc,
|
void createTestTasks(TaskFactory& factory, TaskDeadlineMissedFunction missedDeadlineFunc,
|
||||||
std::vector<PeriodicTaskIF*>& taskVec);
|
std::vector<PeriodicTaskIF*>& taskVec);
|
||||||
};
|
}; // namespace initmission
|
||||||
|
|
||||||
#endif /* BSP_Q7S_INITMISSION_H_ */
|
#endif /* BSP_Q7S_INITMISSION_H_ */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,7 @@ void setStatics();
|
|||||||
void produce(void* args);
|
void produce(void* args);
|
||||||
|
|
||||||
void createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, UartComIF** uartComIF,
|
void createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, UartComIF** uartComIF,
|
||||||
SpiComIF** spiComIF);
|
SpiComIF** spiComIF);
|
||||||
void createTmpComponents();
|
void createTmpComponents();
|
||||||
void createPcduComponents();
|
void createPcduComponents();
|
||||||
void createRadSensorComponent(LinuxLibgpioIF* gpioComIF);
|
void createRadSensorComponent(LinuxLibgpioIF* gpioComIF);
|
||||||
@ -22,9 +22,9 @@ void createSolarArrayDeploymentComponents();
|
|||||||
void createSyrlinksComponents();
|
void createSyrlinksComponents();
|
||||||
void createRtdComponents(LinuxLibgpioIF* gpioComIF);
|
void createRtdComponents(LinuxLibgpioIF* gpioComIF);
|
||||||
void createReactionWheelComponents(LinuxLibgpioIF* gpioComIF);
|
void createReactionWheelComponents(LinuxLibgpioIF* gpioComIF);
|
||||||
void createCcsdsComponents(LinuxLibgpioIF *gpioComIF);
|
void createCcsdsComponents(LinuxLibgpioIF* gpioComIF);
|
||||||
void createTestComponents(LinuxLibgpioIF* gpioComIF);
|
void createTestComponents(LinuxLibgpioIF* gpioComIF);
|
||||||
|
|
||||||
};
|
}; // namespace ObjectFactory
|
||||||
|
|
||||||
#endif /* BSP_Q7S_OBJECTFACTORY_H_ */
|
#endif /* BSP_Q7S_OBJECTFACTORY_H_ */
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
#include "ParameterHandler.h"
|
#include "ParameterHandler.h"
|
||||||
|
|
||||||
ParameterHandler::ParameterHandler(std::string mountPrefix): mountPrefix(mountPrefix) {
|
ParameterHandler::ParameterHandler(std::string mountPrefix) : mountPrefix(mountPrefix) {}
|
||||||
}
|
|
||||||
|
|
||||||
void ParameterHandler::setMountPrefix(std::string prefix) {
|
void ParameterHandler::setMountPrefix(std::string prefix) { mountPrefix = prefix; }
|
||||||
mountPrefix = prefix;
|
|
||||||
}
|
|
||||||
|
@ -4,19 +4,17 @@
|
|||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ParameterHandler {
|
class ParameterHandler {
|
||||||
public:
|
public:
|
||||||
ParameterHandler(std::string mountPrefix);
|
ParameterHandler(std::string mountPrefix);
|
||||||
|
|
||||||
void setMountPrefix(std::string prefix);
|
void setMountPrefix(std::string prefix);
|
||||||
|
|
||||||
void setUpDummyParameter();
|
void setUpDummyParameter();
|
||||||
private:
|
|
||||||
std::string mountPrefix;
|
private:
|
||||||
DummyParameter dummyParam;
|
std::string mountPrefix;
|
||||||
|
DummyParameter dummyParam;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* BSP_Q7S_CORE_PARAMETERHANDLER_H_ */
|
#endif /* BSP_Q7S_CORE_PARAMETERHANDLER_H_ */
|
||||||
|
@ -1,43 +1,44 @@
|
|||||||
#include "obsw.h"
|
#include "obsw.h"
|
||||||
#include "OBSWVersion.h"
|
|
||||||
#include "OBSWConfig.h"
|
|
||||||
#include "InitMission.h"
|
|
||||||
#include "watchdogConf.h"
|
|
||||||
|
|
||||||
#include "fsfw/tasks/TaskFactory.h"
|
|
||||||
#include "fsfw/FSFWVersion.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "InitMission.h"
|
||||||
|
#include "OBSWConfig.h"
|
||||||
|
#include "OBSWVersion.h"
|
||||||
|
#include "fsfw/FSFWVersion.h"
|
||||||
|
#include "fsfw/tasks/TaskFactory.h"
|
||||||
|
#include "watchdogConf.h"
|
||||||
|
|
||||||
static int OBSW_ALREADY_RUNNING = -2;
|
static int OBSW_ALREADY_RUNNING = -2;
|
||||||
|
|
||||||
int obsw::obsw() {
|
int obsw::obsw() {
|
||||||
std::cout << "-- EIVE OBSW --" << std::endl;
|
std::cout << "-- EIVE OBSW --" << std::endl;
|
||||||
#if BOARD_TE0720 == 0
|
#if BOARD_TE0720 == 0
|
||||||
std::cout << "-- Compiled for Linux (Xiphos Q7S) --" << std::endl;
|
std::cout << "-- Compiled for Linux (Xiphos Q7S) --" << std::endl;
|
||||||
#else
|
#else
|
||||||
std::cout << "-- Compiled for Linux (TE0720) --" << std::endl;
|
std::cout << "-- Compiled for Linux (TE0720) --" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
std::cout << "-- OBSW v" << SW_VERSION << "." << SW_SUBVERSION <<
|
std::cout << "-- OBSW v" << SW_VERSION << "." << SW_SUBVERSION << "." << SW_REVISION << ", FSFW v"
|
||||||
"." << SW_REVISION << ", FSFW v" << FSFW_VERSION << "." << FSFW_SUBVERSION << "." <<
|
<< FSFW_VERSION << "." << FSFW_SUBVERSION << "." << FSFW_REVISION << "--" << std::endl;
|
||||||
FSFW_REVISION << "--" << std::endl;
|
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
|
||||||
std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl;
|
|
||||||
|
|
||||||
#if Q7S_CHECK_FOR_ALREADY_RUNNING_IMG == 1
|
#if Q7S_CHECK_FOR_ALREADY_RUNNING_IMG == 1
|
||||||
// Check special file here. This file is created or deleted by the eive-watchdog application
|
// Check special file here. This file is created or deleted by the eive-watchdog application
|
||||||
// or systemd service!
|
// or systemd service!
|
||||||
if(std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) {
|
if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) {
|
||||||
sif::warning << "File " << watchdog::RUNNING_FILE_NAME << " exists so the software might "
|
sif::warning << "File " << watchdog::RUNNING_FILE_NAME
|
||||||
"already be running. Check if obsw systemd service has been stopped." << std::endl;
|
<< " exists so the software might "
|
||||||
return OBSW_ALREADY_RUNNING;
|
"already be running. Check if obsw systemd service has been stopped."
|
||||||
}
|
<< std::endl;
|
||||||
|
return OBSW_ALREADY_RUNNING;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
initmission::initMission();
|
initmission::initMission();
|
||||||
|
|
||||||
for(;;) {
|
for (;;) {
|
||||||
/* Suspend main thread by sleeping it. */
|
/* Suspend main thread by sleeping it. */
|
||||||
TaskFactory::delayTask(5000);
|
TaskFactory::delayTask(5000);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,206 +1,192 @@
|
|||||||
#include <fsfw/src/fsfw/serialize/SerializeAdapter.h>
|
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
|
||||||
#include "PlocMemoryDumper.h"
|
#include "PlocMemoryDumper.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fsfw/src/fsfw/serialize/SerializeAdapter.h>
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
PlocMemoryDumper::PlocMemoryDumper(object_id_t objectId) :
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
SystemObject(objectId), commandActionHelper(this), actionHelper(this, nullptr) {
|
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
|
PlocMemoryDumper::PlocMemoryDumper(object_id_t objectId)
|
||||||
|
: SystemObject(objectId), commandActionHelper(this), actionHelper(this, nullptr) {
|
||||||
|
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
PlocMemoryDumper::~PlocMemoryDumper() {
|
PlocMemoryDumper::~PlocMemoryDumper() {}
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PlocMemoryDumper::initialize() {
|
ReturnValue_t PlocMemoryDumper::initialize() {
|
||||||
|
ReturnValue_t result = SystemObject::initialize();
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = commandActionHelper.initialize();
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = actionHelper.initialize(commandQueue);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t result = SystemObject::initialize();
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = commandActionHelper.initialize();
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = actionHelper.initialize(commandQueue);
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PlocMemoryDumper::performOperation(uint8_t operationCode) {
|
ReturnValue_t PlocMemoryDumper::performOperation(uint8_t operationCode) {
|
||||||
readCommandQueue();
|
readCommandQueue();
|
||||||
doStateMachine();
|
doStateMachine();
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PlocMemoryDumper::executeAction(ActionId_t actionId,
|
ReturnValue_t PlocMemoryDumper::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
|
const uint8_t* data, size_t size) {
|
||||||
|
if (state != State::IDLE) {
|
||||||
|
return IS_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
if (state != State::IDLE) {
|
switch (actionId) {
|
||||||
return IS_BUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (actionId) {
|
|
||||||
case DUMP_MRAM: {
|
case DUMP_MRAM: {
|
||||||
size_t deserializeSize = sizeof(mram.startAddress) + sizeof(mram.endAddress);
|
size_t deserializeSize = sizeof(mram.startAddress) + sizeof(mram.endAddress);
|
||||||
SerializeAdapter::deSerialize(&mram.startAddress, &data, &deserializeSize,
|
SerializeAdapter::deSerialize(&mram.startAddress, &data, &deserializeSize,
|
||||||
SerializeIF::Endianness::BIG);
|
SerializeIF::Endianness::BIG);
|
||||||
SerializeAdapter::deSerialize(&mram.endAddress, &data, &deserializeSize,
|
SerializeAdapter::deSerialize(&mram.endAddress, &data, &deserializeSize,
|
||||||
SerializeIF::Endianness::BIG);
|
SerializeIF::Endianness::BIG);
|
||||||
if (mram.endAddress > MAX_MRAM_ADDRESS) {
|
if (mram.endAddress > MAX_MRAM_ADDRESS) {
|
||||||
return MRAM_ADDRESS_TOO_HIGH;
|
return MRAM_ADDRESS_TOO_HIGH;
|
||||||
}
|
}
|
||||||
if (mram.endAddress <= mram.startAddress) {
|
if (mram.endAddress <= mram.startAddress) {
|
||||||
return MRAM_INVALID_ADDRESS_COMBINATION;
|
return MRAM_INVALID_ADDRESS_COMBINATION;
|
||||||
}
|
}
|
||||||
state = State::COMMAND_FIRST_MRAM_DUMP;
|
state = State::COMMAND_FIRST_MRAM_DUMP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
sif::warning << "PlocMemoryDumper::executeAction: Received command with invalid action id"
|
sif::warning << "PlocMemoryDumper::executeAction: Received command with invalid action id"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return INVALID_ACTION_ID;
|
return INVALID_ACTION_ID;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return EXECUTION_FINISHED;
|
return EXECUTION_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t PlocMemoryDumper::getCommandQueue() const {
|
MessageQueueId_t PlocMemoryDumper::getCommandQueue() const { return commandQueue->getId(); }
|
||||||
return commandQueue->getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageQueueIF* PlocMemoryDumper::getCommandQueuePtr() {
|
MessageQueueIF* PlocMemoryDumper::getCommandQueuePtr() { return commandQueue; }
|
||||||
return commandQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlocMemoryDumper::readCommandQueue() {
|
void PlocMemoryDumper::readCommandQueue() {
|
||||||
CommandMessage message;
|
CommandMessage message;
|
||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
|
|
||||||
for (result = commandQueue->receiveMessage(&message); result == HasReturnvaluesIF::RETURN_OK;
|
for (result = commandQueue->receiveMessage(&message); result == HasReturnvaluesIF::RETURN_OK;
|
||||||
result = commandQueue->receiveMessage(&message)) {
|
result = commandQueue->receiveMessage(&message)) {
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
result = actionHelper.handleActionMessage(&message);
|
|
||||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = commandActionHelper.handleReply(&message);
|
|
||||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
sif::debug << "PlocMemoryDumper::readCommandQueue: Received message with invalid format"
|
|
||||||
<< std::endl;
|
|
||||||
}
|
}
|
||||||
|
result = actionHelper.handleActionMessage(&message);
|
||||||
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = commandActionHelper.handleReply(&message);
|
||||||
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sif::debug << "PlocMemoryDumper::readCommandQueue: Received message with invalid format"
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlocMemoryDumper::doStateMachine() {
|
void PlocMemoryDumper::doStateMachine() {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case State::IDLE:
|
case State::IDLE:
|
||||||
break;
|
break;
|
||||||
case State::COMMAND_FIRST_MRAM_DUMP:
|
case State::COMMAND_FIRST_MRAM_DUMP:
|
||||||
commandNextMramDump(PLOC_SPV::FIRST_MRAM_DUMP);
|
commandNextMramDump(PLOC_SPV::FIRST_MRAM_DUMP);
|
||||||
break;
|
break;
|
||||||
case State::COMMAND_CONSECUTIVE_MRAM_DUMP:
|
case State::COMMAND_CONSECUTIVE_MRAM_DUMP:
|
||||||
commandNextMramDump(PLOC_SPV::CONSECUTIVE_MRAM_DUMP);
|
commandNextMramDump(PLOC_SPV::CONSECUTIVE_MRAM_DUMP);
|
||||||
break;
|
break;
|
||||||
case State::EXECUTING_MRAM_DUMP:
|
case State::EXECUTING_MRAM_DUMP:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sif::debug << "PlocMemoryDumper::doStateMachine: Invalid state" << std::endl;
|
sif::debug << "PlocMemoryDumper::doStateMachine: Invalid state" << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlocMemoryDumper::stepSuccessfulReceived(ActionId_t actionId,
|
void PlocMemoryDumper::stepSuccessfulReceived(ActionId_t actionId, uint8_t step) {}
|
||||||
uint8_t step) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlocMemoryDumper::stepFailedReceived(ActionId_t actionId, uint8_t step,
|
void PlocMemoryDumper::stepFailedReceived(ActionId_t actionId, uint8_t step,
|
||||||
ReturnValue_t returnCode) {
|
ReturnValue_t returnCode) {}
|
||||||
}
|
|
||||||
|
|
||||||
void PlocMemoryDumper::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) {
|
void PlocMemoryDumper::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlocMemoryDumper::completionSuccessfulReceived(ActionId_t actionId) {
|
void PlocMemoryDumper::completionSuccessfulReceived(ActionId_t actionId) {
|
||||||
switch (pendingCommand) {
|
switch (pendingCommand) {
|
||||||
case (PLOC_SPV::FIRST_MRAM_DUMP):
|
case (PLOC_SPV::FIRST_MRAM_DUMP):
|
||||||
case (PLOC_SPV::CONSECUTIVE_MRAM_DUMP):
|
case (PLOC_SPV::CONSECUTIVE_MRAM_DUMP):
|
||||||
if (mram.endAddress == mram.startAddress) {
|
if (mram.endAddress == mram.startAddress) {
|
||||||
triggerEvent(MRAM_DUMP_FINISHED);
|
triggerEvent(MRAM_DUMP_FINISHED);
|
||||||
state = State::IDLE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
state = State::COMMAND_CONSECUTIVE_MRAM_DUMP;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sif::debug << "PlocMemoryDumper::completionSuccessfulReceived: Invalid pending command"
|
|
||||||
<< std::endl;
|
|
||||||
state = State::IDLE;
|
state = State::IDLE;
|
||||||
break;
|
} else {
|
||||||
}
|
state = State::COMMAND_CONSECUTIVE_MRAM_DUMP;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sif::debug << "PlocMemoryDumper::completionSuccessfulReceived: Invalid pending command"
|
||||||
|
<< std::endl;
|
||||||
|
state = State::IDLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlocMemoryDumper::completionFailedReceived(ActionId_t actionId,
|
void PlocMemoryDumper::completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) {
|
||||||
ReturnValue_t returnCode) {
|
switch (pendingCommand) {
|
||||||
switch(pendingCommand) {
|
case (PLOC_SPV::FIRST_MRAM_DUMP):
|
||||||
case(PLOC_SPV::FIRST_MRAM_DUMP):
|
case (PLOC_SPV::CONSECUTIVE_MRAM_DUMP):
|
||||||
case(PLOC_SPV::CONSECUTIVE_MRAM_DUMP):
|
triggerEvent(MRAM_DUMP_FAILED, mram.lastStartAddress);
|
||||||
triggerEvent(MRAM_DUMP_FAILED, mram.lastStartAddress);
|
break;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
sif::debug << "PlocMemoryDumper::completionFailedReceived: Invalid pending command "
|
sif::debug << "PlocMemoryDumper::completionFailedReceived: Invalid pending command "
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
state = State::IDLE;
|
state = State::IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlocMemoryDumper::commandNextMramDump(ActionId_t dumpCommand) {
|
void PlocMemoryDumper::commandNextMramDump(ActionId_t dumpCommand) {
|
||||||
ReturnValue_t result = RETURN_OK;
|
ReturnValue_t result = RETURN_OK;
|
||||||
|
|
||||||
uint32_t tempStartAddress = 0;
|
uint32_t tempStartAddress = 0;
|
||||||
uint32_t tempEndAddress = 0;
|
uint32_t tempEndAddress = 0;
|
||||||
|
|
||||||
if (mram.endAddress - mram.startAddress > MAX_MRAM_DUMP_SIZE) {
|
if (mram.endAddress - mram.startAddress > MAX_MRAM_DUMP_SIZE) {
|
||||||
tempStartAddress = mram.startAddress;
|
tempStartAddress = mram.startAddress;
|
||||||
tempEndAddress = mram.startAddress + MAX_MRAM_DUMP_SIZE;
|
tempEndAddress = mram.startAddress + MAX_MRAM_DUMP_SIZE;
|
||||||
mram.startAddress += MAX_MRAM_DUMP_SIZE;
|
mram.startAddress += MAX_MRAM_DUMP_SIZE;
|
||||||
mram.lastStartAddress = tempStartAddress;
|
mram.lastStartAddress = tempStartAddress;
|
||||||
}
|
} else {
|
||||||
else {
|
tempStartAddress = mram.startAddress;
|
||||||
tempStartAddress = mram.startAddress;
|
tempEndAddress = mram.endAddress;
|
||||||
tempEndAddress = mram.endAddress;
|
mram.startAddress = mram.endAddress;
|
||||||
mram.startAddress = mram.endAddress;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
MemoryParams params(tempStartAddress, tempEndAddress);
|
MemoryParams params(tempStartAddress, tempEndAddress);
|
||||||
|
|
||||||
result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER,
|
result =
|
||||||
dumpCommand, ¶ms);
|
commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, dumpCommand, ¶ms);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
sif::warning << "PlocMemoryDumper::commandNextMramDump: Failed to send mram dump command "
|
sif::warning << "PlocMemoryDumper::commandNextMramDump: Failed to send mram dump command "
|
||||||
<< "with start address " << tempStartAddress << " and end address "
|
<< "with start address " << tempStartAddress << " and end address "
|
||||||
<< tempEndAddress << std::endl;
|
<< tempEndAddress << std::endl;
|
||||||
triggerEvent(SEND_MRAM_DUMP_FAILED, result, tempStartAddress);
|
triggerEvent(SEND_MRAM_DUMP_FAILED, result, tempStartAddress);
|
||||||
state = State::IDLE;
|
state = State::IDLE;
|
||||||
pendingCommand = NONE;
|
pendingCommand = NONE;
|
||||||
return;
|
|
||||||
}
|
|
||||||
state = State::EXECUTING_MRAM_DUMP;
|
|
||||||
pendingCommand = dumpCommand;
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
state = State::EXECUTING_MRAM_DUMP;
|
||||||
|
pendingCommand = dumpCommand;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,18 +3,18 @@
|
|||||||
|
|
||||||
#include <bsp_q7s/devices/devicedefinitions/PlocMemDumpDefinitions.h>
|
#include <bsp_q7s/devices/devicedefinitions/PlocMemDumpDefinitions.h>
|
||||||
#include <bsp_q7s/devices/devicedefinitions/PlocSupervisorDefinitions.h>
|
#include <bsp_q7s/devices/devicedefinitions/PlocSupervisorDefinitions.h>
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "fsfw/action/CommandActionHelper.h"
|
#include "bsp_q7s/memory/SdCardManager.h"
|
||||||
#include "fsfw/action/ActionHelper.h"
|
#include "fsfw/action/ActionHelper.h"
|
||||||
#include "fsfw/action/HasActionsIF.h"
|
#include "fsfw/action/CommandActionHelper.h"
|
||||||
#include "fsfw/action/CommandsActionsIF.h"
|
#include "fsfw/action/CommandsActionsIF.h"
|
||||||
|
#include "fsfw/action/HasActionsIF.h"
|
||||||
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||||
#include "fsfw/objectmanager/SystemObject.h"
|
|
||||||
#include "bsp_q7s/memory/SdCardManager.h"
|
|
||||||
#include "linux/fsfwconfig/objects/systemObjectList.h"
|
|
||||||
#include "fsfw/tmtcpacket/SpacePacket.h"
|
#include "fsfw/tmtcpacket/SpacePacket.h"
|
||||||
|
#include "linux/fsfwconfig/objects/systemObjectList.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Because the buffer of the linux tty driver is limited to 2 x 65535 bytes, this class is
|
* @brief Because the buffer of the linux tty driver is limited to 2 x 65535 bytes, this class is
|
||||||
@ -25,91 +25,90 @@
|
|||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
*/
|
*/
|
||||||
class PlocMemoryDumper : public SystemObject,
|
class PlocMemoryDumper : public SystemObject,
|
||||||
public HasActionsIF,
|
public HasActionsIF,
|
||||||
public ExecutableObjectIF,
|
public ExecutableObjectIF,
|
||||||
public HasReturnvaluesIF,
|
public HasReturnvaluesIF,
|
||||||
public CommandsActionsIF {
|
public CommandsActionsIF {
|
||||||
public:
|
public:
|
||||||
|
static const ActionId_t NONE = 0;
|
||||||
|
static const ActionId_t DUMP_MRAM = 1;
|
||||||
|
|
||||||
static const ActionId_t NONE = 0;
|
PlocMemoryDumper(object_id_t objectId);
|
||||||
static const ActionId_t DUMP_MRAM = 1;
|
virtual ~PlocMemoryDumper();
|
||||||
|
|
||||||
PlocMemoryDumper(object_id_t objectId);
|
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||||
virtual ~PlocMemoryDumper();
|
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
|
const uint8_t* data, size_t size);
|
||||||
|
MessageQueueId_t getCommandQueue() const;
|
||||||
|
ReturnValue_t initialize() override;
|
||||||
|
MessageQueueIF* getCommandQueuePtr() override;
|
||||||
|
void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override;
|
||||||
|
void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) override;
|
||||||
|
void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) override;
|
||||||
|
void completionSuccessfulReceived(ActionId_t actionId) override;
|
||||||
|
void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override;
|
||||||
|
|
||||||
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
private:
|
||||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
static const uint32_t QUEUE_SIZE = 10;
|
||||||
const uint8_t* data, size_t size);
|
|
||||||
MessageQueueId_t getCommandQueue() const;
|
|
||||||
ReturnValue_t initialize() override;
|
|
||||||
MessageQueueIF* getCommandQueuePtr() override;
|
|
||||||
void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override;
|
|
||||||
void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) override;
|
|
||||||
void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) override;
|
|
||||||
void completionSuccessfulReceived(ActionId_t actionId) override;
|
|
||||||
void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override;
|
|
||||||
|
|
||||||
private:
|
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_MEMORY_DUMPER;
|
||||||
|
|
||||||
static const uint32_t QUEUE_SIZE = 10;
|
//! [EXPORT] : [COMMENT] The capacity of the MRAM amounts to 512 kB. Thus the maximum address must
|
||||||
|
//! not be higher than 0x7d000.
|
||||||
|
static const ReturnValue_t MRAM_ADDRESS_TOO_HIGH = MAKE_RETURN_CODE(0xA0);
|
||||||
|
//! [EXPORT] : [COMMENT] The specified end address is lower than the start address
|
||||||
|
static const ReturnValue_t MRAM_INVALID_ADDRESS_COMBINATION = MAKE_RETURN_CODE(0xA1);
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_MEMORY_DUMPER;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_MEMORY_DUMPER;
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] The capacity of the MRAM amounts to 512 kB. Thus the maximum address must not be higher than 0x7d000.
|
//! [EXPORT] : [COMMENT] Failed to send mram dump command to supervisor handler
|
||||||
static const ReturnValue_t MRAM_ADDRESS_TOO_HIGH = MAKE_RETURN_CODE(0xA0);
|
//! P1: Return value of commandAction function
|
||||||
//! [EXPORT] : [COMMENT] The specified end address is lower than the start address
|
//! P2: Start address of MRAM to dump with this command
|
||||||
static const ReturnValue_t MRAM_INVALID_ADDRESS_COMBINATION = MAKE_RETURN_CODE(0xA1);
|
static const Event SEND_MRAM_DUMP_FAILED = MAKE_EVENT(0, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Received completion failure report form PLOC supervisor handler
|
||||||
|
//! P1: MRAM start address of failing dump command
|
||||||
|
static const Event MRAM_DUMP_FAILED = MAKE_EVENT(1, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] MRAM dump finished successfully
|
||||||
|
static const Event MRAM_DUMP_FINISHED = MAKE_EVENT(2, severity::LOW);
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_MEMORY_DUMPER;
|
// Maximum size of mram dump which can be retrieved with one command
|
||||||
|
static const uint32_t MAX_MRAM_DUMP_SIZE = 100000;
|
||||||
|
static const uint32_t MAX_MRAM_ADDRESS = 0x7d000;
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] Failed to send mram dump command to supervisor handler
|
MessageQueueIF* commandQueue = nullptr;
|
||||||
//! P1: Return value of commandAction function
|
|
||||||
//! P2: Start address of MRAM to dump with this command
|
|
||||||
static const Event SEND_MRAM_DUMP_FAILED = MAKE_EVENT(0, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] Received completion failure report form PLOC supervisor handler
|
|
||||||
//! P1: MRAM start address of failing dump command
|
|
||||||
static const Event MRAM_DUMP_FAILED = MAKE_EVENT(1, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] MRAM dump finished successfully
|
|
||||||
static const Event MRAM_DUMP_FINISHED = MAKE_EVENT(2, severity::LOW);
|
|
||||||
|
|
||||||
// Maximum size of mram dump which can be retrieved with one command
|
CommandActionHelper commandActionHelper;
|
||||||
static const uint32_t MAX_MRAM_DUMP_SIZE = 100000;
|
|
||||||
static const uint32_t MAX_MRAM_ADDRESS = 0x7d000;
|
|
||||||
|
|
||||||
MessageQueueIF* commandQueue = nullptr;
|
ActionHelper actionHelper;
|
||||||
|
|
||||||
CommandActionHelper commandActionHelper;
|
enum class State : uint8_t {
|
||||||
|
IDLE,
|
||||||
|
COMMAND_FIRST_MRAM_DUMP,
|
||||||
|
COMMAND_CONSECUTIVE_MRAM_DUMP,
|
||||||
|
EXECUTING_MRAM_DUMP
|
||||||
|
};
|
||||||
|
|
||||||
ActionHelper actionHelper;
|
State state = State::IDLE;
|
||||||
|
|
||||||
enum class State: uint8_t {
|
ActionId_t pendingCommand = NONE;
|
||||||
IDLE,
|
|
||||||
COMMAND_FIRST_MRAM_DUMP,
|
|
||||||
COMMAND_CONSECUTIVE_MRAM_DUMP,
|
|
||||||
EXECUTING_MRAM_DUMP
|
|
||||||
};
|
|
||||||
|
|
||||||
State state = State::IDLE;
|
typedef struct MemoryInfo {
|
||||||
|
// Stores the start address of the next memory range to dump
|
||||||
|
uint32_t startAddress;
|
||||||
|
uint32_t endAddress;
|
||||||
|
// Stores the start address of the last sent dump command
|
||||||
|
uint32_t lastStartAddress;
|
||||||
|
} MemoryInfo_t;
|
||||||
|
|
||||||
ActionId_t pendingCommand = NONE;
|
MemoryInfo_t mram = {0, 0, 0};
|
||||||
|
|
||||||
typedef struct MemoryInfo {
|
void readCommandQueue();
|
||||||
// Stores the start address of the next memory range to dump
|
void doStateMachine();
|
||||||
uint32_t startAddress;
|
|
||||||
uint32_t endAddress;
|
|
||||||
// Stores the start address of the last sent dump command
|
|
||||||
uint32_t lastStartAddress;
|
|
||||||
} MemoryInfo_t;
|
|
||||||
|
|
||||||
MemoryInfo_t mram = {0, 0, 0};
|
/**
|
||||||
|
* @brief Sends the next mram dump command to the PLOC supervisor handler.
|
||||||
void readCommandQueue();
|
*/
|
||||||
void doStateMachine();
|
void commandNextMramDump(ActionId_t dumpCommand);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Sends the next mram dump command to the PLOC supervisor handler.
|
|
||||||
*/
|
|
||||||
void commandNextMramDump(ActionId_t dumpCommand);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_DEVICES_PLOCMEMORYDUMPER_H_ */
|
#endif /* MISSION_DEVICES_PLOCMEMORYDUMPER_H_ */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,12 +1,12 @@
|
|||||||
#ifndef MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_
|
#ifndef MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_
|
||||||
#define MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_
|
#define MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_
|
||||||
|
|
||||||
#include "devicedefinitions/PlocSupervisorDefinitions.h"
|
|
||||||
#include <bsp_q7s/memory/SdCardManager.h>
|
#include <bsp_q7s/memory/SdCardManager.h>
|
||||||
|
|
||||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||||
#include <fsfw_hal/linux/uart/UartComIF.h>
|
#include <fsfw_hal/linux/uart/UartComIF.h>
|
||||||
|
|
||||||
|
#include "devicedefinitions/PlocSupervisorDefinitions.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is the device handler for the supervisor of the PLOC which is programmed by
|
* @brief This is the device handler for the supervisor of the PLOC which is programmed by
|
||||||
* Thales.
|
* Thales.
|
||||||
@ -19,324 +19,327 @@
|
|||||||
* Arbeitsdaten/08_Used%20Components/PLOC&fileid=940960
|
* Arbeitsdaten/08_Used%20Components/PLOC&fileid=940960
|
||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
*/
|
*/
|
||||||
class PlocSupervisorHandler: public DeviceHandlerBase {
|
class PlocSupervisorHandler : public DeviceHandlerBase {
|
||||||
public:
|
public:
|
||||||
|
PlocSupervisorHandler(object_id_t objectId, object_id_t uartComIFid, CookieIF* comCookie);
|
||||||
|
virtual ~PlocSupervisorHandler();
|
||||||
|
|
||||||
PlocSupervisorHandler(object_id_t objectId, object_id_t uartComIFid, CookieIF * comCookie);
|
virtual ReturnValue_t initialize() override;
|
||||||
virtual ~PlocSupervisorHandler();
|
|
||||||
|
|
||||||
virtual ReturnValue_t initialize() override;
|
protected:
|
||||||
|
void doStartUp() override;
|
||||||
|
void doShutDown() override;
|
||||||
|
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
|
||||||
|
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override;
|
||||||
|
void fillCommandAndReplyMap() override;
|
||||||
|
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData,
|
||||||
|
size_t commandDataLen) override;
|
||||||
|
ReturnValue_t scanForReply(const uint8_t* start, size_t remainingSize, DeviceCommandId_t* foundId,
|
||||||
|
size_t* foundLen) override;
|
||||||
|
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) override;
|
||||||
|
void setNormalDatapoolEntriesInvalid() override;
|
||||||
|
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
||||||
|
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
|
LocalDataPoolManager& poolManager) override;
|
||||||
|
ReturnValue_t enableReplyInReplyMap(DeviceCommandMap::iterator command,
|
||||||
|
uint8_t expectedReplies = 1, bool useAlternateId = false,
|
||||||
|
DeviceCommandId_t alternateReplyID = 0) override;
|
||||||
|
size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override;
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
void doStartUp() override;
|
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_SUPERVISOR_HANDLER;
|
||||||
void doShutDown() override;
|
|
||||||
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) override;
|
|
||||||
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t * id) override;
|
|
||||||
void fillCommandAndReplyMap() override;
|
|
||||||
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
|
||||||
const uint8_t * commandData,size_t commandDataLen) override;
|
|
||||||
ReturnValue_t scanForReply(const uint8_t *start, size_t remainingSize,
|
|
||||||
DeviceCommandId_t *foundId, size_t *foundLen) override;
|
|
||||||
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id,
|
|
||||||
const uint8_t *packet) override;
|
|
||||||
void setNormalDatapoolEntriesInvalid() override;
|
|
||||||
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
|
||||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
|
||||||
LocalDataPoolManager& poolManager) override;
|
|
||||||
ReturnValue_t enableReplyInReplyMap(DeviceCommandMap::iterator command,
|
|
||||||
uint8_t expectedReplies = 1, bool useAlternateId = false,
|
|
||||||
DeviceCommandId_t alternateReplyID = 0) override;
|
|
||||||
size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override;
|
|
||||||
|
|
||||||
private:
|
//! [EXPORT] : [COMMENT] Space Packet received from PLOC supervisor has invalid CRC
|
||||||
|
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA0);
|
||||||
|
//! [EXPORT] : [COMMENT] Received ACK failure reply from PLOC supervisor
|
||||||
|
static const ReturnValue_t RECEIVED_ACK_FAILURE = MAKE_RETURN_CODE(0xA1);
|
||||||
|
//! [EXPORT] : [COMMENT] Received execution failure reply from PLOC supervisor
|
||||||
|
static const ReturnValue_t RECEIVED_EXE_FAILURE = MAKE_RETURN_CODE(0xA2);
|
||||||
|
//! [EXPORT] : [COMMENT] Received space packet with invalid APID from PLOC supervisor
|
||||||
|
static const ReturnValue_t INVALID_APID = MAKE_RETURN_CODE(0xA3);
|
||||||
|
//! [EXPORT] : [COMMENT] Failed to read current system time
|
||||||
|
static const ReturnValue_t GET_TIME_FAILURE = MAKE_RETURN_CODE(0xA4);
|
||||||
|
//! [EXPORT] : [COMMENT] Invalid communication interface specified
|
||||||
|
static const ReturnValue_t INVALID_UART_COM_IF = MAKE_RETURN_CODE(0xA5);
|
||||||
|
//! [EXPORT] : [COMMENT] Received command with invalid watchdog parameter. Valid watchdogs are 0
|
||||||
|
//! for PS, 1 for PL and 2 for INT
|
||||||
|
static const ReturnValue_t INVALID_WATCHDOG = MAKE_RETURN_CODE(0xA6);
|
||||||
|
//! [EXPORT] : [COMMENT] Received watchdog timeout config command with invalid timeout. Valid
|
||||||
|
//! timeouts must be in the range between 1000 and 360000 ms.
|
||||||
|
static const ReturnValue_t INVALID_WATCHDOG_TIMEOUT = MAKE_RETURN_CODE(0xA7);
|
||||||
|
//! [EXPORT] : [COMMENT] Received latchup config command with invalid latchup ID
|
||||||
|
static const ReturnValue_t INVALID_LATCHUP_ID = MAKE_RETURN_CODE(0xA8);
|
||||||
|
//! [EXPORT] : [COMMENT] Received set adc sweep period command with invalid sweep period. Must be
|
||||||
|
//! larger than 21.
|
||||||
|
static const ReturnValue_t SWEEP_PERIOD_TOO_SMALL = MAKE_RETURN_CODE(0xA9);
|
||||||
|
//! [EXPORT] : [COMMENT] Receive auto EM test command with invalid test param. Valid params are 1
|
||||||
|
//! and 2.
|
||||||
|
static const ReturnValue_t INVALID_TEST_PARAM = MAKE_RETURN_CODE(0xAA);
|
||||||
|
//! [EXPORT] : [COMMENT] Returned when scanning for MRAM dump packets failed.
|
||||||
|
static const ReturnValue_t MRAM_PACKET_PARSING_FAILURE = MAKE_RETURN_CODE(0xAB);
|
||||||
|
//! [EXPORT] : [COMMENT] Returned when the start and stop addresses of the MRAM dump or MRAM wipe
|
||||||
|
//! commands are invalid (e.g. start address bigger than stop address)
|
||||||
|
static const ReturnValue_t INVALID_MRAM_ADDRESSES = MAKE_RETURN_CODE(0xAC);
|
||||||
|
//! [EXPORT] : [COMMENT] Expect reception of an MRAM dump packet but received space packet with
|
||||||
|
//! other apid.
|
||||||
|
static const ReturnValue_t NO_MRAM_PACKET = MAKE_RETURN_CODE(0xAD);
|
||||||
|
//! [EXPORT] : [COMMENT] Path to PLOC directory on SD card does not exist
|
||||||
|
static const ReturnValue_t PATH_DOES_NOT_EXIST = MAKE_RETURN_CODE(0xAE);
|
||||||
|
//! [EXPORT] : [COMMENT] MRAM dump file does not exists. The file should actually already have
|
||||||
|
//! been created with the reception of the first dump packet.
|
||||||
|
static const ReturnValue_t MRAM_FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xAF);
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_SUPERVISOR_HANDLER;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER;
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] Space Packet received from PLOC supervisor has invalid CRC
|
//! [EXPORT] : [COMMENT] PLOC supervisor crc failure in telemetry packet
|
||||||
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA0);
|
static const Event SUPV_MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW);
|
||||||
//! [EXPORT] : [COMMENT] Received ACK failure reply from PLOC supervisor
|
//! [EXPORT] : [COMMENT] PLOC supervisor received acknowledgment failure report
|
||||||
static const ReturnValue_t RECEIVED_ACK_FAILURE = MAKE_RETURN_CODE(0xA1);
|
static const Event SUPV_ACK_FAILURE = MAKE_EVENT(2, severity::LOW);
|
||||||
//! [EXPORT] : [COMMENT] Received execution failure reply from PLOC supervisor
|
//! [EXPORT] : [COMMENT] PLOC received execution failure report
|
||||||
static const ReturnValue_t RECEIVED_EXE_FAILURE = MAKE_RETURN_CODE(0xA2);
|
static const Event SUPV_EXE_FAILURE = MAKE_EVENT(3, severity::LOW);
|
||||||
//! [EXPORT] : [COMMENT] Received space packet with invalid APID from PLOC supervisor
|
//! [EXPORT] : [COMMENT] PLOC supervisor reply has invalid crc
|
||||||
static const ReturnValue_t INVALID_APID = MAKE_RETURN_CODE(0xA3);
|
static const Event SUPV_CRC_FAILURE_EVENT = MAKE_EVENT(4, severity::LOW);
|
||||||
//! [EXPORT] : [COMMENT] Failed to read current system time
|
|
||||||
static const ReturnValue_t GET_TIME_FAILURE = MAKE_RETURN_CODE(0xA4);
|
|
||||||
//! [EXPORT] : [COMMENT] Invalid communication interface specified
|
|
||||||
static const ReturnValue_t INVALID_UART_COM_IF = MAKE_RETURN_CODE(0xA5);
|
|
||||||
//! [EXPORT] : [COMMENT] Received command with invalid watchdog parameter. Valid watchdogs are 0 for PS, 1 for PL and 2 for INT
|
|
||||||
static const ReturnValue_t INVALID_WATCHDOG = MAKE_RETURN_CODE(0xA6);
|
|
||||||
//! [EXPORT] : [COMMENT] Received watchdog timeout config command with invalid timeout. Valid timeouts must be in the range between 1000 and 360000 ms.
|
|
||||||
static const ReturnValue_t INVALID_WATCHDOG_TIMEOUT = MAKE_RETURN_CODE(0xA7);
|
|
||||||
//! [EXPORT] : [COMMENT] Received latchup config command with invalid latchup ID
|
|
||||||
static const ReturnValue_t INVALID_LATCHUP_ID = MAKE_RETURN_CODE(0xA8);
|
|
||||||
//! [EXPORT] : [COMMENT] Received set adc sweep period command with invalid sweep period. Must be larger than 21.
|
|
||||||
static const ReturnValue_t SWEEP_PERIOD_TOO_SMALL = MAKE_RETURN_CODE(0xA9);
|
|
||||||
//! [EXPORT] : [COMMENT] Receive auto EM test command with invalid test param. Valid params are 1 and 2.
|
|
||||||
static const ReturnValue_t INVALID_TEST_PARAM = MAKE_RETURN_CODE(0xAA);
|
|
||||||
//! [EXPORT] : [COMMENT] Returned when scanning for MRAM dump packets failed.
|
|
||||||
static const ReturnValue_t MRAM_PACKET_PARSING_FAILURE = MAKE_RETURN_CODE(0xAB);
|
|
||||||
//! [EXPORT] : [COMMENT] Returned when the start and stop addresses of the MRAM dump or MRAM wipe commands are invalid (e.g. start address bigger than stop address)
|
|
||||||
static const ReturnValue_t INVALID_MRAM_ADDRESSES = MAKE_RETURN_CODE(0xAC);
|
|
||||||
//! [EXPORT] : [COMMENT] Expect reception of an MRAM dump packet but received space packet with other apid.
|
|
||||||
static const ReturnValue_t NO_MRAM_PACKET = MAKE_RETURN_CODE(0xAD);
|
|
||||||
//! [EXPORT] : [COMMENT] Path to PLOC directory on SD card does not exist
|
|
||||||
static const ReturnValue_t PATH_DOES_NOT_EXIST = MAKE_RETURN_CODE(0xAE);
|
|
||||||
//! [EXPORT] : [COMMENT] MRAM dump file does not exists. The file should actually already have been created with the reception of the first dump packet.
|
|
||||||
static const ReturnValue_t MRAM_FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xAF);
|
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_SUPERVISOR_HANDLER;
|
static const uint16_t APID_MASK = 0x7FF;
|
||||||
|
static const uint16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF;
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] PLOC supervisor crc failure in telemetry packet
|
uint8_t commandBuffer[PLOC_SPV::MAX_COMMAND_SIZE];
|
||||||
static const Event SUPV_MEMORY_READ_RPT_CRC_FAILURE = MAKE_EVENT(1, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] PLOC supervisor received acknowledgment failure report
|
|
||||||
static const Event SUPV_ACK_FAILURE = MAKE_EVENT(2, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] PLOC received execution failure report
|
|
||||||
static const Event SUPV_EXE_FAILURE = MAKE_EVENT(3, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] PLOC supervisor reply has invalid crc
|
|
||||||
static const Event SUPV_CRC_FAILURE_EVENT = MAKE_EVENT(4, severity::LOW);
|
|
||||||
|
|
||||||
static const uint16_t APID_MASK = 0x7FF;
|
/**
|
||||||
static const uint16_t PACKET_SEQUENCE_COUNT_MASK = 0x3FFF;
|
* This variable is used to store the id of the next reply to receive. This is necessary
|
||||||
|
* because the PLOC sends as reply to each command at least one acknowledgment and execution
|
||||||
|
* report.
|
||||||
|
*/
|
||||||
|
DeviceCommandId_t nextReplyId = PLOC_SPV::NONE;
|
||||||
|
|
||||||
uint8_t commandBuffer[PLOC_SPV::MAX_COMMAND_SIZE];
|
UartComIF* uartComIf = nullptr;
|
||||||
|
|
||||||
/**
|
PLOC_SPV::HkSet hkset;
|
||||||
* This variable is used to store the id of the next reply to receive. This is necessary
|
PLOC_SPV::BootStatusReport bootStatusReport;
|
||||||
* because the PLOC sends as reply to each command at least one acknowledgment and execution
|
PLOC_SPV::LatchupStatusReport latchupStatusReport;
|
||||||
* report.
|
|
||||||
*/
|
|
||||||
DeviceCommandId_t nextReplyId = PLOC_SPV::NONE;
|
|
||||||
|
|
||||||
UartComIF* uartComIf = nullptr;
|
/** Number of expected replies following the MRAM dump command */
|
||||||
|
uint32_t expectedMramDumpPackets = 0;
|
||||||
|
uint32_t receivedMramDumpPackets = 0;
|
||||||
|
/** Set to true as soon as a complete space packet is present in the spacePacketBuffer */
|
||||||
|
bool packetInBuffer = false;
|
||||||
|
/** Points to the next free position in the space packet buffer */
|
||||||
|
uint16_t bufferTop = 0;
|
||||||
|
|
||||||
PLOC_SPV::HkSet hkset;
|
/** This buffer is used to concatenate space packets received in two different read steps */
|
||||||
PLOC_SPV::BootStatusReport bootStatusReport;
|
uint8_t spacePacketBuffer[PLOC_SPV::MAX_PACKET_SIZE];
|
||||||
PLOC_SPV::LatchupStatusReport latchupStatusReport;
|
|
||||||
|
|
||||||
/** Number of expected replies following the MRAM dump command */
|
|
||||||
uint32_t expectedMramDumpPackets = 0;
|
|
||||||
uint32_t receivedMramDumpPackets = 0;
|
|
||||||
/** Set to true as soon as a complete space packet is present in the spacePacketBuffer */
|
|
||||||
bool packetInBuffer = false;
|
|
||||||
/** Points to the next free position in the space packet buffer */
|
|
||||||
uint16_t bufferTop = 0;
|
|
||||||
|
|
||||||
/** This buffer is used to concatenate space packets received in two different read steps */
|
|
||||||
uint8_t spacePacketBuffer[PLOC_SPV::MAX_PACKET_SIZE];
|
|
||||||
|
|
||||||
#if BOARD_TE0720 == 0
|
#if BOARD_TE0720 == 0
|
||||||
SdCardManager* sdcMan = nullptr;
|
SdCardManager* sdcMan = nullptr;
|
||||||
#endif /* BOARD_TE0720 == 0 */
|
#endif /* BOARD_TE0720 == 0 */
|
||||||
|
|
||||||
/** Path to PLOC specific files on SD card */
|
/** Path to PLOC specific files on SD card */
|
||||||
std::string plocFilePath = "ploc";
|
std::string plocFilePath = "ploc";
|
||||||
std::string activeMramFile;
|
std::string activeMramFile;
|
||||||
|
|
||||||
/** Setting this variable to true will enable direct downlink of MRAM packets */
|
/** Setting this variable to true will enable direct downlink of MRAM packets */
|
||||||
bool downlinkMramDump = false;
|
bool downlinkMramDump = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function checks the crc of the received PLOC reply.
|
* @brief This function checks the crc of the received PLOC reply.
|
||||||
*
|
*
|
||||||
* @param start Pointer to the first byte of the reply.
|
* @param start Pointer to the first byte of the reply.
|
||||||
* @param foundLen Pointer to the length of the whole packet.
|
* @param foundLen Pointer to the length of the whole packet.
|
||||||
*
|
*
|
||||||
* @return RETURN_OK if CRC is ok, otherwise CRC_FAILURE.
|
* @return RETURN_OK if CRC is ok, otherwise CRC_FAILURE.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t verifyPacket(const uint8_t* start, size_t foundLen);
|
ReturnValue_t verifyPacket(const uint8_t* start, size_t foundLen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function handles the acknowledgment report.
|
* @brief This function handles the acknowledgment report.
|
||||||
*
|
*
|
||||||
* @param data Pointer to the data holding the acknowledgment report.
|
* @param data Pointer to the data holding the acknowledgment report.
|
||||||
*
|
*
|
||||||
* @return RETURN_OK if successful, otherwise an error code.
|
* @return RETURN_OK if successful, otherwise an error code.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t handleAckReport(const uint8_t* data);
|
ReturnValue_t handleAckReport(const uint8_t* data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function handles the data of a execution report.
|
* @brief This function handles the data of a execution report.
|
||||||
*
|
*
|
||||||
* @param data Pointer to the received data packet.
|
* @param data Pointer to the received data packet.
|
||||||
*
|
*
|
||||||
* @return RETURN_OK if successful, otherwise an error code.
|
* @return RETURN_OK if successful, otherwise an error code.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t handleExecutionReport(const uint8_t* data);
|
ReturnValue_t handleExecutionReport(const uint8_t* data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function handles the housekeeping report. This means verifying the CRC of the
|
* @brief This function handles the housekeeping report. This means verifying the CRC of the
|
||||||
* reply and filling the appropriate dataset.
|
* reply and filling the appropriate dataset.
|
||||||
*
|
*
|
||||||
* @param data Pointer to the data buffer holding the housekeeping read report.
|
* @param data Pointer to the data buffer holding the housekeeping read report.
|
||||||
*
|
*
|
||||||
* @return RETURN_OK if successful, otherwise an error code.
|
* @return RETURN_OK if successful, otherwise an error code.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t handleHkReport(const uint8_t* data);
|
ReturnValue_t handleHkReport(const uint8_t* data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function calls the function to check the CRC of the received boot status report
|
* @brief This function calls the function to check the CRC of the received boot status report
|
||||||
* and fills the associated dataset with the boot status information.
|
* and fills the associated dataset with the boot status information.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t handleBootStatusReport(const uint8_t* data);
|
ReturnValue_t handleBootStatusReport(const uint8_t* data);
|
||||||
|
|
||||||
ReturnValue_t handleLatchupStatusReport(const uint8_t* data);
|
ReturnValue_t handleLatchupStatusReport(const uint8_t* data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Depending on the current active command, this function sets the reply id of the
|
* @brief Depending on the current active command, this function sets the reply id of the
|
||||||
* next reply after a successful acknowledgment report has been received. This is
|
* next reply after a successful acknowledgment report has been received. This is
|
||||||
* required by the function getNextReplyLength() to identify the length of the next
|
* required by the function getNextReplyLength() to identify the length of the next
|
||||||
* reply to read.
|
* reply to read.
|
||||||
*/
|
*/
|
||||||
void setNextReplyId();
|
void setNextReplyId();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function handles action message replies in case the telemetry has been
|
* @brief This function handles action message replies in case the telemetry has been
|
||||||
* requested by another object.
|
* requested by another object.
|
||||||
*
|
*
|
||||||
* @param data Pointer to the telemetry data.
|
* @param data Pointer to the telemetry data.
|
||||||
* @param dataSize Size of telemetry in bytes.
|
* @param dataSize Size of telemetry in bytes.
|
||||||
* @param replyId Id of the reply. This will be added to the ActionMessage.
|
* @param replyId Id of the reply. This will be added to the ActionMessage.
|
||||||
*/
|
*/
|
||||||
void handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId);
|
void handleDeviceTM(const uint8_t* data, size_t dataSize, DeviceCommandId_t replyId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function prepares a space packet which does not transport any data in the
|
* @brief This function prepares a space packet which does not transport any data in the
|
||||||
* packet data field apart from the crc.
|
* packet data field apart from the crc.
|
||||||
*/
|
*/
|
||||||
void prepareEmptyCmd(uint16_t apid);
|
void prepareEmptyCmd(uint16_t apid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function initializes the space packet to select the boot image of the MPSoC.
|
* @brief This function initializes the space packet to select the boot image of the MPSoC.
|
||||||
*/
|
*/
|
||||||
void prepareSelBootImageCmd(const uint8_t * commandData);
|
void prepareSelBootImageCmd(const uint8_t* commandData);
|
||||||
|
|
||||||
void prepareDisableHk();
|
void prepareDisableHk();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function fills the commandBuffer with the data to update the time of the
|
* @brief This function fills the commandBuffer with the data to update the time of the
|
||||||
* PLOC supervisor.
|
* PLOC supervisor.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t prepareSetTimeRefCmd();
|
ReturnValue_t prepareSetTimeRefCmd();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function fills the commandBuffer with the data to change the boot timeout
|
* @brief This function fills the commandBuffer with the data to change the boot timeout
|
||||||
* value in the PLOC supervisor.
|
* value in the PLOC supervisor.
|
||||||
*/
|
*/
|
||||||
void prepareSetBootTimeoutCmd(const uint8_t * commandData);
|
void prepareSetBootTimeoutCmd(const uint8_t* commandData);
|
||||||
|
|
||||||
void prepareRestartTriesCmd(const uint8_t * commandData);
|
void prepareRestartTriesCmd(const uint8_t* commandData);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function fills the command buffer with the packet to enable or disable the
|
* @brief This function fills the command buffer with the packet to enable or disable the
|
||||||
* watchdogs on the PLOC.
|
* watchdogs on the PLOC.
|
||||||
*/
|
*/
|
||||||
void prepareWatchdogsEnableCmd(const uint8_t * commandData);
|
void prepareWatchdogsEnableCmd(const uint8_t* commandData);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function fills the command buffer with the packet to set the watchdog timer
|
* @brief This function fills the command buffer with the packet to set the watchdog timer
|
||||||
* of one of the three watchdogs (PS, PL, INT).
|
* of one of the three watchdogs (PS, PL, INT).
|
||||||
*/
|
*/
|
||||||
ReturnValue_t prepareWatchdogsConfigTimeoutCmd(const uint8_t * commandData);
|
ReturnValue_t prepareWatchdogsConfigTimeoutCmd(const uint8_t* commandData);
|
||||||
|
|
||||||
ReturnValue_t prepareLatchupConfigCmd(const uint8_t* commandData,
|
ReturnValue_t prepareLatchupConfigCmd(const uint8_t* commandData,
|
||||||
DeviceCommandId_t deviceCommand);
|
DeviceCommandId_t deviceCommand);
|
||||||
ReturnValue_t prepareAutoCalibrateAlertCmd(const uint8_t* commandData);
|
ReturnValue_t prepareAutoCalibrateAlertCmd(const uint8_t* commandData);
|
||||||
ReturnValue_t prepareSetAlertLimitCmd(const uint8_t* commandData);
|
ReturnValue_t prepareSetAlertLimitCmd(const uint8_t* commandData);
|
||||||
ReturnValue_t prepareSetAlertIrqFilterCmd(const uint8_t* commandData);
|
ReturnValue_t prepareSetAlertIrqFilterCmd(const uint8_t* commandData);
|
||||||
ReturnValue_t prepareSetAdcSweetPeriodCmd(const uint8_t* commandData);
|
ReturnValue_t prepareSetAdcSweetPeriodCmd(const uint8_t* commandData);
|
||||||
void prepareSetAdcEnabledChannelsCmd(const uint8_t* commandData);
|
void prepareSetAdcEnabledChannelsCmd(const uint8_t* commandData);
|
||||||
void prepareSetAdcWindowAndStrideCmd(const uint8_t* commandData);
|
void prepareSetAdcWindowAndStrideCmd(const uint8_t* commandData);
|
||||||
void prepareSetAdcThresholdCmd(const uint8_t* commandData);
|
void prepareSetAdcThresholdCmd(const uint8_t* commandData);
|
||||||
void prepareEnableNvmsCmd(const uint8_t* commandData);
|
void prepareEnableNvmsCmd(const uint8_t* commandData);
|
||||||
void prepareSelectNvmCmd(const uint8_t* commandData);
|
void prepareSelectNvmCmd(const uint8_t* commandData);
|
||||||
ReturnValue_t prepareRunAutoEmTest(const uint8_t* commandData);
|
ReturnValue_t prepareRunAutoEmTest(const uint8_t* commandData);
|
||||||
ReturnValue_t prepareWipeMramCmd(const uint8_t* commandData);
|
ReturnValue_t prepareWipeMramCmd(const uint8_t* commandData);
|
||||||
ReturnValue_t prepareDumpMramCmd(const uint8_t* commandData);
|
ReturnValue_t prepareDumpMramCmd(const uint8_t* commandData);
|
||||||
void preparePrintCpuStatsCmd(const uint8_t* commandData);
|
void preparePrintCpuStatsCmd(const uint8_t* commandData);
|
||||||
void prepareSetDbgVerbosityCmd(const uint8_t* commandData);
|
void prepareSetDbgVerbosityCmd(const uint8_t* commandData);
|
||||||
void prepareSetGpioCmd(const uint8_t* commandData);
|
void prepareSetGpioCmd(const uint8_t* commandData);
|
||||||
void prepareReadGpioCmd(const uint8_t* commandData);
|
void prepareReadGpioCmd(const uint8_t* commandData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Copies the content of a space packet to the command buffer.
|
||||||
|
*/
|
||||||
|
void packetToOutBuffer(uint8_t* packetData, size_t fullSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Copies the content of a space packet to the command buffer.
|
* @brief In case an acknowledgment failure reply has been received this function disables
|
||||||
*/
|
* all previously enabled commands and resets the exepected replies variable of an
|
||||||
void packetToOutBuffer(uint8_t* packetData, size_t fullSize);
|
* active command.
|
||||||
|
*/
|
||||||
|
void disableAllReplies();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief In case an acknowledgment failure reply has been received this function disables
|
* @brief This function sends a failure report if the active action was commanded by an other
|
||||||
* all previously enabled commands and resets the exepected replies variable of an
|
* object.
|
||||||
* active command.
|
*
|
||||||
*/
|
* @param replyId The id of the reply which signals a failure.
|
||||||
void disableAllReplies();
|
* @param status A status byte which gives information about the failure type.
|
||||||
|
*/
|
||||||
|
void sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function sends a failure report if the active action was commanded by an other
|
* @brief This function disables the execution report reply. Within this function also the
|
||||||
* object.
|
* the variable expectedReplies of an active command will be set to 0.
|
||||||
*
|
*/
|
||||||
* @param replyId The id of the reply which signals a failure.
|
void disableExeReportReply();
|
||||||
* @param status A status byte which gives information about the failure type.
|
|
||||||
*/
|
|
||||||
void sendFailureReport(DeviceCommandId_t replyId, ReturnValue_t status);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function disables the execution report reply. Within this function also the
|
* @brief Function is called in scanForReply and fills the spacePacketBuffer with the read
|
||||||
* the variable expectedReplies of an active command will be set to 0.
|
* data until a full packet has been received.
|
||||||
*/
|
*/
|
||||||
void disableExeReportReply();
|
ReturnValue_t parseMramPackets(const uint8_t* packet, size_t remainingSize, size_t* foundlen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Function is called in scanForReply and fills the spacePacketBuffer with the read
|
* @brief This function generates the Service 8 packets for the MRAM dump data.
|
||||||
* data until a full packet has been received.
|
*/
|
||||||
*/
|
ReturnValue_t handleMramDumpPacket(DeviceCommandId_t id);
|
||||||
ReturnValue_t parseMramPackets(const uint8_t *packet, size_t remainingSize, size_t* foundlen);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function generates the Service 8 packets for the MRAM dump data.
|
* @brief With this function the number of expected replies following an MRAM dump command
|
||||||
*/
|
* will be increased. This is necessary to release the command in case not all replies
|
||||||
ReturnValue_t handleMramDumpPacket(DeviceCommandId_t id);
|
* have been received.
|
||||||
|
*/
|
||||||
|
void increaseExpectedMramReplies(DeviceCommandId_t id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief With this function the number of expected replies following an MRAM dump command
|
* @brief Function checks if the packet written to the space packet buffer is really a
|
||||||
* will be increased. This is necessary to release the command in case not all replies
|
* MRAM dump packet.
|
||||||
* have been received.
|
*/
|
||||||
*/
|
ReturnValue_t checkMramPacketApid();
|
||||||
void increaseExpectedMramReplies(DeviceCommandId_t id);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Function checks if the packet written to the space packet buffer is really a
|
* @brief Writes the data of the MRAM dump to a file. The file will be created when receiving
|
||||||
* MRAM dump packet.
|
* the first packet.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t checkMramPacketApid();
|
ReturnValue_t handleMramDumpFile(DeviceCommandId_t id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Writes the data of the MRAM dump to a file. The file will be created when receiving
|
* @brief Extracts the length field of a spacePacket referenced by the spacePacket pointer.
|
||||||
* the first packet.
|
*
|
||||||
*/
|
* @param spacePacket Pointer to the buffer holding the space packet.
|
||||||
ReturnValue_t handleMramDumpFile(DeviceCommandId_t id);
|
*
|
||||||
|
* @return The value stored in the length field of the data field.
|
||||||
|
*/
|
||||||
|
uint16_t readSpacePacketLength(uint8_t* spacePacket);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extracts the length field of a spacePacket referenced by the spacePacket pointer.
|
* @brief Extracts the sequence flags from a space packet referenced by the spacePacket
|
||||||
*
|
* pointer.
|
||||||
* @param spacePacket Pointer to the buffer holding the space packet.
|
*
|
||||||
*
|
* @param spacePacket Pointer to the buffer holding the space packet.
|
||||||
* @return The value stored in the length field of the data field.
|
*
|
||||||
*/
|
* @return uint8_t where the two least significant bits hold the sequence flags.
|
||||||
uint16_t readSpacePacketLength(uint8_t* spacePacket);
|
*/
|
||||||
|
uint8_t readSequenceFlags(uint8_t* spacePacket);
|
||||||
|
|
||||||
/**
|
ReturnValue_t createMramDumpFile();
|
||||||
* @brief Extracts the sequence flags from a space packet referenced by the spacePacket
|
ReturnValue_t getTimeStampString(std::string& timeStamp);
|
||||||
* pointer.
|
|
||||||
*
|
|
||||||
* @param spacePacket Pointer to the buffer holding the space packet.
|
|
||||||
*
|
|
||||||
* @return uint8_t where the two least significant bits hold the sequence flags.
|
|
||||||
*/
|
|
||||||
uint8_t readSequenceFlags(uint8_t* spacePacket);
|
|
||||||
|
|
||||||
ReturnValue_t createMramDumpFile();
|
|
||||||
ReturnValue_t getTimeStampString(std::string& timeStamp);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_ */
|
#endif /* MISSION_DEVICES_PLOCSUPERVISORHANDLER_H_ */
|
||||||
|
@ -1,405 +1,393 @@
|
|||||||
#include "fsfw/ipc/QueueFactory.h"
|
|
||||||
#include "PlocUpdater.h"
|
#include "PlocUpdater.h"
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
PlocUpdater::PlocUpdater(object_id_t objectId) :
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
SystemObject(objectId), commandActionHelper(this), actionHelper(this, nullptr) {
|
|
||||||
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
|
PlocUpdater::PlocUpdater(object_id_t objectId)
|
||||||
|
: SystemObject(objectId), commandActionHelper(this), actionHelper(this, nullptr) {
|
||||||
|
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
PlocUpdater::~PlocUpdater() {
|
PlocUpdater::~PlocUpdater() {}
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t PlocUpdater::initialize() {
|
ReturnValue_t PlocUpdater::initialize() {
|
||||||
#if BOARD_TE0720 == 0
|
#if BOARD_TE0720 == 0
|
||||||
sdcMan = SdCardManager::instance();
|
sdcMan = SdCardManager::instance();
|
||||||
#endif
|
#endif
|
||||||
ReturnValue_t result = SystemObject::initialize();
|
ReturnValue_t result = SystemObject::initialize();
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
result = commandActionHelper.initialize();
|
result = commandActionHelper.initialize();
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
result = actionHelper.initialize(commandQueue);
|
result = actionHelper.initialize(commandQueue);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PlocUpdater::performOperation(uint8_t operationCode) {
|
ReturnValue_t PlocUpdater::performOperation(uint8_t operationCode) {
|
||||||
readCommandQueue();
|
readCommandQueue();
|
||||||
doStateMachine();
|
doStateMachine();
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PlocUpdater::executeAction(ActionId_t actionId,
|
ReturnValue_t PlocUpdater::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
|
const uint8_t* data, size_t size) {
|
||||||
ReturnValue_t result = RETURN_FAILED;
|
ReturnValue_t result = RETURN_FAILED;
|
||||||
|
|
||||||
if (state != State::IDLE) {
|
if (state != State::IDLE) {
|
||||||
return IS_BUSY;
|
return IS_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size > MAX_PLOC_UPDATE_PATH) {
|
if (size > MAX_PLOC_UPDATE_PATH) {
|
||||||
return NAME_TOO_LONG;
|
return NAME_TOO_LONG;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (actionId) {
|
switch (actionId) {
|
||||||
case UPDATE_A_UBOOT:
|
case UPDATE_A_UBOOT:
|
||||||
image = Image::A;
|
image = Image::A;
|
||||||
partition = Partition::UBOOT;
|
partition = Partition::UBOOT;
|
||||||
break;
|
break;
|
||||||
case UPDATE_A_BITSTREAM:
|
case UPDATE_A_BITSTREAM:
|
||||||
image = Image::A;
|
image = Image::A;
|
||||||
partition = Partition::BITSTREAM;
|
partition = Partition::BITSTREAM;
|
||||||
break;
|
break;
|
||||||
case UPDATE_A_LINUX:
|
case UPDATE_A_LINUX:
|
||||||
image = Image::A;
|
image = Image::A;
|
||||||
partition = Partition::LINUX_OS;
|
partition = Partition::LINUX_OS;
|
||||||
break;
|
break;
|
||||||
case UPDATE_A_APP_SW:
|
case UPDATE_A_APP_SW:
|
||||||
image = Image::A;
|
image = Image::A;
|
||||||
partition = Partition::APP_SW;
|
partition = Partition::APP_SW;
|
||||||
break;
|
break;
|
||||||
case UPDATE_B_UBOOT:
|
case UPDATE_B_UBOOT:
|
||||||
image = Image::B;
|
image = Image::B;
|
||||||
partition = Partition::UBOOT;
|
partition = Partition::UBOOT;
|
||||||
break;
|
break;
|
||||||
case UPDATE_B_BITSTREAM:
|
case UPDATE_B_BITSTREAM:
|
||||||
image = Image::B;
|
image = Image::B;
|
||||||
partition = Partition::BITSTREAM;
|
partition = Partition::BITSTREAM;
|
||||||
break;
|
break;
|
||||||
case UPDATE_B_LINUX:
|
case UPDATE_B_LINUX:
|
||||||
image = Image::B;
|
image = Image::B;
|
||||||
partition = Partition::LINUX_OS;
|
partition = Partition::LINUX_OS;
|
||||||
break;
|
break;
|
||||||
case UPDATE_B_APP_SW:
|
case UPDATE_B_APP_SW:
|
||||||
image = Image::B;
|
image = Image::B;
|
||||||
partition = Partition::APP_SW;
|
partition = Partition::APP_SW;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return INVALID_ACTION_ID;
|
return INVALID_ACTION_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = getImageLocation(data, size);
|
result = getImageLocation(data, size);
|
||||||
|
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
state = State::UPDATE_AVAILABLE;
|
state = State::UPDATE_AVAILABLE;
|
||||||
|
|
||||||
return EXECUTION_FINISHED;
|
return EXECUTION_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t PlocUpdater::getCommandQueue() const {
|
MessageQueueId_t PlocUpdater::getCommandQueue() const { return commandQueue->getId(); }
|
||||||
return commandQueue->getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageQueueIF* PlocUpdater::getCommandQueuePtr() {
|
MessageQueueIF* PlocUpdater::getCommandQueuePtr() { return commandQueue; }
|
||||||
return commandQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlocUpdater::readCommandQueue() {
|
void PlocUpdater::readCommandQueue() {
|
||||||
CommandMessage message;
|
CommandMessage message;
|
||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
|
|
||||||
for (result = commandQueue->receiveMessage(&message); result == HasReturnvaluesIF::RETURN_OK;
|
for (result = commandQueue->receiveMessage(&message); result == HasReturnvaluesIF::RETURN_OK;
|
||||||
result = commandQueue->receiveMessage(&message)) {
|
result = commandQueue->receiveMessage(&message)) {
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
result = actionHelper.handleActionMessage(&message);
|
|
||||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = commandActionHelper.handleReply(&message);
|
|
||||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
sif::debug << "PlocUpdater::readCommandQueue: Received message with invalid format"
|
|
||||||
<< std::endl;
|
|
||||||
}
|
}
|
||||||
|
result = actionHelper.handleActionMessage(&message);
|
||||||
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = commandActionHelper.handleReply(&message);
|
||||||
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sif::debug << "PlocUpdater::readCommandQueue: Received message with invalid format"
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlocUpdater::doStateMachine() {
|
void PlocUpdater::doStateMachine() {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case State::IDLE:
|
case State::IDLE:
|
||||||
break;
|
break;
|
||||||
case State::UPDATE_AVAILABLE:
|
case State::UPDATE_AVAILABLE:
|
||||||
commandUpdateAvailable();
|
commandUpdateAvailable();
|
||||||
break;
|
break;
|
||||||
case State::UPDATE_TRANSFER:
|
case State::UPDATE_TRANSFER:
|
||||||
commandUpdatePacket();
|
commandUpdatePacket();
|
||||||
break;
|
break;
|
||||||
case State::UPDATE_VERIFY:
|
case State::UPDATE_VERIFY:
|
||||||
commandUpdateVerify();
|
commandUpdateVerify();
|
||||||
break;
|
break;
|
||||||
case State::COMMAND_EXECUTING:
|
case State::COMMAND_EXECUTING:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sif::debug << "PlocUpdater::doStateMachine: Invalid state" << std::endl;
|
sif::debug << "PlocUpdater::doStateMachine: Invalid state" << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PlocUpdater::checkNameLength(size_t size) {
|
ReturnValue_t PlocUpdater::checkNameLength(size_t size) {
|
||||||
if (size > MAX_PLOC_UPDATE_PATH) {
|
if (size > MAX_PLOC_UPDATE_PATH) {
|
||||||
return NAME_TOO_LONG;
|
return NAME_TOO_LONG;
|
||||||
}
|
}
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) {
|
ReturnValue_t PlocUpdater::getImageLocation(const uint8_t* data, size_t size) {
|
||||||
ReturnValue_t result = checkNameLength(size);
|
ReturnValue_t result = checkNameLength(size);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if BOARD_TE0720 == 0
|
#if BOARD_TE0720 == 0
|
||||||
// Check if file is stored on SD card and if associated SD card is mounted
|
// Check if file is stored on SD card and if associated SD card is mounted
|
||||||
if (std::string(reinterpret_cast<const char*>(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_0_MOUNT_POINT)) {
|
if (std::string(reinterpret_cast<const char*>(data), SD_PREFIX_LENGTH) ==
|
||||||
if (!sdcMan->isSdCardMounted(sd::SLOT_0)) {
|
std::string(SdCardManager::SD_0_MOUNT_POINT)) {
|
||||||
sif::warning << "PlocUpdater::getImageLocation: SD card 0 not mounted" << std::endl;
|
if (!sdcMan->isSdCardMounted(sd::SLOT_0)) {
|
||||||
return SD_NOT_MOUNTED;
|
sif::warning << "PlocUpdater::getImageLocation: SD card 0 not mounted" << std::endl;
|
||||||
}
|
return SD_NOT_MOUNTED;
|
||||||
}
|
}
|
||||||
else if (std::string(reinterpret_cast<const char*>(data), SD_PREFIX_LENGTH) == std::string(SdCardManager::SD_1_MOUNT_POINT)) {
|
} else if (std::string(reinterpret_cast<const char*>(data), SD_PREFIX_LENGTH) ==
|
||||||
if (!sdcMan->isSdCardMounted(sd::SLOT_0)) {
|
std::string(SdCardManager::SD_1_MOUNT_POINT)) {
|
||||||
sif::warning << "PlocUpdater::getImageLocation: SD card 1 not mounted" << std::endl;
|
if (!sdcMan->isSdCardMounted(sd::SLOT_0)) {
|
||||||
return SD_NOT_MOUNTED;
|
sif::warning << "PlocUpdater::getImageLocation: SD card 1 not mounted" << std::endl;
|
||||||
}
|
return SD_NOT_MOUNTED;
|
||||||
}
|
|
||||||
else {
|
|
||||||
//update image not stored on SD card
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// update image not stored on SD card
|
||||||
|
}
|
||||||
#endif /* BOARD_TE0720 == 0 */
|
#endif /* BOARD_TE0720 == 0 */
|
||||||
|
|
||||||
updateFile = std::string(reinterpret_cast<const char*>(data), size);
|
updateFile = std::string(reinterpret_cast<const char*>(data), size);
|
||||||
|
|
||||||
// Check if file exists
|
// Check if file exists
|
||||||
if(not std::filesystem::exists(updateFile)) {
|
if (not std::filesystem::exists(updateFile)) {
|
||||||
return FILE_NOT_EXISTS;
|
return FILE_NOT_EXISTS;
|
||||||
}
|
}
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlocUpdater::stepSuccessfulReceived(ActionId_t actionId,
|
void PlocUpdater::stepSuccessfulReceived(ActionId_t actionId, uint8_t step) {}
|
||||||
uint8_t step) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlocUpdater::stepFailedReceived(ActionId_t actionId, uint8_t step,
|
void PlocUpdater::stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) {}
|
||||||
ReturnValue_t returnCode) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlocUpdater::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) {
|
void PlocUpdater::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlocUpdater::completionSuccessfulReceived(ActionId_t actionId) {
|
void PlocUpdater::completionSuccessfulReceived(ActionId_t actionId) {
|
||||||
switch (pendingCommand) {
|
switch (pendingCommand) {
|
||||||
case (PLOC_SPV::UPDATE_AVAILABLE):
|
case (PLOC_SPV::UPDATE_AVAILABLE):
|
||||||
state = State::UPDATE_TRANSFER;
|
state = State::UPDATE_TRANSFER;
|
||||||
break;
|
break;
|
||||||
case (PLOC_SPV::UPDATE_IMAGE_DATA):
|
case (PLOC_SPV::UPDATE_IMAGE_DATA):
|
||||||
if (remainingPackets == 0) {
|
if (remainingPackets == 0) {
|
||||||
packetsSent = 0; // Reset packets sent variable for next update sequence
|
packetsSent = 0; // Reset packets sent variable for next update sequence
|
||||||
state = State::UPDATE_VERIFY;
|
state = State::UPDATE_VERIFY;
|
||||||
}
|
} else {
|
||||||
else {
|
state = State::UPDATE_TRANSFER;
|
||||||
state = State::UPDATE_TRANSFER;
|
}
|
||||||
}
|
break;
|
||||||
break;
|
|
||||||
case (PLOC_SPV::UPDATE_VERIFY):
|
case (PLOC_SPV::UPDATE_VERIFY):
|
||||||
triggerEvent(UPDATE_FINISHED);
|
triggerEvent(UPDATE_FINISHED);
|
||||||
state = State::IDLE;
|
state = State::IDLE;
|
||||||
pendingCommand = PLOC_SPV::NONE;
|
pendingCommand = PLOC_SPV::NONE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sif::debug << "PlocUpdater::completionSuccessfulReceived: Invalid pending command"
|
sif::debug << "PlocUpdater::completionSuccessfulReceived: Invalid pending command"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
state = State::IDLE;
|
state = State::IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlocUpdater::completionFailedReceived(ActionId_t actionId,
|
void PlocUpdater::completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) {
|
||||||
ReturnValue_t returnCode) {
|
switch (pendingCommand) {
|
||||||
switch(pendingCommand) {
|
case (PLOC_SPV::UPDATE_AVAILABLE): {
|
||||||
case(PLOC_SPV::UPDATE_AVAILABLE): {
|
triggerEvent(UPDATE_AVAILABLE_FAILED);
|
||||||
triggerEvent(UPDATE_AVAILABLE_FAILED);
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case(PLOC_SPV::UPDATE_IMAGE_DATA): {
|
case (PLOC_SPV::UPDATE_IMAGE_DATA): {
|
||||||
triggerEvent(UPDATE_TRANSFER_FAILED, packetsSent);
|
triggerEvent(UPDATE_TRANSFER_FAILED, packetsSent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(PLOC_SPV::UPDATE_VERIFY): {
|
case (PLOC_SPV::UPDATE_VERIFY): {
|
||||||
triggerEvent(UPDATE_VERIFY_FAILED);
|
triggerEvent(UPDATE_VERIFY_FAILED);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
sif::debug << "PlocUpdater::completionFailedReceived: Invalid pending command "
|
sif::debug << "PlocUpdater::completionFailedReceived: Invalid pending command " << std::endl;
|
||||||
<< std::endl;
|
break;
|
||||||
break;
|
}
|
||||||
}
|
state = State::IDLE;
|
||||||
state = State::IDLE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlocUpdater::commandUpdateAvailable() {
|
void PlocUpdater::commandUpdateAvailable() {
|
||||||
ReturnValue_t result = RETURN_OK;
|
ReturnValue_t result = RETURN_OK;
|
||||||
|
|
||||||
if (not std::filesystem::exists(updateFile)) {
|
if (not std::filesystem::exists(updateFile)) {
|
||||||
triggerEvent(UPDATE_FILE_NOT_EXISTS, static_cast<uint8_t>(state));
|
triggerEvent(UPDATE_FILE_NOT_EXISTS, static_cast<uint8_t>(state));
|
||||||
state = State::IDLE;
|
state = State::IDLE;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ifstream file(updateFile, std::ifstream::binary);
|
|
||||||
file.seekg(0, file.end);
|
|
||||||
imageSize = static_cast<size_t>(file.tellg());
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
numOfUpdatePackets = imageSize / MAX_SP_DATA ;
|
|
||||||
if (imageSize % MAX_SP_DATA) {
|
|
||||||
numOfUpdatePackets++;
|
|
||||||
}
|
|
||||||
|
|
||||||
remainingPackets = numOfUpdatePackets;
|
|
||||||
packetsSent = 0;
|
|
||||||
|
|
||||||
calcImageCrc();
|
|
||||||
|
|
||||||
PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_AVAILABLE, static_cast<uint8_t>(image),
|
|
||||||
static_cast<uint8_t>(partition), imageSize, imageCrc, numOfUpdatePackets);
|
|
||||||
|
|
||||||
result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER,
|
|
||||||
PLOC_SPV::UPDATE_AVAILABLE, packet.getWholeData(), packet.getFullSize());
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update available"
|
|
||||||
<< " packet to supervisor handler" << std::endl;
|
|
||||||
triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_AVAILABLE);
|
|
||||||
state = State::IDLE;
|
|
||||||
pendingCommand = PLOC_SPV::NONE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pendingCommand = PLOC_SPV::UPDATE_AVAILABLE;
|
|
||||||
state = State::COMMAND_EXECUTING;
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ifstream file(updateFile, std::ifstream::binary);
|
||||||
|
file.seekg(0, file.end);
|
||||||
|
imageSize = static_cast<size_t>(file.tellg());
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
numOfUpdatePackets = imageSize / MAX_SP_DATA;
|
||||||
|
if (imageSize % MAX_SP_DATA) {
|
||||||
|
numOfUpdatePackets++;
|
||||||
|
}
|
||||||
|
|
||||||
|
remainingPackets = numOfUpdatePackets;
|
||||||
|
packetsSent = 0;
|
||||||
|
|
||||||
|
calcImageCrc();
|
||||||
|
|
||||||
|
PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_AVAILABLE, static_cast<uint8_t>(image),
|
||||||
|
static_cast<uint8_t>(partition), imageSize, imageCrc,
|
||||||
|
numOfUpdatePackets);
|
||||||
|
|
||||||
|
result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER,
|
||||||
|
PLOC_SPV::UPDATE_AVAILABLE, packet.getWholeData(),
|
||||||
|
packet.getFullSize());
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update available"
|
||||||
|
<< " packet to supervisor handler" << std::endl;
|
||||||
|
triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_AVAILABLE);
|
||||||
|
state = State::IDLE;
|
||||||
|
pendingCommand = PLOC_SPV::NONE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pendingCommand = PLOC_SPV::UPDATE_AVAILABLE;
|
||||||
|
state = State::COMMAND_EXECUTING;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlocUpdater::commandUpdatePacket() {
|
void PlocUpdater::commandUpdatePacket() {
|
||||||
ReturnValue_t result = RETURN_OK;
|
ReturnValue_t result = RETURN_OK;
|
||||||
uint16_t payloadLength = 0;
|
uint16_t payloadLength = 0;
|
||||||
|
|
||||||
if (not std::filesystem::exists(updateFile)) {
|
if (not std::filesystem::exists(updateFile)) {
|
||||||
triggerEvent(UPDATE_FILE_NOT_EXISTS, static_cast<uint8_t>(state), packetsSent);
|
triggerEvent(UPDATE_FILE_NOT_EXISTS, static_cast<uint8_t>(state), packetsSent);
|
||||||
state = State::IDLE;
|
state = State::IDLE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ifstream file(updateFile, std::ifstream::binary);
|
std::ifstream file(updateFile, std::ifstream::binary);
|
||||||
file.seekg(packetsSent * MAX_SP_DATA, file.beg);
|
file.seekg(packetsSent * MAX_SP_DATA, file.beg);
|
||||||
|
|
||||||
if (remainingPackets == 1) {
|
if (remainingPackets == 1) {
|
||||||
payloadLength = imageSize - static_cast<uint16_t>(file.tellg());
|
payloadLength = imageSize - static_cast<uint16_t>(file.tellg());
|
||||||
}
|
} else {
|
||||||
else {
|
payloadLength = MAX_SP_DATA;
|
||||||
payloadLength = MAX_SP_DATA;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
PLOC_SPV::UpdatePacket packet(payloadLength);
|
PLOC_SPV::UpdatePacket packet(payloadLength);
|
||||||
file.read(reinterpret_cast<char*>(packet.getDataFieldPointer()), payloadLength);
|
file.read(reinterpret_cast<char*>(packet.getDataFieldPointer()), payloadLength);
|
||||||
file.close();
|
file.close();
|
||||||
// sequence count of first packet is 1
|
// sequence count of first packet is 1
|
||||||
packet.setPacketSequenceCount((packetsSent + 1) & PLOC_SPV::SEQUENCE_COUNT_MASK);
|
packet.setPacketSequenceCount((packetsSent + 1) & PLOC_SPV::SEQUENCE_COUNT_MASK);
|
||||||
if (numOfUpdatePackets > 1) {
|
if (numOfUpdatePackets > 1) {
|
||||||
adjustSequenceFlags(packet);
|
adjustSequenceFlags(packet);
|
||||||
}
|
}
|
||||||
packet.makeCrc();
|
packet.makeCrc();
|
||||||
|
|
||||||
result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER,
|
result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER,
|
||||||
PLOC_SPV::UPDATE_IMAGE_DATA, packet.getWholeData(), packet.getFullSize());
|
PLOC_SPV::UPDATE_IMAGE_DATA, packet.getWholeData(),
|
||||||
|
packet.getFullSize());
|
||||||
|
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update"
|
sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update"
|
||||||
<< " packet to supervisor handler" << std::endl;
|
<< " packet to supervisor handler" << std::endl;
|
||||||
triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_IMAGE_DATA);
|
triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_IMAGE_DATA);
|
||||||
state = State::IDLE;
|
state = State::IDLE;
|
||||||
pendingCommand = PLOC_SPV::NONE;
|
pendingCommand = PLOC_SPV::NONE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
remainingPackets--;
|
remainingPackets--;
|
||||||
packetsSent++;
|
packetsSent++;
|
||||||
|
|
||||||
pendingCommand = PLOC_SPV::UPDATE_IMAGE_DATA;
|
pendingCommand = PLOC_SPV::UPDATE_IMAGE_DATA;
|
||||||
state = State::COMMAND_EXECUTING;
|
state = State::COMMAND_EXECUTING;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlocUpdater::commandUpdateVerify() {
|
void PlocUpdater::commandUpdateVerify() {
|
||||||
ReturnValue_t result = RETURN_OK;
|
ReturnValue_t result = RETURN_OK;
|
||||||
|
|
||||||
PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_VERIFY, static_cast<uint8_t>(image),
|
PLOC_SPV::UpdateInfo packet(PLOC_SPV::APID_UPDATE_VERIFY, static_cast<uint8_t>(image),
|
||||||
static_cast<uint8_t>(partition), imageSize, imageCrc, numOfUpdatePackets);
|
static_cast<uint8_t>(partition), imageSize, imageCrc,
|
||||||
|
numOfUpdatePackets);
|
||||||
|
|
||||||
result = commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER,
|
result =
|
||||||
PLOC_SPV::UPDATE_VERIFY, packet.getWholeData(), packet.getFullSize());
|
commandActionHelper.commandAction(objects::PLOC_SUPERVISOR_HANDLER, PLOC_SPV::UPDATE_VERIFY,
|
||||||
if (result != RETURN_OK) {
|
packet.getWholeData(), packet.getFullSize());
|
||||||
sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update available"
|
if (result != RETURN_OK) {
|
||||||
<< " packet to supervisor handler" << std::endl;
|
sif::warning << "PlocUpdater::commandUpdateAvailable: Failed to send update available"
|
||||||
triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_VERIFY);
|
<< " packet to supervisor handler" << std::endl;
|
||||||
state = State::IDLE;
|
triggerEvent(ACTION_COMMANDING_FAILED, result, PLOC_SPV::UPDATE_VERIFY);
|
||||||
pendingCommand = PLOC_SPV::NONE;
|
state = State::IDLE;
|
||||||
return;
|
pendingCommand = PLOC_SPV::NONE;
|
||||||
}
|
|
||||||
state = State::COMMAND_EXECUTING;
|
|
||||||
pendingCommand = PLOC_SPV::UPDATE_VERIFY;
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
state = State::COMMAND_EXECUTING;
|
||||||
|
pendingCommand = PLOC_SPV::UPDATE_VERIFY;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlocUpdater::calcImageCrc() {
|
void PlocUpdater::calcImageCrc() {
|
||||||
std::ifstream file(updateFile, std::ifstream::binary);
|
std::ifstream file(updateFile, std::ifstream::binary);
|
||||||
file.seekg(0, file.end);
|
file.seekg(0, file.end);
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
uint32_t bit;
|
uint32_t bit;
|
||||||
uint32_t remainder = INITIAL_REMAINDER_32;
|
uint32_t remainder = INITIAL_REMAINDER_32;
|
||||||
char input;
|
char input;
|
||||||
for (count = 0; count < imageSize; count++) {
|
for (count = 0; count < imageSize; count++) {
|
||||||
file.seekg(count, file.beg);
|
file.seekg(count, file.beg);
|
||||||
file.read(&input, 1);
|
file.read(&input, 1);
|
||||||
remainder ^= (input << 16);
|
remainder ^= (input << 16);
|
||||||
for (bit = 8; bit > 0; --bit) {
|
for (bit = 8; bit > 0; --bit) {
|
||||||
if (remainder & TOPBIT_32) {
|
if (remainder & TOPBIT_32) {
|
||||||
remainder = (remainder << 1) ^ POLYNOMIAL_32;
|
remainder = (remainder << 1) ^ POLYNOMIAL_32;
|
||||||
} else {
|
} else {
|
||||||
remainder = (remainder << 1);
|
remainder = (remainder << 1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
file.close();
|
}
|
||||||
imageCrc = (remainder ^ FINAL_XOR_VALUE_32);
|
file.close();
|
||||||
|
imageCrc = (remainder ^ FINAL_XOR_VALUE_32);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlocUpdater::adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet) {
|
void PlocUpdater::adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet) {
|
||||||
if (packetsSent == 0) {
|
if (packetsSent == 0) {
|
||||||
packet.setSequenceFlags(static_cast<uint8_t>(PLOC_SPV::SequenceFlags::FIRST_PKT));
|
packet.setSequenceFlags(static_cast<uint8_t>(PLOC_SPV::SequenceFlags::FIRST_PKT));
|
||||||
}
|
} else if (remainingPackets == 1) {
|
||||||
else if (remainingPackets == 1) {
|
packet.setSequenceFlags(static_cast<uint8_t>(PLOC_SPV::SequenceFlags::LAST_PKT));
|
||||||
packet.setSequenceFlags(static_cast<uint8_t>(PLOC_SPV::SequenceFlags::LAST_PKT));
|
} else {
|
||||||
}
|
packet.setSequenceFlags(static_cast<uint8_t>(PLOC_SPV::SequenceFlags::CONTINUED_PKT));
|
||||||
else {
|
}
|
||||||
packet.setSequenceFlags(static_cast<uint8_t>(PLOC_SPV::SequenceFlags::CONTINUED_PKT));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,181 +2,170 @@
|
|||||||
#define MISSION_DEVICES_PLOCUPDATER_H_
|
#define MISSION_DEVICES_PLOCUPDATER_H_
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
|
#include "bsp_q7s/memory/SdCardManager.h"
|
||||||
#include "devicedefinitions/PlocSupervisorDefinitions.h"
|
#include "devicedefinitions/PlocSupervisorDefinitions.h"
|
||||||
|
|
||||||
#include "fsfw/action/CommandActionHelper.h"
|
|
||||||
#include "fsfw/action/ActionHelper.h"
|
#include "fsfw/action/ActionHelper.h"
|
||||||
#include "fsfw/action/HasActionsIF.h"
|
#include "fsfw/action/CommandActionHelper.h"
|
||||||
#include "fsfw/action/CommandsActionsIF.h"
|
#include "fsfw/action/CommandsActionsIF.h"
|
||||||
|
#include "fsfw/action/HasActionsIF.h"
|
||||||
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||||
#include "fsfw/objectmanager/SystemObject.h"
|
|
||||||
#include "bsp_q7s/memory/SdCardManager.h"
|
|
||||||
#include "linux/fsfwconfig/objects/systemObjectList.h"
|
|
||||||
#include "fsfw/tmtcpacket/SpacePacket.h"
|
#include "fsfw/tmtcpacket/SpacePacket.h"
|
||||||
|
#include "linux/fsfwconfig/objects/systemObjectList.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief An object of this class can be used to perform the software updates of the PLOC. The
|
* @brief An object of this class can be used to perform the software updates of the PLOC. The
|
||||||
* software update will be read from one of the SD cards, split into multiple space
|
* software update will be read from one of the SD cards, split into multiple space
|
||||||
* packets and sent to the PlocSupervisorHandler.
|
* packets and sent to the PlocSupervisorHandler.
|
||||||
*
|
*
|
||||||
* @details The MPSoC has two boot memories (NVM0 and NVM1) where each stores two images (Partition A
|
* @details The MPSoC has two boot memories (NVM0 and NVM1) where each stores two images (Partition
|
||||||
* and Partition B)
|
* A and Partition B)
|
||||||
*
|
*
|
||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
*/
|
*/
|
||||||
class PlocUpdater : public SystemObject,
|
class PlocUpdater : public SystemObject,
|
||||||
public HasActionsIF,
|
public HasActionsIF,
|
||||||
public ExecutableObjectIF,
|
public ExecutableObjectIF,
|
||||||
public HasReturnvaluesIF,
|
public HasReturnvaluesIF,
|
||||||
public CommandsActionsIF {
|
public CommandsActionsIF {
|
||||||
public:
|
public:
|
||||||
|
static const ActionId_t UPDATE_A_UBOOT = 0;
|
||||||
|
static const ActionId_t UPDATE_A_BITSTREAM = 1;
|
||||||
|
static const ActionId_t UPDATE_A_LINUX = 2;
|
||||||
|
static const ActionId_t UPDATE_A_APP_SW = 3;
|
||||||
|
static const ActionId_t UPDATE_B_UBOOT = 4;
|
||||||
|
static const ActionId_t UPDATE_B_BITSTREAM = 5;
|
||||||
|
static const ActionId_t UPDATE_B_LINUX = 6;
|
||||||
|
static const ActionId_t UPDATE_B_APP_SW = 7;
|
||||||
|
|
||||||
static const ActionId_t UPDATE_A_UBOOT = 0;
|
PlocUpdater(object_id_t objectId);
|
||||||
static const ActionId_t UPDATE_A_BITSTREAM = 1;
|
virtual ~PlocUpdater();
|
||||||
static const ActionId_t UPDATE_A_LINUX = 2;
|
|
||||||
static const ActionId_t UPDATE_A_APP_SW = 3;
|
|
||||||
static const ActionId_t UPDATE_B_UBOOT = 4;
|
|
||||||
static const ActionId_t UPDATE_B_BITSTREAM = 5;
|
|
||||||
static const ActionId_t UPDATE_B_LINUX = 6;
|
|
||||||
static const ActionId_t UPDATE_B_APP_SW = 7;
|
|
||||||
|
|
||||||
PlocUpdater(object_id_t objectId);
|
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||||
virtual ~PlocUpdater();
|
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
|
const uint8_t* data, size_t size);
|
||||||
|
MessageQueueId_t getCommandQueue() const;
|
||||||
|
ReturnValue_t initialize() override;
|
||||||
|
MessageQueueIF* getCommandQueuePtr() override;
|
||||||
|
void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override;
|
||||||
|
void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) override;
|
||||||
|
void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) override;
|
||||||
|
void completionSuccessfulReceived(ActionId_t actionId) override;
|
||||||
|
void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override;
|
||||||
|
|
||||||
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
private:
|
||||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_UPDATER;
|
||||||
const uint8_t* data, size_t size);
|
|
||||||
MessageQueueId_t getCommandQueue() const;
|
|
||||||
ReturnValue_t initialize() override;
|
|
||||||
MessageQueueIF* getCommandQueuePtr() override;
|
|
||||||
void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override;
|
|
||||||
void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) override;
|
|
||||||
void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) override;
|
|
||||||
void completionSuccessfulReceived(ActionId_t actionId) override;
|
|
||||||
void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override;
|
|
||||||
|
|
||||||
private:
|
//! [EXPORT] : [COMMENT] Updater is already performing an update
|
||||||
|
static const ReturnValue_t UPDATER_BUSY = MAKE_RETURN_CODE(0xA0);
|
||||||
|
//! [EXPORT] : [COMMENT] Received update command with invalid path string (too long).
|
||||||
|
static const ReturnValue_t NAME_TOO_LONG = MAKE_RETURN_CODE(0xA1);
|
||||||
|
//! [EXPORT] : [COMMENT] Received command to initiate update but SD card with update image not
|
||||||
|
//! mounted.
|
||||||
|
static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA2);
|
||||||
|
//! [EXPORT] : [COMMENT] Update file received with update command does not exist.
|
||||||
|
static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA3);
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::PLOC_UPDATER;
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_UPDATER;
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] Updater is already performing an update
|
//! [EXPORT] : [COMMENT] Try to read update file but the file does not exist.
|
||||||
static const ReturnValue_t UPDATER_BUSY = MAKE_RETURN_CODE(0xA0);
|
//! P1: Indicates in which state the file read fails
|
||||||
//! [EXPORT] : [COMMENT] Received update command with invalid path string (too long).
|
//! P2: During the update transfer the second parameter gives information about the number of
|
||||||
static const ReturnValue_t NAME_TOO_LONG = MAKE_RETURN_CODE(0xA1);
|
//! already sent packets
|
||||||
//! [EXPORT] : [COMMENT] Received command to initiate update but SD card with update image not mounted.
|
static const Event UPDATE_FILE_NOT_EXISTS = MAKE_EVENT(0, severity::LOW);
|
||||||
static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA2);
|
//! [EXPORT] : [COMMENT] Failed to send command to supervisor handler
|
||||||
//! [EXPORT] : [COMMENT] Update file received with update command does not exist.
|
//! P1: Return value of CommandActionHelper::commandAction
|
||||||
static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA3);
|
//! P2: Action ID of command to send
|
||||||
|
static const Event ACTION_COMMANDING_FAILED = MAKE_EVENT(1, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Supervisor handler replied action message indicating a command execution
|
||||||
|
//! failure of the update available command
|
||||||
|
static const Event UPDATE_AVAILABLE_FAILED = MAKE_EVENT(2, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Supervisor handler failed to transfer an update space packet.
|
||||||
|
//! P1: Parameter holds the number of update packets already sent (inclusive the failed packet)
|
||||||
|
static const Event UPDATE_TRANSFER_FAILED = MAKE_EVENT(3, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Supervisor failed to execute the update verify command.
|
||||||
|
static const Event UPDATE_VERIFY_FAILED = MAKE_EVENT(4, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] MPSoC update successful completed
|
||||||
|
static const Event UPDATE_FINISHED = MAKE_EVENT(5, severity::INFO);
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PLOC_UPDATER;
|
static const uint32_t QUEUE_SIZE = config::PLOC_UPDATER_QUEUE_SIZE;
|
||||||
|
static const size_t MAX_PLOC_UPDATE_PATH = 50;
|
||||||
|
static const size_t SD_PREFIX_LENGTH = 8;
|
||||||
|
// Maximum size of update payload data per space packet (max size of space packet is 1024 bytes)
|
||||||
|
static const size_t MAX_SP_DATA = 1016;
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] Try to read update file but the file does not exist.
|
static const uint32_t TOPBIT_32 = (1 << 31);
|
||||||
//! P1: Indicates in which state the file read fails
|
static const uint32_t POLYNOMIAL_32 = 0x04C11DB7;
|
||||||
//! P2: During the update transfer the second parameter gives information about the number of already sent packets
|
static const uint32_t INITIAL_REMAINDER_32 = 0xFFFFFFFF;
|
||||||
static const Event UPDATE_FILE_NOT_EXISTS = MAKE_EVENT(0, severity::LOW);
|
static const uint32_t FINAL_XOR_VALUE_32 = 0xFFFFFFFF;
|
||||||
//! [EXPORT] : [COMMENT] Failed to send command to supervisor handler
|
|
||||||
//! P1: Return value of CommandActionHelper::commandAction
|
|
||||||
//! P2: Action ID of command to send
|
|
||||||
static const Event ACTION_COMMANDING_FAILED = MAKE_EVENT(1, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] Supervisor handler replied action message indicating a command execution failure of the update available command
|
|
||||||
static const Event UPDATE_AVAILABLE_FAILED = MAKE_EVENT(2, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] Supervisor handler failed to transfer an update space packet.
|
|
||||||
//! P1: Parameter holds the number of update packets already sent (inclusive the failed packet)
|
|
||||||
static const Event UPDATE_TRANSFER_FAILED = MAKE_EVENT(3, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] Supervisor failed to execute the update verify command.
|
|
||||||
static const Event UPDATE_VERIFY_FAILED = MAKE_EVENT(4, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] MPSoC update successful completed
|
|
||||||
static const Event UPDATE_FINISHED = MAKE_EVENT(5, severity::INFO);
|
|
||||||
|
|
||||||
static const uint32_t QUEUE_SIZE = config::PLOC_UPDATER_QUEUE_SIZE;
|
MessageQueueIF* commandQueue = nullptr;
|
||||||
static const size_t MAX_PLOC_UPDATE_PATH = 50;
|
|
||||||
static const size_t SD_PREFIX_LENGTH = 8;
|
|
||||||
// Maximum size of update payload data per space packet (max size of space packet is 1024 bytes)
|
|
||||||
static const size_t MAX_SP_DATA = 1016;
|
|
||||||
|
|
||||||
static const uint32_t TOPBIT_32 = (1 << 31);
|
|
||||||
static const uint32_t POLYNOMIAL_32 = 0x04C11DB7;
|
|
||||||
static const uint32_t INITIAL_REMAINDER_32 = 0xFFFFFFFF;
|
|
||||||
static const uint32_t FINAL_XOR_VALUE_32 = 0xFFFFFFFF;
|
|
||||||
|
|
||||||
MessageQueueIF* commandQueue = nullptr;
|
|
||||||
|
|
||||||
#if BOARD_TE0720 == 0
|
#if BOARD_TE0720 == 0
|
||||||
SdCardManager* sdcMan = nullptr;
|
SdCardManager* sdcMan = nullptr;
|
||||||
#endif
|
#endif
|
||||||
CommandActionHelper commandActionHelper;
|
CommandActionHelper commandActionHelper;
|
||||||
|
|
||||||
ActionHelper actionHelper;
|
ActionHelper actionHelper;
|
||||||
|
|
||||||
enum class State: uint8_t {
|
enum class State : uint8_t {
|
||||||
IDLE,
|
IDLE,
|
||||||
UPDATE_AVAILABLE,
|
UPDATE_AVAILABLE,
|
||||||
UPDATE_TRANSFER,
|
UPDATE_TRANSFER,
|
||||||
UPDATE_VERIFY,
|
UPDATE_VERIFY,
|
||||||
COMMAND_EXECUTING
|
COMMAND_EXECUTING
|
||||||
};
|
};
|
||||||
|
|
||||||
State state = State::IDLE;
|
State state = State::IDLE;
|
||||||
|
|
||||||
ActionId_t pendingCommand = PLOC_SPV::NONE;
|
ActionId_t pendingCommand = PLOC_SPV::NONE;
|
||||||
|
|
||||||
enum class Image: uint8_t {
|
enum class Image : uint8_t { NONE, A, B };
|
||||||
NONE,
|
|
||||||
A,
|
|
||||||
B
|
|
||||||
};
|
|
||||||
|
|
||||||
Image image = Image::NONE;
|
Image image = Image::NONE;
|
||||||
|
|
||||||
enum class Partition: uint8_t {
|
enum class Partition : uint8_t { NONE, UBOOT, BITSTREAM, LINUX_OS, APP_SW };
|
||||||
NONE,
|
|
||||||
UBOOT,
|
|
||||||
BITSTREAM,
|
|
||||||
LINUX_OS,
|
|
||||||
APP_SW
|
|
||||||
};
|
|
||||||
|
|
||||||
Partition partition = Partition::NONE;
|
Partition partition = Partition::NONE;
|
||||||
|
|
||||||
uint32_t packetsSent = 0;
|
uint32_t packetsSent = 0;
|
||||||
uint32_t remainingPackets = 0;
|
uint32_t remainingPackets = 0;
|
||||||
// Number of packets required to transfer the update image
|
// Number of packets required to transfer the update image
|
||||||
uint32_t numOfUpdatePackets = 0;
|
uint32_t numOfUpdatePackets = 0;
|
||||||
|
|
||||||
std::string updateFile;
|
std::string updateFile;
|
||||||
uint32_t imageSize = 0;
|
uint32_t imageSize = 0;
|
||||||
uint32_t imageCrc = 0;
|
uint32_t imageCrc = 0;
|
||||||
|
|
||||||
void readCommandQueue();
|
void readCommandQueue();
|
||||||
void doStateMachine();
|
void doStateMachine();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Extracts the path and name of the update image from the service 8 command data.
|
* @brief Extracts the path and name of the update image from the service 8 command data.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t getImageLocation(const uint8_t* data, size_t size);
|
ReturnValue_t getImageLocation(const uint8_t* data, size_t size);
|
||||||
|
|
||||||
ReturnValue_t checkNameLength(size_t size);
|
ReturnValue_t checkNameLength(size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Prepares and sends update available command to PLOC supervisor handler.
|
* @brief Prepares and sends update available command to PLOC supervisor handler.
|
||||||
*/
|
*/
|
||||||
void commandUpdateAvailable();
|
void commandUpdateAvailable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Prepares and sends and update packet to the PLOC supervisor handler.
|
* @brief Prepares and sends and update packet to the PLOC supervisor handler.
|
||||||
*/
|
*/
|
||||||
void commandUpdatePacket();
|
void commandUpdatePacket();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Prepares and sends the update verification packet to the PLOC supervisor handler.
|
* @brief Prepares and sends the update verification packet to the PLOC supervisor handler.
|
||||||
*/
|
*/
|
||||||
void commandUpdateVerify();
|
void commandUpdateVerify();
|
||||||
|
|
||||||
void calcImageCrc();
|
void calcImageCrc();
|
||||||
|
|
||||||
void adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet);
|
void adjustSequenceFlags(PLOC_SPV::UpdatePacket& packet);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_DEVICES_PLOCUPDATER_H_ */
|
#endif /* MISSION_DEVICES_PLOCUPDATER_H_ */
|
||||||
|
@ -3,31 +3,26 @@
|
|||||||
|
|
||||||
#include <fsfw/src/fsfw/serialize/SerialLinkedListAdapter.h>
|
#include <fsfw/src/fsfw/serialize/SerialLinkedListAdapter.h>
|
||||||
|
|
||||||
class MemoryParams: public SerialLinkedListAdapter<SerializeIF> {
|
class MemoryParams : public SerialLinkedListAdapter<SerializeIF> {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
* @param startAddress Start of address range to dump
|
||||||
|
* @param endAddress End of address range to dump
|
||||||
|
*/
|
||||||
|
MemoryParams(uint32_t startAddress, uint32_t endAddress)
|
||||||
|
: startAddress(startAddress), endAddress(endAddress) {
|
||||||
|
setLinks();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
private:
|
||||||
* @brief Constructor
|
void setLinks() {
|
||||||
* @param startAddress Start of address range to dump
|
setStart(&startAddress);
|
||||||
* @param endAddress End of address range to dump
|
startAddress.setNext(&endAddress);
|
||||||
*/
|
}
|
||||||
MemoryParams(uint32_t startAddress, uint32_t endAddress) :
|
|
||||||
startAddress(startAddress), endAddress(endAddress) {
|
|
||||||
setLinks();
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
|
|
||||||
void setLinks() {
|
|
||||||
setStart(&startAddress);
|
|
||||||
startAddress.setNext(&endAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
SerializeElement<uint32_t> startAddress;
|
|
||||||
SerializeElement<uint32_t> endAddress;
|
|
||||||
|
|
||||||
|
SerializeElement<uint32_t> startAddress;
|
||||||
|
SerializeElement<uint32_t> endAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_PLOCMEMDUMPDEFINITIONS_H_ */
|
#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_PLOCMEMDUMPDEFINITIONS_H_ */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,78 +1,62 @@
|
|||||||
#include "ArcsecDatalinkLayer.h"
|
#include "ArcsecDatalinkLayer.h"
|
||||||
|
|
||||||
ArcsecDatalinkLayer::ArcsecDatalinkLayer() {
|
ArcsecDatalinkLayer::ArcsecDatalinkLayer() { slipInit(); }
|
||||||
slipInit();
|
|
||||||
}
|
|
||||||
|
|
||||||
ArcsecDatalinkLayer::~ArcsecDatalinkLayer() {
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ArcsecDatalinkLayer::decodeFrame(const uint8_t* rawData, size_t rawDataSize,
|
ReturnValue_t ArcsecDatalinkLayer::decodeFrame(const uint8_t* rawData, size_t rawDataSize,
|
||||||
size_t* bytesLeft) {
|
size_t* bytesLeft) {
|
||||||
size_t bytePos = 0;
|
size_t bytePos = 0;
|
||||||
for (bytePos = 0; bytePos < rawDataSize; bytePos++) {
|
for (bytePos = 0; bytePos < rawDataSize; bytePos++) {
|
||||||
enum arc_dec_result decResult = arc_transport_decode_body(*(rawData + bytePos), &slipInfo,
|
enum arc_dec_result decResult =
|
||||||
decodedFrame, &decFrameSize);
|
arc_transport_decode_body(*(rawData + bytePos), &slipInfo, decodedFrame, &decFrameSize);
|
||||||
*bytesLeft = rawDataSize - bytePos - 1;
|
*bytesLeft = rawDataSize - bytePos - 1;
|
||||||
switch (decResult) {
|
switch (decResult) {
|
||||||
case ARC_DEC_INPROGRESS: {
|
case ARC_DEC_INPROGRESS: {
|
||||||
if (bytePos == rawDataSize - 1) {
|
if (bytePos == rawDataSize - 1) {
|
||||||
return DEC_IN_PROGRESS;
|
return DEC_IN_PROGRESS;
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
case ARC_DEC_ERROR_FRAME_SHORT:
|
|
||||||
return REPLY_TOO_SHORT;
|
|
||||||
case ARC_DEC_ERROR_CHECKSUM:
|
|
||||||
return CRC_FAILURE;
|
|
||||||
case ARC_DEC_ASYNC:
|
|
||||||
case ARC_DEC_SYNC: {
|
|
||||||
// Reset length of SLIP struct for next frame
|
|
||||||
slipInfo.length = 0;
|
|
||||||
return RETURN_OK;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
sif::debug << "ArcsecDatalinkLayer::decodeFrame: Unknown result code" << std::endl;
|
|
||||||
break;
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case ARC_DEC_ERROR_FRAME_SHORT:
|
||||||
|
return REPLY_TOO_SHORT;
|
||||||
|
case ARC_DEC_ERROR_CHECKSUM:
|
||||||
|
return CRC_FAILURE;
|
||||||
|
case ARC_DEC_ASYNC:
|
||||||
|
case ARC_DEC_SYNC: {
|
||||||
|
// Reset length of SLIP struct for next frame
|
||||||
|
slipInfo.length = 0;
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
sif::debug << "ArcsecDatalinkLayer::decodeFrame: Unknown result code" << std::endl;
|
||||||
|
break;
|
||||||
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
return RETURN_FAILED;
|
}
|
||||||
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t ArcsecDatalinkLayer::getReplyFrameType() {
|
uint8_t ArcsecDatalinkLayer::getReplyFrameType() { return decodedFrame[0]; }
|
||||||
return decodedFrame[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t* ArcsecDatalinkLayer::getReply() {
|
const uint8_t* ArcsecDatalinkLayer::getReply() { return &decodedFrame[1]; }
|
||||||
return &decodedFrame[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
void ArcsecDatalinkLayer::encodeFrame(const uint8_t* data, uint32_t length) {
|
void ArcsecDatalinkLayer::encodeFrame(const uint8_t* data, uint32_t length) {
|
||||||
arc_transport_encode_body(data, length, encBuffer, &encFrameSize);
|
arc_transport_encode_body(data, length, encBuffer, &encFrameSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* ArcsecDatalinkLayer::getEncodedFrame() {
|
uint8_t* ArcsecDatalinkLayer::getEncodedFrame() { return encBuffer; }
|
||||||
return encBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t ArcsecDatalinkLayer::getEncodedLength() {
|
uint32_t ArcsecDatalinkLayer::getEncodedLength() { return encFrameSize; }
|
||||||
return encFrameSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t ArcsecDatalinkLayer::getStatusField() {
|
uint8_t ArcsecDatalinkLayer::getStatusField() { return *(decodedFrame + STATUS_OFFSET); }
|
||||||
return *(decodedFrame + STATUS_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t ArcsecDatalinkLayer::getId() {
|
|
||||||
return *(decodedFrame + ID_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
uint8_t ArcsecDatalinkLayer::getId() { return *(decodedFrame + ID_OFFSET); }
|
||||||
|
@ -5,96 +5,94 @@
|
|||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "common/misc.h"
|
#include "common/misc.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Helper class to handle the datalinklayer of replies from the star tracker of arcsec.
|
* @brief Helper class to handle the datalinklayer of replies from the star tracker of arcsec.
|
||||||
*/
|
*/
|
||||||
class ArcsecDatalinkLayer: public HasReturnvaluesIF {
|
class ArcsecDatalinkLayer : public HasReturnvaluesIF {
|
||||||
public:
|
public:
|
||||||
|
static const uint8_t INTERFACE_ID = CLASS_ID::STR_HANDLER;
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::STR_HANDLER;
|
//! [EXPORT] : [COMMENT] More data required to complete frame
|
||||||
|
static const ReturnValue_t DEC_IN_PROGRESS = MAKE_RETURN_CODE(0xA0);
|
||||||
|
//! [EXPORT] : [COMMENT] Data too short to represent a valid frame
|
||||||
|
static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xA1);
|
||||||
|
//! [EXPORT] : [COMMENT] Detected CRC failure in received frame
|
||||||
|
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA2);
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] More data required to complete frame
|
static const uint8_t STATUS_OK = 0;
|
||||||
static const ReturnValue_t DEC_IN_PROGRESS = MAKE_RETURN_CODE(0xA0);
|
|
||||||
//! [EXPORT] : [COMMENT] Data too short to represent a valid frame
|
|
||||||
static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xA1);
|
|
||||||
//! [EXPORT] : [COMMENT] Detected CRC failure in received frame
|
|
||||||
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA2);
|
|
||||||
|
|
||||||
static const uint8_t STATUS_OK = 0;
|
ArcsecDatalinkLayer();
|
||||||
|
virtual ~ArcsecDatalinkLayer();
|
||||||
|
|
||||||
ArcsecDatalinkLayer();
|
/**
|
||||||
virtual ~ArcsecDatalinkLayer();
|
* @brief Applies decoding to data referenced by rawData pointer
|
||||||
|
*
|
||||||
|
* @param rawData Pointer to raw data received from star tracker
|
||||||
|
* @param rawDataSize Size of raw data stream
|
||||||
|
* @param remainingBytes Number of bytes left
|
||||||
|
*/
|
||||||
|
ReturnValue_t decodeFrame(const uint8_t* rawData, size_t rawDataSize, size_t* bytesLeft);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Applies decoding to data referenced by rawData pointer
|
* @brief SLIP encodes data pointed to by data pointer.
|
||||||
*
|
*
|
||||||
* @param rawData Pointer to raw data received from star tracker
|
* @param data Pointer to data to encode
|
||||||
* @param rawDataSize Size of raw data stream
|
* @param length Length of buffer to encode
|
||||||
* @param remainingBytes Number of bytes left
|
*/
|
||||||
*/
|
void encodeFrame(const uint8_t* data, uint32_t length);
|
||||||
ReturnValue_t decodeFrame(const uint8_t* rawData, size_t rawDataSize, size_t* bytesLeft);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SLIP encodes data pointed to by data pointer.
|
* @brief Returns the frame type field of a decoded frame.
|
||||||
*
|
*/
|
||||||
* @param data Pointer to data to encode
|
uint8_t getReplyFrameType();
|
||||||
* @param length Length of buffer to encode
|
|
||||||
*/
|
|
||||||
void encodeFrame(const uint8_t* data, uint32_t length);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the frame type field of a decoded frame.
|
* @brief Returns pointer to reply packet (first entry normally action ID, telemetry ID etc.)
|
||||||
*/
|
*/
|
||||||
uint8_t getReplyFrameType();
|
const uint8_t* getReply();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns pointer to reply packet (first entry normally action ID, telemetry ID etc.)
|
* @brief Returns size of encoded frame
|
||||||
*/
|
*/
|
||||||
const uint8_t* getReply();
|
uint32_t getEncodedLength();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns size of encoded frame
|
* @brief Returns pointer to encoded frame
|
||||||
*/
|
*/
|
||||||
uint32_t getEncodedLength();
|
uint8_t* getEncodedFrame();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns pointer to encoded frame
|
* @brief Returns status of reply
|
||||||
*/
|
*/
|
||||||
uint8_t* getEncodedFrame();
|
uint8_t getStatusField();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns status of reply
|
* @brief Returns ID of reply
|
||||||
*/
|
*/
|
||||||
uint8_t getStatusField();
|
uint8_t getId();
|
||||||
|
|
||||||
/**
|
private:
|
||||||
* @brief Returns ID of reply
|
static const uint8_t ID_OFFSET = 1;
|
||||||
*/
|
static const uint8_t STATUS_OFFSET = 2;
|
||||||
uint8_t getId();
|
|
||||||
|
|
||||||
private:
|
// Used by arcsec slip decoding function process received data
|
||||||
|
uint8_t rxBuffer[StarTracker::MAX_FRAME_SIZE];
|
||||||
|
// Decoded frame will be copied to this buffer
|
||||||
|
uint8_t decodedFrame[StarTracker::MAX_FRAME_SIZE];
|
||||||
|
// Buffer where encoded frames will be stored. First byte of encoded frame represents type of
|
||||||
|
// reply
|
||||||
|
uint8_t encBuffer[StarTracker::MAX_FRAME_SIZE * 2 + 2];
|
||||||
|
// Size of decoded frame
|
||||||
|
uint32_t decFrameSize = 0;
|
||||||
|
// Size of encoded frame
|
||||||
|
uint32_t encFrameSize = 0;
|
||||||
|
|
||||||
static const uint8_t ID_OFFSET = 1;
|
slip_decode_state slipInfo;
|
||||||
static const uint8_t STATUS_OFFSET = 2;
|
|
||||||
|
|
||||||
// Used by arcsec slip decoding function process received data
|
void slipInit();
|
||||||
uint8_t rxBuffer[StarTracker::MAX_FRAME_SIZE];
|
|
||||||
// Decoded frame will be copied to this buffer
|
|
||||||
uint8_t decodedFrame[StarTracker::MAX_FRAME_SIZE];
|
|
||||||
// Buffer where encoded frames will be stored. First byte of encoded frame represents type of
|
|
||||||
// reply
|
|
||||||
uint8_t encBuffer[StarTracker::MAX_FRAME_SIZE * 2 + 2];
|
|
||||||
// Size of decoded frame
|
|
||||||
uint32_t decFrameSize = 0;
|
|
||||||
// Size of encoded frame
|
|
||||||
uint32_t encFrameSize = 0;
|
|
||||||
|
|
||||||
slip_decode_state slipInfo;
|
|
||||||
|
|
||||||
void slipInit();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ */
|
#endif /* BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ */
|
||||||
|
@ -5,122 +5,122 @@
|
|||||||
* @brief Keys used in JSON file of ARCSEC.
|
* @brief Keys used in JSON file of ARCSEC.
|
||||||
*/
|
*/
|
||||||
namespace arcseckeys {
|
namespace arcseckeys {
|
||||||
static const char PROPERTIES[] = "properties";
|
static const char PROPERTIES[] = "properties";
|
||||||
static const char NAME[] = "name";
|
static const char NAME[] = "name";
|
||||||
static const char VALUE[] = "value";
|
static const char VALUE[] = "value";
|
||||||
|
|
||||||
static const char LIMITS[] = "limits";
|
static const char LIMITS[] = "limits";
|
||||||
static const char ACTION[] = "action";
|
static const char ACTION[] = "action";
|
||||||
static const char FPGA18CURRENT[] = "FPGA18Current";
|
static const char FPGA18CURRENT[] = "FPGA18Current";
|
||||||
static const char FPGA25CURRENT[] = "FPGA25Current";
|
static const char FPGA25CURRENT[] = "FPGA25Current";
|
||||||
static const char FPGA10CURRENT[] = "FPGA10Current";
|
static const char FPGA10CURRENT[] = "FPGA10Current";
|
||||||
static const char MCUCURRENT[] = "MCUCurrent";
|
static const char MCUCURRENT[] = "MCUCurrent";
|
||||||
static const char CMOS21CURRENT[] = "CMOS21Current";
|
static const char CMOS21CURRENT[] = "CMOS21Current";
|
||||||
static const char CMOSPIXCURRENT[] = "CMOSPixCurrent";
|
static const char CMOSPIXCURRENT[] = "CMOSPixCurrent";
|
||||||
static const char CMOS33CURRENT[] = "CMOS33Current";
|
static const char CMOS33CURRENT[] = "CMOS33Current";
|
||||||
static const char CMOSVRESCURRENT[] = "CMOSVResCurrent";
|
static const char CMOSVRESCURRENT[] = "CMOSVResCurrent";
|
||||||
static const char CMOS_TEMPERATURE[] = "CMOSTemperature";
|
static const char CMOS_TEMPERATURE[] = "CMOSTemperature";
|
||||||
static const char MCU_TEMPERATURE[] = "MCUTemperature";
|
static const char MCU_TEMPERATURE[] = "MCUTemperature";
|
||||||
|
|
||||||
static const char MOUNTING[] = "mounting";
|
static const char MOUNTING[] = "mounting";
|
||||||
static const char qw[] = "qw";
|
static const char qw[] = "qw";
|
||||||
static const char qx[] = "qx";
|
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 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";
|
||||||
static const char EXPOSURE[] = "exposure";
|
static const char EXPOSURE[] = "exposure";
|
||||||
static const char INTERVAL[] = "interval";
|
static const char INTERVAL[] = "interval";
|
||||||
static const char OFFSET[] = "offset";
|
static const char OFFSET[] = "offset";
|
||||||
static const char PGAGAIN[] = "PGAGain";
|
static const char PGAGAIN[] = "PGAGain";
|
||||||
static const char ADCGAIN[] = "ADCGain";
|
static const char ADCGAIN[] = "ADCGain";
|
||||||
static const char REG_1[] = "reg1";
|
static const char REG_1[] = "reg1";
|
||||||
static const char VAL_1[] = "val1";
|
static const char VAL_1[] = "val1";
|
||||||
static const char REG_2[] = "reg2";
|
static const char REG_2[] = "reg2";
|
||||||
static const char VAL_2[] = "val2";
|
static const char VAL_2[] = "val2";
|
||||||
static const char REG_3[] = "reg3";
|
static const char REG_3[] = "reg3";
|
||||||
static const char VAL_3[] = "val3";
|
static const char VAL_3[] = "val3";
|
||||||
static const char REG_4[] = "reg4";
|
static const char REG_4[] = "reg4";
|
||||||
static const char VAL_4[] = "val4";
|
static const char VAL_4[] = "val4";
|
||||||
static const char REG_5[] = "reg5";
|
static const char REG_5[] = "reg5";
|
||||||
static const char VAL_5[] = "val5";
|
static const char VAL_5[] = "val5";
|
||||||
static const char REG_6[] = "reg6";
|
static const char REG_6[] = "reg6";
|
||||||
static const char VAL_6[] = "val6";
|
static const char VAL_6[] = "val6";
|
||||||
static const char REG_7[] = "reg7";
|
static const char REG_7[] = "reg7";
|
||||||
static const char VAL_7[] = "val7";
|
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 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";
|
||||||
static const char MIN_DISTANCE[] = "minDistance";
|
static const char MIN_DISTANCE[] = "minDistance";
|
||||||
static const char NEIGHBOUR_DISTANCE[] = "neighbourDistance";
|
static const char NEIGHBOUR_DISTANCE[] = "neighbourDistance";
|
||||||
static const char NEIGHBOUR_BRIGHT_PIXELS[] = "neighbourBrightPixels";
|
static const char NEIGHBOUR_BRIGHT_PIXELS[] = "neighbourBrightPixels";
|
||||||
static const char MIN_TOTAL_VALUE[] = "minTotalValue";
|
static const char MIN_TOTAL_VALUE[] = "minTotalValue";
|
||||||
static const char MAX_TOTAL_VALUE[] = "maxTotalValue";
|
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 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";
|
||||||
|
|
||||||
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 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";
|
||||||
static const char MAX_MAGNITUDE[] = "maxmagnitude";
|
static const char MAX_MAGNITUDE[] = "maxmagnitude";
|
||||||
static const char GAUSSIAN_CMAX[] = "gaussianCmax";
|
static const char GAUSSIAN_CMAX[] = "gaussianCmax";
|
||||||
static const char GAUSSIAN_CMIN[] = "gaussianCmin";
|
static const char GAUSSIAN_CMIN[] = "gaussianCmin";
|
||||||
static const char TRANSMATRIX_00[] = "transmatrix00";
|
static const char TRANSMATRIX_00[] = "transmatrix00";
|
||||||
static const char TRANSMATRIX_01[] = "transmatrix01";
|
static const char TRANSMATRIX_01[] = "transmatrix01";
|
||||||
static const char TRANSMATRIX_10[] = "transmatrix10";
|
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 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";
|
||||||
static const char FOV_HEIGHT[] = "fov_height";
|
static const char FOV_HEIGHT[] = "fov_height";
|
||||||
static const char FLOAT_STAR_LIMIT[] = "float_star_limit";
|
static const char FLOAT_STAR_LIMIT[] = "float_star_limit";
|
||||||
static const char CLOSE_STAR_LIMIT[] = "close_star_limit";
|
static const char CLOSE_STAR_LIMIT[] = "close_star_limit";
|
||||||
static const char RATING_WEIGHT_CLOSE_STAR_COUNT[] = "rating_weight_close_star_count";
|
static const char RATING_WEIGHT_CLOSE_STAR_COUNT[] = "rating_weight_close_star_count";
|
||||||
static const char RATING_WEIGHT_FRACTION_CLOSE[] = "rating_weight_fraction_close";
|
static const char RATING_WEIGHT_FRACTION_CLOSE[] = "rating_weight_fraction_close";
|
||||||
static const char RATING_WEIGHT_MEAN_SUM[] = "rating_weight_mean_sum";
|
static const char RATING_WEIGHT_MEAN_SUM[] = "rating_weight_mean_sum";
|
||||||
static const char RATING_WEIGHT_DB_STAR_COUNT[] = "rating_weight_db_star_count";
|
static const char RATING_WEIGHT_DB_STAR_COUNT[] = "rating_weight_db_star_count";
|
||||||
static const char MAX_COMBINATIONS[] = "max_combinations";
|
static const char MAX_COMBINATIONS[] = "max_combinations";
|
||||||
static const char NR_STARS_STOP[] = "nr_stars_stop";
|
static const char NR_STARS_STOP[] = "nr_stars_stop";
|
||||||
static const char FRACTION_CLOSE_STOP[] = "fraction_close_stop";
|
static const char FRACTION_CLOSE_STOP[] = "fraction_close_stop";
|
||||||
|
|
||||||
static const char MATCHING[] = "matching";
|
static const char MATCHING[] = "matching";
|
||||||
static const char SQUARED_DISTANCE_LIMIT[] = "squaredDistanceLimit";
|
static const char SQUARED_DISTANCE_LIMIT[] = "squaredDistanceLimit";
|
||||||
static const char SQUARED_SHIFT_LIMIT[] = "squaredShiftLimit";
|
static const char SQUARED_SHIFT_LIMIT[] = "squaredShiftLimit";
|
||||||
|
|
||||||
static const char VALIDATION[] = "validation";
|
static const char VALIDATION[] = "validation";
|
||||||
static const char STABLE_COUNT[] = "stable_count";
|
static const char STABLE_COUNT[] = "stable_count";
|
||||||
static const char MAX_DIFFERENCE[] = "max_difference";
|
static const char MAX_DIFFERENCE[] = "max_difference";
|
||||||
static const char MIN_TRACKER_CONFIDENCE[] = "min_trackerConfidence";
|
static const char MIN_TRACKER_CONFIDENCE[] = "min_trackerConfidence";
|
||||||
static const char MIN_MATCHED_STARS[] = "min_matchedStars";
|
static const char MIN_MATCHED_STARS[] = "min_matchedStars";
|
||||||
|
|
||||||
static const char TRACKING[] = "tracking";
|
static const char TRACKING[] = "tracking";
|
||||||
static const char THIN_LIMIT[] = "thinLimit";
|
static const char THIN_LIMIT[] = "thinLimit";
|
||||||
static const char OUTLIER_THRESHOLD[] = "outlierThreshold";
|
static const char OUTLIER_THRESHOLD[] = "outlierThreshold";
|
||||||
static const char OUTLIER_THRESHOLD_QUEST[] = "outlierThresholdQUEST";
|
static const char OUTLIER_THRESHOLD_QUEST[] = "outlierThresholdQUEST";
|
||||||
static const char TRACKER_CHOICE[] = "trackerChoice";
|
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_minConfidence";
|
||||||
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";
|
||||||
}
|
} // namespace arcseckeys
|
||||||
|
|
||||||
#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_ARCSECJSONKEYS_H_ */
|
#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_ARCSECJSONKEYS_H_ */
|
||||||
|
@ -1,94 +1,95 @@
|
|||||||
#include "ArcsecJsonParamBase.h"
|
#include "ArcsecJsonParamBase.h"
|
||||||
|
|
||||||
#include "ArcsecJsonKeys.h"
|
#include "ArcsecJsonKeys.h"
|
||||||
|
|
||||||
ArcsecJsonParamBase::ArcsecJsonParamBase(std::string setName) : setName(setName) {}
|
ArcsecJsonParamBase::ArcsecJsonParamBase(std::string setName) : setName(setName) {}
|
||||||
|
|
||||||
ReturnValue_t ArcsecJsonParamBase::create(std::string fullname, uint8_t* buffer) {
|
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) {
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = createCommand(buffer);
|
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
result = createCommand(buffer);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ArcsecJsonParamBase::getParam(const std::string name, std::string& value) {
|
ReturnValue_t ArcsecJsonParamBase::getParam(const std::string name, std::string& value) {
|
||||||
for (json::iterator it = set.begin(); it != set.end(); ++it) {
|
for (json::iterator it = set.begin(); it != set.end(); ++it) {
|
||||||
if ((*it)[arcseckeys::NAME] == name) {
|
if ((*it)[arcseckeys::NAME] == name) {
|
||||||
value = (*it)[arcseckeys::VALUE];
|
value = (*it)[arcseckeys::VALUE];
|
||||||
convertEmpty(value);
|
convertEmpty(value);
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return PARAM_NOT_EXISTS;
|
}
|
||||||
|
return PARAM_NOT_EXISTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArcsecJsonParamBase::convertEmpty(std::string& value) {
|
void ArcsecJsonParamBase::convertEmpty(std::string& value) {
|
||||||
if (value == "") {
|
if (value == "") {
|
||||||
value = "0";
|
value = "0";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArcsecJsonParamBase::addfloat(const std::string value, uint8_t* buffer) {
|
void ArcsecJsonParamBase::addfloat(const std::string value, uint8_t* buffer) {
|
||||||
float param = std::stof(value);
|
float param = std::stof(value);
|
||||||
std::memcpy(buffer, ¶m, sizeof(param));
|
std::memcpy(buffer, ¶m, sizeof(param));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArcsecJsonParamBase::adduint8(const std::string value, uint8_t* buffer) {
|
void ArcsecJsonParamBase::adduint8(const std::string value, uint8_t* buffer) {
|
||||||
uint8_t param = std::stoi(value);
|
uint8_t param = std::stoi(value);
|
||||||
std::memcpy(buffer, ¶m, sizeof(param));
|
std::memcpy(buffer, ¶m, sizeof(param));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArcsecJsonParamBase::addint16(const std::string value, uint8_t* buffer) {
|
void ArcsecJsonParamBase::addint16(const std::string value, uint8_t* buffer) {
|
||||||
int16_t param = std::stoi(value);
|
int16_t param = std::stoi(value);
|
||||||
std::memcpy(buffer, ¶m, sizeof(param));
|
std::memcpy(buffer, ¶m, sizeof(param));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArcsecJsonParamBase::adduint16(const std::string value, uint8_t* buffer) {
|
void ArcsecJsonParamBase::adduint16(const std::string value, uint8_t* buffer) {
|
||||||
uint16_t param = std::stoi(value);
|
uint16_t param = std::stoi(value);
|
||||||
std::memcpy(buffer, ¶m, sizeof(param));
|
std::memcpy(buffer, ¶m, sizeof(param));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArcsecJsonParamBase::adduint32(const std::string value, uint8_t* buffer) {
|
void ArcsecJsonParamBase::adduint32(const std::string value, uint8_t* buffer) {
|
||||||
uint32_t param = std::stoi(value);
|
uint32_t param = std::stoi(value);
|
||||||
std::memcpy(buffer, ¶m, sizeof(param));
|
std::memcpy(buffer, ¶m, sizeof(param));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArcsecJsonParamBase::addSetParamHeader(uint8_t* buffer, uint8_t setId) {
|
void ArcsecJsonParamBase::addSetParamHeader(uint8_t* buffer, uint8_t setId) {
|
||||||
*buffer = static_cast<uint8_t>(TMTC_SETPARAMREQ);
|
*buffer = static_cast<uint8_t>(TMTC_SETPARAMREQ);
|
||||||
*(buffer + 1) = setId;
|
*(buffer + 1) = setId;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ArcsecJsonParamBase::init(const std::string filename) {
|
ReturnValue_t ArcsecJsonParamBase::init(const std::string filename) {
|
||||||
ReturnValue_t result = RETURN_OK;
|
ReturnValue_t result = RETURN_OK;
|
||||||
if (not std::filesystem::exists(filename)) {
|
if (not std::filesystem::exists(filename)) {
|
||||||
sif::warning << "ArcsecJsonParamBase::init: JSON file " << filename << " does not exist"
|
sif::warning << "ArcsecJsonParamBase::init: JSON file " << filename << " does not exist"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return JSON_FILE_NOT_EXISTS;
|
return JSON_FILE_NOT_EXISTS;
|
||||||
}
|
}
|
||||||
createJsonObject(filename);
|
createJsonObject(filename);
|
||||||
result = initSet();
|
result = initSet();
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArcsecJsonParamBase::createJsonObject(const std::string fullname) {
|
void ArcsecJsonParamBase::createJsonObject(const std::string fullname) {
|
||||||
json j;
|
json j;
|
||||||
std::ifstream file(fullname);
|
std::ifstream file(fullname);
|
||||||
file >> j;
|
file >> j;
|
||||||
file.close();
|
file.close();
|
||||||
properties = j[arcseckeys::PROPERTIES];
|
properties = j[arcseckeys::PROPERTIES];
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t ArcsecJsonParamBase::initSet() {
|
ReturnValue_t ArcsecJsonParamBase::initSet() {
|
||||||
for (json::iterator it = properties.begin(); it != properties.end(); ++it) {
|
for (json::iterator it = properties.begin(); it != properties.end(); ++it) {
|
||||||
if ((*it)["name"] == setName) {
|
if ((*it)["name"] == setName) {
|
||||||
set = (*it)["fields"];
|
set = (*it)["fields"];
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return SET_NOT_EXISTS;
|
}
|
||||||
|
return SET_NOT_EXISTS;
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
#ifndef BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_
|
#ifndef BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_
|
||||||
#define BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_
|
#define BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
|
||||||
#include "StarTrackerDefinitions.h"
|
#include "StarTrackerDefinitions.h"
|
||||||
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "thirdparty/arcsec_star_tracker/common/generated/tmtcstructs.h"
|
#include "thirdparty/arcsec_star_tracker/common/generated/tmtcstructs.h"
|
||||||
#include "thirdparty/arcsec_star_tracker/common/genericstructs.h"
|
#include "thirdparty/arcsec_star_tracker/common/genericstructs.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
@ -23,127 +23,124 @@ using json = nlohmann::json;
|
|||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
*/
|
*/
|
||||||
class ArcsecJsonParamBase : public HasReturnvaluesIF {
|
class ArcsecJsonParamBase : public HasReturnvaluesIF {
|
||||||
public:
|
public:
|
||||||
|
static const uint8_t INTERFACE_ID = CLASS_ID::ARCSEC_JSON_BASE;
|
||||||
|
//! [EXPORT] : [COMMENT] Specified json file does not exist
|
||||||
|
static const ReturnValue_t JSON_FILE_NOT_EXISTS = MAKE_RETURN_CODE(1);
|
||||||
|
//! [EXPORT] : [COMMENT] Requested set does not exist in json file
|
||||||
|
static const ReturnValue_t SET_NOT_EXISTS = MAKE_RETURN_CODE(2);
|
||||||
|
//! [EXPORT] : [COMMENT] Requested parameter does not exist in json file
|
||||||
|
static const ReturnValue_t PARAM_NOT_EXISTS = MAKE_RETURN_CODE(3);
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::ARCSEC_JSON_BASE;
|
/**
|
||||||
//! [EXPORT] : [COMMENT] Specified json file does not exist
|
* @brief Constructor
|
||||||
static const ReturnValue_t JSON_FILE_NOT_EXISTS = MAKE_RETURN_CODE(1);
|
*
|
||||||
//! [EXPORT] : [COMMENT] Requested set does not exist in json file
|
* @param fullname Name with absolute path of json file containing the parameters to set.
|
||||||
static const ReturnValue_t SET_NOT_EXISTS = MAKE_RETURN_CODE(2);
|
*/
|
||||||
//! [EXPORT] : [COMMENT] Requested parameter does not exist in json file
|
ArcsecJsonParamBase(std::string setName);
|
||||||
static const ReturnValue_t PARAM_NOT_EXISTS = MAKE_RETURN_CODE(3);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructor
|
* @brief Fills a buffer with a parameter set
|
||||||
*
|
*
|
||||||
* @param fullname Name with absolute path of json file containing the parameters to set.
|
* @param fullname The name including the absolute path of the json file containing the
|
||||||
*/
|
* parameter set.
|
||||||
ArcsecJsonParamBase(std::string setName);
|
* @param buffer Pointer to the buffer the command will be written to
|
||||||
|
*/
|
||||||
|
ReturnValue_t create(std::string fullname, uint8_t* buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Fills a buffer with a parameter set
|
* @brief Returns the size of the parameter command.
|
||||||
*
|
*/
|
||||||
* @param fullname The name including the absolute path of the json file containing the
|
virtual size_t getSize() = 0;
|
||||||
* parameter set.
|
|
||||||
* @param buffer Pointer to the buffer the command will be written to
|
|
||||||
*/
|
|
||||||
ReturnValue_t create(std::string fullname, uint8_t* buffer);
|
|
||||||
|
|
||||||
/**
|
protected:
|
||||||
* @brief Returns the size of the parameter command.
|
/**
|
||||||
*/
|
* @brief Reads the value of a parameter from a json set
|
||||||
virtual size_t getSize() = 0;
|
*
|
||||||
|
* @param name The name of the parameter
|
||||||
|
* @param value The string representation of the read value
|
||||||
|
*
|
||||||
|
* @return RETURN_OK if successful, otherwise PARAM_NOT_EXISTS
|
||||||
|
*/
|
||||||
|
ReturnValue_t getParam(const std::string name, std::string& value);
|
||||||
|
|
||||||
protected:
|
/**
|
||||||
|
* @brief Converts empty string which is equal to define a value as zero.
|
||||||
|
*/
|
||||||
|
void convertEmpty(std::string& value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads the value of a parameter from a json set
|
* @brief This function adds a float represented as string to a buffer
|
||||||
*
|
*
|
||||||
* @param name The name of the parameter
|
* @param value The float in string representation to add
|
||||||
* @param value The string representation of the read value
|
* @param buffer Pointer to the buffer the float will be written to
|
||||||
*
|
*/
|
||||||
* @return RETURN_OK if successful, otherwise PARAM_NOT_EXISTS
|
void addfloat(const std::string value, uint8_t* buffer);
|
||||||
*/
|
|
||||||
ReturnValue_t getParam(const std::string name, std::string& value);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Converts empty string which is equal to define a value as zero.
|
* @brief This function adds a uint8_t represented as string to a buffer
|
||||||
*/
|
*
|
||||||
void convertEmpty(std::string& value);
|
* @param value The uint8_t in string representation to add
|
||||||
|
* @param buffer Pointer to the buffer the uint8_t will be written to
|
||||||
|
*/
|
||||||
|
void adduint8(const std::string value, uint8_t* buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function adds a float represented as string to a buffer
|
* @brief This function adds a int16_t represented as string to a buffer
|
||||||
*
|
*
|
||||||
* @param value The float in string representation to add
|
* @param value The int16_t in string representation to add
|
||||||
* @param buffer Pointer to the buffer the float will be written to
|
* @param buffer Pointer to the buffer the int16_t will be written to
|
||||||
*/
|
*/
|
||||||
void addfloat(const std::string value, uint8_t* buffer);
|
void addint16(const std::string value, uint8_t* buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function adds a uint8_t represented as string to a buffer
|
* @brief This function adds a uint16_t represented as string to a buffer
|
||||||
*
|
*
|
||||||
* @param value The uint8_t in string representation to add
|
* @param value The uint16_t in string representation to add
|
||||||
* @param buffer Pointer to the buffer the uint8_t will be written to
|
* @param buffer Pointer to the buffer the uint16_t will be written to
|
||||||
*/
|
*/
|
||||||
void adduint8(const std::string value, uint8_t* buffer);
|
void adduint16(const std::string value, uint8_t* buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function adds a int16_t represented as string to a buffer
|
* @brief This function adds a uint32_t represented as string to a buffer
|
||||||
*
|
*
|
||||||
* @param value The int16_t in string representation to add
|
* @param value The uint32_t in string representation to add
|
||||||
* @param buffer Pointer to the buffer the int16_t will be written to
|
* @param buffer Pointer to the buffer the uint32_t will be written to
|
||||||
*/
|
*/
|
||||||
void addint16(const std::string value, uint8_t* buffer);
|
void adduint32(const std::string value, uint8_t* buffer);
|
||||||
|
|
||||||
/**
|
void addSetParamHeader(uint8_t* buffer, uint8_t setId);
|
||||||
* @brief This function adds a uint16_t represented as string to a buffer
|
|
||||||
*
|
|
||||||
* @param value The uint16_t in string representation to add
|
|
||||||
* @param buffer Pointer to the buffer the uint16_t will be written to
|
|
||||||
*/
|
|
||||||
void adduint16(const std::string value, uint8_t* buffer);
|
|
||||||
|
|
||||||
/**
|
private:
|
||||||
* @brief This function adds a uint32_t represented as string to a buffer
|
json properties;
|
||||||
*
|
json set;
|
||||||
* @param value The uint32_t in string representation to add
|
std::string setName;
|
||||||
* @param buffer Pointer to the buffer the uint32_t will be written to
|
|
||||||
*/
|
|
||||||
void adduint32(const std::string value, uint8_t* buffer);
|
|
||||||
|
|
||||||
void addSetParamHeader(uint8_t* buffer, uint8_t setId);
|
/**
|
||||||
|
* @brief This function must be implemented by the derived class to define creation of a
|
||||||
|
* parameter command.
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t createCommand(uint8_t* buffer) = 0;
|
||||||
|
|
||||||
private:
|
/**
|
||||||
|
* @brief Initializes the properties json object and the set json object
|
||||||
|
*
|
||||||
|
* @param fullname Name including absolute path to json file
|
||||||
|
* @param setName The name of the set to work on
|
||||||
|
*
|
||||||
|
* @param return JSON_FILE_NOT_EXISTS if specified file does not exist, otherwise
|
||||||
|
* RETURN_OK
|
||||||
|
*/
|
||||||
|
ReturnValue_t init(const std::string filename);
|
||||||
|
|
||||||
json properties;
|
void createJsonObject(const std::string fullname);
|
||||||
json set;
|
|
||||||
std::string setName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function must be implemented by the derived class to define creation of a
|
* @brief Extracts the json set object form the json file
|
||||||
* parameter command.
|
*
|
||||||
*/
|
* @param setName The name of the set to create the json object from
|
||||||
virtual ReturnValue_t createCommand(uint8_t* buffer) = 0;
|
*/
|
||||||
|
ReturnValue_t initSet();
|
||||||
/**
|
|
||||||
* @brief Initializes the properties json object and the set json object
|
|
||||||
*
|
|
||||||
* @param fullname Name including absolute path to json file
|
|
||||||
* @param setName The name of the set to work on
|
|
||||||
*
|
|
||||||
* @param return JSON_FILE_NOT_EXISTS if specified file does not exist, otherwise
|
|
||||||
* RETURN_OK
|
|
||||||
*/
|
|
||||||
ReturnValue_t init(const std::string filename);
|
|
||||||
|
|
||||||
void createJsonObject(const std::string fullname);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Extracts the json set object form the json file
|
|
||||||
*
|
|
||||||
* @param setName The name of the set to create the json object from
|
|
||||||
*/
|
|
||||||
ReturnValue_t initSet();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_ */
|
#endif /* BSP_Q7S_DEVICES_STARTRACKER_ARCSECJSONPARAMBASE_H_ */
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -9,207 +9,168 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
|
||||||
#include "ArcsecJsonParamBase.h"
|
#include "ArcsecJsonParamBase.h"
|
||||||
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generates command to set the limit parameters
|
* @brief Generates command to set the limit parameters
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Limits : public ArcsecJsonParamBase {
|
class Limits : public ArcsecJsonParamBase {
|
||||||
public:
|
public:
|
||||||
|
Limits();
|
||||||
|
|
||||||
Limits();
|
size_t getSize();
|
||||||
|
|
||||||
size_t getSize();
|
private:
|
||||||
|
static const size_t COMMAND_SIZE = 43;
|
||||||
|
|
||||||
private:
|
virtual ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||||
|
|
||||||
static const size_t COMMAND_SIZE = 43;
|
|
||||||
|
|
||||||
virtual ReturnValue_t createCommand(uint8_t* buffer) override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generates the command to configure the tracking algorithm.
|
* @brief Generates the command to configure the tracking algorithm.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Tracking : public ArcsecJsonParamBase {
|
class Tracking : public ArcsecJsonParamBase {
|
||||||
public:
|
public:
|
||||||
|
Tracking();
|
||||||
|
|
||||||
Tracking();
|
size_t getSize();
|
||||||
|
|
||||||
size_t getSize();
|
private:
|
||||||
|
static const size_t COMMAND_SIZE = 15;
|
||||||
private:
|
|
||||||
|
|
||||||
static const size_t COMMAND_SIZE = 15;
|
|
||||||
|
|
||||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
|
||||||
|
|
||||||
|
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
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Mounting : public ArcsecJsonParamBase {
|
class Mounting : public ArcsecJsonParamBase {
|
||||||
public:
|
public:
|
||||||
|
Mounting();
|
||||||
|
|
||||||
Mounting();
|
size_t getSize();
|
||||||
|
|
||||||
size_t getSize();
|
private:
|
||||||
|
static const size_t COMMAND_SIZE = 18;
|
||||||
private:
|
|
||||||
|
|
||||||
static const size_t COMMAND_SIZE = 18;
|
|
||||||
|
|
||||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
|
||||||
|
|
||||||
|
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
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Camera : public ArcsecJsonParamBase {
|
class Camera : public ArcsecJsonParamBase {
|
||||||
public:
|
public:
|
||||||
|
Camera();
|
||||||
|
|
||||||
Camera();
|
size_t getSize();
|
||||||
|
|
||||||
size_t getSize();
|
private:
|
||||||
|
static const size_t COMMAND_SIZE = 43;
|
||||||
private:
|
|
||||||
|
|
||||||
static const size_t COMMAND_SIZE = 43;
|
|
||||||
|
|
||||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
|
||||||
|
|
||||||
|
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generates the command to configure the blob algorithm
|
* @brief Generates the command to configure the blob algorithm
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Blob : public ArcsecJsonParamBase {
|
class Blob : public ArcsecJsonParamBase {
|
||||||
public:
|
public:
|
||||||
|
Blob();
|
||||||
|
|
||||||
Blob();
|
size_t getSize();
|
||||||
|
|
||||||
size_t getSize();
|
private:
|
||||||
|
static const size_t COMMAND_SIZE = 24;
|
||||||
private:
|
|
||||||
|
|
||||||
static const size_t COMMAND_SIZE = 24;
|
|
||||||
|
|
||||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
|
||||||
|
|
||||||
|
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generates the command to configure the centroiding algorithm
|
* @brief Generates the command to configure the centroiding algorithm
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Centroiding : public ArcsecJsonParamBase {
|
class Centroiding : public ArcsecJsonParamBase {
|
||||||
public:
|
public:
|
||||||
|
Centroiding();
|
||||||
|
|
||||||
Centroiding();
|
size_t getSize();
|
||||||
|
|
||||||
size_t getSize();
|
private:
|
||||||
|
static const size_t COMMAND_SIZE = 47;
|
||||||
private:
|
|
||||||
|
|
||||||
static const size_t COMMAND_SIZE = 47;
|
|
||||||
|
|
||||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
|
||||||
|
|
||||||
|
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generates the command to configure the LISA (lost in space algorithm)
|
* @brief Generates the command to configure the LISA (lost in space algorithm)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Lisa : public ArcsecJsonParamBase {
|
class Lisa : public ArcsecJsonParamBase {
|
||||||
public:
|
public:
|
||||||
|
Lisa();
|
||||||
|
|
||||||
Lisa();
|
size_t getSize();
|
||||||
|
|
||||||
size_t getSize();
|
private:
|
||||||
|
static const size_t COMMAND_SIZE = 48;
|
||||||
private:
|
|
||||||
|
|
||||||
static const size_t COMMAND_SIZE = 48;
|
|
||||||
|
|
||||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
|
||||||
|
|
||||||
|
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generates the command to configure the matching algorithm
|
* @brief Generates the command to configure the matching algorithm
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Matching : public ArcsecJsonParamBase {
|
class Matching : public ArcsecJsonParamBase {
|
||||||
public:
|
public:
|
||||||
|
Matching();
|
||||||
|
|
||||||
Matching();
|
size_t getSize();
|
||||||
|
|
||||||
size_t getSize();
|
private:
|
||||||
|
static const size_t COMMAND_SIZE = 10;
|
||||||
private:
|
|
||||||
|
|
||||||
static const size_t COMMAND_SIZE = 10;
|
|
||||||
|
|
||||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
|
||||||
|
|
||||||
|
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generates the command to configure the validation parameters
|
* @brief Generates the command to configure the validation parameters
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Validation : public ArcsecJsonParamBase {
|
class Validation : public ArcsecJsonParamBase {
|
||||||
public:
|
public:
|
||||||
|
Validation();
|
||||||
|
|
||||||
Validation();
|
size_t getSize();
|
||||||
|
|
||||||
size_t getSize();
|
private:
|
||||||
|
static const size_t COMMAND_SIZE = 12;
|
||||||
private:
|
|
||||||
|
|
||||||
static const size_t COMMAND_SIZE = 12;
|
|
||||||
|
|
||||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
|
||||||
|
|
||||||
|
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Generates command to configure the mechanism of automatically switching between the
|
* @brief Generates command to configure the mechanism of automatically switching between the
|
||||||
* LISA and other algorithms.
|
* LISA and other algorithms.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Algo : public ArcsecJsonParamBase {
|
class Algo : public ArcsecJsonParamBase {
|
||||||
public:
|
public:
|
||||||
|
Algo();
|
||||||
|
|
||||||
Algo();
|
size_t getSize();
|
||||||
|
|
||||||
size_t getSize();
|
private:
|
||||||
|
static const size_t COMMAND_SIZE = 13;
|
||||||
private:
|
|
||||||
|
|
||||||
static const size_t COMMAND_SIZE = 13;
|
|
||||||
|
|
||||||
ReturnValue_t createCommand(uint8_t* buffer) override;
|
|
||||||
|
|
||||||
|
ReturnValue_t createCommand(uint8_t* buffer) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ */
|
#endif /* BSP_Q7S_DEVICES_DEVICEDEFINITIONS_STARTRACKERJSONCOMMANDS_H_ */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2,396 +2,396 @@
|
|||||||
#define BSP_Q7S_DEVICES_STRHELPER_H_
|
#define BSP_Q7S_DEVICES_STRHELPER_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "ArcsecDatalinkLayer.h"
|
#include "ArcsecDatalinkLayer.h"
|
||||||
#include "fsfw/osal/linux/BinarySemaphore.h"
|
|
||||||
#include "bsp_q7s/memory/SdCardManager.h"
|
#include "bsp_q7s/memory/SdCardManager.h"
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/devicehandlers/CookieIF.h"
|
||||||
#include "fsfw/objectmanager/SystemObject.h"
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
|
#include "fsfw/osal/linux/BinarySemaphore.h"
|
||||||
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||||
#include "fsfw_hal/linux/uart/UartComIF.h"
|
#include "fsfw_hal/linux/uart/UartComIF.h"
|
||||||
#include "fsfw/devicehandlers/CookieIF.h"
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "thirdparty/arcsec_star_tracker/common/generated/tmtcstructs.h"
|
#include "thirdparty/arcsec_star_tracker/client/generated/actionreq.h"
|
||||||
#include "thirdparty/arcsec_star_tracker/client/generated/actionreq.h"
|
#include "thirdparty/arcsec_star_tracker/common/generated/tmtcstructs.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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.
|
||||||
*/
|
*/
|
||||||
class StrHelper: public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF {
|
class StrHelper : public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF {
|
||||||
public:
|
public:
|
||||||
|
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HELPER;
|
||||||
|
|
||||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HELPER;
|
//! [EXPORT] : [COMMENT] Image upload failed
|
||||||
|
static const Event IMAGE_UPLOAD_FAILED = MAKE_EVENT(0, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Image download failed
|
||||||
|
static const Event IMAGE_DOWNLOAD_FAILED = MAKE_EVENT(1, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Uploading image to star tracker was successfulop
|
||||||
|
static const Event IMAGE_UPLOAD_SUCCESSFUL = MAKE_EVENT(2, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Image download was successful
|
||||||
|
static const Event IMAGE_DOWNLOAD_SUCCESSFUL = MAKE_EVENT(3, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Finished flash write procedure successfully
|
||||||
|
static const Event FLASH_WRITE_SUCCESSFUL = MAKE_EVENT(4, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Finished flash read procedure successfully
|
||||||
|
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
|
||||||
|
static const Event FLASH_READ_FAILED = MAKE_EVENT(7, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Download of FPGA image successful
|
||||||
|
static const Event FPGA_DOWNLOAD_SUCCESSFUL = MAKE_EVENT(8, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Download of FPGA image failed
|
||||||
|
static const Event FPGA_DOWNLOAD_FAILED = MAKE_EVENT(9, 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
|
||||||
|
//! P1: Return code of failed communication interface read call
|
||||||
|
//! P1: Upload/download position for which the read call failed
|
||||||
|
static const Event STR_HELPER_READING_REPLY_FAILED = MAKE_EVENT(12, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Unexpected stop of decoding sequence
|
||||||
|
//! P1: Return code of failed communication interface read call
|
||||||
|
//! P1: Upload/download position for which the read call failed
|
||||||
|
static const Event STR_HELPER_COM_ERROR = MAKE_EVENT(13, severity::LOW);
|
||||||
|
//! [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
|
||||||
|
static const Event STR_HELPER_NO_REPLY = MAKE_EVENT(14, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] 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
|
||||||
|
static const Event STR_HELPER_DEC_ERROR = MAKE_EVENT(15, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Position mismatch
|
||||||
|
//! 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);
|
||||||
|
//! [EXPORT] : [COMMENT] Specified file does not exist
|
||||||
|
//! P1: Internal state of str helper
|
||||||
|
static const Event STR_HELPER_FILE_NOT_EXISTS = MAKE_EVENT(17, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Sending packet to star tracker failed
|
||||||
|
//! P1: Return code of communication interface sendMessage function
|
||||||
|
//! P2: Position of upload/download packet, or address of flash write/read request for which
|
||||||
|
//! sending failed
|
||||||
|
static const Event STR_HELPER_SENDING_PACKET_FAILED = MAKE_EVENT(18, severity::LOW);
|
||||||
|
//! [EXPORT] : [COMMENT] Communication interface requesting reply failed
|
||||||
|
//! P1: Return code of failed request
|
||||||
|
//! P1: Upload/download position, or address of flash write/read request for which transmission
|
||||||
|
//! failed
|
||||||
|
static const Event STR_HELPER_REQUESTING_MSG_FAILED = MAKE_EVENT(19, severity::LOW);
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] Image upload failed
|
StrHelper(object_id_t objectId);
|
||||||
static const Event IMAGE_UPLOAD_FAILED = MAKE_EVENT(0, severity::LOW);
|
virtual ~StrHelper();
|
||||||
//! [EXPORT] : [COMMENT] Image download failed
|
|
||||||
static const Event IMAGE_DOWNLOAD_FAILED = MAKE_EVENT(1, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] Uploading image to star tracker was successfulop
|
|
||||||
static const Event IMAGE_UPLOAD_SUCCESSFUL = MAKE_EVENT(2, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] Image download was successful
|
|
||||||
static const Event IMAGE_DOWNLOAD_SUCCESSFUL = MAKE_EVENT(3, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] Finished flash write procedure successfully
|
|
||||||
static const Event FLASH_WRITE_SUCCESSFUL = MAKE_EVENT(4, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] Finished flash read procedure successfully
|
|
||||||
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
|
|
||||||
static const Event FLASH_READ_FAILED = MAKE_EVENT(7, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] Download of FPGA image successful
|
|
||||||
static const Event FPGA_DOWNLOAD_SUCCESSFUL = MAKE_EVENT(8, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] Download of FPGA image failed
|
|
||||||
static const Event FPGA_DOWNLOAD_FAILED = MAKE_EVENT(9, 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
|
|
||||||
//!P1: Return code of failed communication interface read call
|
|
||||||
//!P1: Upload/download position for which the read call failed
|
|
||||||
static const Event STR_HELPER_READING_REPLY_FAILED = MAKE_EVENT(12, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] Unexpected stop of decoding sequence
|
|
||||||
//!P1: Return code of failed communication interface read call
|
|
||||||
//!P1: Upload/download position for which the read call failed
|
|
||||||
static const Event STR_HELPER_COM_ERROR = MAKE_EVENT(13, severity::LOW);
|
|
||||||
//! [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
|
|
||||||
static const Event STR_HELPER_NO_REPLY = MAKE_EVENT(14, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] 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
|
|
||||||
static const Event STR_HELPER_DEC_ERROR = MAKE_EVENT(15, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] Position mismatch
|
|
||||||
//! 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);
|
|
||||||
//! [EXPORT] : [COMMENT] Specified file does not exist
|
|
||||||
//!P1: Internal state of str helper
|
|
||||||
static const Event STR_HELPER_FILE_NOT_EXISTS = MAKE_EVENT(17, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] Sending packet to star tracker failed
|
|
||||||
//!P1: Return code of communication interface sendMessage function
|
|
||||||
//!P2: Position of upload/download packet, or address of flash write/read request for which sending failed
|
|
||||||
static const Event STR_HELPER_SENDING_PACKET_FAILED = MAKE_EVENT(18, severity::LOW);
|
|
||||||
//! [EXPORT] : [COMMENT] Communication interface requesting reply failed
|
|
||||||
//!P1: Return code of failed request
|
|
||||||
//!P1: Upload/download position, or address of flash write/read request for which transmission failed
|
|
||||||
static const Event STR_HELPER_REQUESTING_MSG_FAILED = MAKE_EVENT(19, severity::LOW);
|
|
||||||
|
|
||||||
StrHelper(object_id_t objectId);
|
ReturnValue_t initialize() override;
|
||||||
virtual ~StrHelper();
|
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||||
|
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t setComIF(DeviceCommunicationIF* communicationInterface_);
|
||||||
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
void setComCookie(CookieIF* comCookie_);
|
||||||
|
|
||||||
ReturnValue_t setComIF(DeviceCommunicationIF* communicationInterface_);
|
/**
|
||||||
void setComCookie(CookieIF* comCookie_);
|
* @brief Starts sequence to upload image to star tracker
|
||||||
|
*
|
||||||
|
* @param uploadImage_ Name including absolute path of the image to upload. Must be previously
|
||||||
|
* transferred to the OBC with the CFDP protocol.
|
||||||
|
*/
|
||||||
|
ReturnValue_t startImageUpload(std::string uploadImage_);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Starts sequence to upload image to star tracker
|
* @brief Calling this function initiates the download of an image from the star tracker.
|
||||||
*
|
*
|
||||||
* @param uploadImage_ Name including absolute path of the image to upload. Must be previously
|
* @param path Path where downloaded image will be stored
|
||||||
* transferred to the OBC with the CFDP protocol.
|
*/
|
||||||
*/
|
ReturnValue_t startImageDownload(std::string path);
|
||||||
ReturnValue_t startImageUpload(std::string uploadImage_);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Calling this function initiates the download of an image from the star tracker.
|
* @brief Starts the flash write procedure
|
||||||
*
|
*
|
||||||
* @param path Path where downloaded image will be stored
|
* @param fullname Full name including absolute path of file to write to flash
|
||||||
*/
|
* @param region Region ID of flash region to write to
|
||||||
ReturnValue_t startImageDownload(std::string path);
|
* @param address Start address of flash write procedure
|
||||||
|
*/
|
||||||
|
ReturnValue_t startFlashWrite(std::string fullname, uint8_t region, uint32_t address);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Starts the flash write procedure
|
* @brief Starts the flash read procedure
|
||||||
*
|
*
|
||||||
* @param fullname Full name including absolute path of file to write to flash
|
* @param path Path where file with read flash data will be created
|
||||||
* @param region Region ID of flash region to write to
|
* @param region Region ID of flash region to read from
|
||||||
* @param address Start address of flash write procedure
|
* @param address Start address of flash section to read
|
||||||
*/
|
* @param length Number of bytes to read from flash
|
||||||
ReturnValue_t startFlashWrite(std::string fullname, uint8_t region, uint32_t address);
|
*/
|
||||||
|
ReturnValue_t startFlashRead(std::string path, uint8_t region, uint32_t address, uint32_t length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Starts the flash read procedure
|
* @brief Starts the download of the FPGA image
|
||||||
*
|
*
|
||||||
* @param path Path where file with read flash data will be created
|
* @param path The path where the file with the downloaded data will be created
|
||||||
* @param region Region ID of flash region to read from
|
* @param startPosition Offset in fpga image to read from
|
||||||
* @param address Start address of flash section to read
|
* @param length Number of bytes to dwonload from the FPGA image
|
||||||
* @param length Number of bytes to read from flash
|
*
|
||||||
*/
|
*/
|
||||||
ReturnValue_t startFlashRead(std::string path, uint8_t region, uint32_t address,
|
ReturnValue_t startFpgaDownload(std::string path, uint32_t startPosition, uint32_t length);
|
||||||
uint32_t length);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Starts the download of the FPGA image
|
* @brief Starts upload of new image to FPGA
|
||||||
*
|
*
|
||||||
* @param path The path where the file with the downloaded data will be created
|
* @param uploadFile Full name of file containing FPGA image data
|
||||||
* @param startPosition Offset in fpga image to read from
|
*/
|
||||||
* @param length Number of bytes to dwonload from the FPGA image
|
ReturnValue_t startFpgaUpload(std::string uploadFile);
|
||||||
*
|
|
||||||
*/
|
|
||||||
ReturnValue_t startFpgaDownload(std::string path, uint32_t startPosition, uint32_t length);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Starts upload of new image to FPGA
|
* @brief Can be used to interrupt a running data transfer.
|
||||||
*
|
*/
|
||||||
* @param uploadFile Full name of file containing FPGA image data
|
void stopProcess();
|
||||||
*/
|
|
||||||
ReturnValue_t startFpgaUpload(std::string uploadFile);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Can be used to interrupt a running data transfer.
|
* @brief Changes the dafault name of downloaded images
|
||||||
*/
|
*/
|
||||||
void stopProcess();
|
void setDownloadImageName(std::string filename);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Changes the dafault name of downloaded images
|
* @brief Sets the name of the file which will be created to store the data read from flash
|
||||||
*/
|
*/
|
||||||
void setDownloadImageName(std::string filename);
|
void setFlashReadFilename(std::string filename);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the name of the file which will be created to store the data read from flash
|
* @brief Set download FPGA image name
|
||||||
*/
|
*/
|
||||||
void setFlashReadFilename(std::string filename);
|
void setDownloadFpgaImage(std::string filename);
|
||||||
|
|
||||||
/**
|
private:
|
||||||
* @brief Set download FPGA image name
|
static const uint8_t INTERFACE_ID = CLASS_ID::STR_HELPER;
|
||||||
*/
|
|
||||||
void setDownloadFpgaImage(std::string filename);
|
|
||||||
|
|
||||||
private:
|
//! [EXPORT] : [COMMENT] SD card specified in path string not mounted
|
||||||
|
static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA0);
|
||||||
|
//! [EXPORT] : [COMMENT] Specified file does not exist on filesystem
|
||||||
|
static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA1);
|
||||||
|
//! [EXPORT] : [COMMENT] Specified path does not exist
|
||||||
|
static const ReturnValue_t PATH_NOT_EXISTS = MAKE_RETURN_CODE(0xA2);
|
||||||
|
//! [EXPORT] : [COMMENT] Failed to create download image or read flash file
|
||||||
|
static const ReturnValue_t FILE_CREATION_FAILED = MAKE_RETURN_CODE(0xA3);
|
||||||
|
//! [EXPORT] : [COMMENT] Region in flash write/read reply does not match expected region
|
||||||
|
static const ReturnValue_t REGION_MISMATCH = MAKE_RETURN_CODE(0xA4);
|
||||||
|
//! [EXPORT] : [COMMENT] Address in flash write/read reply does not match expected address
|
||||||
|
static const ReturnValue_t ADDRESS_MISMATCH = MAKE_RETURN_CODE(0xA5);
|
||||||
|
//! [EXPORT] : [COMMENT] Length in flash write/read reply does not match expected length
|
||||||
|
static const ReturnValue_t LENGTH_MISMATCH = MAKE_RETURN_CODE(0xA6);
|
||||||
|
//! [EXPORT] : [COMMENT] Status field in reply signals error
|
||||||
|
static const ReturnValue_t STATUS_ERROR = MAKE_RETURN_CODE(0xA7);
|
||||||
|
//! [EXPORT] : [COMMENT] Reply has invalid type ID (should be of action reply type)
|
||||||
|
static const ReturnValue_t INVALID_TYPE_ID = MAKE_RETURN_CODE(0xA8);
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::STR_HELPER;
|
// Size of one image part which can be sent per action request
|
||||||
|
static const size_t SIZE_IMAGE_PART = 1024;
|
||||||
|
|
||||||
//! [EXPORT] : [COMMENT] SD card specified in path string not mounted
|
class ImageDownload {
|
||||||
static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(0xA0);
|
public:
|
||||||
//! [EXPORT] : [COMMENT] Specified file does not exist on filesystem
|
static const uint32_t LAST_POSITION = 4095;
|
||||||
static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA1);
|
};
|
||||||
//! [EXPORT] : [COMMENT] Specified path does not exist
|
|
||||||
static const ReturnValue_t PATH_NOT_EXISTS = MAKE_RETURN_CODE(0xA2);
|
|
||||||
//! [EXPORT] : [COMMENT] Failed to create download image or read flash file
|
|
||||||
static const ReturnValue_t FILE_CREATION_FAILED = MAKE_RETURN_CODE(0xA3);
|
|
||||||
//! [EXPORT] : [COMMENT] Region in flash write/read reply does not match expected region
|
|
||||||
static const ReturnValue_t REGION_MISMATCH = MAKE_RETURN_CODE(0xA4);
|
|
||||||
//! [EXPORT] : [COMMENT] Address in flash write/read reply does not match expected address
|
|
||||||
static const ReturnValue_t ADDRESS_MISMATCH = MAKE_RETURN_CODE(0xA5);
|
|
||||||
//! [EXPORT] : [COMMENT] Length in flash write/read reply does not match expected length
|
|
||||||
static const ReturnValue_t LENGTH_MISMATCH = MAKE_RETURN_CODE(0xA6);
|
|
||||||
//! [EXPORT] : [COMMENT] Status field in reply signals error
|
|
||||||
static const ReturnValue_t STATUS_ERROR = MAKE_RETURN_CODE(0xA7);
|
|
||||||
//! [EXPORT] : [COMMENT] Reply has invalid type ID (should be of action reply type)
|
|
||||||
static const ReturnValue_t INVALID_TYPE_ID = MAKE_RETURN_CODE(0xA8);
|
|
||||||
|
|
||||||
// Size of one image part which can be sent per action request
|
class FpgaDownload {
|
||||||
static const size_t SIZE_IMAGE_PART = 1024;
|
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 ImageDownload {
|
class FpgaUpload {
|
||||||
public:
|
public:
|
||||||
static const uint32_t LAST_POSITION = 4095;
|
static const uint32_t MAX_DATA = 1024;
|
||||||
};
|
// Full name of file to upload
|
||||||
|
std::string uploadFile;
|
||||||
|
};
|
||||||
|
FpgaUpload fpgaUpload;
|
||||||
|
|
||||||
class FpgaDownload {
|
static const uint32_t MAX_POLLS = 10000;
|
||||||
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 {
|
static const uint8_t ACTION_DATA_OFFSET = 2;
|
||||||
public:
|
static const uint8_t POS_OFFSET = 2;
|
||||||
static const uint32_t MAX_DATA = 1024;
|
static const uint8_t IMAGE_DATA_OFFSET = 5;
|
||||||
// Full name of file to upload
|
static const uint8_t FLASH_READ_DATA_OFFSET = 8;
|
||||||
std::string uploadFile;
|
static const uint8_t REGION_OFFSET = 2;
|
||||||
};
|
static const uint8_t ADDRESS_OFFSET = 3;
|
||||||
FpgaUpload fpgaUpload;
|
static const uint8_t LENGTH_OFFSET = 7;
|
||||||
|
static const size_t IMAGE_DATA_SIZE = 1024;
|
||||||
|
static const size_t MAX_FLASH_DATA = 1024;
|
||||||
|
static const size_t CONFIG_MAX_DOWNLOAD_RETRIES = 3;
|
||||||
|
|
||||||
static const uint32_t MAX_POLLS = 10000;
|
enum class InternalState {
|
||||||
|
IDLE,
|
||||||
|
UPLOAD_IMAGE,
|
||||||
|
DOWNLOAD_IMAGE,
|
||||||
|
FLASH_WRITE,
|
||||||
|
FLASH_READ,
|
||||||
|
DOWNLOAD_FPGA_IMAGE,
|
||||||
|
UPLOAD_FPGA_IMAGE
|
||||||
|
};
|
||||||
|
|
||||||
static const uint8_t ACTION_DATA_OFFSET = 2;
|
InternalState internalState = InternalState::IDLE;
|
||||||
static const uint8_t POS_OFFSET = 2;
|
|
||||||
static const uint8_t IMAGE_DATA_OFFSET = 5;
|
|
||||||
static const uint8_t FLASH_READ_DATA_OFFSET = 8;
|
|
||||||
static const uint8_t REGION_OFFSET = 2;
|
|
||||||
static const uint8_t ADDRESS_OFFSET = 3;
|
|
||||||
static const uint8_t LENGTH_OFFSET = 7;
|
|
||||||
static const size_t IMAGE_DATA_SIZE = 1024;
|
|
||||||
static const size_t MAX_FLASH_DATA = 1024;
|
|
||||||
static const size_t CONFIG_MAX_DOWNLOAD_RETRIES = 3;
|
|
||||||
|
|
||||||
enum class InternalState {
|
ArcsecDatalinkLayer datalinkLayer;
|
||||||
IDLE,
|
|
||||||
UPLOAD_IMAGE,
|
|
||||||
DOWNLOAD_IMAGE,
|
|
||||||
FLASH_WRITE,
|
|
||||||
FLASH_READ,
|
|
||||||
DOWNLOAD_FPGA_IMAGE,
|
|
||||||
UPLOAD_FPGA_IMAGE
|
|
||||||
};
|
|
||||||
|
|
||||||
InternalState internalState = InternalState::IDLE;
|
BinarySemaphore semaphore;
|
||||||
|
|
||||||
ArcsecDatalinkLayer datalinkLayer;
|
class UploadImage {
|
||||||
|
public:
|
||||||
|
// Name including absolute path of image to upload
|
||||||
|
std::string uploadFile;
|
||||||
|
};
|
||||||
|
UploadImage uploadImage;
|
||||||
|
|
||||||
BinarySemaphore semaphore;
|
class DownloadImage {
|
||||||
|
public:
|
||||||
|
// Path where the downloaded image will be stored
|
||||||
|
std::string path;
|
||||||
|
// Default name of downloaded image, can be changed via command
|
||||||
|
std::string filename = "image.bin";
|
||||||
|
};
|
||||||
|
DownloadImage downloadImage;
|
||||||
|
|
||||||
class UploadImage {
|
class FlashWrite {
|
||||||
public:
|
public:
|
||||||
// Name including absolute path of image to upload
|
// File which contains data to write when executing the flash write command
|
||||||
std::string uploadFile;
|
std::string fullname;
|
||||||
};
|
// Will be set with the flash write command
|
||||||
UploadImage uploadImage;
|
uint8_t region = 0;
|
||||||
|
// Will be set with the flash write command and specifies the start address where to write the
|
||||||
|
// flash data to
|
||||||
|
uint32_t address = 0;
|
||||||
|
};
|
||||||
|
FlashWrite flashWrite;
|
||||||
|
|
||||||
class DownloadImage {
|
class FlashRead {
|
||||||
public:
|
public:
|
||||||
// Path where the downloaded image will be stored
|
// Path where the file containing the read data will be stored
|
||||||
std::string path;
|
std::string path = "";
|
||||||
// Default name of downloaded image, can be changed via command
|
// Default name of file containing the data read from flash, can be changed via command
|
||||||
std::string filename = "image.bin";
|
std::string filename = "flashread.bin";
|
||||||
};
|
// Will be set with the flash read command
|
||||||
DownloadImage downloadImage;
|
uint8_t region = 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
|
||||||
|
uint32_t size = 0;
|
||||||
|
};
|
||||||
|
FlashRead flashRead;
|
||||||
|
|
||||||
class FlashWrite {
|
SdCardManager* sdcMan = nullptr;
|
||||||
public:
|
|
||||||
// File which contains data to write when executing the flash write command
|
|
||||||
std::string fullname;
|
|
||||||
// Will be set with the flash write command
|
|
||||||
uint8_t region = 0;
|
|
||||||
// Will be set with the flash write command and specifies the start address where to write the
|
|
||||||
// flash data to
|
|
||||||
uint32_t address = 0;
|
|
||||||
};
|
|
||||||
FlashWrite flashWrite;
|
|
||||||
|
|
||||||
class FlashRead {
|
uint8_t commandBuffer[StarTracker::MAX_FRAME_SIZE];
|
||||||
public:
|
|
||||||
// Path where the file containing the read data will be stored
|
|
||||||
std::string path = "";
|
|
||||||
// Default name of file containing the data read from flash, can be changed via command
|
|
||||||
std::string filename = "flashread.bin";
|
|
||||||
// Will be set with the flash read command
|
|
||||||
uint8_t region = 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
|
|
||||||
uint32_t size = 0;
|
|
||||||
};
|
|
||||||
FlashRead flashRead;
|
|
||||||
|
|
||||||
SdCardManager* sdcMan = nullptr;
|
bool terminate = false;
|
||||||
|
|
||||||
uint8_t commandBuffer[StarTracker::MAX_FRAME_SIZE];
|
/**
|
||||||
|
* UART communication object responsible for low level access of star tracker
|
||||||
|
* Must be set by star tracker handler
|
||||||
|
*/
|
||||||
|
UartComIF* uartComIF = nullptr;
|
||||||
|
// Communication cookie. Must be set by the star tracker handler
|
||||||
|
CookieIF* comCookie = nullptr;
|
||||||
|
|
||||||
bool terminate = false;
|
// Queue id of raw data receiver
|
||||||
|
MessageQueueId_t rawDataReceiver = MessageQueueIF::NO_QUEUE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UART communication object responsible for low level access of star tracker
|
* @brief Performs image uploading
|
||||||
* Must be set by star tracker handler
|
*/
|
||||||
*/
|
ReturnValue_t performImageUpload();
|
||||||
UartComIF* uartComIF = nullptr;
|
|
||||||
// Communication cookie. Must be set by the star tracker handler
|
|
||||||
CookieIF* comCookie = nullptr;
|
|
||||||
|
|
||||||
// Queue id of raw data receiver
|
/**
|
||||||
MessageQueueId_t rawDataReceiver = MessageQueueIF::NO_QUEUE;
|
* @brief Performs download of last taken image from the star tracker.
|
||||||
|
*
|
||||||
|
* @details Download is split over multiple packets transporting each a maximum of 1024 bytes.
|
||||||
|
* In case the download of one position fails, the same packet will be again
|
||||||
|
* requested. If the download of the packet fails CONFIG_MAX_DOWNLOAD_RETRIES times,
|
||||||
|
* the download will be stopped.
|
||||||
|
*/
|
||||||
|
ReturnValue_t performImageDownload();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Performs image uploading
|
* @brief Handles flash write procedure
|
||||||
*/
|
*
|
||||||
ReturnValue_t performImageUpload();
|
* @return RETURN_OK if successful, otherwise RETURN_FAILED
|
||||||
|
*/
|
||||||
|
ReturnValue_t performFlashWrite();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Performs download of last taken image from the star tracker.
|
* @brief Sends a sequence of commands to the star tracker to read larger parts from the
|
||||||
*
|
* flash memory.
|
||||||
* @details Download is split over multiple packets transporting each a maximum of 1024 bytes.
|
*/
|
||||||
* In case the download of one position fails, the same packet will be again
|
ReturnValue_t performFlashRead();
|
||||||
* requested. If the download of the packet fails CONFIG_MAX_DOWNLOAD_RETRIES times,
|
|
||||||
* the download will be stopped.
|
|
||||||
*/
|
|
||||||
ReturnValue_t performImageDownload();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handles flash write procedure
|
* @brief Performs the download of the FPGA image which requires to be slip over multiple
|
||||||
*
|
* action requests.
|
||||||
* @return RETURN_OK if successful, otherwise RETURN_FAILED
|
*/
|
||||||
*/
|
ReturnValue_t performFpgaDownload();
|
||||||
ReturnValue_t performFlashWrite();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sends a sequence of commands to the star tracker to read larger parts from the
|
* @brief Performs upload of new FPGA image. Upload sequence split over multiple commands
|
||||||
* flash memory.
|
* because one command can only transport 1024 bytes of image data.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t performFlashRead();
|
ReturnValue_t performFpgaUpload();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Performs the download of the FPGA image which requires to be slip over multiple
|
* @brief Sends packet to the star tracker and reads reply by using the communication
|
||||||
* action requests.
|
* interface
|
||||||
*/
|
*
|
||||||
ReturnValue_t performFpgaDownload();
|
* @param size Size of data beforehand written to the commandBuffer
|
||||||
|
* @param parameter Parameter 2 of trigger event function
|
||||||
|
*
|
||||||
|
* @return RETURN_OK if successful, otherwise RETURN_FAILED
|
||||||
|
*/
|
||||||
|
ReturnValue_t sendAndRead(size_t size, uint32_t parameter);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Performs upload of new FPGA image. Upload sequence split over multiple commands
|
* @brief Checks the header (type id and status fields) of the action reply
|
||||||
* because one command can only transport 1024 bytes of image data.
|
*
|
||||||
*/
|
* @return RETURN_OK if reply confirms success of packet transfer, otherwise REUTRN_FAILED
|
||||||
ReturnValue_t performFpgaUpload();
|
*/
|
||||||
|
ReturnValue_t checkActionReply();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sends packet to the star tracker and reads reply by using the communication
|
* @brief Checks the position field in a star tracker upload/download reply.
|
||||||
* interface
|
*
|
||||||
*
|
* @param expectedPosition Value of expected position
|
||||||
* @param size Size of data beforehand written to the commandBuffer
|
*
|
||||||
* @param parameter Parameter 2 of trigger event function
|
* @return RETURN_OK if received position matches expected position, otherwise RETURN_FAILED
|
||||||
*
|
*/
|
||||||
* @return RETURN_OK if successful, otherwise RETURN_FAILED
|
ReturnValue_t checkReplyPosition(uint32_t expectedPosition);
|
||||||
*/
|
|
||||||
ReturnValue_t sendAndRead(size_t size, uint32_t parameter);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks the header (type id and status fields) of the action reply
|
* @brief Checks the region, address and length value of a flash write or read reply.
|
||||||
*
|
*
|
||||||
* @return RETURN_OK if reply confirms success of packet transfer, otherwise REUTRN_FAILED
|
* @return RETURN_OK if values match expected values, otherwise appropriate error return
|
||||||
*/
|
* value.
|
||||||
ReturnValue_t checkActionReply();
|
*/
|
||||||
|
ReturnValue_t checkFlashActionReply(uint8_t region_, uint32_t address_, uint16_t length_);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks the position field in a star tracker upload/download reply.
|
* @brief Checks the reply to the fpga download and upload request
|
||||||
*
|
*
|
||||||
* @param expectedPosition Value of expected position
|
* @param expectedPosition The expected position value in the reply
|
||||||
*
|
* @param expectedLength The expected length field in the reply
|
||||||
* @return RETURN_OK if received position matches expected position, otherwise RETURN_FAILED
|
*/
|
||||||
*/
|
ReturnValue_t checkFpgaActionReply(uint32_t expectedPosition, uint32_t expectedLength);
|
||||||
ReturnValue_t checkReplyPosition(uint32_t expectedPosition);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks the region, address and length value of a flash write or read reply.
|
* @brief Checks if a path points to an sd card and whether the SD card is monuted.
|
||||||
*
|
*
|
||||||
* @return RETURN_OK if values match expected values, otherwise appropriate error return
|
* @return SD_NOT_MOUNTED id SD card is not mounted, otherwise RETURN_OK
|
||||||
* value.
|
*/
|
||||||
*/
|
ReturnValue_t checkPath(std::string name);
|
||||||
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.
|
|
||||||
*
|
|
||||||
* @return SD_NOT_MOUNTED id SD card is not mounted, otherwise RETURN_OK
|
|
||||||
*/
|
|
||||||
ReturnValue_t checkPath(std::string name);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* BSP_Q7S_DEVICES_STRHELPER_H_ */
|
#endif /* BSP_Q7S_DEVICES_STRHELPER_H_ */
|
||||||
|
@ -1,512 +1,504 @@
|
|||||||
#include "gpioCallbacks.h"
|
#include "gpioCallbacks.h"
|
||||||
#include "busConf.h"
|
|
||||||
#include <devices/gpioIds.h>
|
#include <devices/gpioIds.h>
|
||||||
|
|
||||||
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
|
|
||||||
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
|
||||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||||
|
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
||||||
|
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
|
||||||
|
|
||||||
|
#include "busConf.h"
|
||||||
|
|
||||||
namespace gpioCallbacks {
|
namespace gpioCallbacks {
|
||||||
|
|
||||||
GpioIF* gpioComInterface;
|
GpioIF* gpioComInterface;
|
||||||
|
|
||||||
void initSpiCsDecoder(GpioIF* gpioComIF) {
|
void initSpiCsDecoder(GpioIF* gpioComIF) {
|
||||||
|
ReturnValue_t result;
|
||||||
|
|
||||||
ReturnValue_t result;
|
if (gpioComIF == nullptr) {
|
||||||
|
sif::debug << "initSpiCsDecoder: Invalid gpioComIF" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (gpioComIF == nullptr) {
|
gpioComInterface = gpioComIF;
|
||||||
sif::debug << "initSpiCsDecoder: Invalid gpioComIF" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpioComInterface = gpioComIF;
|
GpioCookie* spiMuxGpios = new GpioCookie;
|
||||||
|
|
||||||
GpioCookie* spiMuxGpios = new GpioCookie;
|
GpiodRegularByLineName* spiMuxBit = nullptr;
|
||||||
|
/** Setting mux bit 1 to low will disable IC21 on the interface board */
|
||||||
|
spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_1_PIN, "SPI Mux Bit 1",
|
||||||
|
gpio::DIR_OUT, gpio::HIGH);
|
||||||
|
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_1, spiMuxBit);
|
||||||
|
/** Setting mux bit 2 to low disables IC1 on the TCS board */
|
||||||
|
spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_2_PIN, "SPI Mux Bit 2",
|
||||||
|
gpio::DIR_OUT, gpio::HIGH);
|
||||||
|
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_2, spiMuxBit);
|
||||||
|
/** 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_3_PIN, "SPI Mux Bit 3",
|
||||||
|
gpio::DIR_OUT, gpio::LOW);
|
||||||
|
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_3, spiMuxBit);
|
||||||
|
|
||||||
GpiodRegularByLineName* spiMuxBit = nullptr;
|
// spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_1_PIN, "SPI Mux Bit 1",
|
||||||
/** Setting mux bit 1 to low will disable IC21 on the interface board */
|
// gpio::OUT, gpio::LOW);
|
||||||
spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_1_PIN, "SPI Mux Bit 1",
|
// spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_1, spiMuxBit);
|
||||||
gpio::DIR_OUT, gpio::HIGH);
|
// /** Setting mux bit 2 to low disables IC1 on the TCS board */
|
||||||
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_1, spiMuxBit);
|
// spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_2_PIN, "SPI Mux Bit 2",
|
||||||
/** Setting mux bit 2 to low disables IC1 on the TCS board */
|
// gpio::OUT, gpio::HIGH); spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_2, spiMuxBit);
|
||||||
spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_2_PIN, "SPI Mux Bit 2",
|
// /** Setting mux bit 3 to low disables IC2 on the TCS board and IC22 on the interface board
|
||||||
gpio::DIR_OUT, gpio::HIGH);
|
// */ spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_3_PIN, "SPI Mux Bit
|
||||||
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_2, spiMuxBit);
|
// 3", gpio::OUT, gpio::LOW); spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_3, spiMuxBit);
|
||||||
/** 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_3_PIN, "SPI Mux Bit 3",
|
|
||||||
gpio::DIR_OUT, gpio::LOW);
|
|
||||||
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_3, spiMuxBit);
|
|
||||||
|
|
||||||
// spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_1_PIN, "SPI Mux Bit 1",
|
/** The following gpios can take arbitrary initial values */
|
||||||
// gpio::OUT, gpio::LOW);
|
spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_4_PIN, "SPI Mux Bit 4",
|
||||||
// spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_1, spiMuxBit);
|
gpio::DIR_OUT, gpio::LOW);
|
||||||
// /** Setting mux bit 2 to low disables IC1 on the TCS board */
|
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_4, spiMuxBit);
|
||||||
// spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_2_PIN, "SPI Mux Bit 2", gpio::OUT, gpio::HIGH);
|
spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_5_PIN, "SPI Mux Bit 5",
|
||||||
// spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_2, spiMuxBit);
|
gpio::DIR_OUT, gpio::LOW);
|
||||||
// /** Setting mux bit 3 to low disables IC2 on the TCS board and IC22 on the interface board */
|
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_5, spiMuxBit);
|
||||||
// spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_3_PIN, "SPI Mux Bit 3", gpio::OUT, gpio::LOW);
|
spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_6_PIN, "SPI Mux Bit 6",
|
||||||
// spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_3, spiMuxBit);
|
gpio::DIR_OUT, gpio::LOW);
|
||||||
|
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_6, spiMuxBit);
|
||||||
|
GpiodRegularByLineName* enRwDecoder =
|
||||||
|
new GpiodRegularByLineName(q7s::gpioNames::EN_RW_CS, "EN_RW_CS", gpio::DIR_OUT, gpio::HIGH);
|
||||||
|
spiMuxGpios->addGpio(gpioIds::EN_RW_CS, enRwDecoder);
|
||||||
|
|
||||||
/** The following gpios can take arbitrary initial values */
|
result = gpioComInterface->addGpios(spiMuxGpios);
|
||||||
spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_4_PIN, "SPI Mux Bit 4",
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
gpio::DIR_OUT, gpio::LOW);
|
sif::error << "initSpiCsDecoder: Failed to add mux bit gpios to gpioComIF" << std::endl;
|
||||||
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_4, spiMuxBit);
|
return;
|
||||||
spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_5_PIN, "SPI Mux Bit 5",
|
}
|
||||||
gpio::DIR_OUT, gpio::LOW);
|
|
||||||
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_5, spiMuxBit);
|
|
||||||
spiMuxBit = new GpiodRegularByLineName(q7s::gpioNames::SPI_MUX_BIT_6_PIN, "SPI Mux Bit 6",
|
|
||||||
gpio::DIR_OUT, gpio::LOW);
|
|
||||||
spiMuxGpios->addGpio(gpioIds::SPI_MUX_BIT_6, spiMuxBit);
|
|
||||||
GpiodRegularByLineName* enRwDecoder = new GpiodRegularByLineName(q7s::gpioNames::EN_RW_CS,
|
|
||||||
"EN_RW_CS", gpio::DIR_OUT, gpio::HIGH);
|
|
||||||
spiMuxGpios->addGpio(gpioIds::EN_RW_CS, enRwDecoder);
|
|
||||||
|
|
||||||
result = gpioComInterface->addGpios(spiMuxGpios);
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
sif::error << "initSpiCsDecoder: Failed to add mux bit gpios to gpioComIF" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
if (gpioComInterface == nullptr) {
|
||||||
|
sif::debug << "spiCsDecoderCallback: No gpioComIF specified. Call initSpiCsDecoder "
|
||||||
|
<< "to specify gpioComIF" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (gpioComInterface == nullptr) {
|
/* Reading is not supported by the callback function */
|
||||||
sif::debug << "spiCsDecoderCallback: No gpioComIF specified. Call initSpiCsDecoder "
|
if (gpioOp == gpio::GpioOperation::READ) {
|
||||||
<< "to specify gpioComIF" << std::endl;
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Reading is not supported by the callback function */
|
if (value == gpio::HIGH) {
|
||||||
if (gpioOp == gpio::GpioOperation::READ) {
|
switch (gpioId) {
|
||||||
return;
|
case (gpioIds::RTD_IC_3): {
|
||||||
|
disableDecoderTcsIc1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::RTD_IC_4): {
|
||||||
|
disableDecoderTcsIc1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::RTD_IC_5): {
|
||||||
|
disableDecoderTcsIc1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::RTD_IC_6): {
|
||||||
|
disableDecoderTcsIc1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::RTD_IC_7): {
|
||||||
|
disableDecoderTcsIc1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::RTD_IC_8): {
|
||||||
|
disableDecoderTcsIc1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::RTD_IC_9): {
|
||||||
|
disableDecoderTcsIc1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::RTD_IC_10): {
|
||||||
|
disableDecoderTcsIc1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::RTD_IC_11): {
|
||||||
|
disableDecoderTcsIc2();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::RTD_IC_12): {
|
||||||
|
disableDecoderTcsIc2();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::RTD_IC_13): {
|
||||||
|
disableDecoderTcsIc2();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::RTD_IC_14): {
|
||||||
|
disableDecoderTcsIc2();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::RTD_IC_15): {
|
||||||
|
disableDecoderTcsIc2();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::RTD_IC_16): {
|
||||||
|
disableDecoderTcsIc2();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::RTD_IC_17): {
|
||||||
|
disableDecoderTcsIc2();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::RTD_IC_18): {
|
||||||
|
disableDecoderTcsIc2();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::CS_SUS_1): {
|
||||||
|
disableDecoderInterfaceBoardIc1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::CS_SUS_2): {
|
||||||
|
disableDecoderInterfaceBoardIc1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::CS_SUS_3): {
|
||||||
|
disableDecoderInterfaceBoardIc2();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::CS_SUS_4): {
|
||||||
|
disableDecoderInterfaceBoardIc2();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::CS_SUS_5): {
|
||||||
|
disableDecoderInterfaceBoardIc2();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::CS_SUS_6): {
|
||||||
|
disableDecoderInterfaceBoardIc1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::CS_SUS_7): {
|
||||||
|
disableDecoderInterfaceBoardIc1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::CS_SUS_8): {
|
||||||
|
disableDecoderInterfaceBoardIc2();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::CS_SUS_9): {
|
||||||
|
disableDecoderInterfaceBoardIc1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::CS_SUS_10): {
|
||||||
|
disableDecoderInterfaceBoardIc1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::CS_SUS_11): {
|
||||||
|
disableDecoderInterfaceBoardIc2();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::CS_SUS_12): {
|
||||||
|
disableDecoderInterfaceBoardIc2();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::CS_SUS_13): {
|
||||||
|
disableDecoderInterfaceBoardIc1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::CS_RW1): {
|
||||||
|
disableRwDecoder();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::CS_RW2): {
|
||||||
|
disableRwDecoder();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::CS_RW3): {
|
||||||
|
disableRwDecoder();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpioIds::CS_RW4): {
|
||||||
|
disableRwDecoder();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
sif::debug << "spiCsDecoderCallback: Invalid gpio id " << gpioId << std::endl;
|
||||||
}
|
}
|
||||||
|
} else if (value == gpio::LOW) {
|
||||||
if (value == gpio::HIGH) {
|
switch (gpioId) {
|
||||||
switch (gpioId) {
|
case (gpioIds::RTD_IC_3): {
|
||||||
case(gpioIds::RTD_IC_3): {
|
selectY7();
|
||||||
disableDecoderTcsIc1();
|
enableDecoderTcsIc1();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(gpioIds::RTD_IC_4): {
|
case (gpioIds::RTD_IC_4): {
|
||||||
disableDecoderTcsIc1();
|
selectY6();
|
||||||
break;
|
enableDecoderTcsIc1();
|
||||||
}
|
break;
|
||||||
case(gpioIds::RTD_IC_5): {
|
}
|
||||||
disableDecoderTcsIc1();
|
case (gpioIds::RTD_IC_5): {
|
||||||
break;
|
selectY5();
|
||||||
}
|
enableDecoderTcsIc1();
|
||||||
case(gpioIds::RTD_IC_6): {
|
break;
|
||||||
disableDecoderTcsIc1();
|
}
|
||||||
break;
|
case (gpioIds::RTD_IC_6): {
|
||||||
}
|
selectY4();
|
||||||
case(gpioIds::RTD_IC_7): {
|
enableDecoderTcsIc1();
|
||||||
disableDecoderTcsIc1();
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case (gpioIds::RTD_IC_7): {
|
||||||
case(gpioIds::RTD_IC_8): {
|
selectY3();
|
||||||
disableDecoderTcsIc1();
|
enableDecoderTcsIc1();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(gpioIds::RTD_IC_9): {
|
case (gpioIds::RTD_IC_8): {
|
||||||
disableDecoderTcsIc1();
|
selectY2();
|
||||||
break;
|
enableDecoderTcsIc1();
|
||||||
}
|
break;
|
||||||
case(gpioIds::RTD_IC_10): {
|
}
|
||||||
disableDecoderTcsIc1();
|
case (gpioIds::RTD_IC_9): {
|
||||||
break;
|
selectY1();
|
||||||
}
|
enableDecoderTcsIc1();
|
||||||
case(gpioIds::RTD_IC_11): {
|
break;
|
||||||
disableDecoderTcsIc2();
|
}
|
||||||
break;
|
case (gpioIds::RTD_IC_10): {
|
||||||
}
|
selectY0();
|
||||||
case(gpioIds::RTD_IC_12): {
|
enableDecoderTcsIc1();
|
||||||
disableDecoderTcsIc2();
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case (gpioIds::RTD_IC_11): {
|
||||||
case(gpioIds::RTD_IC_13): {
|
selectY7();
|
||||||
disableDecoderTcsIc2();
|
enableDecoderTcsIc2();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(gpioIds::RTD_IC_14): {
|
case (gpioIds::RTD_IC_12): {
|
||||||
disableDecoderTcsIc2();
|
selectY6();
|
||||||
break;
|
enableDecoderTcsIc2();
|
||||||
}
|
break;
|
||||||
case(gpioIds::RTD_IC_15): {
|
}
|
||||||
disableDecoderTcsIc2();
|
case (gpioIds::RTD_IC_13): {
|
||||||
break;
|
selectY5();
|
||||||
}
|
enableDecoderTcsIc2();
|
||||||
case(gpioIds::RTD_IC_16): {
|
break;
|
||||||
disableDecoderTcsIc2();
|
}
|
||||||
break;
|
case (gpioIds::RTD_IC_14): {
|
||||||
}
|
selectY4();
|
||||||
case(gpioIds::RTD_IC_17): {
|
enableDecoderTcsIc2();
|
||||||
disableDecoderTcsIc2();
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case (gpioIds::RTD_IC_15): {
|
||||||
case(gpioIds::RTD_IC_18): {
|
selectY3();
|
||||||
disableDecoderTcsIc2();
|
enableDecoderTcsIc2();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(gpioIds::CS_SUS_1): {
|
case (gpioIds::RTD_IC_16): {
|
||||||
disableDecoderInterfaceBoardIc1();
|
selectY2();
|
||||||
break;
|
enableDecoderTcsIc2();
|
||||||
}
|
break;
|
||||||
case(gpioIds::CS_SUS_2): {
|
}
|
||||||
disableDecoderInterfaceBoardIc1();
|
case (gpioIds::RTD_IC_17): {
|
||||||
break;
|
selectY1();
|
||||||
}
|
enableDecoderTcsIc2();
|
||||||
case(gpioIds::CS_SUS_3): {
|
break;
|
||||||
disableDecoderInterfaceBoardIc2();
|
}
|
||||||
break;
|
case (gpioIds::RTD_IC_18): {
|
||||||
}
|
selectY0();
|
||||||
case(gpioIds::CS_SUS_4): {
|
enableDecoderTcsIc2();
|
||||||
disableDecoderInterfaceBoardIc2();
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case (gpioIds::CS_SUS_1): {
|
||||||
case(gpioIds::CS_SUS_5): {
|
selectY0();
|
||||||
disableDecoderInterfaceBoardIc2();
|
enableDecoderInterfaceBoardIc1();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(gpioIds::CS_SUS_6): {
|
case (gpioIds::CS_SUS_2): {
|
||||||
disableDecoderInterfaceBoardIc1();
|
selectY1();
|
||||||
break;
|
enableDecoderInterfaceBoardIc1();
|
||||||
}
|
break;
|
||||||
case(gpioIds::CS_SUS_7): {
|
}
|
||||||
disableDecoderInterfaceBoardIc1();
|
case (gpioIds::CS_SUS_3): {
|
||||||
break;
|
selectY0();
|
||||||
}
|
enableDecoderInterfaceBoardIc2();
|
||||||
case(gpioIds::CS_SUS_8): {
|
break;
|
||||||
disableDecoderInterfaceBoardIc2();
|
}
|
||||||
break;
|
case (gpioIds::CS_SUS_4): {
|
||||||
}
|
selectY1();
|
||||||
case(gpioIds::CS_SUS_9): {
|
enableDecoderInterfaceBoardIc2();
|
||||||
disableDecoderInterfaceBoardIc1();
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case (gpioIds::CS_SUS_5): {
|
||||||
case(gpioIds::CS_SUS_10): {
|
selectY2();
|
||||||
disableDecoderInterfaceBoardIc1();
|
enableDecoderInterfaceBoardIc2();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(gpioIds::CS_SUS_11): {
|
case (gpioIds::CS_SUS_6): {
|
||||||
disableDecoderInterfaceBoardIc2();
|
selectY2();
|
||||||
break;
|
enableDecoderInterfaceBoardIc1();
|
||||||
}
|
break;
|
||||||
case(gpioIds::CS_SUS_12): {
|
}
|
||||||
disableDecoderInterfaceBoardIc2();
|
case (gpioIds::CS_SUS_7): {
|
||||||
break;
|
selectY3();
|
||||||
}
|
enableDecoderInterfaceBoardIc1();
|
||||||
case(gpioIds::CS_SUS_13): {
|
break;
|
||||||
disableDecoderInterfaceBoardIc1();
|
}
|
||||||
break;
|
case (gpioIds::CS_SUS_8): {
|
||||||
}
|
selectY3();
|
||||||
case(gpioIds::CS_RW1): {
|
enableDecoderInterfaceBoardIc2();
|
||||||
disableRwDecoder();
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case (gpioIds::CS_SUS_9): {
|
||||||
case(gpioIds::CS_RW2): {
|
selectY4();
|
||||||
disableRwDecoder();
|
enableDecoderInterfaceBoardIc1();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(gpioIds::CS_RW3): {
|
case (gpioIds::CS_SUS_10): {
|
||||||
disableRwDecoder();
|
selectY5();
|
||||||
break;
|
enableDecoderInterfaceBoardIc1();
|
||||||
}
|
break;
|
||||||
case(gpioIds::CS_RW4): {
|
}
|
||||||
disableRwDecoder();
|
case (gpioIds::CS_SUS_11): {
|
||||||
break;
|
selectY4();
|
||||||
}
|
enableDecoderInterfaceBoardIc2();
|
||||||
default:
|
break;
|
||||||
sif::debug << "spiCsDecoderCallback: Invalid gpio id " << gpioId << std::endl;
|
}
|
||||||
}
|
case (gpioIds::CS_SUS_12): {
|
||||||
}
|
selectY5();
|
||||||
else if (value == gpio::LOW) {
|
enableDecoderInterfaceBoardIc2();
|
||||||
switch (gpioId) {
|
break;
|
||||||
case(gpioIds::RTD_IC_3): {
|
}
|
||||||
selectY7();
|
case (gpioIds::CS_SUS_13): {
|
||||||
enableDecoderTcsIc1();
|
selectY6();
|
||||||
break;
|
enableDecoderInterfaceBoardIc1();
|
||||||
}
|
break;
|
||||||
case(gpioIds::RTD_IC_4): {
|
}
|
||||||
selectY6();
|
case (gpioIds::CS_RW1): {
|
||||||
enableDecoderTcsIc1();
|
selectY0();
|
||||||
break;
|
enableRwDecoder();
|
||||||
}
|
break;
|
||||||
case(gpioIds::RTD_IC_5): {
|
}
|
||||||
selectY5();
|
case (gpioIds::CS_RW2): {
|
||||||
enableDecoderTcsIc1();
|
selectY1();
|
||||||
break;
|
enableRwDecoder();
|
||||||
}
|
break;
|
||||||
case(gpioIds::RTD_IC_6): {
|
}
|
||||||
selectY4();
|
case (gpioIds::CS_RW3): {
|
||||||
enableDecoderTcsIc1();
|
selectY2();
|
||||||
break;
|
enableRwDecoder();
|
||||||
}
|
break;
|
||||||
case(gpioIds::RTD_IC_7): {
|
}
|
||||||
selectY3();
|
case (gpioIds::CS_RW4): {
|
||||||
enableDecoderTcsIc1();
|
selectY3();
|
||||||
break;
|
enableRwDecoder();
|
||||||
}
|
break;
|
||||||
case(gpioIds::RTD_IC_8): {
|
}
|
||||||
selectY2();
|
default:
|
||||||
enableDecoderTcsIc1();
|
sif::debug << "spiCsDecoderCallback: Invalid gpio id " << gpioId << std::endl;
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::RTD_IC_9): {
|
|
||||||
selectY1();
|
|
||||||
enableDecoderTcsIc1();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::RTD_IC_10): {
|
|
||||||
selectY0();
|
|
||||||
enableDecoderTcsIc1();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::RTD_IC_11): {
|
|
||||||
selectY7();
|
|
||||||
enableDecoderTcsIc2();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::RTD_IC_12): {
|
|
||||||
selectY6();
|
|
||||||
enableDecoderTcsIc2();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::RTD_IC_13): {
|
|
||||||
selectY5();
|
|
||||||
enableDecoderTcsIc2();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::RTD_IC_14): {
|
|
||||||
selectY4();
|
|
||||||
enableDecoderTcsIc2();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::RTD_IC_15): {
|
|
||||||
selectY3();
|
|
||||||
enableDecoderTcsIc2();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::RTD_IC_16): {
|
|
||||||
selectY2();
|
|
||||||
enableDecoderTcsIc2();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::RTD_IC_17): {
|
|
||||||
selectY1();
|
|
||||||
enableDecoderTcsIc2();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::RTD_IC_18): {
|
|
||||||
selectY0();
|
|
||||||
enableDecoderTcsIc2();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::CS_SUS_1): {
|
|
||||||
selectY0();
|
|
||||||
enableDecoderInterfaceBoardIc1();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::CS_SUS_2): {
|
|
||||||
selectY1();
|
|
||||||
enableDecoderInterfaceBoardIc1();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::CS_SUS_3): {
|
|
||||||
selectY0();
|
|
||||||
enableDecoderInterfaceBoardIc2();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::CS_SUS_4): {
|
|
||||||
selectY1();
|
|
||||||
enableDecoderInterfaceBoardIc2();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::CS_SUS_5): {
|
|
||||||
selectY2();
|
|
||||||
enableDecoderInterfaceBoardIc2();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::CS_SUS_6): {
|
|
||||||
selectY2();
|
|
||||||
enableDecoderInterfaceBoardIc1();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::CS_SUS_7): {
|
|
||||||
selectY3();
|
|
||||||
enableDecoderInterfaceBoardIc1();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::CS_SUS_8): {
|
|
||||||
selectY3();
|
|
||||||
enableDecoderInterfaceBoardIc2();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::CS_SUS_9): {
|
|
||||||
selectY4();
|
|
||||||
enableDecoderInterfaceBoardIc1();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::CS_SUS_10): {
|
|
||||||
selectY5();
|
|
||||||
enableDecoderInterfaceBoardIc1();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::CS_SUS_11): {
|
|
||||||
selectY4();
|
|
||||||
enableDecoderInterfaceBoardIc2();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::CS_SUS_12): {
|
|
||||||
selectY5();
|
|
||||||
enableDecoderInterfaceBoardIc2();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::CS_SUS_13): {
|
|
||||||
selectY6();
|
|
||||||
enableDecoderInterfaceBoardIc1();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::CS_RW1): {
|
|
||||||
selectY0();
|
|
||||||
enableRwDecoder();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::CS_RW2): {
|
|
||||||
selectY1();
|
|
||||||
enableRwDecoder();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::CS_RW3): {
|
|
||||||
selectY2();
|
|
||||||
enableRwDecoder();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpioIds::CS_RW4): {
|
|
||||||
selectY3();
|
|
||||||
enableRwDecoder();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
sif::debug << "spiCsDecoderCallback: Invalid gpio id " << gpioId << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sif::debug << "spiCsDecoderCallback: Invalid value. Must be 0 or 1" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
sif::debug << "spiCsDecoderCallback: Invalid value. Must be 0 or 1" << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void enableDecoderTcsIc1() {
|
void enableDecoderTcsIc1() {
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void enableDecoderTcsIc2() {
|
void enableDecoderTcsIc2() {
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void enableDecoderInterfaceBoardIc1() {
|
void enableDecoderInterfaceBoardIc1() {
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_2);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_2);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void enableDecoderInterfaceBoardIc2() {
|
void enableDecoderInterfaceBoardIc2() {
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1);
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_3);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_2);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disableDecoderTcsIc1() {
|
void disableDecoderTcsIc1() {
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1);
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disableDecoderTcsIc2() {
|
void disableDecoderTcsIc2() {
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disableDecoderInterfaceBoardIc1() {
|
void disableDecoderInterfaceBoardIc1() {
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1);
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disableDecoderInterfaceBoardIc2() {
|
void disableDecoderInterfaceBoardIc2() {
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_1);
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_2);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void enableRwDecoder() {
|
void enableRwDecoder() { gpioComInterface->pullHigh(gpioIds::EN_RW_CS); }
|
||||||
gpioComInterface->pullHigh(gpioIds::EN_RW_CS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disableRwDecoder() {
|
void disableRwDecoder() { gpioComInterface->pullLow(gpioIds::EN_RW_CS); }
|
||||||
gpioComInterface->pullLow(gpioIds::EN_RW_CS);
|
|
||||||
}
|
|
||||||
|
|
||||||
void selectY0() {
|
void selectY0() {
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectY1() {
|
void selectY1() {
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectY2() {
|
void selectY2() {
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectY3() {
|
void selectY3() {
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectY4() {
|
void selectY4() {
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectY5() {
|
void selectY5() {
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_5);
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectY6() {
|
void selectY6() {
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_4);
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectY7() {
|
void selectY7() {
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_4);
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_5);
|
||||||
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
|
gpioComInterface->pullHigh(gpioIds::SPI_MUX_BIT_6);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disableAllDecoder() {
|
void disableAllDecoder() {
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_3);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_1);
|
||||||
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_2);
|
gpioComInterface->pullLow(gpioIds::SPI_MUX_BIT_2);
|
||||||
gpioComInterface->pullLow(gpioIds::EN_RW_CS);
|
gpioComInterface->pullLow(gpioIds::EN_RW_CS);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace gpioCallbacks
|
||||||
|
@ -1,74 +1,73 @@
|
|||||||
#ifndef LINUX_GPIO_GPIOCALLBACKS_H_
|
#ifndef LINUX_GPIO_GPIOCALLBACKS_H_
|
||||||
#define LINUX_GPIO_GPIOCALLBACKS_H_
|
#define LINUX_GPIO_GPIOCALLBACKS_H_
|
||||||
|
|
||||||
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
|
|
||||||
#include <fsfw_hal/common/gpio/GpioIF.h>
|
#include <fsfw_hal/common/gpio/GpioIF.h>
|
||||||
|
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
|
||||||
|
|
||||||
namespace gpioCallbacks {
|
namespace gpioCallbacks {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function initializes the GPIOs used to control the SN74LVC138APWR decoders on
|
* @brief This function initializes the GPIOs used to control the SN74LVC138APWR decoders on
|
||||||
* the TCS Board and the interface board.
|
* the TCS Board and the interface board.
|
||||||
*/
|
*/
|
||||||
void initSpiCsDecoder(GpioIF* gpioComIF);
|
void initSpiCsDecoder(GpioIF* gpioComIF);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function implements the decoding to multiply gpios by using the decoder
|
* @brief This function implements the decoding to multiply gpios by using the decoder
|
||||||
* chips SN74LVC138APWR on the TCS board and the interface board.
|
* chips SN74LVC138APWR on the TCS board and the interface board.
|
||||||
*/
|
*/
|
||||||
void spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gpioOp,
|
void spiCsDecoderCallback(gpioId_t gpioId, gpio::GpioOperation gpioOp, gpio::Levels value,
|
||||||
gpio::Levels value, void* args);
|
void* args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function sets mux bits 1-3 to a state which will only enable the decoder
|
* @brief This function sets mux bits 1-3 to a state which will only enable the decoder
|
||||||
* on the TCS board which is named to IC1 in the schematic.
|
* on the TCS board which is named to IC1 in the schematic.
|
||||||
*/
|
*/
|
||||||
void enableDecoderTcsIc1();
|
void enableDecoderTcsIc1();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function sets mux bits 1-3 to a state which will only enable the decoder
|
* @brief This function sets mux bits 1-3 to a state which will only enable the decoder
|
||||||
* on the TCS board which is named to IC2 in the schematic.
|
* on the TCS board which is named to IC2 in the schematic.
|
||||||
*/
|
*/
|
||||||
void enableDecoderTcsIc2();
|
void enableDecoderTcsIc2();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function sets mux bits 1-3 to a state which will only enable the decoder
|
* @brief This function sets mux bits 1-3 to a state which will only enable the decoder
|
||||||
* on the inteface board board which is named to IC21 in the schematic.
|
* on the inteface board board which is named to IC21 in the schematic.
|
||||||
*/
|
*/
|
||||||
void enableDecoderInterfaceBoardIc1();
|
void enableDecoderInterfaceBoardIc1();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function sets mux bits 1-3 to a state which will only enable the decoder
|
* @brief This function sets mux bits 1-3 to a state which will only enable the decoder
|
||||||
* on the inteface board board which is named to IC22 in the schematic.
|
* on the inteface board board which is named to IC22 in the schematic.
|
||||||
*/
|
*/
|
||||||
void enableDecoderInterfaceBoardIc2();
|
void enableDecoderInterfaceBoardIc2();
|
||||||
|
|
||||||
void disableDecoderTcsIc1();
|
void disableDecoderTcsIc1();
|
||||||
void disableDecoderTcsIc2();
|
void disableDecoderTcsIc2();
|
||||||
void disableDecoderInterfaceBoardIc1();
|
void disableDecoderInterfaceBoardIc1();
|
||||||
void disableDecoderInterfaceBoardIc2();
|
void disableDecoderInterfaceBoardIc2();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enables the reaction wheel chip select decoder (IC3).
|
* @brief Enables the reaction wheel chip select decoder (IC3).
|
||||||
*/
|
*/
|
||||||
void enableRwDecoder();
|
void enableRwDecoder();
|
||||||
void disableRwDecoder();
|
void disableRwDecoder();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function disables all decoder.
|
* @brief This function disables all decoder.
|
||||||
*/
|
*/
|
||||||
void disableAllDecoder();
|
void disableAllDecoder();
|
||||||
|
|
||||||
/** The following functions enable the appropriate channel of the currently enabled decoder */
|
/** The following functions enable the appropriate channel of the currently enabled decoder */
|
||||||
void selectY0();
|
void selectY0();
|
||||||
void selectY1();
|
void selectY1();
|
||||||
void selectY2();
|
void selectY2();
|
||||||
void selectY3();
|
void selectY3();
|
||||||
void selectY4();
|
void selectY4();
|
||||||
void selectY5();
|
void selectY5();
|
||||||
void selectY6();
|
void selectY6();
|
||||||
void selectY7();
|
void selectY7();
|
||||||
}
|
} // namespace gpioCallbacks
|
||||||
|
|
||||||
#endif /* LINUX_GPIO_GPIOCALLBACKS_H_ */
|
#endif /* LINUX_GPIO_GPIOCALLBACKS_H_ */
|
||||||
|
@ -12,12 +12,11 @@
|
|||||||
* @brief This is the main program for the target hardware.
|
* @brief This is the main program for the target hardware.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int main(void)
|
int main(void) {
|
||||||
{
|
using namespace std;
|
||||||
using namespace std;
|
|
||||||
#if Q7S_SIMPLE_MODE == 0
|
#if Q7S_SIMPLE_MODE == 0
|
||||||
return obsw::obsw();
|
return obsw::obsw();
|
||||||
#else
|
#else
|
||||||
return simple::simple();
|
return simple::simple();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1,257 +1,241 @@
|
|||||||
#include "FileSystemHandler.h"
|
#include "FileSystemHandler.h"
|
||||||
|
|
||||||
#include "bsp_q7s/core/CoreController.h"
|
|
||||||
|
|
||||||
#include "fsfw/tasks/TaskFactory.h"
|
|
||||||
#include "fsfw/memory/GenericFileSystemMessage.h"
|
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fstream>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
FileSystemHandler::FileSystemHandler(object_id_t fileSystemHandler):
|
#include "bsp_q7s/core/CoreController.h"
|
||||||
SystemObject(fileSystemHandler) {
|
#include "fsfw/ipc/QueueFactory.h"
|
||||||
mq = QueueFactory::instance()->createMessageQueue(FS_MAX_QUEUE_SIZE);
|
#include "fsfw/memory/GenericFileSystemMessage.h"
|
||||||
|
#include "fsfw/tasks/TaskFactory.h"
|
||||||
|
|
||||||
|
FileSystemHandler::FileSystemHandler(object_id_t fileSystemHandler)
|
||||||
|
: SystemObject(fileSystemHandler) {
|
||||||
|
mq = QueueFactory::instance()->createMessageQueue(FS_MAX_QUEUE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystemHandler::~FileSystemHandler() {
|
FileSystemHandler::~FileSystemHandler() { QueueFactory::instance()->deleteMessageQueue(mq); }
|
||||||
QueueFactory::instance()->deleteMessageQueue(mq);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FileSystemHandler::performOperation(uint8_t unsignedChar) {
|
ReturnValue_t FileSystemHandler::performOperation(uint8_t unsignedChar) {
|
||||||
while(true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
fileSystemHandlerLoop();
|
fileSystemHandlerLoop();
|
||||||
}
|
} catch (std::bad_alloc& e) {
|
||||||
catch(std::bad_alloc& e) {
|
// Restart OBSW, hints at a memory leak
|
||||||
// Restart OBSW, hints at a memory leak
|
sif::error << "Allocation error in FileSystemHandler::performOperation" << e.what()
|
||||||
sif::error << "Allocation error in FileSystemHandler::performOperation"
|
<< std::endl;
|
||||||
<< e.what() << std::endl;
|
// Set up an error file or a special flag in the scratch buffer for these cases
|
||||||
// Set up an error file or a special flag in the scratch buffer for these cases
|
triggerEvent(CoreController::ALLOC_FAILURE, 0, 0);
|
||||||
triggerEvent(CoreController::ALLOC_FAILURE, 0 , 0);
|
CoreController::incrementAllocationFailureCount();
|
||||||
CoreController::incrementAllocationFailureCount();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FileSystemHandler::fileSystemHandlerLoop() {
|
void FileSystemHandler::fileSystemHandlerLoop() {
|
||||||
CommandMessage filemsg;
|
CommandMessage filemsg;
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
while(true) {
|
while (true) {
|
||||||
if(opCounter % 5 == 0) {
|
if (opCounter % 5 == 0) {
|
||||||
if(coreCtrl->sdInitFinished()) {
|
if (coreCtrl->sdInitFinished()) {
|
||||||
fileSystemCheckup();
|
fileSystemCheckup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = mq->receiveMessage(&filemsg);
|
result = mq->receiveMessage(&filemsg);
|
||||||
if(result == MessageQueueIF::EMPTY) {
|
if (result == MessageQueueIF::EMPTY) {
|
||||||
break;
|
break;
|
||||||
}
|
} else if (result != HasReturnvaluesIF::RETURN_FAILED) {
|
||||||
else if(result != HasReturnvaluesIF::RETURN_FAILED) {
|
sif::warning << "FileSystemHandler::performOperation: Message reception failed!" << std::endl;
|
||||||
sif::warning << "FileSystemHandler::performOperation: Message reception failed!"
|
break;
|
||||||
<< std::endl;
|
}
|
||||||
break;
|
Command_t command = filemsg.getCommand();
|
||||||
}
|
switch (command) {
|
||||||
Command_t command = filemsg.getCommand();
|
case (GenericFileSystemMessage::CMD_CREATE_DIRECTORY): {
|
||||||
switch(command) {
|
break;
|
||||||
case(GenericFileSystemMessage::CMD_CREATE_DIRECTORY): {
|
}
|
||||||
break;
|
case (GenericFileSystemMessage::CMD_CREATE_FILE): {
|
||||||
}
|
break;
|
||||||
case(GenericFileSystemMessage::CMD_CREATE_FILE): {
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
opCounter++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This task will have a low priority and will run permanently in the background
|
|
||||||
// so we will just run in a permanent loop here and check file system
|
|
||||||
// messages permanently
|
|
||||||
opCounter++;
|
opCounter++;
|
||||||
TaskFactory::instance()->delayTask(1000);
|
}
|
||||||
|
|
||||||
|
// This task will have a low priority and will run permanently in the background
|
||||||
|
// so we will just run in a permanent loop here and check file system
|
||||||
|
// messages permanently
|
||||||
|
opCounter++;
|
||||||
|
TaskFactory::instance()->delayTask(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileSystemHandler::fileSystemCheckup() {
|
void FileSystemHandler::fileSystemCheckup() {
|
||||||
SdCardManager::SdStatePair statusPair;
|
SdCardManager::SdStatePair statusPair;
|
||||||
sdcMan->getSdCardActiveStatus(statusPair);
|
sdcMan->getSdCardActiveStatus(statusPair);
|
||||||
sd::SdCard preferredSdCard;
|
sd::SdCard preferredSdCard;
|
||||||
sdcMan->getPreferredSdCard(preferredSdCard);
|
sdcMan->getPreferredSdCard(preferredSdCard);
|
||||||
if((preferredSdCard == sd::SdCard::SLOT_0) and
|
if ((preferredSdCard == sd::SdCard::SLOT_0) and (statusPair.first == sd::SdState::MOUNTED)) {
|
||||||
(statusPair.first == sd::SdState::MOUNTED)) {
|
currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT;
|
||||||
currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT;
|
} else if ((preferredSdCard == sd::SdCard::SLOT_1) and
|
||||||
|
(statusPair.second == sd::SdState::MOUNTED)) {
|
||||||
|
currentMountPrefix = SdCardManager::SD_1_MOUNT_POINT;
|
||||||
|
} else {
|
||||||
|
std::string sdString;
|
||||||
|
if (preferredSdCard == sd::SdCard::SLOT_0) {
|
||||||
|
sdString = "0";
|
||||||
|
} else {
|
||||||
|
sdString = "1";
|
||||||
}
|
}
|
||||||
else if((preferredSdCard == sd::SdCard::SLOT_1) and
|
sif::warning << "FileSystemHandler::performOperation: "
|
||||||
(statusPair.second == sd::SdState::MOUNTED)) {
|
"Inconsistent state detected"
|
||||||
currentMountPrefix = SdCardManager::SD_1_MOUNT_POINT;
|
<< std::endl;
|
||||||
}
|
sif::warning << "Preferred SD card is " << sdString
|
||||||
else {
|
<< " but does not appear to be mounted. Attempting fix.." << std::endl;
|
||||||
std::string sdString;
|
// This function will appear to fix the inconsistent state
|
||||||
if(preferredSdCard == sd::SdCard::SLOT_0) {
|
ReturnValue_t result = sdcMan->sanitizeState(&statusPair, preferredSdCard);
|
||||||
sdString = "0";
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
}
|
// Oh no.
|
||||||
else {
|
triggerEvent(SdCardManager::SANITIZATION_FAILED, 0, 0);
|
||||||
sdString = "1";
|
sif::error << "FileSystemHandler::fileSystemCheckup: Sanitization failed" << std::endl;
|
||||||
}
|
|
||||||
sif::warning << "FileSystemHandler::performOperation: "
|
|
||||||
"Inconsistent state detected" << std::endl;
|
|
||||||
sif::warning << "Preferred SD card is " << sdString <<
|
|
||||||
" but does not appear to be mounted. Attempting fix.." << std::endl;
|
|
||||||
// This function will appear to fix the inconsistent state
|
|
||||||
ReturnValue_t result = sdcMan->sanitizeState(&statusPair, preferredSdCard);
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
// Oh no.
|
|
||||||
triggerEvent(SdCardManager::SANITIZATION_FAILED, 0, 0);
|
|
||||||
sif::error << "FileSystemHandler::fileSystemCheckup: Sanitization failed" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueId_t FileSystemHandler::getCommandQueue() const {
|
MessageQueueId_t FileSystemHandler::getCommandQueue() const { return mq->getId(); }
|
||||||
return mq->getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FileSystemHandler::initialize() {
|
ReturnValue_t FileSystemHandler::initialize() {
|
||||||
coreCtrl = ObjectManager::instance()->get<CoreController>(objects::CORE_CONTROLLER);
|
coreCtrl = ObjectManager::instance()->get<CoreController>(objects::CORE_CONTROLLER);
|
||||||
if(coreCtrl == nullptr) {
|
if (coreCtrl == nullptr) {
|
||||||
sif::error << "FileSystemHandler::initialize: Could not retrieve core controller handle" <<
|
sif::error << "FileSystemHandler::initialize: Could not retrieve core controller handle"
|
||||||
std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
sdcMan = SdCardManager::instance();
|
sdcMan = SdCardManager::instance();
|
||||||
sd::SdCard preferredSdCard;
|
sd::SdCard preferredSdCard;
|
||||||
ReturnValue_t result = sdcMan->getPreferredSdCard(preferredSdCard);
|
ReturnValue_t result = sdcMan->getPreferredSdCard(preferredSdCard);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if(preferredSdCard == sd::SdCard::SLOT_0) {
|
if (preferredSdCard == sd::SdCard::SLOT_0) {
|
||||||
currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT;
|
currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT;
|
||||||
}
|
} else if (preferredSdCard == sd::SdCard::SLOT_1) {
|
||||||
else if(preferredSdCard == sd::SdCard::SLOT_1) {
|
currentMountPrefix = SdCardManager::SD_1_MOUNT_POINT;
|
||||||
currentMountPrefix = SdCardManager::SD_1_MOUNT_POINT;
|
}
|
||||||
}
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t FileSystemHandler::appendToFile(const char* repositoryPath,
|
ReturnValue_t FileSystemHandler::appendToFile(const char* repositoryPath, const char* filename,
|
||||||
const char* filename, const uint8_t* data, size_t size,
|
const uint8_t* data, size_t size,
|
||||||
uint16_t packetNumber, FileSystemArgsIF* args) {
|
uint16_t packetNumber, FileSystemArgsIF* args) {
|
||||||
auto path = getInitPath(args) / repositoryPath / filename;
|
auto path = getInitPath(args) / repositoryPath / filename;
|
||||||
if(not std::filesystem::exists(path)) {
|
if (not std::filesystem::exists(path)) {
|
||||||
return FILE_DOES_NOT_EXIST;
|
return FILE_DOES_NOT_EXIST;
|
||||||
}
|
}
|
||||||
std::ofstream file(path, std::ios_base::app|std::ios_base::out);
|
std::ofstream file(path, std::ios_base::app | std::ios_base::out);
|
||||||
file.write(reinterpret_cast<const char*>(data), size);
|
file.write(reinterpret_cast<const char*>(data), size);
|
||||||
if(not file.good()) {
|
if (not file.good()) {
|
||||||
return GENERIC_FILE_ERROR;
|
|
||||||
}
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FileSystemHandler::createFile(const char* repositoryPath,
|
|
||||||
const char* filename, const uint8_t* data, size_t size, FileSystemArgsIF* args) {
|
|
||||||
auto path = getInitPath(args) / filename;
|
|
||||||
if(std::filesystem::exists(path)) {
|
|
||||||
return FILE_ALREADY_EXISTS;
|
|
||||||
}
|
|
||||||
std::ofstream file(path);
|
|
||||||
file.write(reinterpret_cast<const char*>(data), size);
|
|
||||||
if(not file.good()) {
|
|
||||||
return GENERIC_FILE_ERROR;
|
|
||||||
}
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FileSystemHandler::removeFile(const char* repositoryPath,
|
|
||||||
const char* filename, FileSystemArgsIF* args) {
|
|
||||||
auto path = getInitPath(args) / repositoryPath / filename;
|
|
||||||
if(not std::filesystem::exists(path)) {
|
|
||||||
return FILE_DOES_NOT_EXIST;
|
|
||||||
}
|
|
||||||
int result = std::remove(path.c_str());
|
|
||||||
if(result != 0) {
|
|
||||||
sif::warning << "FileSystemHandler::deleteFile: Failed with code " << result << std::endl;
|
|
||||||
return GENERIC_FILE_ERROR;
|
|
||||||
}
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FileSystemHandler:: createDirectory(const char* repositoryPath, const char* dirname,
|
|
||||||
bool createParentDirs, FileSystemArgsIF* args) {
|
|
||||||
auto path = getInitPath(args) / repositoryPath / dirname;
|
|
||||||
if(std::filesystem::exists(path)) {
|
|
||||||
return DIRECTORY_ALREADY_EXISTS;
|
|
||||||
}
|
|
||||||
if(std::filesystem::create_directory(path)) {
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
|
||||||
sif::warning << "Creating directory " << path << " failed" << std::endl;
|
|
||||||
return GENERIC_FILE_ERROR;
|
return GENERIC_FILE_ERROR;
|
||||||
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t FileSystemHandler::createFile(const char* repositoryPath, const char* filename,
|
||||||
|
const uint8_t* data, size_t size,
|
||||||
|
FileSystemArgsIF* args) {
|
||||||
|
auto path = getInitPath(args) / filename;
|
||||||
|
if (std::filesystem::exists(path)) {
|
||||||
|
return FILE_ALREADY_EXISTS;
|
||||||
|
}
|
||||||
|
std::ofstream file(path);
|
||||||
|
file.write(reinterpret_cast<const char*>(data), size);
|
||||||
|
if (not file.good()) {
|
||||||
|
return GENERIC_FILE_ERROR;
|
||||||
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t FileSystemHandler::removeFile(const char* repositoryPath, const char* filename,
|
||||||
|
FileSystemArgsIF* args) {
|
||||||
|
auto path = getInitPath(args) / repositoryPath / filename;
|
||||||
|
if (not std::filesystem::exists(path)) {
|
||||||
|
return FILE_DOES_NOT_EXIST;
|
||||||
|
}
|
||||||
|
int result = std::remove(path.c_str());
|
||||||
|
if (result != 0) {
|
||||||
|
sif::warning << "FileSystemHandler::deleteFile: Failed with code " << result << std::endl;
|
||||||
|
return GENERIC_FILE_ERROR;
|
||||||
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t FileSystemHandler::createDirectory(const char* repositoryPath, const char* dirname,
|
||||||
|
bool createParentDirs, FileSystemArgsIF* args) {
|
||||||
|
auto path = getInitPath(args) / repositoryPath / dirname;
|
||||||
|
if (std::filesystem::exists(path)) {
|
||||||
|
return DIRECTORY_ALREADY_EXISTS;
|
||||||
|
}
|
||||||
|
if (std::filesystem::create_directory(path)) {
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
sif::warning << "Creating directory " << path << " failed" << std::endl;
|
||||||
|
return GENERIC_FILE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t FileSystemHandler::removeDirectory(const char* repositoryPath, const char* dirname,
|
ReturnValue_t FileSystemHandler::removeDirectory(const char* repositoryPath, const char* dirname,
|
||||||
bool deleteRecurively, FileSystemArgsIF* args) {
|
bool deleteRecurively, FileSystemArgsIF* args) {
|
||||||
auto path = getInitPath(args) / repositoryPath / dirname;
|
auto path = getInitPath(args) / repositoryPath / dirname;
|
||||||
if(not std::filesystem::exists(path)) {
|
if (not std::filesystem::exists(path)) {
|
||||||
return DIRECTORY_DOES_NOT_EXIST;
|
return DIRECTORY_DOES_NOT_EXIST;
|
||||||
|
}
|
||||||
|
std::error_code err;
|
||||||
|
if (not deleteRecurively) {
|
||||||
|
if (std::filesystem::remove(path, err)) {
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
} else {
|
||||||
|
// Check error code. Most probably denied permissions because folder is not empty
|
||||||
|
sif::warning << "FileSystemHandler::removeDirectory: Deleting directory failed with "
|
||||||
|
"code "
|
||||||
|
<< err.value() << ": " << strerror(err.value()) << std::endl;
|
||||||
|
if (err.value() == ENOTEMPTY) {
|
||||||
|
return DIRECTORY_NOT_EMPTY;
|
||||||
|
} else {
|
||||||
|
return GENERIC_FILE_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
std::error_code err;
|
} else {
|
||||||
if(not deleteRecurively) {
|
if (std::filesystem::remove_all(path, err)) {
|
||||||
if(std::filesystem::remove(path, err)) {
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
} else {
|
||||||
}
|
sif::warning << "FileSystemHandler::removeDirectory: Deleting directory failed with "
|
||||||
else {
|
"code "
|
||||||
// Check error code. Most probably denied permissions because folder is not empty
|
<< err.value() << ": " << strerror(err.value()) << std::endl;
|
||||||
sif::warning << "FileSystemHandler::removeDirectory: Deleting directory failed with "
|
// Check error code
|
||||||
"code " << err.value() << ": " << strerror(err.value()) << std::endl;
|
if (err.value() == ENOTEMPTY) {
|
||||||
if(err.value() == ENOTEMPTY) {
|
return DIRECTORY_NOT_EMPTY;
|
||||||
return DIRECTORY_NOT_EMPTY;
|
} else {
|
||||||
}
|
return GENERIC_FILE_ERROR;
|
||||||
else {
|
}
|
||||||
return GENERIC_FILE_ERROR;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(std::filesystem::remove_all(path, err)) {
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sif::warning << "FileSystemHandler::removeDirectory: Deleting directory failed with "
|
|
||||||
"code " << err.value() << ": " << strerror(err.value()) << std::endl;
|
|
||||||
// Check error code
|
|
||||||
if(err.value() == ENOTEMPTY) {
|
|
||||||
return DIRECTORY_NOT_EMPTY;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return GENERIC_FILE_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t FileSystemHandler::renameFile(const char *repositoryPath, const char *oldFilename,
|
ReturnValue_t FileSystemHandler::renameFile(const char* repositoryPath, const char* oldFilename,
|
||||||
const char *newFilename, FileSystemArgsIF *args) {
|
const char* newFilename, FileSystemArgsIF* args) {
|
||||||
auto basepath = getInitPath(args) / repositoryPath;
|
auto basepath = getInitPath(args) / repositoryPath;
|
||||||
std::filesystem::rename(basepath / oldFilename, basepath / newFilename);
|
std::filesystem::rename(basepath / oldFilename, basepath / newFilename);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileSystemHandler::parseCfg(FsCommandCfg *cfg, bool& useMountPrefix) {
|
void FileSystemHandler::parseCfg(FsCommandCfg* cfg, bool& useMountPrefix) {
|
||||||
if(cfg != nullptr) {
|
if (cfg != nullptr) {
|
||||||
useMountPrefix = cfg->useMountPrefix;
|
useMountPrefix = cfg->useMountPrefix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::filesystem::path FileSystemHandler::getInitPath(FileSystemArgsIF* args) {
|
std::filesystem::path FileSystemHandler::getInitPath(FileSystemArgsIF* args) {
|
||||||
bool useMountPrefix = true;
|
bool useMountPrefix = true;
|
||||||
parseCfg(reinterpret_cast<FsCommandCfg*>(args), useMountPrefix);
|
parseCfg(reinterpret_cast<FsCommandCfg*>(args), useMountPrefix);
|
||||||
std::string path;
|
std::string path;
|
||||||
if(useMountPrefix) {
|
if (useMountPrefix) {
|
||||||
path = currentMountPrefix;
|
path = currentMountPrefix;
|
||||||
}
|
}
|
||||||
return std::filesystem::path(path);
|
return std::filesystem::path(path);
|
||||||
}
|
}
|
||||||
|
@ -1,71 +1,67 @@
|
|||||||
#ifndef BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_
|
#ifndef BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_
|
||||||
#define BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_
|
#define BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_
|
||||||
|
|
||||||
#include "SdCardManager.h"
|
|
||||||
#include "OBSWConfig.h"
|
|
||||||
|
|
||||||
#include "fsfw/ipc/MessageQueueIF.h"
|
|
||||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
|
||||||
#include "fsfw/objectmanager/SystemObject.h"
|
|
||||||
#include "fsfw/memory/HasFileSystemIF.h"
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "OBSWConfig.h"
|
||||||
|
#include "SdCardManager.h"
|
||||||
|
#include "fsfw/ipc/MessageQueueIF.h"
|
||||||
|
#include "fsfw/memory/HasFileSystemIF.h"
|
||||||
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
|
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||||
|
|
||||||
class CoreController;
|
class CoreController;
|
||||||
|
|
||||||
class FileSystemHandler: public SystemObject,
|
class FileSystemHandler : public SystemObject, public ExecutableObjectIF, public HasFileSystemIF {
|
||||||
public ExecutableObjectIF,
|
public:
|
||||||
public HasFileSystemIF {
|
struct FsCommandCfg : public FileSystemArgsIF {
|
||||||
public:
|
// Can be used to automatically use mount prefix of active SD card.
|
||||||
struct FsCommandCfg: public FileSystemArgsIF {
|
// Otherwise, the operator has to specify the full path to the mounted SD card as well.
|
||||||
// Can be used to automatically use mount prefix of active SD card.
|
bool useMountPrefix = false;
|
||||||
// Otherwise, the operator has to specify the full path to the mounted SD card as well.
|
};
|
||||||
bool useMountPrefix = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
FileSystemHandler(object_id_t fileSystemHandler);
|
FileSystemHandler(object_id_t fileSystemHandler);
|
||||||
virtual~ FileSystemHandler();
|
virtual ~FileSystemHandler();
|
||||||
|
|
||||||
ReturnValue_t performOperation(uint8_t) override;
|
ReturnValue_t performOperation(uint8_t) override;
|
||||||
|
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to get the MessageQueueId_t of the implementing object
|
* Function to get the MessageQueueId_t of the implementing object
|
||||||
* @return MessageQueueId_t of the object
|
* @return MessageQueueId_t of the object
|
||||||
*/
|
*/
|
||||||
MessageQueueId_t getCommandQueue() const override;
|
MessageQueueId_t getCommandQueue() const override;
|
||||||
ReturnValue_t appendToFile(const char* repositoryPath,
|
ReturnValue_t appendToFile(const char* repositoryPath, const char* filename, const uint8_t* data,
|
||||||
const char* filename, const uint8_t* data, size_t size,
|
size_t size, uint16_t packetNumber,
|
||||||
uint16_t packetNumber, FileSystemArgsIF* args = nullptr) override;
|
FileSystemArgsIF* args = nullptr) override;
|
||||||
ReturnValue_t createFile(const char* repositoryPath,
|
ReturnValue_t createFile(const char* repositoryPath, const char* filename,
|
||||||
const char* filename, const uint8_t* data = nullptr,
|
const uint8_t* data = nullptr, size_t size = 0,
|
||||||
size_t size = 0, FileSystemArgsIF* args = nullptr) override;
|
FileSystemArgsIF* args = nullptr) override;
|
||||||
ReturnValue_t removeFile(const char* repositoryPath,
|
ReturnValue_t removeFile(const char* repositoryPath, const char* filename,
|
||||||
const char* filename, FileSystemArgsIF* args = nullptr) override;
|
FileSystemArgsIF* args = nullptr) override;
|
||||||
ReturnValue_t createDirectory(const char* repositoryPath, const char* dirname,
|
ReturnValue_t createDirectory(const char* repositoryPath, const char* dirname,
|
||||||
bool createParentDirs, FileSystemArgsIF* args = nullptr) override;
|
bool createParentDirs, FileSystemArgsIF* args = nullptr) override;
|
||||||
ReturnValue_t removeDirectory(const char* repositoryPath, const char* dirname,
|
ReturnValue_t removeDirectory(const char* repositoryPath, const char* dirname,
|
||||||
bool deleteRecurively = false, FileSystemArgsIF* args = nullptr) override;
|
bool deleteRecurively = false,
|
||||||
ReturnValue_t renameFile(const char* repositoryPath, const char* oldFilename,
|
FileSystemArgsIF* args = nullptr) override;
|
||||||
const char* newFilename, FileSystemArgsIF* args = nullptr) override;
|
ReturnValue_t renameFile(const char* repositoryPath, const char* oldFilename,
|
||||||
|
const char* newFilename, FileSystemArgsIF* args = nullptr) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CoreController* coreCtrl = nullptr;
|
CoreController* coreCtrl = nullptr;
|
||||||
MessageQueueIF* mq = nullptr;
|
MessageQueueIF* mq = nullptr;
|
||||||
std::string currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT;
|
std::string currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT;
|
||||||
static constexpr uint32_t FS_MAX_QUEUE_SIZE = config::OBSW_FILESYSTEM_HANDLER_QUEUE_SIZE;
|
static constexpr uint32_t FS_MAX_QUEUE_SIZE = config::OBSW_FILESYSTEM_HANDLER_QUEUE_SIZE;
|
||||||
|
|
||||||
SdCardManager* sdcMan = nullptr;
|
SdCardManager* sdcMan = nullptr;
|
||||||
uint8_t opCounter = 0;
|
uint8_t opCounter = 0;
|
||||||
|
|
||||||
void fileSystemHandlerLoop();
|
void fileSystemHandlerLoop();
|
||||||
void fileSystemCheckup();
|
void fileSystemCheckup();
|
||||||
std::filesystem::path getInitPath(FileSystemArgsIF* args);
|
std::filesystem::path getInitPath(FileSystemArgsIF* args);
|
||||||
void parseCfg(FsCommandCfg* cfg, bool& useMountPrefix);
|
void parseCfg(FsCommandCfg* cfg, bool& useMountPrefix);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* BSP_Q7S_MEMORY_FILESYSTEMMANAGER_H_ */
|
#endif /* BSP_Q7S_MEMORY_FILESYSTEMMANAGER_H_ */
|
||||||
|
@ -1,487 +1,462 @@
|
|||||||
#include "SdCardManager.h"
|
#include "SdCardManager.h"
|
||||||
#include "scratchApi.h"
|
|
||||||
|
|
||||||
#include "linux/utility/utility.h"
|
|
||||||
|
|
||||||
#include "fsfw/ipc/MutexFactory.h"
|
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <filesystem>
|
|
||||||
#include <cstring>
|
#include "fsfw/ipc/MutexFactory.h"
|
||||||
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
#include "linux/utility/utility.h"
|
||||||
|
#include "scratchApi.h"
|
||||||
|
|
||||||
SdCardManager* SdCardManager::factoryInstance = nullptr;
|
SdCardManager* SdCardManager::factoryInstance = nullptr;
|
||||||
|
|
||||||
SdCardManager::SdCardManager(): cmdExecutor(256) {
|
SdCardManager::SdCardManager() : cmdExecutor(256) {}
|
||||||
}
|
|
||||||
|
|
||||||
SdCardManager::~SdCardManager() {
|
SdCardManager::~SdCardManager() {}
|
||||||
}
|
|
||||||
|
|
||||||
void SdCardManager::create() {
|
void SdCardManager::create() {
|
||||||
if(factoryInstance == nullptr) {
|
if (factoryInstance == nullptr) {
|
||||||
factoryInstance = new SdCardManager();
|
factoryInstance = new SdCardManager();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SdCardManager* SdCardManager::instance() {
|
SdCardManager* SdCardManager::instance() {
|
||||||
SdCardManager::create();
|
SdCardManager::create();
|
||||||
return SdCardManager::factoryInstance;
|
return SdCardManager::factoryInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard,
|
ReturnValue_t SdCardManager::switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard,
|
||||||
SdStatePair* statusPair) {
|
SdStatePair* statusPair) {
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
if(doMountSdCard) {
|
if (doMountSdCard) {
|
||||||
if(not blocking) {
|
if (not blocking) {
|
||||||
sif::warning << "SdCardManager::switchOnSdCard: Two-step command but manager is"
|
sif::warning << "SdCardManager::switchOnSdCard: Two-step command but manager is"
|
||||||
" not configured for blocking operation. "
|
" not configured for blocking operation. "
|
||||||
"Forcing blocking mode.." << std::endl;
|
"Forcing blocking mode.."
|
||||||
blocking = true;
|
<< std::endl;
|
||||||
}
|
blocking = true;
|
||||||
}
|
}
|
||||||
std::unique_ptr<SdStatePair> sdStatusPtr;
|
}
|
||||||
if(statusPair == nullptr) {
|
std::unique_ptr<SdStatePair> sdStatusPtr;
|
||||||
sdStatusPtr = std::make_unique<SdStatePair>();
|
if (statusPair == nullptr) {
|
||||||
statusPair = sdStatusPtr.get();
|
sdStatusPtr = std::make_unique<SdStatePair>();
|
||||||
result = getSdCardActiveStatus(*statusPair);
|
statusPair = sdStatusPtr.get();
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
result = getSdCardActiveStatus(*statusPair);
|
||||||
return result;
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
}
|
return result;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Not allowed, this function turns on one SD card
|
// Not allowed, this function turns on one SD card
|
||||||
if(sdCard == sd::SdCard::BOTH) {
|
if (sdCard == sd::SdCard::BOTH) {
|
||||||
sif::warning << "SdCardManager::switchOffSdCard: API does not allow sd::SdStatus::BOTH"
|
sif::warning << "SdCardManager::switchOffSdCard: API does not allow sd::SdStatus::BOTH"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
sd::SdState currentState;
|
sd::SdState currentState;
|
||||||
if(sdCard == sd::SdCard::SLOT_0) {
|
if (sdCard == sd::SdCard::SLOT_0) {
|
||||||
currentState = statusPair->first;
|
currentState = statusPair->first;
|
||||||
}
|
} else if (sdCard == sd::SdCard::SLOT_1) {
|
||||||
else if(sdCard == sd::SdCard::SLOT_1) {
|
currentState = statusPair->second;
|
||||||
currentState = statusPair->second;
|
} else {
|
||||||
}
|
// Should not happen
|
||||||
else {
|
currentState = sd::SdState::OFF;
|
||||||
// Should not happen
|
}
|
||||||
currentState = sd::SdState::OFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(currentState == sd::SdState::ON) {
|
if (currentState == sd::SdState::ON) {
|
||||||
if(not doMountSdCard) {
|
if (not doMountSdCard) {
|
||||||
return ALREADY_ON;
|
return ALREADY_ON;
|
||||||
}
|
} else {
|
||||||
else {
|
return mountSdCard(sdCard);
|
||||||
return mountSdCard(sdCard);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(currentState == sd::SdState::MOUNTED) {
|
|
||||||
result = ALREADY_MOUNTED;
|
|
||||||
}
|
|
||||||
else if(currentState == sd::SdState::OFF) {
|
|
||||||
result = setSdCardState(sdCard, true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
}
|
}
|
||||||
|
} else if (currentState == sd::SdState::MOUNTED) {
|
||||||
|
result = ALREADY_MOUNTED;
|
||||||
|
} else if (currentState == sd::SdState::OFF) {
|
||||||
|
result = setSdCardState(sdCard, true);
|
||||||
|
} else {
|
||||||
|
result = HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK or not doMountSdCard) {
|
if (result != HasReturnvaluesIF::RETURN_OK or not doMountSdCard) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mountSdCard(sdCard);
|
return mountSdCard(sdCard);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard,
|
ReturnValue_t SdCardManager::switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard,
|
||||||
SdStatePair* statusPair) {
|
SdStatePair* statusPair) {
|
||||||
std::pair<sd::SdState, sd::SdState> active;
|
std::pair<sd::SdState, sd::SdState> active;
|
||||||
ReturnValue_t result = getSdCardActiveStatus(active);
|
ReturnValue_t result = getSdCardActiveStatus(active);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
if (doUnmountSdCard) {
|
||||||
|
if (not blocking) {
|
||||||
|
sif::warning << "SdCardManager::switchOffSdCard: Two-step command but manager is"
|
||||||
|
" not configured for blocking operation. Forcing blocking mode.."
|
||||||
|
<< std::endl;
|
||||||
|
blocking = true;
|
||||||
}
|
}
|
||||||
if(doUnmountSdCard) {
|
}
|
||||||
if(not blocking) {
|
// Not allowed, this function turns off one SD card
|
||||||
sif::warning << "SdCardManager::switchOffSdCard: Two-step command but manager is"
|
if (sdCard == sd::SdCard::BOTH) {
|
||||||
" not configured for blocking operation. Forcing blocking mode.." << std::endl;
|
sif::warning << "SdCardManager::switchOffSdCard: API does not allow sd::SdStatus::BOTH"
|
||||||
blocking = true;
|
<< std::endl;
|
||||||
}
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
if (sdCard == sd::SdCard::SLOT_0) {
|
||||||
|
if (active.first == sd::SdState::OFF) {
|
||||||
|
return ALREADY_OFF;
|
||||||
}
|
}
|
||||||
// Not allowed, this function turns off one SD card
|
} else if (sdCard == sd::SdCard::SLOT_1) {
|
||||||
if(sdCard == sd::SdCard::BOTH) {
|
if (active.second == sd::SdState::OFF) {
|
||||||
sif::warning << "SdCardManager::switchOffSdCard: API does not allow sd::SdStatus::BOTH"
|
return ALREADY_OFF;
|
||||||
<< std::endl;
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
}
|
|
||||||
if(sdCard == sd::SdCard::SLOT_0) {
|
|
||||||
if(active.first == sd::SdState::OFF) {
|
|
||||||
return ALREADY_OFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(sdCard == sd::SdCard::SLOT_1) {
|
|
||||||
if(active.second == sd::SdState::OFF) {
|
|
||||||
return ALREADY_OFF;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(doUnmountSdCard) {
|
if (doUnmountSdCard) {
|
||||||
result = unmountSdCard(sdCard);
|
result = unmountSdCard(sdCard);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return setSdCardState(sdCard, false);
|
return setSdCardState(sdCard, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) {
|
ReturnValue_t SdCardManager::setSdCardState(sd::SdCard sdCard, bool on) {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) {
|
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) {
|
||||||
return CommandExecutor::COMMAND_PENDING;
|
return CommandExecutor::COMMAND_PENDING;
|
||||||
}
|
}
|
||||||
string sdstring = "";
|
string sdstring = "";
|
||||||
string statestring = "";
|
string statestring = "";
|
||||||
if(sdCard == sd::SdCard::SLOT_0) {
|
if (sdCard == sd::SdCard::SLOT_0) {
|
||||||
sdstring = "0";
|
sdstring = "0";
|
||||||
}
|
} else if (sdCard == sd::SdCard::SLOT_1) {
|
||||||
else if(sdCard == sd::SdCard::SLOT_1) {
|
sdstring = "1";
|
||||||
sdstring = "1";
|
}
|
||||||
}
|
if (on) {
|
||||||
if(on) {
|
currentOp = Operations::SWITCHING_ON;
|
||||||
currentOp = Operations::SWITCHING_ON;
|
statestring = "on";
|
||||||
statestring = "on";
|
} else {
|
||||||
}
|
currentOp = Operations::SWITCHING_OFF;
|
||||||
else {
|
statestring = "off";
|
||||||
currentOp = Operations::SWITCHING_OFF;
|
}
|
||||||
statestring = "off";
|
ostringstream command;
|
||||||
}
|
command << "q7hw sd set " << sdstring << " " << statestring;
|
||||||
ostringstream command;
|
cmdExecutor.load(command.str(), blocking, printCmdOutput);
|
||||||
command << "q7hw sd set " << sdstring << " " << statestring;
|
ReturnValue_t result = cmdExecutor.execute();
|
||||||
cmdExecutor.load(command.str(), blocking, printCmdOutput);
|
if (blocking and result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
ReturnValue_t result = cmdExecutor.execute();
|
utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::setSdCardState");
|
||||||
if(blocking and result != HasReturnvaluesIF::RETURN_OK) {
|
}
|
||||||
utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::setSdCardState");
|
return result;
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SdCardManager::getSdCardActiveStatus(SdStatePair& active) {
|
ReturnValue_t SdCardManager::getSdCardActiveStatus(SdStatePair& active) {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
if(not filesystem::exists(SD_STATE_FILE)) {
|
if (not filesystem::exists(SD_STATE_FILE)) {
|
||||||
return STATUS_FILE_NEXISTS;
|
return STATUS_FILE_NEXISTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now the file should exist in any case. Still check whether it exists.
|
// Now the file should exist in any case. Still check whether it exists.
|
||||||
fstream sdStatus(SD_STATE_FILE);
|
fstream sdStatus(SD_STATE_FILE);
|
||||||
if (not sdStatus.good()) {
|
if (not sdStatus.good()) {
|
||||||
return STATUS_FILE_NEXISTS;
|
return STATUS_FILE_NEXISTS;
|
||||||
}
|
}
|
||||||
string line;
|
string line;
|
||||||
uint8_t idx = 0;
|
uint8_t idx = 0;
|
||||||
sd::SdCard currentSd = sd::SdCard::SLOT_0;
|
sd::SdCard currentSd = sd::SdCard::SLOT_0;
|
||||||
// Process status file line by line
|
// Process status file line by line
|
||||||
while (std::getline(sdStatus, line)) {
|
while (std::getline(sdStatus, line)) {
|
||||||
processSdStatusLine(active, line, idx, currentSd);
|
processSdStatusLine(active, line, idx, currentSd);
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) {
|
ReturnValue_t SdCardManager::mountSdCard(sd::SdCard sdCard) {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) {
|
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) {
|
||||||
return CommandExecutor::COMMAND_PENDING;
|
return CommandExecutor::COMMAND_PENDING;
|
||||||
}
|
}
|
||||||
if(sdCard == sd::SdCard::BOTH) {
|
if (sdCard == sd::SdCard::BOTH) {
|
||||||
sif::warning << "SdCardManager::mountSdCard: API does not allow sd::SdStatus::BOTH"
|
sif::warning << "SdCardManager::mountSdCard: API does not allow sd::SdStatus::BOTH"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
string mountDev;
|
string mountDev;
|
||||||
string mountPoint;
|
string mountPoint;
|
||||||
if(sdCard == sd::SdCard::SLOT_0) {
|
if (sdCard == sd::SdCard::SLOT_0) {
|
||||||
mountDev = SD_0_DEV_NAME;
|
mountDev = SD_0_DEV_NAME;
|
||||||
mountPoint = SD_0_MOUNT_POINT;
|
mountPoint = SD_0_MOUNT_POINT;
|
||||||
}
|
} else if (sdCard == sd::SdCard::SLOT_1) {
|
||||||
else if(sdCard == sd::SdCard::SLOT_1) {
|
mountDev = SD_1_DEV_NAME;
|
||||||
mountDev = SD_1_DEV_NAME;
|
mountPoint = SD_1_MOUNT_POINT;
|
||||||
mountPoint = SD_1_MOUNT_POINT;
|
}
|
||||||
}
|
if (not filesystem::exists(mountDev)) {
|
||||||
if(not filesystem::exists(mountDev)) {
|
sif::warning << "SdCardManager::mountSdCard: Device file does not exists. Make sure to"
|
||||||
sif::warning << "SdCardManager::mountSdCard: Device file does not exists. Make sure to"
|
" turn on the SD card"
|
||||||
" turn on the SD card" << std::endl;
|
<< std::endl;
|
||||||
return MOUNT_ERROR;
|
return MOUNT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(not blocking) {
|
if (not blocking) {
|
||||||
currentOp = Operations::MOUNTING;
|
currentOp = Operations::MOUNTING;
|
||||||
}
|
}
|
||||||
string sdMountCommand = "mount " + mountDev + " " + mountPoint;
|
string sdMountCommand = "mount " + mountDev + " " + mountPoint;
|
||||||
cmdExecutor.load(sdMountCommand, blocking, printCmdOutput);
|
cmdExecutor.load(sdMountCommand, blocking, printCmdOutput);
|
||||||
ReturnValue_t result = cmdExecutor.execute();
|
ReturnValue_t result = cmdExecutor.execute();
|
||||||
if(blocking and result != HasReturnvaluesIF::RETURN_OK) {
|
if (blocking and result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard");
|
utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard");
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) {
|
ReturnValue_t SdCardManager::unmountSdCard(sd::SdCard sdCard) {
|
||||||
if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) {
|
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) {
|
||||||
return CommandExecutor::COMMAND_PENDING;
|
return CommandExecutor::COMMAND_PENDING;
|
||||||
}
|
}
|
||||||
using namespace std;
|
using namespace std;
|
||||||
if(sdCard == sd::SdCard::BOTH) {
|
if (sdCard == sd::SdCard::BOTH) {
|
||||||
sif::warning << "SdCardManager::unmountSdCard: API does not allow sd::SdStatus::BOTH"
|
sif::warning << "SdCardManager::unmountSdCard: API does not allow sd::SdStatus::BOTH"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
string mountPoint;
|
string mountPoint;
|
||||||
if(sdCard == sd::SdCard::SLOT_0) {
|
if (sdCard == sd::SdCard::SLOT_0) {
|
||||||
mountPoint = SD_0_MOUNT_POINT;
|
mountPoint = SD_0_MOUNT_POINT;
|
||||||
}
|
} else if (sdCard == sd::SdCard::SLOT_1) {
|
||||||
else if(sdCard == sd::SdCard::SLOT_1) {
|
mountPoint = SD_1_MOUNT_POINT;
|
||||||
mountPoint = SD_1_MOUNT_POINT;
|
}
|
||||||
}
|
if (not filesystem::exists(mountPoint)) {
|
||||||
if(not filesystem::exists(mountPoint)) {
|
sif::error << "SdCardManager::unmountSdCard: Default mount point " << mountPoint
|
||||||
sif::error << "SdCardManager::unmountSdCard: Default mount point " << mountPoint <<
|
<< "does not exist" << std::endl;
|
||||||
"does not exist" << std::endl;
|
return UNMOUNT_ERROR;
|
||||||
return UNMOUNT_ERROR;
|
}
|
||||||
}
|
if (filesystem::is_empty(mountPoint)) {
|
||||||
if(filesystem::is_empty(mountPoint)) {
|
// The mount point will always exist, but if it is empty, that is strong hint that
|
||||||
// The mount point will always exist, but if it is empty, that is strong hint that
|
// the SD card was not mounted properly. Still proceed with operation.
|
||||||
// the SD card was not mounted properly. Still proceed with operation.
|
sif::warning << "SdCardManager::unmountSdCard: Mount point is empty!" << std::endl;
|
||||||
sif::warning << "SdCardManager::unmountSdCard: Mount point is empty!" << std::endl;
|
}
|
||||||
}
|
string sdUnmountCommand = "umount " + mountPoint;
|
||||||
string sdUnmountCommand = "umount " + mountPoint;
|
if (not blocking) {
|
||||||
if(not blocking) {
|
currentOp = Operations::UNMOUNTING;
|
||||||
currentOp = Operations::UNMOUNTING;
|
}
|
||||||
}
|
cmdExecutor.load(sdUnmountCommand, blocking, printCmdOutput);
|
||||||
cmdExecutor.load(sdUnmountCommand, blocking, printCmdOutput);
|
ReturnValue_t result = cmdExecutor.execute();
|
||||||
ReturnValue_t result = cmdExecutor.execute();
|
if (blocking and result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
if(blocking and result != HasReturnvaluesIF::RETURN_OK) {
|
utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::unmountSdCard");
|
||||||
utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::unmountSdCard");
|
}
|
||||||
}
|
return result;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SdCardManager::sanitizeState(SdStatePair* statusPair, sd::SdCard prefSdCard) {
|
ReturnValue_t SdCardManager::sanitizeState(SdStatePair* statusPair, sd::SdCard prefSdCard) {
|
||||||
std::unique_ptr<SdStatePair> sdStatusPtr;
|
std::unique_ptr<SdStatePair> sdStatusPtr;
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
// Enforce blocking operation for now. Be careful to reset it when returning prematurely!
|
// Enforce blocking operation for now. Be careful to reset it when returning prematurely!
|
||||||
bool resetNonBlockingState = false;
|
bool resetNonBlockingState = false;
|
||||||
if(not this->blocking) {
|
if (not this->blocking) {
|
||||||
blocking = true;
|
blocking = true;
|
||||||
resetNonBlockingState = true;
|
resetNonBlockingState = true;
|
||||||
}
|
}
|
||||||
if(prefSdCard == sd::SdCard::NONE) {
|
if (prefSdCard == sd::SdCard::NONE) {
|
||||||
result = getPreferredSdCard(prefSdCard);
|
result = getPreferredSdCard(prefSdCard);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {}
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
}
|
|
||||||
if(statusPair == nullptr) {
|
|
||||||
sdStatusPtr = std::make_unique<SdStatePair>();
|
|
||||||
statusPair = sdStatusPtr.get();
|
|
||||||
getSdCardActiveStatus(*statusPair);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (statusPair == nullptr) {
|
||||||
|
sdStatusPtr = std::make_unique<SdStatePair>();
|
||||||
|
statusPair = sdStatusPtr.get();
|
||||||
|
getSdCardActiveStatus(*statusPair);
|
||||||
|
}
|
||||||
|
|
||||||
if(statusPair->first == sd::SdState::ON) {
|
if (statusPair->first == sd::SdState::ON) {
|
||||||
result = mountSdCard(prefSdCard);
|
result = mountSdCard(prefSdCard);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = switchOnSdCard(prefSdCard, true, statusPair);
|
result = switchOnSdCard(prefSdCard, true, statusPair);
|
||||||
if(resetNonBlockingState) {
|
if (resetNonBlockingState) {
|
||||||
blocking = false;
|
blocking = false;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SdCardManager::resetState() {
|
void SdCardManager::resetState() {
|
||||||
cmdExecutor.reset();
|
cmdExecutor.reset();
|
||||||
currentOp = Operations::IDLE;
|
currentOp = Operations::IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SdCardManager::processSdStatusLine(std::pair<sd::SdState, sd::SdState> &active,
|
void SdCardManager::processSdStatusLine(std::pair<sd::SdState, sd::SdState>& active,
|
||||||
std::string& line, uint8_t& idx, sd::SdCard& currentSd) {
|
std::string& line, uint8_t& idx, sd::SdCard& currentSd) {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
istringstream iss(line);
|
istringstream iss(line);
|
||||||
string word;
|
string word;
|
||||||
bool slotLine = false;
|
bool slotLine = false;
|
||||||
bool mountLine = false;
|
bool mountLine = false;
|
||||||
while(iss >> word) {
|
while (iss >> word) {
|
||||||
if (word == "Slot") {
|
if (word == "Slot") {
|
||||||
slotLine = true;
|
slotLine = true;
|
||||||
}
|
|
||||||
if(word == "Mounted") {
|
|
||||||
mountLine = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(slotLine) {
|
|
||||||
if (word == "1:") {
|
|
||||||
currentSd = sd::SdCard::SLOT_1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(word == "on") {
|
|
||||||
if(currentSd == sd::SdCard::SLOT_0) {
|
|
||||||
active.first = sd::SdState::ON;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
active.second = sd::SdState::ON;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (word == "off") {
|
|
||||||
if(currentSd == sd::SdCard::SLOT_0) {
|
|
||||||
active.first = sd::SdState::OFF;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
active.second = sd::SdState::OFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mountLine) {
|
|
||||||
if(currentSd == sd::SdCard::SLOT_0) {
|
|
||||||
active.first = sd::SdState::MOUNTED;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
active.second = sd::SdState::MOUNTED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(idx > 5) {
|
|
||||||
sif::warning << "SdCardManager::sdCardActive: /tmp/sd_status.txt has more than 6 "
|
|
||||||
"lines and might be invalid!" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
idx++;
|
if (word == "Mounted") {
|
||||||
|
mountLine = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slotLine) {
|
||||||
|
if (word == "1:") {
|
||||||
|
currentSd = sd::SdCard::SLOT_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (word == "on") {
|
||||||
|
if (currentSd == sd::SdCard::SLOT_0) {
|
||||||
|
active.first = sd::SdState::ON;
|
||||||
|
} else {
|
||||||
|
active.second = sd::SdState::ON;
|
||||||
|
}
|
||||||
|
} else if (word == "off") {
|
||||||
|
if (currentSd == sd::SdCard::SLOT_0) {
|
||||||
|
active.first = sd::SdState::OFF;
|
||||||
|
} else {
|
||||||
|
active.second = sd::SdState::OFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mountLine) {
|
||||||
|
if (currentSd == sd::SdCard::SLOT_0) {
|
||||||
|
active.first = sd::SdState::MOUNTED;
|
||||||
|
} else {
|
||||||
|
active.second = sd::SdState::MOUNTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx > 5) {
|
||||||
|
sif::warning << "SdCardManager::sdCardActive: /tmp/sd_status.txt has more than 6 "
|
||||||
|
"lines and might be invalid!"
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SdCardManager::getPreferredSdCard(sd::SdCard& sdCard) const {
|
ReturnValue_t SdCardManager::getPreferredSdCard(sd::SdCard& sdCard) const {
|
||||||
uint8_t prefSdCard = 0;
|
uint8_t prefSdCard = 0;
|
||||||
ReturnValue_t result = scratch::readNumber(scratch::PREFERED_SDC_KEY, prefSdCard);
|
ReturnValue_t result = scratch::readNumber(scratch::PREFERED_SDC_KEY, prefSdCard);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
sdCard = static_cast<sd::SdCard>(prefSdCard);
|
sdCard = static_cast<sd::SdCard>(prefSdCard);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SdCardManager::setPreferredSdCard(sd::SdCard sdCard) {
|
ReturnValue_t SdCardManager::setPreferredSdCard(sd::SdCard sdCard) {
|
||||||
if(sdCard == sd::SdCard::BOTH) {
|
if (sdCard == sd::SdCard::BOTH) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
return scratch::writeNumber(scratch::PREFERED_SDC_KEY, static_cast<uint8_t>(sdCard));
|
return scratch::writeNumber(scratch::PREFERED_SDC_KEY, static_cast<uint8_t>(sdCard));
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SdCardManager::updateSdCardStateFile() {
|
ReturnValue_t SdCardManager::updateSdCardStateFile() {
|
||||||
if(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) {
|
if (cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING) {
|
||||||
return CommandExecutor::COMMAND_PENDING;
|
return CommandExecutor::COMMAND_PENDING;
|
||||||
}
|
}
|
||||||
// Use q7hw utility and pipe the command output into the state file
|
// Use q7hw utility and pipe the command output into the state file
|
||||||
std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE);
|
std::string updateCmd = "q7hw sd info all > " + std::string(SD_STATE_FILE);
|
||||||
cmdExecutor.load(updateCmd, blocking, printCmdOutput);
|
cmdExecutor.load(updateCmd, blocking, printCmdOutput);
|
||||||
ReturnValue_t result = cmdExecutor.execute();
|
ReturnValue_t result = cmdExecutor.execute();
|
||||||
if(blocking and result != HasReturnvaluesIF::RETURN_OK) {
|
if (blocking and result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard");
|
utility::handleSystemError(cmdExecutor.getLastError(), "SdCardManager::mountSdCard");
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SdCardManager::getCurrentMountPrefix(sd::SdCard prefSdCard) {
|
std::string SdCardManager::getCurrentMountPrefix(sd::SdCard prefSdCard) {
|
||||||
if(prefSdCard == sd::SdCard::NONE) {
|
if (prefSdCard == sd::SdCard::NONE) {
|
||||||
ReturnValue_t result = getPreferredSdCard(prefSdCard);
|
ReturnValue_t result = getPreferredSdCard(prefSdCard);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return SD_0_MOUNT_POINT;
|
return SD_0_MOUNT_POINT;
|
||||||
}
|
|
||||||
}
|
|
||||||
if(prefSdCard == sd::SdCard::SLOT_0) {
|
|
||||||
return SD_0_MOUNT_POINT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return SD_1_MOUNT_POINT;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (prefSdCard == sd::SdCard::SLOT_0) {
|
||||||
|
return SD_0_MOUNT_POINT;
|
||||||
|
} else {
|
||||||
|
return SD_1_MOUNT_POINT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations ¤tOp) {
|
SdCardManager::OpStatus SdCardManager::checkCurrentOp(Operations& currentOp) {
|
||||||
CommandExecutor::States state = cmdExecutor.getCurrentState();
|
CommandExecutor::States state = cmdExecutor.getCurrentState();
|
||||||
if(state == CommandExecutor::States::IDLE or state == CommandExecutor::States::COMMAND_LOADED) {
|
if (state == CommandExecutor::States::IDLE or state == CommandExecutor::States::COMMAND_LOADED) {
|
||||||
return OpStatus::IDLE;
|
return OpStatus::IDLE;
|
||||||
}
|
}
|
||||||
currentOp = this->currentOp;
|
currentOp = this->currentOp;
|
||||||
bool bytesRead = false;
|
bool bytesRead = false;
|
||||||
|
|
||||||
#if OBSW_ENABLE_TIMERS == 1
|
#if OBSW_ENABLE_TIMERS == 1
|
||||||
Timer timer;
|
Timer timer;
|
||||||
timer.setTimer(100);
|
timer.setTimer(100);
|
||||||
uint32_t remainingTimeMs = 0;
|
uint32_t remainingTimeMs = 0;
|
||||||
#endif
|
#endif
|
||||||
while(true) {
|
while (true) {
|
||||||
ReturnValue_t result = cmdExecutor.check(bytesRead);
|
ReturnValue_t result = cmdExecutor.check(bytesRead);
|
||||||
// This timer can prevent deadlocks due to missconfigurations
|
// This timer can prevent deadlocks due to missconfigurations
|
||||||
#if OBSW_ENABLE_TIMERS == 1
|
#if OBSW_ENABLE_TIMERS == 1
|
||||||
timer.getTimer(&remainingTimeMs);
|
timer.getTimer(&remainingTimeMs);
|
||||||
if(remainingTimeMs == 0) {
|
if (remainingTimeMs == 0) {
|
||||||
sif::error << "SdCardManager::checkCurrentOp: Timeout!" << std::endl;
|
sif::error << "SdCardManager::checkCurrentOp: Timeout!" << std::endl;
|
||||||
return OpStatus::FAIL;
|
return OpStatus::FAIL;
|
||||||
}
|
|
||||||
#endif
|
|
||||||
switch(result) {
|
|
||||||
case(CommandExecutor::BYTES_READ): {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
case(CommandExecutor::EXECUTION_FINISHED): {
|
|
||||||
return OpStatus::SUCCESS;
|
|
||||||
}
|
|
||||||
case(HasReturnvaluesIF::RETURN_OK): {
|
|
||||||
return OpStatus::ONGOING;
|
|
||||||
}
|
|
||||||
case(HasReturnvaluesIF::RETURN_FAILED): {
|
|
||||||
return OpStatus::FAIL;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
sif::warning << "SdCardManager::checkCurrentOp: Unhandled case" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
switch (result) {
|
||||||
|
case (CommandExecutor::BYTES_READ): {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
case (CommandExecutor::EXECUTION_FINISHED): {
|
||||||
|
return OpStatus::SUCCESS;
|
||||||
|
}
|
||||||
|
case (HasReturnvaluesIF::RETURN_OK): {
|
||||||
|
return OpStatus::ONGOING;
|
||||||
|
}
|
||||||
|
case (HasReturnvaluesIF::RETURN_FAILED): {
|
||||||
|
return OpStatus::FAIL;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
sif::warning << "SdCardManager::checkCurrentOp: Unhandled case" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SdCardManager::setBlocking(bool blocking) {
|
void SdCardManager::setBlocking(bool blocking) { this->blocking = blocking; }
|
||||||
this->blocking = blocking;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SdCardManager::setPrintCommandOutput(bool print) {
|
void SdCardManager::setPrintCommandOutput(bool print) { this->printCmdOutput = print; }
|
||||||
this->printCmdOutput = print;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SdCardManager::isSdCardMounted(sd::SdCard sdCard) {
|
bool SdCardManager::isSdCardMounted(sd::SdCard sdCard) {
|
||||||
SdCardManager::SdStatePair active;
|
SdCardManager::SdStatePair active;
|
||||||
ReturnValue_t result = this->getSdCardActiveStatus(active);
|
ReturnValue_t result = this->getSdCardActiveStatus(active);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::debug << "SdCardManager::isSdCardMounted: Failed to get SD card active state";
|
sif::debug << "SdCardManager::isSdCardMounted: Failed to get SD card active state";
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (sdCard == sd::SLOT_0) {
|
|
||||||
if (active.first == sd::MOUNTED) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (sdCard == sd::SLOT_1) {
|
|
||||||
if (active.second == sd::MOUNTED) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sif::debug << "SdCardManager::isSdCardMounted: Unknown SD card specified" << std::endl;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
if (sdCard == sd::SLOT_0) {
|
||||||
|
if (active.first == sd::MOUNTED) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (sdCard == sd::SLOT_1) {
|
||||||
|
if (active.second == sd::MOUNTED) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sif::debug << "SdCardManager::isSdCardMounted: Unknown SD card specified" << std::endl;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
#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_hal/linux/CommandExecutor.h"
|
|
||||||
#include "definitions.h"
|
|
||||||
#include "returnvalues/classIds.h"
|
|
||||||
#include "events/subsystemIdRanges.h"
|
|
||||||
|
|
||||||
#include "fsfw/events/Event.h"
|
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
|
||||||
|
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <utility>
|
|
||||||
#include <string>
|
|
||||||
#include <optional>
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "definitions.h"
|
||||||
|
#include "events/subsystemIdRanges.h"
|
||||||
|
#include "fsfw/events/Event.h"
|
||||||
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
|
#include "fsfw_hal/linux/CommandExecutor.h"
|
||||||
|
#include "returnvalues/classIds.h"
|
||||||
|
|
||||||
class MutexIF;
|
class MutexIF;
|
||||||
|
|
||||||
@ -24,202 +23,188 @@ class MutexIF;
|
|||||||
* state
|
* state
|
||||||
*/
|
*/
|
||||||
class SdCardManager {
|
class SdCardManager {
|
||||||
friend class SdCardAccess;
|
friend class SdCardAccess;
|
||||||
public:
|
|
||||||
enum class Operations {
|
|
||||||
SWITCHING_ON,
|
|
||||||
SWITCHING_OFF,
|
|
||||||
MOUNTING,
|
|
||||||
UNMOUNTING,
|
|
||||||
IDLE
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class OpStatus {
|
public:
|
||||||
IDLE,
|
enum class Operations { SWITCHING_ON, SWITCHING_OFF, MOUNTING, UNMOUNTING, IDLE };
|
||||||
TIMEOUT,
|
|
||||||
ONGOING,
|
|
||||||
SUCCESS,
|
|
||||||
FAIL
|
|
||||||
};
|
|
||||||
|
|
||||||
using SdStatePair = std::pair<sd::SdState, sd::SdState>;
|
enum class OpStatus { IDLE, TIMEOUT, ONGOING, SUCCESS, FAIL };
|
||||||
|
|
||||||
static constexpr uint8_t INTERFACE_ID = CLASS_ID::SD_CARD_MANAGER;
|
using SdStatePair = std::pair<sd::SdState, sd::SdState>;
|
||||||
|
|
||||||
static constexpr ReturnValue_t OP_ONGOING =
|
static constexpr uint8_t INTERFACE_ID = CLASS_ID::SD_CARD_MANAGER;
|
||||||
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 0);
|
|
||||||
static constexpr ReturnValue_t ALREADY_ON =
|
|
||||||
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 1);
|
|
||||||
static constexpr ReturnValue_t ALREADY_MOUNTED =
|
|
||||||
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 2);
|
|
||||||
static constexpr ReturnValue_t ALREADY_OFF =
|
|
||||||
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 3);
|
|
||||||
static constexpr ReturnValue_t STATUS_FILE_NEXISTS =
|
|
||||||
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 10);
|
|
||||||
static constexpr ReturnValue_t STATUS_FILE_FORMAT_INVALID =
|
|
||||||
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 11);
|
|
||||||
static constexpr ReturnValue_t MOUNT_ERROR =
|
|
||||||
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 12);
|
|
||||||
static constexpr ReturnValue_t UNMOUNT_ERROR =
|
|
||||||
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 13);
|
|
||||||
static constexpr ReturnValue_t SYSTEM_CALL_ERROR =
|
|
||||||
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 14);
|
|
||||||
static constexpr ReturnValue_t POPEN_CALL_ERROR =
|
|
||||||
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 15);
|
|
||||||
|
|
||||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FILE_SYSTEM;
|
static constexpr ReturnValue_t OP_ONGOING = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 0);
|
||||||
|
static constexpr ReturnValue_t ALREADY_ON = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 1);
|
||||||
|
static constexpr ReturnValue_t ALREADY_MOUNTED =
|
||||||
|
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 2);
|
||||||
|
static constexpr ReturnValue_t ALREADY_OFF = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 3);
|
||||||
|
static constexpr ReturnValue_t STATUS_FILE_NEXISTS =
|
||||||
|
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 10);
|
||||||
|
static constexpr ReturnValue_t STATUS_FILE_FORMAT_INVALID =
|
||||||
|
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 11);
|
||||||
|
static constexpr ReturnValue_t MOUNT_ERROR = HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 12);
|
||||||
|
static constexpr ReturnValue_t UNMOUNT_ERROR =
|
||||||
|
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 13);
|
||||||
|
static constexpr ReturnValue_t SYSTEM_CALL_ERROR =
|
||||||
|
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 14);
|
||||||
|
static constexpr ReturnValue_t POPEN_CALL_ERROR =
|
||||||
|
HasReturnvaluesIF::makeReturnCode(INTERFACE_ID, 15);
|
||||||
|
|
||||||
static constexpr Event SANITIZATION_FAILED = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW);
|
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::FILE_SYSTEM;
|
||||||
|
|
||||||
// C++17 does not support constexpr std::string yet
|
static constexpr Event SANITIZATION_FAILED = event::makeEvent(SUBSYSTEM_ID, 0, severity::LOW);
|
||||||
static constexpr char SD_0_DEV_NAME[] = "/dev/mmcblk0p1";
|
|
||||||
static constexpr char SD_1_DEV_NAME[] = "/dev/mmcblk1p1";
|
|
||||||
static constexpr char SD_0_MOUNT_POINT[] = "/mnt/sd0";
|
|
||||||
static constexpr char SD_1_MOUNT_POINT[] = "/mnt/sd1";
|
|
||||||
static constexpr char SD_STATE_FILE[] = "/tmp/sd_status.txt";
|
|
||||||
|
|
||||||
virtual ~SdCardManager();
|
// C++17 does not support constexpr std::string yet
|
||||||
|
static constexpr char SD_0_DEV_NAME[] = "/dev/mmcblk0p1";
|
||||||
|
static constexpr char SD_1_DEV_NAME[] = "/dev/mmcblk1p1";
|
||||||
|
static constexpr char SD_0_MOUNT_POINT[] = "/mnt/sd0";
|
||||||
|
static constexpr char SD_1_MOUNT_POINT[] = "/mnt/sd1";
|
||||||
|
static constexpr char SD_STATE_FILE[] = "/tmp/sd_status.txt";
|
||||||
|
|
||||||
static void create();
|
virtual ~SdCardManager();
|
||||||
|
|
||||||
/**
|
static void create();
|
||||||
* Returns the single instance of the SD card manager.
|
|
||||||
*/
|
|
||||||
static SdCardManager* instance();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the preferred SD card which will determine which SD card will be used as the primary
|
* Returns the single instance of the SD card manager.
|
||||||
* SD card in hot redundant and cold redundant mode. This function will not switch the
|
*/
|
||||||
* SD cards which are currently on and mounted, this needs to be implemented by
|
static SdCardManager* instance();
|
||||||
* an upper layer by using #switchOffSdCard , #switchOnSdCard and #updateSdCardStateFile
|
|
||||||
* @param sdCard
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ReturnValue_t setPreferredSdCard(sd::SdCard sdCard);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the currently configured preferred SD card
|
* Set the preferred SD card which will determine which SD card will be used as the primary
|
||||||
* @param sdCard
|
* SD card in hot redundant and cold redundant mode. This function will not switch the
|
||||||
* @return
|
* SD cards which are currently on and mounted, this needs to be implemented by
|
||||||
*/
|
* an upper layer by using #switchOffSdCard , #switchOnSdCard and #updateSdCardStateFile
|
||||||
ReturnValue_t getPreferredSdCard(sd::SdCard& sdCard) const;
|
* @param sdCard
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ReturnValue_t setPreferredSdCard(sd::SdCard sdCard);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch on the specified SD card.
|
* Get the currently configured preferred SD card
|
||||||
* @param sdCard
|
* @param sdCard
|
||||||
* @param doMountSdCard Mount the SD card after switching it on, which is necessary
|
* @return
|
||||||
* to use it
|
*/
|
||||||
* @param statusPair If the status pair is already available, it can be passed here
|
ReturnValue_t getPreferredSdCard(sd::SdCard& sdCard) const;
|
||||||
* @return - RETURN_OK on success, ALREADY_ON if it is already on,
|
|
||||||
* SYSTEM_CALL_ERROR on system error
|
|
||||||
*/
|
|
||||||
ReturnValue_t switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard = true,
|
|
||||||
SdStatePair* statusPair = nullptr);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch off the specified SD card.
|
* Switch on the specified SD card.
|
||||||
* @param sdCard
|
* @param sdCard
|
||||||
* @param doUnmountSdCard Unmount the SD card before switching the card off, which makes
|
* @param doMountSdCard Mount the SD card after switching it on, which is necessary
|
||||||
* the operation safer
|
* to use it
|
||||||
* @param statusPair If the status pair is already available, it can be passed here
|
* @param statusPair If the status pair is already available, it can be passed here
|
||||||
* @return - RETURN_OK on success, ALREADY_ON if it is already on,
|
* @return - RETURN_OK on success, ALREADY_ON if it is already on,
|
||||||
* SYSTEM_CALL_ERROR on system error
|
* SYSTEM_CALL_ERROR on system error
|
||||||
*/
|
*/
|
||||||
ReturnValue_t switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard = true,
|
ReturnValue_t switchOnSdCard(sd::SdCard sdCard, bool doMountSdCard = true,
|
||||||
SdStatePair* statusPair = nullptr);
|
SdStatePair* statusPair = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the state file or creates one if it does not exist. You need to call this
|
* Switch off the specified SD card.
|
||||||
* function before calling #sdCardActive
|
* @param sdCard
|
||||||
* @return
|
* @param doUnmountSdCard Unmount the SD card before switching the card off, which makes
|
||||||
* - RETURN_OK if the state file was updated successfully
|
* the operation safer
|
||||||
* - CommandExecutor::COMMAND_PENDING: Non-blocking command is pending
|
* @param statusPair If the status pair is already available, it can be passed here
|
||||||
* - RETURN_FAILED: blocking command failed
|
* @return - RETURN_OK on success, ALREADY_ON if it is already on,
|
||||||
*/
|
* SYSTEM_CALL_ERROR on system error
|
||||||
ReturnValue_t updateSdCardStateFile();
|
*/
|
||||||
|
ReturnValue_t switchOffSdCard(sd::SdCard sdCard, bool doUnmountSdCard = true,
|
||||||
|
SdStatePair* statusPair = nullptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the state of the SD cards. If the state file does not exist, this function will
|
* Update the state file or creates one if it does not exist. You need to call this
|
||||||
* take care of updating it. If it does not, the function will use the state file to get
|
* function before calling #sdCardActive
|
||||||
* the status of the SD cards and set the field of the provided boolean pair.
|
* @return
|
||||||
* @param active Pair of booleans, where the first entry is the state of the first SD card
|
* - RETURN_OK if the state file was updated successfully
|
||||||
* and the second one the state of the second SD card
|
* - CommandExecutor::COMMAND_PENDING: Non-blocking command is pending
|
||||||
* @return - RETURN_OK if the state was read successfully
|
* - RETURN_FAILED: blocking command failed
|
||||||
* - STATUS_FILE_FORMAT_INVALID if there was an issue with the state file. The user
|
*/
|
||||||
* should call #updateSdCardStateFile again in that case
|
ReturnValue_t updateSdCardStateFile();
|
||||||
* - STATUS_FILE_NEXISTS if the status file does not exist
|
|
||||||
*/
|
|
||||||
ReturnValue_t getSdCardActiveStatus(SdStatePair& active);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mount the specified SD card. This is necessary to use it.
|
* Get the state of the SD cards. If the state file does not exist, this function will
|
||||||
* @param sdCard
|
* take care of updating it. If it does not, the function will use the state file to get
|
||||||
* @return
|
* the status of the SD cards and set the field of the provided boolean pair.
|
||||||
*/
|
* @param active Pair of booleans, where the first entry is the state of the first SD card
|
||||||
ReturnValue_t mountSdCard(sd::SdCard sdCard);
|
* and the second one the state of the second SD card
|
||||||
/**
|
* @return - RETURN_OK if the state was read successfully
|
||||||
* Unmount the specified SD card. This is recommended before switching it off. The SD card
|
* - STATUS_FILE_FORMAT_INVALID if there was an issue with the state file. The user
|
||||||
* can't be used after it has been unmounted.
|
* should call #updateSdCardStateFile again in that case
|
||||||
* @param sdCard
|
* - STATUS_FILE_NEXISTS if the status file does not exist
|
||||||
* @return
|
*/
|
||||||
*/
|
ReturnValue_t getSdCardActiveStatus(SdStatePair& active);
|
||||||
ReturnValue_t unmountSdCard(sd::SdCard sdCard);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In case that there is a discrepancy between the preferred SD card and the currently
|
* Mount the specified SD card. This is necessary to use it.
|
||||||
* mounted one, this function will sanitize the state by attempting to mount the
|
* @param sdCard
|
||||||
* currently preferred SD card. If the caller already has state information, it can be
|
* @return
|
||||||
* passed into the function. For now, this operation will be enforced in blocking mode.
|
*/
|
||||||
* @param statusPair Current SD card status capture with #getSdCardActiveStatus
|
ReturnValue_t mountSdCard(sd::SdCard sdCard);
|
||||||
* @param prefSdCard Preferred SD card captured with #getPreferredSdCard
|
/**
|
||||||
* @throws std::bad_alloc if one of the two arguments was a nullptr and an allocation failed
|
* Unmount the specified SD card. This is recommended before switching it off. The SD card
|
||||||
* @return
|
* can't be used after it has been unmounted.
|
||||||
*/
|
* @param sdCard
|
||||||
ReturnValue_t sanitizeState(SdStatePair* statusPair = nullptr,
|
* @return
|
||||||
sd::SdCard prefSdCard = sd::SdCard::NONE);
|
*/
|
||||||
|
ReturnValue_t unmountSdCard(sd::SdCard sdCard);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If sd::SdCard::NONE is passed as an argument, this function will get the currently
|
* In case that there is a discrepancy between the preferred SD card and the currently
|
||||||
* preferred SD card from the scratch buffer.
|
* mounted one, this function will sanitize the state by attempting to mount the
|
||||||
* @param prefSdCardPtr
|
* currently preferred SD card. If the caller already has state information, it can be
|
||||||
* @return
|
* passed into the function. For now, this operation will be enforced in blocking mode.
|
||||||
*/
|
* @param statusPair Current SD card status capture with #getSdCardActiveStatus
|
||||||
std::string getCurrentMountPrefix(sd::SdCard prefSdCardPtr = sd::SdCard::NONE);
|
* @param prefSdCard Preferred SD card captured with #getPreferredSdCard
|
||||||
|
* @throws std::bad_alloc if one of the two arguments was a nullptr and an allocation failed
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ReturnValue_t sanitizeState(SdStatePair* statusPair = nullptr,
|
||||||
|
sd::SdCard prefSdCard = sd::SdCard::NONE);
|
||||||
|
|
||||||
OpStatus checkCurrentOp(Operations& currentOp);
|
/**
|
||||||
|
* If sd::SdCard::NONE is passed as an argument, this function will get the currently
|
||||||
|
* preferred SD card from the scratch buffer.
|
||||||
|
* @param prefSdCardPtr
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
std::string getCurrentMountPrefix(sd::SdCard prefSdCardPtr = sd::SdCard::NONE);
|
||||||
|
|
||||||
/**
|
OpStatus checkCurrentOp(Operations& currentOp);
|
||||||
* If there are issues with the state machine, it can be reset with this function
|
|
||||||
*/
|
|
||||||
void resetState();
|
|
||||||
|
|
||||||
void setBlocking(bool blocking);
|
/**
|
||||||
void setPrintCommandOutput(bool print);
|
* If there are issues with the state machine, it can be reset with this function
|
||||||
|
*/
|
||||||
|
void resetState();
|
||||||
|
|
||||||
/**
|
void setBlocking(bool blocking);
|
||||||
* @brief Checks if an SD card is mounted
|
void setPrintCommandOutput(bool print);
|
||||||
*
|
|
||||||
* @param sdCard The SD crad to check
|
|
||||||
*
|
|
||||||
* @return true if mounted, otherwise false
|
|
||||||
*/
|
|
||||||
bool isSdCardMounted(sd::SdCard sdCard);
|
|
||||||
private:
|
|
||||||
CommandExecutor cmdExecutor;
|
|
||||||
Operations currentOp = Operations::IDLE;
|
|
||||||
bool blocking = false;
|
|
||||||
bool printCmdOutput = true;
|
|
||||||
|
|
||||||
SdCardManager();
|
/**
|
||||||
|
* @brief Checks if an SD card is mounted
|
||||||
|
*
|
||||||
|
* @param sdCard The SD crad to check
|
||||||
|
*
|
||||||
|
* @return true if mounted, otherwise false
|
||||||
|
*/
|
||||||
|
bool isSdCardMounted(sd::SdCard sdCard);
|
||||||
|
|
||||||
ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on);
|
private:
|
||||||
|
CommandExecutor cmdExecutor;
|
||||||
|
Operations currentOp = Operations::IDLE;
|
||||||
|
bool blocking = false;
|
||||||
|
bool printCmdOutput = true;
|
||||||
|
|
||||||
void processSdStatusLine(SdStatePair& active, std::string& line, uint8_t& idx,
|
SdCardManager();
|
||||||
sd::SdCard& currentSd);
|
|
||||||
|
|
||||||
std::string currentPrefix;
|
ReturnValue_t setSdCardState(sd::SdCard sdCard, bool on);
|
||||||
|
|
||||||
static SdCardManager* factoryInstance;
|
void processSdStatusLine(SdStatePair& active, std::string& line, uint8_t& idx,
|
||||||
|
sd::SdCard& currentSd);
|
||||||
|
|
||||||
|
std::string currentPrefix;
|
||||||
|
|
||||||
|
static SdCardManager* factoryInstance;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_ */
|
#endif /* BSP_Q7S_MEMORY_SDCARDACCESSMANAGER_H_ */
|
||||||
|
@ -5,22 +5,15 @@
|
|||||||
|
|
||||||
namespace sd {
|
namespace sd {
|
||||||
|
|
||||||
enum SdState: uint8_t {
|
enum SdState : uint8_t {
|
||||||
OFF = 0,
|
OFF = 0,
|
||||||
ON = 1,
|
ON = 1,
|
||||||
// A mounted SD card is on as well
|
// A mounted SD card is on as well
|
||||||
MOUNTED = 2
|
MOUNTED = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SdCard: uint8_t {
|
enum SdCard : uint8_t { SLOT_0 = 0, SLOT_1 = 1, BOTH, NONE };
|
||||||
SLOT_0 = 0,
|
|
||||||
SLOT_1 = 1,
|
|
||||||
BOTH,
|
|
||||||
NONE
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace sd
|
||||||
|
|
||||||
#endif /* BSP_Q7S_MEMORY_DEFINITIONS_H_ */
|
#endif /* BSP_Q7S_MEMORY_DEFINITIONS_H_ */
|
||||||
|
@ -1,49 +1,50 @@
|
|||||||
#include "scratchApi.h"
|
#include "scratchApi.h"
|
||||||
|
|
||||||
ReturnValue_t scratch::writeString(std::string name, std::string string) {
|
ReturnValue_t scratch::writeString(std::string name, std::string string) {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "xsc_scratch write " << name << " \"" << string << "\"";
|
oss << "xsc_scratch write " << name << " \"" << string << "\"";
|
||||||
int result = std::system(oss.str().c_str());
|
int result = std::system(oss.str().c_str());
|
||||||
if(result != 0) {
|
if (result != 0) {
|
||||||
utility::handleSystemError(result, "scratch::writeString");
|
utility::handleSystemError(result, "scratch::writeString");
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t scratch::readString(std::string key, std::string &string) {
|
ReturnValue_t scratch::readString(std::string key, std::string &string) {
|
||||||
std::ifstream file;
|
std::ifstream file;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
ReturnValue_t result = readToFile(key, file, filename);
|
ReturnValue_t result = readToFile(key, file, filename);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
if (not std::getline(file, line)) {
|
if (not std::getline(file, line)) {
|
||||||
std::remove(filename.c_str());
|
std::remove(filename.c_str());
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t pos = line.find("=");
|
size_t pos = line.find("=");
|
||||||
if(pos == std::string::npos) {
|
if (pos == std::string::npos) {
|
||||||
sif::warning << "scratch::readNumber: Output file format invalid, "
|
sif::warning << "scratch::readNumber: Output file format invalid, "
|
||||||
"no \"=\" found" << std::endl;
|
"no \"=\" found"
|
||||||
// Could not find value
|
<< std::endl;
|
||||||
std::remove(filename.c_str());
|
// Could not find value
|
||||||
return KEY_NOT_FOUND;
|
std::remove(filename.c_str());
|
||||||
}
|
return KEY_NOT_FOUND;
|
||||||
string = line.substr(pos + 1);
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
string = line.substr(pos + 1);
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t scratch::clearValue(std::string key) {
|
ReturnValue_t scratch::clearValue(std::string key) {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "xsc_scratch clear " << key;
|
oss << "xsc_scratch clear " << key;
|
||||||
int result = std::system(oss.str().c_str());
|
int result = std::system(oss.str().c_str());
|
||||||
if(result != 0) {
|
if (result != 0) {
|
||||||
utility::handleSystemError(result, "scratch::clearValue");
|
utility::handleSystemError(result, "scratch::clearValue");
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
#ifndef BSP_Q7S_MEMORY_SCRATCHAPI_H_
|
#ifndef BSP_Q7S_MEMORY_SCRATCHAPI_H_
|
||||||
#define BSP_Q7S_MEMORY_SCRATCHAPI_H_
|
#define BSP_Q7S_MEMORY_SCRATCHAPI_H_
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
#include "linux/utility/utility.h"
|
#include "linux/utility/utility.h"
|
||||||
#include "returnvalues/classIds.h"
|
#include "returnvalues/classIds.h"
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief API for the scratch buffer
|
* @brief API for the scratch buffer
|
||||||
*/
|
*/
|
||||||
@ -48,7 +48,7 @@ ReturnValue_t readString(std::string key, std::string& string);
|
|||||||
* @param num Number. Template allows to set signed, unsigned and floating point numbers
|
* @param num Number. Template allows to set signed, unsigned and floating point numbers
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
template<typename T, class = typename std::enable_if<std::is_integral<T>::value>::type>
|
template <typename T, class = typename std::enable_if<std::is_integral<T>::value>::type>
|
||||||
inline ReturnValue_t writeNumber(std::string key, T num) noexcept;
|
inline ReturnValue_t writeNumber(std::string key, T num) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,90 +59,88 @@ inline ReturnValue_t writeNumber(std::string key, T num) noexcept;
|
|||||||
* @param num
|
* @param num
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
template<typename T, class = typename std::enable_if<std::is_integral<T>::value>::type>
|
template <typename T, class = typename std::enable_if<std::is_integral<T>::value>::type>
|
||||||
inline ReturnValue_t readNumber(std::string key, T& num) noexcept;
|
inline ReturnValue_t readNumber(std::string key, T& num) noexcept;
|
||||||
|
|
||||||
|
|
||||||
// Anonymous namespace
|
// Anonymous namespace
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static uint8_t counter = 0;
|
static uint8_t counter = 0;
|
||||||
|
|
||||||
ReturnValue_t readToFile(std::string name, std::ifstream& file, std::string& filename) {
|
ReturnValue_t readToFile(std::string name, std::ifstream& file, std::string& filename) {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
filename = "/tmp/sro" + std::to_string(counter++);
|
filename = "/tmp/sro" + std::to_string(counter++);
|
||||||
ostringstream oss;
|
ostringstream oss;
|
||||||
oss << "xsc_scratch read " << name << " > " << filename;
|
oss << "xsc_scratch read " << name << " > " << filename;
|
||||||
|
|
||||||
int result = std::system(oss.str().c_str());
|
int result = std::system(oss.str().c_str());
|
||||||
if(result != 0) {
|
if (result != 0) {
|
||||||
if(result == 256) {
|
if (result == 256) {
|
||||||
sif::warning << "scratch::readNumber: Key " << name << " does not exist" << std::endl;
|
sif::warning << "scratch::readNumber: Key " << name << " does not exist" << std::endl;
|
||||||
// Could not find value
|
// Could not find value
|
||||||
std::remove(filename.c_str());
|
std::remove(filename.c_str());
|
||||||
return KEY_NOT_FOUND;
|
return KEY_NOT_FOUND;
|
||||||
}
|
} else {
|
||||||
else {
|
utility::handleSystemError(result, "scratch::readNumber");
|
||||||
utility::handleSystemError(result, "scratch::readNumber");
|
std::remove(filename.c_str());
|
||||||
std::remove(filename.c_str());
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
file.open(filename);
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
file.open(filename);
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of anonymous namespace
|
} // End of anonymous namespace
|
||||||
|
|
||||||
template<typename T, class = typename std::enable_if<std::is_integral<T>::value>::type>
|
template <typename T, class = typename std::enable_if<std::is_integral<T>::value>::type>
|
||||||
inline ReturnValue_t writeNumber(std::string key, T num) noexcept {
|
inline ReturnValue_t writeNumber(std::string key, T num) noexcept {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "xsc_scratch write " << key << " " << std::to_string(num);
|
oss << "xsc_scratch write " << key << " " << std::to_string(num);
|
||||||
int result = std::system(oss.str().c_str());
|
int result = std::system(oss.str().c_str());
|
||||||
if(result != 0) {
|
if (result != 0) {
|
||||||
utility::handleSystemError(result, "scratch::writeNumber");
|
utility::handleSystemError(result, "scratch::writeNumber");
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, class = typename std::enable_if<std::is_integral<T>::value>::type>
|
template <typename T, class = typename std::enable_if<std::is_integral<T>::value>::type>
|
||||||
inline ReturnValue_t readNumber(std::string key, T& num) noexcept {
|
inline ReturnValue_t readNumber(std::string key, T& num) noexcept {
|
||||||
using namespace std;
|
using namespace std;
|
||||||
ifstream file;
|
ifstream file;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
ReturnValue_t result = readToFile(key, file, filename);
|
ReturnValue_t result = readToFile(key, file, filename);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
std::remove(filename.c_str());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
string line;
|
|
||||||
if (not std::getline(file, line)) {
|
|
||||||
std::remove(filename.c_str());
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t pos = line.find("=");
|
|
||||||
if(pos == string::npos) {
|
|
||||||
sif::warning << "scratch::readNumber: Output file format invalid, "
|
|
||||||
"no \"=\" found" << std::endl;
|
|
||||||
// Could not find value
|
|
||||||
std::remove(filename.c_str());
|
|
||||||
return KEY_NOT_FOUND;
|
|
||||||
}
|
|
||||||
std::string valueAsString = line.substr(pos + 1);
|
|
||||||
try {
|
|
||||||
num = std::stoi(valueAsString);
|
|
||||||
}
|
|
||||||
catch(std::invalid_argument& e) {
|
|
||||||
sif::warning << "scratch::readNumber: stoi call failed with " << e.what() << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::remove(filename.c_str());
|
std::remove(filename.c_str());
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
string line;
|
||||||
|
if (not std::getline(file, line)) {
|
||||||
|
std::remove(filename.c_str());
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t pos = line.find("=");
|
||||||
|
if (pos == string::npos) {
|
||||||
|
sif::warning << "scratch::readNumber: Output file format invalid, "
|
||||||
|
"no \"=\" found"
|
||||||
|
<< std::endl;
|
||||||
|
// Could not find value
|
||||||
|
std::remove(filename.c_str());
|
||||||
|
return KEY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
std::string valueAsString = line.substr(pos + 1);
|
||||||
|
try {
|
||||||
|
num = std::stoi(valueAsString);
|
||||||
|
} catch (std::invalid_argument& e) {
|
||||||
|
sif::warning << "scratch::readNumber: stoi call failed with " << e.what() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::remove(filename.c_str());
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace scratch
|
||||||
|
|
||||||
#endif /* BSP_Q7S_MEMORY_SCRATCHAPI_H_ */
|
#endif /* BSP_Q7S_MEMORY_SCRATCHAPI_H_ */
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "simple.h"
|
#include "simple.h"
|
||||||
|
|
||||||
#include "q7sConfig.h"
|
#include "q7sConfig.h"
|
||||||
|
|
||||||
#if Q7S_SIMPLE_ADD_FILE_SYSTEM_TEST == 1
|
#if Q7S_SIMPLE_ADD_FILE_SYSTEM_TEST == 1
|
||||||
@ -6,16 +7,13 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int simple::simple() {
|
int simple::simple() {
|
||||||
cout << "-- Q7S Simple Application --" << endl;
|
cout << "-- Q7S Simple Application --" << endl;
|
||||||
#if Q7S_SIMPLE_ADD_FILE_SYSTEM_TEST == 1
|
#if Q7S_SIMPLE_ADD_FILE_SYSTEM_TEST == 1
|
||||||
{
|
{ FileSystemTest fileSystemTest; }
|
||||||
FileSystemTest fileSystemTest;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if TE0720_GPIO_TEST
|
#if TE0720_GPIO_TEST
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
#include <bsp_q7s/spi/Q7sSpiComIF.h>
|
#include <bsp_q7s/spi/Q7sSpiComIF.h>
|
||||||
|
|
||||||
Q7sSpiComIF::Q7sSpiComIF(object_id_t objectId, GpioIF* gpioComIF) :
|
Q7sSpiComIF::Q7sSpiComIF(object_id_t objectId, GpioIF* gpioComIF) : SpiComIF(objectId, gpioComIF) {}
|
||||||
SpiComIF(objectId, gpioComIF) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Q7sSpiComIF::~Q7sSpiComIF() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Q7sSpiComIF::~Q7sSpiComIF() {}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This additional communication interface is required because the SPI busses behind the
|
* @brief This additional communication interface is required because the SPI busses behind the
|
||||||
* devices "/dev/spi2.0" and "dev/spidev3.0" are multiplexed to one SPI interface.
|
* devices "/dev/spi2.0" and "dev/spidev3.0" are multiplexed to one SPI interface.
|
||||||
@ -17,17 +16,17 @@
|
|||||||
* the SPI interface. The multiplexing is performed via a GPIO connected to a VHDL
|
* the SPI interface. The multiplexing is performed via a GPIO connected to a VHDL
|
||||||
* module responsible for switching between the to SPI peripherals.
|
* module responsible for switching between the to SPI peripherals.
|
||||||
*/
|
*/
|
||||||
class Q7sSpiComIF: public SpiComIF {
|
class Q7sSpiComIF : public SpiComIF {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Constructor
|
* @brief Constructor
|
||||||
*
|
*
|
||||||
* @param objectId
|
* @param objectId
|
||||||
* @param gpioComIF
|
* @param gpioComIF
|
||||||
* @param gpioSwitchId The gpio ID of the GPIO connected to the SPI mux module in the PL.
|
* @param gpioSwitchId The gpio ID of the GPIO connected to the SPI mux module in the PL.
|
||||||
*/
|
*/
|
||||||
Q7sSpiComIF(object_id_t objectId, GpioIF* gpioComIF, gpioId_t gpioSwitchId);
|
Q7sSpiComIF(object_id_t objectId, GpioIF* gpioComIF, gpioId_t gpioSwitchId);
|
||||||
virtual ~Q7sSpiComIF();
|
virtual ~Q7sSpiComIF();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* BSP_Q7S_SPI_Q7SSPICOMIF_H_ */
|
#endif /* BSP_Q7S_SPI_Q7SSPICOMIF_H_ */
|
||||||
|
@ -1,34 +1,32 @@
|
|||||||
#include "GpioCookie.h"
|
#include "GpioCookie.h"
|
||||||
|
|
||||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||||
|
|
||||||
GpioCookie::GpioCookie() {
|
GpioCookie::GpioCookie() {}
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t GpioCookie::addGpio(gpioId_t gpioId, GpioBase* gpioConfig){
|
ReturnValue_t GpioCookie::addGpio(gpioId_t gpioId, GpioBase* gpioConfig) {
|
||||||
if (gpioConfig == nullptr) {
|
if (gpioConfig == nullptr) {
|
||||||
sif::debug << "GpioCookie::addGpio: gpioConfig is nullpointer" << std::endl;
|
sif::debug << "GpioCookie::addGpio: gpioConfig is nullpointer" << std::endl;
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
auto gpioMapIter = gpioMap.find(gpioId);
|
||||||
|
if (gpioMapIter == gpioMap.end()) {
|
||||||
|
auto statusPair = gpioMap.emplace(gpioId, gpioConfig);
|
||||||
|
if (statusPair.second == false) {
|
||||||
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
|
sif::error << "GpioCookie::addGpio: Failed to add GPIO " << gpioId << " to GPIO map"
|
||||||
|
<< std::endl;
|
||||||
|
#endif
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
auto gpioMapIter = gpioMap.find(gpioId);
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
if(gpioMapIter == gpioMap.end()) {
|
}
|
||||||
auto statusPair = gpioMap.emplace(gpioId, gpioConfig);
|
|
||||||
if (statusPair.second == false) {
|
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
sif::error << "GpioCookie::addGpio: Failed to add GPIO " << gpioId <<
|
sif::error << "GpioCookie::addGpio: GPIO already exists in GPIO map " << std::endl;
|
||||||
" to GPIO map" << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
|
||||||
sif::error << "GpioCookie::addGpio: GPIO already exists in GPIO map " << std::endl;
|
|
||||||
#endif
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GpioMap GpioCookie::getGpioMap() const {
|
GpioMap GpioCookie::getGpioMap() const { return gpioMap; }
|
||||||
return gpioMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
GpioCookie::~GpioCookie() {}
|
GpioCookie::~GpioCookie() {}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
#ifndef LINUX_GPIO_GPIOCOOKIE_H_
|
#ifndef LINUX_GPIO_GPIOCOOKIE_H_
|
||||||
#define LINUX_GPIO_GPIOCOOKIE_H_
|
#define LINUX_GPIO_GPIOCOOKIE_H_
|
||||||
|
|
||||||
#include "GpioIF.h"
|
|
||||||
#include "gpioDefinitions.h"
|
|
||||||
#include <fsfw/devicehandlers/CookieIF.h>
|
#include <fsfw/devicehandlers/CookieIF.h>
|
||||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||||
|
|
||||||
|
#include "GpioIF.h"
|
||||||
|
#include "gpioDefinitions.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Cookie for the GpioIF. Allows the GpioIF to determine which
|
* @brief Cookie for the GpioIF. Allows the GpioIF to determine which
|
||||||
* GPIOs to initialize and whether they should be configured as in- or
|
* GPIOs to initialize and whether they should be configured as in- or
|
||||||
@ -16,24 +17,23 @@
|
|||||||
*
|
*
|
||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
*/
|
*/
|
||||||
class GpioCookie: public CookieIF {
|
class GpioCookie : public CookieIF {
|
||||||
public:
|
public:
|
||||||
|
GpioCookie();
|
||||||
|
|
||||||
GpioCookie();
|
virtual ~GpioCookie();
|
||||||
|
|
||||||
virtual ~GpioCookie();
|
ReturnValue_t addGpio(gpioId_t gpioId, GpioBase* gpioConfig);
|
||||||
|
/**
|
||||||
|
* @brief Get map with registered GPIOs.
|
||||||
|
*/
|
||||||
|
GpioMap getGpioMap() const;
|
||||||
|
|
||||||
ReturnValue_t addGpio(gpioId_t gpioId, GpioBase* gpioConfig);
|
private:
|
||||||
/**
|
/**
|
||||||
* @brief Get map with registered GPIOs.
|
* Returns a copy of the internal GPIO map.
|
||||||
*/
|
*/
|
||||||
GpioMap getGpioMap() const;
|
GpioMap gpioMap;
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* Returns a copy of the internal GPIO map.
|
|
||||||
*/
|
|
||||||
GpioMap gpioMap;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* LINUX_GPIO_GPIOCOOKIE_H_ */
|
#endif /* LINUX_GPIO_GPIOCOOKIE_H_ */
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
#ifndef LINUX_GPIO_GPIOIF_H_
|
#ifndef LINUX_GPIO_GPIOIF_H_
|
||||||
#define LINUX_GPIO_GPIOIF_H_
|
#define LINUX_GPIO_GPIOIF_H_
|
||||||
|
|
||||||
#include "gpioDefinitions.h"
|
|
||||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
|
||||||
#include <fsfw/devicehandlers/CookieIF.h>
|
#include <fsfw/devicehandlers/CookieIF.h>
|
||||||
|
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||||
|
|
||||||
|
#include "gpioDefinitions.h"
|
||||||
|
|
||||||
class GpioCookie;
|
class GpioCookie;
|
||||||
|
|
||||||
@ -13,42 +14,41 @@ class GpioCookie;
|
|||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
*/
|
*/
|
||||||
class GpioIF : public HasReturnvaluesIF {
|
class GpioIF : public HasReturnvaluesIF {
|
||||||
public:
|
public:
|
||||||
|
virtual ~GpioIF(){};
|
||||||
|
|
||||||
virtual ~GpioIF() {};
|
/**
|
||||||
|
* @brief Called by the GPIO using object.
|
||||||
|
* @param cookie Cookie specifying informations of the GPIOs required
|
||||||
|
* by a object.
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t addGpios(GpioCookie* cookie) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Called by the GPIO using object.
|
* @brief By implementing this function a child must provide the
|
||||||
* @param cookie Cookie specifying informations of the GPIOs required
|
* functionality to pull a certain GPIO to high logic level.
|
||||||
* by a object.
|
*
|
||||||
*/
|
* @param gpioId A unique number which specifies the GPIO to drive.
|
||||||
virtual ReturnValue_t addGpios(GpioCookie* cookie) = 0;
|
* @return Returns RETURN_OK for success. This should never return RETURN_FAILED.
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t pullHigh(gpioId_t gpioId) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief By implementing this function a child must provide the
|
* @brief By implementing this function a child must provide the
|
||||||
* functionality to pull a certain GPIO to high logic level.
|
* functionality to pull a certain GPIO to low logic level.
|
||||||
*
|
*
|
||||||
* @param gpioId A unique number which specifies the GPIO to drive.
|
* @param gpioId A unique number which specifies the GPIO to drive.
|
||||||
* @return Returns RETURN_OK for success. This should never return RETURN_FAILED.
|
*/
|
||||||
*/
|
virtual ReturnValue_t pullLow(gpioId_t gpioId) = 0;
|
||||||
virtual ReturnValue_t pullHigh(gpioId_t gpioId) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief By implementing this function a child must provide the
|
* @brief This function requires a child to implement the functionality to read the state of
|
||||||
* functionality to pull a certain GPIO to low logic level.
|
* an ouput or input gpio.
|
||||||
*
|
*
|
||||||
* @param gpioId A unique number which specifies the GPIO to drive.
|
* @param gpioId A unique number which specifies the GPIO to read.
|
||||||
*/
|
* @param gpioState State of GPIO will be written to this pointer.
|
||||||
virtual ReturnValue_t pullLow(gpioId_t gpioId) = 0;
|
*/
|
||||||
|
virtual ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) = 0;
|
||||||
/**
|
|
||||||
* @brief This function requires a child to implement the functionality to read the state of
|
|
||||||
* an ouput or input gpio.
|
|
||||||
*
|
|
||||||
* @param gpioId A unique number which specifies the GPIO to read.
|
|
||||||
* @param gpioState State of GPIO will be written to this pointer.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* LINUX_GPIO_GPIOIF_H_ */
|
#endif /* LINUX_GPIO_GPIOIF_H_ */
|
||||||
|
@ -1,302 +1,295 @@
|
|||||||
#include "LinuxLibgpioIF.h"
|
#include "LinuxLibgpioIF.h"
|
||||||
#include "GpioCookie.h"
|
|
||||||
|
|
||||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||||
|
#include <gpiod.h>
|
||||||
#include <linux/gpio/gpioDefinitions.h>
|
#include <linux/gpio/gpioDefinitions.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <unistd.h>
|
|
||||||
#include <gpiod.h>
|
|
||||||
|
|
||||||
|
#include "GpioCookie.h"
|
||||||
|
|
||||||
LinuxLibgpioIF::LinuxLibgpioIF(object_id_t objectId) : SystemObject(objectId) {
|
LinuxLibgpioIF::LinuxLibgpioIF(object_id_t objectId) : SystemObject(objectId) {
|
||||||
struct gpiod_chip* chip = gpiod_chip_open_by_label("/amba_pl/gpio@42030000");
|
struct gpiod_chip* chip = gpiod_chip_open_by_label("/amba_pl/gpio@42030000");
|
||||||
|
|
||||||
sif::debug << chip->name << std::endl;
|
sif::debug << chip->name << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
LinuxLibgpioIF::~LinuxLibgpioIF() {
|
LinuxLibgpioIF::~LinuxLibgpioIF() {}
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::addGpios(GpioCookie* gpioCookie) {
|
ReturnValue_t LinuxLibgpioIF::addGpios(GpioCookie* gpioCookie) {
|
||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
if(gpioCookie == nullptr) {
|
if (gpioCookie == nullptr) {
|
||||||
sif::error << "LinuxLibgpioIF::initialize: Invalid cookie" << std::endl;
|
sif::error << "LinuxLibgpioIF::initialize: Invalid cookie" << std::endl;
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
GpioMap mapToAdd = gpioCookie->getGpioMap();
|
GpioMap mapToAdd = gpioCookie->getGpioMap();
|
||||||
|
|
||||||
/* Check whether this ID already exists in the map and remove duplicates */
|
/* Check whether this ID already exists in the map and remove duplicates */
|
||||||
result = checkForConflicts(mapToAdd);
|
result = checkForConflicts(mapToAdd);
|
||||||
if (result != RETURN_OK){
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = configureGpios(mapToAdd);
|
result = configureGpios(mapToAdd);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register new GPIOs in gpioMap */
|
/* Register new GPIOs in gpioMap */
|
||||||
gpioMap.insert(mapToAdd.begin(), mapToAdd.end());
|
gpioMap.insert(mapToAdd.begin(), mapToAdd.end());
|
||||||
|
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
||||||
for(auto& gpioConfig: mapToAdd) {
|
for (auto& gpioConfig : mapToAdd) {
|
||||||
switch(gpioConfig.second->gpioType) {
|
switch (gpioConfig.second->gpioType) {
|
||||||
case(gpio::GpioTypes::NONE): {
|
case (gpio::GpioTypes::NONE): {
|
||||||
return GPIO_INVALID_INSTANCE;
|
return GPIO_INVALID_INSTANCE;
|
||||||
}
|
}
|
||||||
case(gpio::GpioTypes::GPIOD_REGULAR): {
|
case (gpio::GpioTypes::GPIOD_REGULAR): {
|
||||||
GpiodRegular* regularGpio = dynamic_cast<GpiodRegular*>(gpioConfig.second);
|
GpiodRegular* regularGpio = dynamic_cast<GpiodRegular*>(gpioConfig.second);
|
||||||
if(regularGpio == nullptr) {
|
if (regularGpio == nullptr) {
|
||||||
return GPIO_INVALID_INSTANCE;
|
return GPIO_INVALID_INSTANCE;
|
||||||
}
|
|
||||||
configureRegularGpio(gpioConfig.first, regularGpio);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpio::GpioTypes::CALLBACK): {
|
|
||||||
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioConfig.second);
|
|
||||||
if(gpioCallback->callback == nullptr) {
|
|
||||||
return GPIO_INVALID_INSTANCE;
|
|
||||||
}
|
|
||||||
gpioCallback->callback(gpioConfig.first, gpio::GpioOperation::WRITE,
|
|
||||||
gpioCallback->initValue, gpioCallback->callbackArgs);
|
|
||||||
}
|
}
|
||||||
|
configureRegularGpio(gpioConfig.first, regularGpio);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (gpio::GpioTypes::CALLBACK): {
|
||||||
|
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioConfig.second);
|
||||||
|
if (gpioCallback->callback == nullptr) {
|
||||||
|
return GPIO_INVALID_INSTANCE;
|
||||||
}
|
}
|
||||||
|
gpioCallback->callback(gpioConfig.first, gpio::GpioOperation::WRITE,
|
||||||
|
gpioCallback->initValue, gpioCallback->callbackArgs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return RETURN_OK;
|
}
|
||||||
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, GpiodRegular *regularGpio) {
|
ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, GpiodRegular* regularGpio) {
|
||||||
std::string chipname;
|
std::string chipname;
|
||||||
unsigned int lineNum;
|
unsigned int lineNum;
|
||||||
struct gpiod_chip *chip;
|
struct gpiod_chip* chip;
|
||||||
gpio::Direction direction;
|
gpio::Direction direction;
|
||||||
std::string consumer;
|
std::string consumer;
|
||||||
struct gpiod_line *lineHandle;
|
struct gpiod_line* lineHandle;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
chipname = regularGpio->chipname;
|
chipname = regularGpio->chipname;
|
||||||
chip = gpiod_chip_open_by_name(chipname.c_str());
|
chip = gpiod_chip_open_by_name(chipname.c_str());
|
||||||
if (!chip) {
|
if (!chip) {
|
||||||
sif::error << "LinuxLibgpioIF::configureGpios: Failed to open chip "
|
sif::error << "LinuxLibgpioIF::configureGpios: Failed to open chip " << chipname
|
||||||
<< chipname << ". Gpio ID: " << gpioId << std::endl;
|
<< ". Gpio ID: " << gpioId << std::endl;
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
lineNum = regularGpio->lineNum;
|
||||||
|
lineHandle = gpiod_chip_get_line(chip, lineNum);
|
||||||
|
if (!lineHandle) {
|
||||||
|
sif::error << "LinuxLibgpioIF::configureGpios: Failed to open line for GPIO with id " << gpioId
|
||||||
|
<< std::endl;
|
||||||
|
gpiod_chip_close(chip);
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
direction = regularGpio->direction;
|
||||||
|
consumer = regularGpio->consumer;
|
||||||
|
/* Configure direction and add a description to the GPIO */
|
||||||
|
switch (direction) {
|
||||||
|
case (gpio::OUT): {
|
||||||
|
result = gpiod_line_request_output(lineHandle, consumer.c_str(), regularGpio->initValue);
|
||||||
|
if (result < 0) {
|
||||||
|
sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " << lineNum
|
||||||
|
<< " from GPIO instance with ID: " << gpioId << std::endl;
|
||||||
|
gpiod_line_release(lineHandle);
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
case (gpio::IN): {
|
||||||
lineNum = regularGpio->lineNum;
|
result = gpiod_line_request_input(lineHandle, consumer.c_str());
|
||||||
lineHandle = gpiod_chip_get_line(chip, lineNum);
|
if (result < 0) {
|
||||||
if (!lineHandle) {
|
sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " << lineNum
|
||||||
sif::error << "LinuxLibgpioIF::configureGpios: Failed to open line for GPIO with id "
|
<< " from GPIO instance with ID: " << gpioId << std::endl;
|
||||||
<< gpioId << std::endl;
|
gpiod_line_release(lineHandle);
|
||||||
gpiod_chip_close(chip);
|
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
direction = regularGpio->direction;
|
|
||||||
consumer = regularGpio->consumer;
|
|
||||||
/* Configure direction and add a description to the GPIO */
|
|
||||||
switch (direction) {
|
|
||||||
case(gpio::OUT): {
|
|
||||||
result = gpiod_line_request_output(lineHandle, consumer.c_str(),
|
|
||||||
regularGpio->initValue);
|
|
||||||
if (result < 0) {
|
|
||||||
sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " << lineNum <<
|
|
||||||
" from GPIO instance with ID: " << gpioId << std::endl;
|
|
||||||
gpiod_line_release(lineHandle);
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case(gpio::IN): {
|
|
||||||
result = gpiod_line_request_input(lineHandle, consumer.c_str());
|
|
||||||
if (result < 0) {
|
|
||||||
sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line "
|
|
||||||
<< lineNum << " from GPIO instance with ID: " << gpioId << std::endl;
|
|
||||||
gpiod_line_release(lineHandle);
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
sif::error << "LinuxLibgpioIF::configureGpios: Invalid direction specified"
|
sif::error << "LinuxLibgpioIF::configureGpios: Invalid direction specified" << std::endl;
|
||||||
<< std::endl;
|
return GPIO_INVALID_INSTANCE;
|
||||||
return GPIO_INVALID_INSTANCE;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
/**
|
||||||
/**
|
* Write line handle to GPIO configuration instance so it can later be used to set or
|
||||||
* Write line handle to GPIO configuration instance so it can later be used to set or
|
* read states of GPIOs.
|
||||||
* read states of GPIOs.
|
*/
|
||||||
*/
|
regularGpio->lineHandle = lineHandle;
|
||||||
regularGpio->lineHandle = lineHandle;
|
return RETURN_OK;
|
||||||
return RETURN_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId) {
|
ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId) {
|
||||||
gpioMapIter = gpioMap.find(gpioId);
|
gpioMapIter = gpioMap.find(gpioId);
|
||||||
if (gpioMapIter == gpioMap.end()) {
|
if (gpioMapIter == gpioMap.end()) {
|
||||||
sif::warning << "LinuxLibgpioIF::driveGpio: Unknown GPIOD ID " << gpioId << std::endl;
|
sif::warning << "LinuxLibgpioIF::driveGpio: Unknown GPIOD ID " << gpioId << std::endl;
|
||||||
return UNKNOWN_GPIO_ID;
|
return UNKNOWN_GPIO_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) {
|
if (gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) {
|
||||||
return driveGpio(gpioId, dynamic_cast<GpiodRegular*>(gpioMapIter->second), 1);
|
return driveGpio(gpioId, dynamic_cast<GpiodRegular*>(gpioMapIter->second), 1);
|
||||||
|
} else {
|
||||||
|
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioMapIter->second);
|
||||||
|
if (gpioCallback->callback == nullptr) {
|
||||||
|
return GPIO_INVALID_INSTANCE;
|
||||||
}
|
}
|
||||||
else {
|
gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::WRITE, 1,
|
||||||
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioMapIter->second);
|
gpioCallback->callbackArgs);
|
||||||
if(gpioCallback->callback == nullptr) {
|
}
|
||||||
return GPIO_INVALID_INSTANCE;
|
return GPIO_TYPE_FAILURE;
|
||||||
}
|
|
||||||
gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::WRITE,
|
|
||||||
1, gpioCallback->callbackArgs);
|
|
||||||
}
|
|
||||||
return GPIO_TYPE_FAILURE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId) {
|
ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId) {
|
||||||
gpioMapIter = gpioMap.find(gpioId);
|
gpioMapIter = gpioMap.find(gpioId);
|
||||||
if (gpioMapIter == gpioMap.end()) {
|
if (gpioMapIter == gpioMap.end()) {
|
||||||
sif::warning << "LinuxLibgpioIF::driveGpio: Unknown GPIOD ID " << gpioId << std::endl;
|
sif::warning << "LinuxLibgpioIF::driveGpio: Unknown GPIOD ID " << gpioId << std::endl;
|
||||||
return UNKNOWN_GPIO_ID;
|
return UNKNOWN_GPIO_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) {
|
if (gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) {
|
||||||
return driveGpio(gpioId, dynamic_cast<GpiodRegular*>(gpioMapIter->second), 0);
|
return driveGpio(gpioId, dynamic_cast<GpiodRegular*>(gpioMapIter->second), 0);
|
||||||
|
} else {
|
||||||
|
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioMapIter->second);
|
||||||
|
if (gpioCallback->callback == nullptr) {
|
||||||
|
return GPIO_INVALID_INSTANCE;
|
||||||
}
|
}
|
||||||
else {
|
gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::WRITE, 0,
|
||||||
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioMapIter->second);
|
gpioCallback->callbackArgs);
|
||||||
if(gpioCallback->callback == nullptr) {
|
}
|
||||||
return GPIO_INVALID_INSTANCE;
|
return GPIO_TYPE_FAILURE;
|
||||||
}
|
|
||||||
gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::WRITE,
|
|
||||||
0, gpioCallback->callbackArgs);
|
|
||||||
}
|
|
||||||
return GPIO_TYPE_FAILURE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId,
|
ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, GpiodRegular* regularGpio,
|
||||||
GpiodRegular* regularGpio, unsigned int logicLevel) {
|
unsigned int logicLevel) {
|
||||||
if(regularGpio == nullptr) {
|
if (regularGpio == nullptr) {
|
||||||
return GPIO_TYPE_FAILURE;
|
return GPIO_TYPE_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = gpiod_line_set_value(regularGpio->lineHandle, logicLevel);
|
int result = gpiod_line_set_value(regularGpio->lineHandle, logicLevel);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
sif::warning << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID " << gpioId <<
|
sif::warning << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID " << gpioId
|
||||||
" to logic level " << logicLevel << std::endl;
|
<< " to logic level " << logicLevel << std::endl;
|
||||||
return DRIVE_GPIO_FAILURE;
|
return DRIVE_GPIO_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) {
|
ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) {
|
||||||
gpioMapIter = gpioMap.find(gpioId);
|
gpioMapIter = gpioMap.find(gpioId);
|
||||||
if (gpioMapIter == gpioMap.end()){
|
if (gpioMapIter == gpioMap.end()) {
|
||||||
sif::warning << "LinuxLibgpioIF::readGpio: Unknown GPIOD ID " << gpioId << std::endl;
|
sif::warning << "LinuxLibgpioIF::readGpio: Unknown GPIOD ID " << gpioId << std::endl;
|
||||||
return UNKNOWN_GPIO_ID;
|
return UNKNOWN_GPIO_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) {
|
||||||
|
GpiodRegular* regularGpio = dynamic_cast<GpiodRegular*>(gpioMapIter->second);
|
||||||
|
if (regularGpio == nullptr) {
|
||||||
|
return GPIO_TYPE_FAILURE;
|
||||||
}
|
}
|
||||||
|
*gpioState = gpiod_line_get_value(regularGpio->lineHandle);
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
|
||||||
if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) {
|
return RETURN_OK;
|
||||||
GpiodRegular* regularGpio = dynamic_cast<GpiodRegular*>(gpioMapIter->second);
|
|
||||||
if(regularGpio == nullptr) {
|
|
||||||
return GPIO_TYPE_FAILURE;
|
|
||||||
}
|
|
||||||
*gpioState = gpiod_line_get_value(regularGpio->lineHandle);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return RETURN_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){
|
ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd) {
|
||||||
ReturnValue_t status = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t status = HasReturnvaluesIF::RETURN_OK;
|
||||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||||
for(auto& gpioConfig: mapToAdd) {
|
for (auto& gpioConfig : mapToAdd) {
|
||||||
switch(gpioConfig.second->gpioType) {
|
switch (gpioConfig.second->gpioType) {
|
||||||
case(gpio::GpioTypes::GPIOD_REGULAR): {
|
case (gpio::GpioTypes::GPIOD_REGULAR): {
|
||||||
auto regularGpio = dynamic_cast<GpiodRegular*>(gpioConfig.second);
|
auto regularGpio = dynamic_cast<GpiodRegular*>(gpioConfig.second);
|
||||||
if(regularGpio == nullptr) {
|
if (regularGpio == nullptr) {
|
||||||
return GPIO_TYPE_FAILURE;
|
return GPIO_TYPE_FAILURE;
|
||||||
}
|
|
||||||
/* Check for conflicts and remove duplicates if necessary */
|
|
||||||
result = checkForConflictsRegularGpio(gpioConfig.first, regularGpio, mapToAdd);
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
status = result;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case(gpio::GpioTypes::CALLBACK): {
|
/* Check for conflicts and remove duplicates if necessary */
|
||||||
auto callbackGpio = dynamic_cast<GpioCallback*>(gpioConfig.second);
|
result = checkForConflictsRegularGpio(gpioConfig.first, regularGpio, mapToAdd);
|
||||||
if(callbackGpio == nullptr) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return GPIO_TYPE_FAILURE;
|
status = result;
|
||||||
}
|
|
||||||
/* Check for conflicts and remove duplicates if necessary */
|
|
||||||
result = checkForConflictsCallbackGpio(gpioConfig.first, callbackGpio, mapToAdd);
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
status = result;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
default: {
|
break;
|
||||||
|
}
|
||||||
|
case (gpio::GpioTypes::CALLBACK): {
|
||||||
|
auto callbackGpio = dynamic_cast<GpioCallback*>(gpioConfig.second);
|
||||||
|
if (callbackGpio == nullptr) {
|
||||||
|
return GPIO_TYPE_FAILURE;
|
||||||
}
|
}
|
||||||
|
/* Check for conflicts and remove duplicates if necessary */
|
||||||
|
result = checkForConflictsCallbackGpio(gpioConfig.first, callbackGpio, mapToAdd);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
status = result;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return status;
|
}
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::checkForConflictsRegularGpio(gpioId_t gpioIdToCheck,
|
ReturnValue_t LinuxLibgpioIF::checkForConflictsRegularGpio(gpioId_t gpioIdToCheck,
|
||||||
GpiodRegular* gpioToCheck, GpioMap& mapToAdd) {
|
GpiodRegular* gpioToCheck,
|
||||||
/* Cross check with private map */
|
GpioMap& mapToAdd) {
|
||||||
gpioMapIter = gpioMap.find(gpioIdToCheck);
|
/* Cross check with private map */
|
||||||
if(gpioMapIter != gpioMap.end()) {
|
gpioMapIter = gpioMap.find(gpioIdToCheck);
|
||||||
if(gpioMapIter->second->gpioType != gpio::GpioTypes::GPIOD_REGULAR) {
|
if (gpioMapIter != gpioMap.end()) {
|
||||||
sif::warning << "LinuxLibgpioIF::checkForConflicts: ID already exists for different "
|
if (gpioMapIter->second->gpioType != gpio::GpioTypes::GPIOD_REGULAR) {
|
||||||
"GPIO type" << gpioIdToCheck << ". Removing duplicate." << std::endl;
|
sif::warning << "LinuxLibgpioIF::checkForConflicts: ID already exists for different "
|
||||||
mapToAdd.erase(gpioIdToCheck);
|
"GPIO type"
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
<< gpioIdToCheck << ". Removing duplicate." << std::endl;
|
||||||
}
|
mapToAdd.erase(gpioIdToCheck);
|
||||||
auto ownRegularGpio = dynamic_cast<GpiodRegular*>(gpioMapIter->second);
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
if(ownRegularGpio == nullptr) {
|
|
||||||
return GPIO_TYPE_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove element from map to add because a entry for this GPIO
|
|
||||||
already exists */
|
|
||||||
sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition"
|
|
||||||
<< " detected. Duplicate will be removed from map to add." << std::endl;
|
|
||||||
mapToAdd.erase(gpioIdToCheck);
|
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
auto ownRegularGpio = dynamic_cast<GpiodRegular*>(gpioMapIter->second);
|
||||||
|
if (ownRegularGpio == nullptr) {
|
||||||
|
return GPIO_TYPE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove element from map to add because a entry for this GPIO
|
||||||
|
already exists */
|
||||||
|
sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition"
|
||||||
|
<< " detected. Duplicate will be removed from map to add." << std::endl;
|
||||||
|
mapToAdd.erase(gpioIdToCheck);
|
||||||
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LinuxLibgpioIF::checkForConflictsCallbackGpio(gpioId_t gpioIdToCheck,
|
ReturnValue_t LinuxLibgpioIF::checkForConflictsCallbackGpio(gpioId_t gpioIdToCheck,
|
||||||
GpioCallback *callbackGpio, GpioMap& mapToAdd) {
|
GpioCallback* callbackGpio,
|
||||||
/* Cross check with private map */
|
GpioMap& mapToAdd) {
|
||||||
gpioMapIter = gpioMap.find(gpioIdToCheck);
|
/* Cross check with private map */
|
||||||
if(gpioMapIter != gpioMap.end()) {
|
gpioMapIter = gpioMap.find(gpioIdToCheck);
|
||||||
if(gpioMapIter->second->gpioType != gpio::GpioTypes::CALLBACK) {
|
if (gpioMapIter != gpioMap.end()) {
|
||||||
sif::warning << "LinuxLibgpioIF::checkForConflicts: ID already exists for different "
|
if (gpioMapIter->second->gpioType != gpio::GpioTypes::CALLBACK) {
|
||||||
"GPIO type" << gpioIdToCheck << ". Removing duplicate." << std::endl;
|
sif::warning << "LinuxLibgpioIF::checkForConflicts: ID already exists for different "
|
||||||
mapToAdd.erase(gpioIdToCheck);
|
"GPIO type"
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
<< gpioIdToCheck << ". Removing duplicate." << std::endl;
|
||||||
}
|
mapToAdd.erase(gpioIdToCheck);
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
/* Remove element from map to add because a entry for this GPIO
|
|
||||||
already exists */
|
|
||||||
sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition"
|
|
||||||
<< " detected. Duplicate will be removed from map to add." << std::endl;
|
|
||||||
mapToAdd.erase(gpioIdToCheck);
|
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
|
/* Remove element from map to add because a entry for this GPIO
|
||||||
|
already exists */
|
||||||
|
sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition"
|
||||||
|
<< " detected. Duplicate will be removed from map to add." << std::endl;
|
||||||
|
mapToAdd.erase(gpioIdToCheck);
|
||||||
|
}
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#ifndef LINUX_GPIO_LINUXLIBGPIOIF_H_
|
#ifndef LINUX_GPIO_LINUXLIBGPIOIF_H_
|
||||||
#define LINUX_GPIO_LINUXLIBGPIOIF_H_
|
#define LINUX_GPIO_LINUXLIBGPIOIF_H_
|
||||||
|
|
||||||
#include <linux/gpio/GpioIF.h>
|
|
||||||
#include <fsfwconfig/returnvalues/classIds.h>
|
|
||||||
#include <fsfw/objectmanager/SystemObject.h>
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
|
#include <fsfwconfig/returnvalues/classIds.h>
|
||||||
|
#include <linux/gpio/GpioIF.h>
|
||||||
|
|
||||||
class GpioCookie;
|
class GpioCookie;
|
||||||
|
|
||||||
@ -15,63 +15,61 @@ class GpioCookie;
|
|||||||
* 2019.1.
|
* 2019.1.
|
||||||
*/
|
*/
|
||||||
class LinuxLibgpioIF : public GpioIF, public SystemObject {
|
class LinuxLibgpioIF : public GpioIF, public SystemObject {
|
||||||
public:
|
public:
|
||||||
|
static const uint8_t gpioRetvalId = CLASS_ID::LINUX_LIBGPIO_IF;
|
||||||
|
|
||||||
static const uint8_t gpioRetvalId = CLASS_ID::LINUX_LIBGPIO_IF;
|
static constexpr ReturnValue_t UNKNOWN_GPIO_ID =
|
||||||
|
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 1);
|
||||||
|
static constexpr ReturnValue_t DRIVE_GPIO_FAILURE =
|
||||||
|
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 2);
|
||||||
|
static constexpr ReturnValue_t GPIO_TYPE_FAILURE =
|
||||||
|
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 3);
|
||||||
|
static constexpr ReturnValue_t GPIO_INVALID_INSTANCE =
|
||||||
|
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 4);
|
||||||
|
|
||||||
static constexpr ReturnValue_t UNKNOWN_GPIO_ID =
|
LinuxLibgpioIF(object_id_t objectId);
|
||||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 1);
|
virtual ~LinuxLibgpioIF();
|
||||||
static constexpr ReturnValue_t DRIVE_GPIO_FAILURE =
|
|
||||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 2);
|
|
||||||
static constexpr ReturnValue_t GPIO_TYPE_FAILURE =
|
|
||||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 3);
|
|
||||||
static constexpr ReturnValue_t GPIO_INVALID_INSTANCE =
|
|
||||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 4);
|
|
||||||
|
|
||||||
LinuxLibgpioIF(object_id_t objectId);
|
ReturnValue_t addGpios(GpioCookie* gpioCookie) override;
|
||||||
virtual ~LinuxLibgpioIF();
|
ReturnValue_t pullHigh(gpioId_t gpioId) override;
|
||||||
|
ReturnValue_t pullLow(gpioId_t gpioId) override;
|
||||||
|
ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override;
|
||||||
|
|
||||||
ReturnValue_t addGpios(GpioCookie* gpioCookie) override;
|
private:
|
||||||
ReturnValue_t pullHigh(gpioId_t gpioId) override;
|
/* Holds the information and configuration of all used GPIOs */
|
||||||
ReturnValue_t pullLow(gpioId_t gpioId) override;
|
GpioMap gpioMap;
|
||||||
ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override;
|
GpioMapIter gpioMapIter;
|
||||||
|
|
||||||
private:
|
/**
|
||||||
/* Holds the information and configuration of all used GPIOs */
|
* @brief This functions drives line of a GPIO specified by the GPIO ID.
|
||||||
GpioMap gpioMap;
|
*
|
||||||
GpioMapIter gpioMapIter;
|
* @param gpioId The GPIO ID of the GPIO to drive.
|
||||||
|
* @param logiclevel The logic level to set. O or 1.
|
||||||
|
*/
|
||||||
|
ReturnValue_t driveGpio(gpioId_t gpioId, GpiodRegularBase& regularGpio, unsigned int logiclevel);
|
||||||
|
|
||||||
/**
|
ReturnValue_t configureRegularGpio(gpioId_t gpioId, GpiodRegularBase& regularGpio);
|
||||||
* @brief This functions drives line of a GPIO specified by the GPIO ID.
|
|
||||||
*
|
|
||||||
* @param gpioId The GPIO ID of the GPIO to drive.
|
|
||||||
* @param logiclevel The logic level to set. O or 1.
|
|
||||||
*/
|
|
||||||
ReturnValue_t driveGpio(gpioId_t gpioId, GpiodRegularBase& regularGpio, unsigned int logiclevel);
|
|
||||||
|
|
||||||
ReturnValue_t configureRegularGpio(gpioId_t gpioId, GpiodRegularBase& regularGpio);
|
/**
|
||||||
|
* @brief This function checks if GPIOs are already registered and whether
|
||||||
|
* there exists a conflict in the GPIO configuration. E.g. the
|
||||||
|
* direction.
|
||||||
|
*
|
||||||
|
* @param mapToAdd The GPIOs which shall be added to the gpioMap.
|
||||||
|
*
|
||||||
|
* @return RETURN_OK if successful, otherwise RETURN_FAILED
|
||||||
|
*/
|
||||||
|
ReturnValue_t checkForConflicts(GpioMap& mapToAdd);
|
||||||
|
|
||||||
/**
|
ReturnValue_t checkForConflictsRegularGpio(gpioId_t gpiodId, GpiodRegular* regularGpio,
|
||||||
* @brief This function checks if GPIOs are already registered and whether
|
GpioMap& mapToAdd);
|
||||||
* there exists a conflict in the GPIO configuration. E.g. the
|
ReturnValue_t checkForConflictsCallbackGpio(gpioId_t gpiodId, GpioCallback* regularGpio,
|
||||||
* direction.
|
GpioMap& mapToAdd);
|
||||||
*
|
|
||||||
* @param mapToAdd The GPIOs which shall be added to the gpioMap.
|
|
||||||
*
|
|
||||||
* @return RETURN_OK if successful, otherwise RETURN_FAILED
|
|
||||||
*/
|
|
||||||
ReturnValue_t checkForConflicts(GpioMap& mapToAdd);
|
|
||||||
|
|
||||||
ReturnValue_t checkForConflictsRegularGpio(gpioId_t gpiodId, GpiodRegular* regularGpio,
|
|
||||||
GpioMap& mapToAdd);
|
|
||||||
ReturnValue_t checkForConflictsCallbackGpio(gpioId_t gpiodId, GpioCallback* regularGpio,
|
|
||||||
GpioMap& mapToAdd);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Performs the initial configuration of all GPIOs specified in the GpioMap mapToAdd.
|
|
||||||
*/
|
|
||||||
ReturnValue_t configureGpios(GpioMap& mapToAdd);
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Performs the initial configuration of all GPIOs specified in the GpioMap mapToAdd.
|
||||||
|
*/
|
||||||
|
ReturnValue_t configureGpios(GpioMap& mapToAdd);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* LINUX_GPIO_LINUXLIBGPIOIF_H_ */
|
#endif /* LINUX_GPIO_LINUXLIBGPIOIF_H_ */
|
||||||
|
@ -8,29 +8,16 @@ using gpioId_t = uint16_t;
|
|||||||
|
|
||||||
namespace gpio {
|
namespace gpio {
|
||||||
|
|
||||||
enum Levels {
|
enum Levels { LOW = 0, HIGH = 1 };
|
||||||
LOW = 0,
|
|
||||||
HIGH = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Direction {
|
enum Direction { IN = 0, OUT = 1 };
|
||||||
IN = 0,
|
|
||||||
OUT = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
enum GpioOperation {
|
enum GpioOperation { READ, WRITE };
|
||||||
READ,
|
|
||||||
WRITE
|
|
||||||
};
|
|
||||||
|
|
||||||
enum GpioTypes {
|
enum GpioTypes { NONE, GPIOD_REGULAR, CALLBACK };
|
||||||
NONE,
|
|
||||||
GPIOD_REGULAR,
|
|
||||||
CALLBACK
|
|
||||||
};
|
|
||||||
|
|
||||||
static constexpr gpioId_t NO_GPIO = -1;
|
static constexpr gpioId_t NO_GPIO = -1;
|
||||||
}
|
} // namespace gpio
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Struct containing information about the GPIO to use. This is
|
* @brief Struct containing information about the GPIO to use. This is
|
||||||
@ -47,51 +34,49 @@ static constexpr gpioId_t NO_GPIO = -1;
|
|||||||
* pointer.
|
* pointer.
|
||||||
*/
|
*/
|
||||||
class GpioBase {
|
class GpioBase {
|
||||||
public:
|
public:
|
||||||
|
GpioBase() = default;
|
||||||
|
|
||||||
GpioBase() = default;
|
GpioBase(gpio::GpioTypes gpioType, std::string consumer, gpio::Direction direction, int initValue)
|
||||||
|
: gpioType(gpioType), consumer(consumer), direction(direction), initValue(initValue) {}
|
||||||
|
|
||||||
GpioBase(gpio::GpioTypes gpioType, std::string consumer, gpio::Direction direction,
|
virtual ~GpioBase(){};
|
||||||
int initValue):
|
|
||||||
gpioType(gpioType), consumer(consumer),direction(direction), initValue(initValue) {}
|
|
||||||
|
|
||||||
virtual~ GpioBase() {};
|
/* Can be used to cast GpioBase to a concrete child implementation */
|
||||||
|
gpio::GpioTypes gpioType = gpio::GpioTypes::NONE;
|
||||||
/* Can be used to cast GpioBase to a concrete child implementation */
|
std::string consumer;
|
||||||
gpio::GpioTypes gpioType = gpio::GpioTypes::NONE;
|
gpio::Direction direction = gpio::Direction::IN;
|
||||||
std::string consumer;
|
int initValue = 0;
|
||||||
gpio::Direction direction = gpio::Direction::IN;
|
|
||||||
int initValue = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class GpiodRegular: public GpioBase {
|
class GpiodRegular : public GpioBase {
|
||||||
public:
|
public:
|
||||||
GpiodRegular(): GpioBase(gpio::GpioTypes::GPIOD_REGULAR, std::string(),
|
GpiodRegular()
|
||||||
gpio::Direction::IN, 0) {};
|
: GpioBase(gpio::GpioTypes::GPIOD_REGULAR, std::string(), gpio::Direction::IN, 0){};
|
||||||
|
|
||||||
GpiodRegular(std::string chipname_, int lineNum_, std::string consumer_,
|
GpiodRegular(std::string chipname_, int lineNum_, std::string consumer_,
|
||||||
gpio::Direction direction_, int initValue_):
|
gpio::Direction direction_, int initValue_)
|
||||||
GpioBase(gpio::GpioTypes::GPIOD_REGULAR, consumer_, direction_, initValue_),
|
: GpioBase(gpio::GpioTypes::GPIOD_REGULAR, consumer_, direction_, initValue_),
|
||||||
chipname(chipname_), lineNum(lineNum_) {}
|
chipname(chipname_),
|
||||||
std::string chipname;
|
lineNum(lineNum_) {}
|
||||||
int lineNum = 0;
|
std::string chipname;
|
||||||
struct gpiod_line* lineHandle = nullptr;
|
int lineNum = 0;
|
||||||
|
struct gpiod_line* lineHandle = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GpioCallback: public GpioBase {
|
class GpioCallback : public GpioBase {
|
||||||
public:
|
public:
|
||||||
GpioCallback(std::string consumer, gpio::Direction direction_, int initValue_,
|
GpioCallback(std::string consumer, gpio::Direction direction_, int initValue_,
|
||||||
void (* callback) (gpioId_t gpioId, gpio::GpioOperation gpioOp, int value, void* args),
|
void (*callback)(gpioId_t gpioId, gpio::GpioOperation gpioOp, int value, void* args),
|
||||||
void* callbackArgs):
|
void* callbackArgs)
|
||||||
GpioBase(gpio::GpioTypes::CALLBACK, consumer, direction_, initValue_),
|
: GpioBase(gpio::GpioTypes::CALLBACK, consumer, direction_, initValue_),
|
||||||
callback(callback), callbackArgs(callbackArgs) {}
|
callback(callback),
|
||||||
|
callbackArgs(callbackArgs) {}
|
||||||
|
|
||||||
void (* callback) (gpioId_t gpioId, gpio::GpioOperation gpioOp,
|
void (*callback)(gpioId_t gpioId, gpio::GpioOperation gpioOp, int value, void* args) = nullptr;
|
||||||
int value, void* args) = nullptr;
|
void* callbackArgs = nullptr;
|
||||||
void* callbackArgs = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
using GpioMap = std::unordered_map<gpioId_t, GpioBase*>;
|
using GpioMap = std::unordered_map<gpioId_t, GpioBase*>;
|
||||||
using GpioMapIter = GpioMap::iterator;
|
using GpioMapIter = GpioMap::iterator;
|
||||||
|
|
||||||
|
@ -1,136 +1,128 @@
|
|||||||
#include <sys/mman.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include <linux/obc/Ptme.h>
|
#include <linux/obc/Ptme.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
CCSDSIPCoreBridge::CCSDSIPCoreBridge(object_id_t objectId, object_id_t tcDestination,
|
CCSDSIPCoreBridge::CCSDSIPCoreBridge(object_id_t objectId, object_id_t tcDestination,
|
||||||
object_id_t tmStoreId, object_id_t tcStoreId, LinuxLibgpioIF* gpioComIF,
|
object_id_t tmStoreId, object_id_t tcStoreId,
|
||||||
std::string uioPtme, gpioId_t papbBusyId, gpioId_t papbEmptyId) :
|
LinuxLibgpioIF* gpioComIF, std::string uioPtme,
|
||||||
TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId), gpioComIF(gpioComIF), uioPtme(
|
gpioId_t papbBusyId, gpioId_t papbEmptyId)
|
||||||
uioPtme), papbBusyId(papbBusyId), papbEmptyId(papbEmptyId) {
|
: TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId),
|
||||||
}
|
gpioComIF(gpioComIF),
|
||||||
|
uioPtme(uioPtme),
|
||||||
|
papbBusyId(papbBusyId),
|
||||||
|
papbEmptyId(papbEmptyId) {}
|
||||||
|
|
||||||
CCSDSIPCoreBridge::~CCSDSIPCoreBridge() {
|
CCSDSIPCoreBridge::~CCSDSIPCoreBridge() {}
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t CCSDSIPCoreBridge::initialize() {
|
ReturnValue_t CCSDSIPCoreBridge::initialize() {
|
||||||
ReturnValue_t result = TmTcBridge::initialize();
|
ReturnValue_t result = TmTcBridge::initialize();
|
||||||
|
|
||||||
fd = open("/dev/uio0", O_RDWR);
|
fd = open("/dev/uio0", O_RDWR);
|
||||||
if (fd < 1) {
|
if (fd < 1) {
|
||||||
sif::debug << "CCSDSIPCoreBridge::initialize: Invalid UIO device file" << std::endl;
|
sif::debug << "CCSDSIPCoreBridge::initialize: Invalid UIO device file" << std::endl;
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map uio device in virtual address space
|
* Map uio device in virtual address space
|
||||||
* PROT_WRITE: Map uio device in writable only mode
|
* PROT_WRITE: Map uio device in writable only mode
|
||||||
*/
|
*/
|
||||||
ptmeBaseAddress = static_cast<uint32_t*>(mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE,
|
ptmeBaseAddress =
|
||||||
MAP_SHARED, fd, 0));
|
static_cast<uint32_t*>(mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
|
||||||
|
|
||||||
if (ptmeBaseAddress == MAP_FAILED) {
|
if (ptmeBaseAddress == MAP_FAILED) {
|
||||||
sif::error << "CCSDSIPCoreBridge::initialize: Failed to map uio address" << std::endl;
|
sif::error << "CCSDSIPCoreBridge::initialize: Failed to map uio address" << std::endl;
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CCSDSIPCoreBridge::handleTm() {
|
ReturnValue_t CCSDSIPCoreBridge::handleTm() {
|
||||||
|
|
||||||
#if OBSW_TEST_CCSDS_PTME == 1
|
#if OBSW_TEST_CCSDS_PTME == 1
|
||||||
return sendTestFrame();
|
return sendTestFrame();
|
||||||
#else
|
#else
|
||||||
return TmTcBridge::handleTm();
|
return TmTcBridge::handleTm();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CCSDSIPCoreBridge::sendTm(const uint8_t * data, size_t dataLen) {
|
ReturnValue_t CCSDSIPCoreBridge::sendTm(const uint8_t* data, size_t dataLen) {
|
||||||
|
if (pollPapbBusySignal() == RETURN_OK) {
|
||||||
|
startPacketTransfer();
|
||||||
|
}
|
||||||
|
|
||||||
if(pollPapbBusySignal() == RETURN_OK) {
|
for (size_t idx = 0; idx < dataLen; idx++) {
|
||||||
startPacketTransfer();
|
if (pollPapbBusySignal() == RETURN_OK) {
|
||||||
|
*(ptmeBaseAddress + PTME_DATA_REG_OFFSET) = static_cast<uint32_t>(*(data + idx));
|
||||||
|
} else {
|
||||||
|
sif::debug << "CCSDSIPCoreBridge::sendTm: Only written " << idx - 1 << " of " << dataLen
|
||||||
|
<< " data" << std::endl;
|
||||||
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(size_t idx = 0; idx < dataLen; idx++) {
|
if (pollPapbBusySignal() == RETURN_OK) {
|
||||||
if(pollPapbBusySignal() == RETURN_OK) {
|
endPacketTransfer();
|
||||||
*(ptmeBaseAddress + PTME_DATA_REG_OFFSET) = static_cast<uint32_t>(*(data + idx));
|
}
|
||||||
}
|
return RETURN_OK;
|
||||||
else {
|
|
||||||
sif::debug << "CCSDSIPCoreBridge::sendTm: Only written " << idx - 1 << " of " << dataLen
|
|
||||||
<< " data" << std::endl;
|
|
||||||
return RETURN_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pollPapbBusySignal() == RETURN_OK) {
|
|
||||||
endPacketTransfer();
|
|
||||||
}
|
|
||||||
return RETURN_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCSDSIPCoreBridge::startPacketTransfer() {
|
void CCSDSIPCoreBridge::startPacketTransfer() { *ptmeBaseAddress = PTME_CONFIG_START; }
|
||||||
*ptmeBaseAddress = PTME_CONFIG_START;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CCSDSIPCoreBridge::endPacketTransfer() {
|
void CCSDSIPCoreBridge::endPacketTransfer() { *ptmeBaseAddress = PTME_CONFIG_END; }
|
||||||
*ptmeBaseAddress = PTME_CONFIG_END;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t CCSDSIPCoreBridge::pollPapbBusySignal() {
|
ReturnValue_t CCSDSIPCoreBridge::pollPapbBusySignal() {
|
||||||
int papbBusyState = 0;
|
int papbBusyState = 0;
|
||||||
ReturnValue_t result = RETURN_OK;
|
ReturnValue_t result = RETURN_OK;
|
||||||
|
|
||||||
/** Check if PAPB interface is ready to receive data */
|
/** Check if PAPB interface is ready to receive data */
|
||||||
result = gpioComIF->readGpio(papbBusyId, &papbBusyState);
|
result = gpioComIF->readGpio(papbBusyId, &papbBusyState);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
sif::debug << "CCSDSIPCoreBridge::pollPapbBusySignal: Failed to read papb busy signal"
|
sif::debug << "CCSDSIPCoreBridge::pollPapbBusySignal: Failed to read papb busy signal"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return RETURN_FAILED;
|
return RETURN_FAILED;
|
||||||
}
|
}
|
||||||
if (!papbBusyState) {
|
if (!papbBusyState) {
|
||||||
sif::debug << "CCSDSIPCoreBridge::pollPapbBusySignal: PAPB busy" << std::endl;
|
sif::debug << "CCSDSIPCoreBridge::pollPapbBusySignal: PAPB busy" << std::endl;
|
||||||
return PAPB_BUSY;
|
return PAPB_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCSDSIPCoreBridge::isPtmeBufferEmpty() {
|
void CCSDSIPCoreBridge::isPtmeBufferEmpty() {
|
||||||
ReturnValue_t result = RETURN_OK;
|
ReturnValue_t result = RETURN_OK;
|
||||||
int papbEmptyState = 1;
|
int papbEmptyState = 1;
|
||||||
|
|
||||||
result = gpioComIF->readGpio(papbEmptyId, &papbEmptyState);
|
result = gpioComIF->readGpio(papbEmptyId, &papbEmptyState);
|
||||||
|
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
sif::debug << "CCSDSIPCoreBridge::isPtmeBufferEmpty: Failed to read papb empty signal"
|
sif::debug << "CCSDSIPCoreBridge::isPtmeBufferEmpty: Failed to read papb empty signal"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (papbEmptyState == 1) {
|
|
||||||
sif::debug << "CCSDSIPCoreBridge::isPtmeBufferEmpty: Buffer is empty" << std::endl;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sif::debug << "CCSDSIPCoreBridge::isPtmeBufferEmpty: Buffer is not empty" << std::endl;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (papbEmptyState == 1) {
|
||||||
|
sif::debug << "CCSDSIPCoreBridge::isPtmeBufferEmpty: Buffer is empty" << std::endl;
|
||||||
|
} else {
|
||||||
|
sif::debug << "CCSDSIPCoreBridge::isPtmeBufferEmpty: Buffer is not empty" << std::endl;
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CCSDSIPCoreBridge::sendTestFrame() {
|
ReturnValue_t CCSDSIPCoreBridge::sendTestFrame() {
|
||||||
/** Size of one complete transfer frame data field amounts to 1105 bytes */
|
/** Size of one complete transfer frame data field amounts to 1105 bytes */
|
||||||
uint8_t testPacket[1105];
|
uint8_t testPacket[1105];
|
||||||
|
|
||||||
/** Fill one test packet */
|
/** Fill one test packet */
|
||||||
for(int idx = 0; idx < 1105; idx++) {
|
for (int idx = 0; idx < 1105; idx++) {
|
||||||
testPacket[idx] = static_cast<uint8_t>(idx & 0xFF);
|
testPacket[idx] = static_cast<uint8_t>(idx & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t result = sendTm(testPacket, 1105);
|
ReturnValue_t result = sendTm(testPacket, 1105);
|
||||||
if(result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
@ -1,131 +1,129 @@
|
|||||||
#ifndef MISSION_OBC_CCSDSIPCOREBRIDGE_H_
|
#ifndef MISSION_OBC_CCSDSIPCOREBRIDGE_H_
|
||||||
#define MISSION_OBC_CCSDSIPCOREBRIDGE_H_
|
#define MISSION_OBC_CCSDSIPCOREBRIDGE_H_
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
|
||||||
#include <fsfw/tmtcservices/TmTcBridge.h>
|
#include <fsfw/tmtcservices/TmTcBridge.h>
|
||||||
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
|
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
|
||||||
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
|
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "OBSWConfig.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This class handles the interfacing to the telemetry (PTME) and telecommand (PDEC) IP
|
* @brief This class handles the interfacing to the telemetry (PTME) and telecommand (PDEC) IP
|
||||||
* cores responsible for the CCSDS encoding and decoding. The IP cores are implemented
|
* cores responsible for the CCSDS encoding and decoding. The IP cores are implemented
|
||||||
* on the programmable logic and are accessible through the linux UIO driver.
|
* on the programmable logic and are accessible through the linux UIO driver.
|
||||||
*/
|
*/
|
||||||
class CCSDSIPCoreBridge: public TmTcBridge {
|
class CCSDSIPCoreBridge : public TmTcBridge {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Constructor
|
* @brief Constructor
|
||||||
*
|
*
|
||||||
* @param objectId
|
* @param objectId
|
||||||
* @param tcDestination
|
* @param tcDestination
|
||||||
* @param tmStoreId
|
* @param tmStoreId
|
||||||
* @param tcStoreId
|
* @param tcStoreId
|
||||||
* @param uioPtme Name of the uio device file which provides access to the PTME IP Core.
|
* @param uioPtme Name of the uio device file which provides access to the PTME IP Core.
|
||||||
* @param papbBusyId The ID of the GPIO which is connected to the PAPBBusy_N signal of the
|
* @param papbBusyId The ID of the GPIO which is connected to the PAPBBusy_N signal of the
|
||||||
* PTME IP Core. A low logic level indicates the PTME is not ready to
|
* PTME IP Core. A low logic level indicates the PTME is not ready to
|
||||||
* receive more data.
|
* receive more data.
|
||||||
* @param papbEmptyId The ID of the GPIO which is connected to the PAPBEmpty signal of the
|
* @param papbEmptyId The ID of the GPIO which is connected to the PAPBEmpty signal of the
|
||||||
* PTME IP Core. The signal is high when there are no packets in the
|
* PTME IP Core. The signal is high when there are no packets in the
|
||||||
* external buffer memory (BRAM).
|
* external buffer memory (BRAM).
|
||||||
*/
|
*/
|
||||||
CCSDSIPCoreBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId,
|
CCSDSIPCoreBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId,
|
||||||
object_id_t tcStoreId, LinuxLibgpioIF* gpioComIF, std::string uioPtme,
|
object_id_t tcStoreId, LinuxLibgpioIF* gpioComIF, std::string uioPtme,
|
||||||
gpioId_t papbBusyId, gpioId_t papbEmptyId);
|
gpioId_t papbBusyId, gpioId_t papbEmptyId);
|
||||||
virtual ~CCSDSIPCoreBridge();
|
virtual ~CCSDSIPCoreBridge();
|
||||||
|
|
||||||
ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/**
|
||||||
|
* Overwriting this function to provide the capability of testing the PTME IP Core
|
||||||
|
* implementation.
|
||||||
|
*/
|
||||||
|
virtual ReturnValue_t handleTm() override;
|
||||||
|
|
||||||
/**
|
virtual ReturnValue_t sendTm(const uint8_t* data, size_t dataLen) override;
|
||||||
* Overwriting this function to provide the capability of testing the PTME IP Core
|
|
||||||
* implementation.
|
|
||||||
*/
|
|
||||||
virtual ReturnValue_t handleTm() override;
|
|
||||||
|
|
||||||
virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override;
|
private:
|
||||||
|
static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_IP_CORE_BRIDGE;
|
||||||
|
|
||||||
private:
|
static const ReturnValue_t PAPB_BUSY = MAKE_RETURN_CODE(0xA0);
|
||||||
|
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_IP_CORE_BRIDGE;
|
/** Size of mapped address space. 4k (minimal size of pl device) */
|
||||||
|
// static const int MAP_SIZE = 0xFA0;
|
||||||
|
static const int MAP_SIZE = 0x1000;
|
||||||
|
|
||||||
static const ReturnValue_t PAPB_BUSY = MAKE_RETURN_CODE(0xA0);
|
/**
|
||||||
|
* Configuration bits:
|
||||||
|
* bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00
|
||||||
|
* bit[2]: Set this bit to 1 to abort a transfered packet
|
||||||
|
* bit[3]: Signals to PTME the start of a new telemetry packet
|
||||||
|
*/
|
||||||
|
static const uint32_t PTME_CONFIG_START = 0x8;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writing this word to the ptme base address signals to the PTME that a complete tm packet has
|
||||||
|
* been transferred.
|
||||||
|
*/
|
||||||
|
static const uint32_t PTME_CONFIG_END = 0x0;
|
||||||
|
|
||||||
/** Size of mapped address space. 4k (minimal size of pl device) */
|
/**
|
||||||
// static const int MAP_SIZE = 0xFA0;
|
* Writing to this offset within the PTME memory space will insert data for encoding to the
|
||||||
static const int MAP_SIZE = 0x1000;
|
* PTME IP core.
|
||||||
|
* The address offset is 0x400 (= 4 * 256)
|
||||||
|
*/
|
||||||
|
static const int PTME_DATA_REG_OFFSET = 256;
|
||||||
|
|
||||||
/**
|
LinuxLibgpioIF* gpioComIF = nullptr;
|
||||||
* Configuration bits:
|
|
||||||
* bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00
|
|
||||||
* bit[2]: Set this bit to 1 to abort a transfered packet
|
|
||||||
* bit[3]: Signals to PTME the start of a new telemetry packet
|
|
||||||
*/
|
|
||||||
static const uint32_t PTME_CONFIG_START = 0x8;
|
|
||||||
|
|
||||||
/**
|
/** The uio device file related to the PTME IP Core */
|
||||||
* Writing this word to the ptme base address signals to the PTME that a complete tm packet has
|
std::string uioPtme;
|
||||||
* been transferred.
|
|
||||||
*/
|
|
||||||
static const uint32_t PTME_CONFIG_END = 0x0;
|
|
||||||
|
|
||||||
/**
|
/** Pulled to low when PTME not ready to receive data */
|
||||||
* Writing to this offset within the PTME memory space will insert data for encoding to the
|
gpioId_t papbBusyId = gpio::NO_GPIO;
|
||||||
* PTME IP core.
|
|
||||||
* The address offset is 0x400 (= 4 * 256)
|
|
||||||
*/
|
|
||||||
static const int PTME_DATA_REG_OFFSET = 256;
|
|
||||||
|
|
||||||
LinuxLibgpioIF* gpioComIF = nullptr;
|
/** High when externally buffer memory of PTME is empty */
|
||||||
|
gpioId_t papbEmptyId = gpio::NO_GPIO;
|
||||||
|
|
||||||
/** The uio device file related to the PTME IP Core */
|
/** The file descriptor of the UIO driver */
|
||||||
std::string uioPtme;
|
int fd;
|
||||||
|
|
||||||
/** Pulled to low when PTME not ready to receive data */
|
uint32_t* ptmeBaseAddress = nullptr;
|
||||||
gpioId_t papbBusyId = gpio::NO_GPIO;
|
|
||||||
|
|
||||||
/** High when externally buffer memory of PTME is empty */
|
/**
|
||||||
gpioId_t papbEmptyId = gpio::NO_GPIO;
|
* @brief This function sends the config byte to the PTME IP Core to initiate a packet
|
||||||
|
* transfer.
|
||||||
|
*/
|
||||||
|
void startPacketTransfer();
|
||||||
|
|
||||||
/** The file descriptor of the UIO driver */
|
/**
|
||||||
int fd;
|
* @brief This function sends the config byte to the PTME IP Core to signal the end of a
|
||||||
|
* packet transfer.
|
||||||
|
*/
|
||||||
|
void endPacketTransfer();
|
||||||
|
|
||||||
uint32_t* ptmeBaseAddress = nullptr;
|
/**
|
||||||
|
* @brief This function reads the papb busy signal indicating whether the PAPB interface is
|
||||||
|
* ready to receive more data or not. PAPB is ready when PAPB_Busy_N == '1'.
|
||||||
|
*
|
||||||
|
* @return RETURN_OK when ready to receive data else PAPB_BUSY.
|
||||||
|
*/
|
||||||
|
ReturnValue_t pollPapbBusySignal();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function sends the config byte to the PTME IP Core to initiate a packet
|
* @brief This function can be used for debugging to check wheter there are packets in
|
||||||
* transfer.
|
* the packet buffer of the PTME or not.
|
||||||
*/
|
*/
|
||||||
void startPacketTransfer();
|
void isPtmeBufferEmpty();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function sends the config byte to the PTME IP Core to signal the end of a
|
* @brief This function sends a complete telemetry transfer frame data field (1105 bytes)
|
||||||
* packet transfer.
|
* to the input of the PTME IP Core. Can be used to test the implementation.
|
||||||
*/
|
*/
|
||||||
void endPacketTransfer();
|
ReturnValue_t sendTestFrame();
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This function reads the papb busy signal indicating whether the PAPB interface is
|
|
||||||
* ready to receive more data or not. PAPB is ready when PAPB_Busy_N == '1'.
|
|
||||||
*
|
|
||||||
* @return RETURN_OK when ready to receive data else PAPB_BUSY.
|
|
||||||
*/
|
|
||||||
ReturnValue_t pollPapbBusySignal();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This function can be used for debugging to check wheter there are packets in
|
|
||||||
* the packet buffer of the PTME or not.
|
|
||||||
*/
|
|
||||||
void isPtmeBufferEmpty();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This function sends a complete telemetry transfer frame data field (1105 bytes)
|
|
||||||
* to the input of the PTME IP Core. Can be used to test the implementation.
|
|
||||||
*/
|
|
||||||
ReturnValue_t sendTestFrame();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_OBC_CCSDSIPCOREBRIDGE_H_ */
|
#endif /* MISSION_OBC_CCSDSIPCOREBRIDGE_H_ */
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
#include <linux/boardtest/I2cTestClass.h>
|
#include <linux/boardtest/I2cTestClass.h>
|
||||||
|
|
||||||
I2cTestClass::I2cTestClass(object_id_t objectId): TestTask(objectId) {
|
I2cTestClass::I2cTestClass(object_id_t objectId) : TestTask(objectId) {}
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t I2cTestClass::performPeriodicAction() {
|
ReturnValue_t I2cTestClass::performPeriodicAction() { return HasReturnvaluesIF::RETURN_OK; }
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
|
||||||
|
@ -3,15 +3,13 @@
|
|||||||
|
|
||||||
#include <test/testtasks/TestTask.h>
|
#include <test/testtasks/TestTask.h>
|
||||||
|
|
||||||
class I2cTestClass: public TestTask {
|
class I2cTestClass : public TestTask {
|
||||||
public:
|
public:
|
||||||
I2cTestClass(object_id_t objectId);
|
I2cTestClass(object_id_t objectId);
|
||||||
|
|
||||||
ReturnValue_t performPeriodicAction() override;
|
ReturnValue_t performPeriodicAction() override;
|
||||||
private:
|
|
||||||
|
|
||||||
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* LINUX_BOARDTEST_I2CTESTCLASS_H_ */
|
#endif /* LINUX_BOARDTEST_I2CTESTCLASS_H_ */
|
||||||
|
@ -1,135 +1,127 @@
|
|||||||
#include "LibgpiodTest.h"
|
#include "LibgpiodTest.h"
|
||||||
|
|
||||||
|
#include <fsfw/objectmanager/ObjectManager.h>
|
||||||
|
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||||
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
|
|
||||||
#include "devices/gpioIds.h"
|
#include "devices/gpioIds.h"
|
||||||
|
|
||||||
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
LibgpiodTest::LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, GpioCookie* gpioCookie)
|
||||||
#include <fsfw/objectmanager/ObjectManager.h>
|
: TestTask(objectId) {
|
||||||
#include <fsfw/tasks/TaskFactory.h>
|
gpioInterface = ObjectManager::instance()->get<GpioIF>(gpioIfobjectId);
|
||||||
|
if (gpioInterface == nullptr) {
|
||||||
LibgpiodTest::LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId,
|
sif::error << "LibgpiodTest::LibgpiodTest: Invalid Gpio interface." << std::endl;
|
||||||
GpioCookie* gpioCookie):
|
}
|
||||||
TestTask(objectId) {
|
gpioInterface->addGpios(gpioCookie);
|
||||||
|
testCase = TestCases::BLINK;
|
||||||
gpioInterface = ObjectManager::instance()->get<GpioIF>(gpioIfobjectId);
|
|
||||||
if (gpioInterface == nullptr) {
|
|
||||||
sif::error << "LibgpiodTest::LibgpiodTest: Invalid Gpio interface." << std::endl;
|
|
||||||
}
|
|
||||||
gpioInterface->addGpios(gpioCookie);
|
|
||||||
testCase = TestCases::BLINK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LibgpiodTest::~LibgpiodTest() {
|
LibgpiodTest::~LibgpiodTest() {}
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LibgpiodTest::performPeriodicAction() {
|
ReturnValue_t LibgpiodTest::performPeriodicAction() {
|
||||||
int gpioState;
|
int gpioState;
|
||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
|
|
||||||
switch(testCase) {
|
switch (testCase) {
|
||||||
case(TestCases::READ): {
|
case (TestCases::READ): {
|
||||||
result = gpioInterface->readGpio(gpioIds::TEST_ID_0, &gpioState);
|
result = gpioInterface->readGpio(gpioIds::TEST_ID_0, &gpioState);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
sif::warning << "LibgpiodTest::performPeriodicAction: Failed to read gpio "
|
sif::warning << "LibgpiodTest::performPeriodicAction: Failed to read gpio " << std::endl;
|
||||||
<< std::endl;
|
return RETURN_FAILED;
|
||||||
return RETURN_FAILED;
|
} else {
|
||||||
}
|
sif::debug << "LibgpiodTest::performPeriodicAction: MIO 0 state = " << gpioState
|
||||||
else {
|
<< std::endl;
|
||||||
sif::debug << "LibgpiodTest::performPeriodicAction: MIO 0 state = " << gpioState
|
}
|
||||||
<< std::endl;
|
break;
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case(TestCases::LOOPBACK): {
|
case (TestCases::LOOPBACK): {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(TestCases::BLINK): {
|
case (TestCases::BLINK): {
|
||||||
result = gpioInterface->readGpio(gpioIds::TEST_ID_0, &gpioState);
|
result = gpioInterface->readGpio(gpioIds::TEST_ID_0, &gpioState);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
sif::warning << "LibgpiodTest::performPeriodicAction: Failed to read gpio " << std::endl;
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
if (gpioState == 1) {
|
||||||
|
result = gpioInterface->pullLow(gpioIds::TEST_ID_0);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::warning << "LibgpiodTest::performPeriodicAction: Failed to read gpio "
|
sif::warning << "LibgpiodTest::performPeriodicAction: Could not pull GPIO low!"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
if (gpioState == 1) {
|
} else if (gpioState == 0) {
|
||||||
result = gpioInterface->pullLow(gpioIds::TEST_ID_0);
|
result = gpioInterface->pullHigh(gpioIds::TEST_ID_0);
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::warning << "LibgpiodTest::performPeriodicAction: Could not pull GPIO low!"
|
sif::warning << "LibgpiodTest::performPeriodicAction: Could not pull GPIO high!"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (gpioState == 0) {
|
|
||||||
result = gpioInterface->pullHigh(gpioIds::TEST_ID_0);
|
|
||||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
sif::warning << "LibgpiodTest::performPeriodicAction: Could not pull GPIO high!"
|
|
||||||
<< std::endl;
|
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sif::warning << "LibgpiodTest::performPeriodicAction: Invalid GPIO state" << std::endl;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
sif::warning << "LibgpiodTest::performPeriodicAction: Invalid GPIO state" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
sif::debug << "LibgpiodTest::performPeriodicAction: Invalid test case" << std::endl;
|
sif::debug << "LibgpiodTest::performPeriodicAction: Invalid test case" << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return RETURN_OK;
|
||||||
return RETURN_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LibgpiodTest::performOneShotAction() {
|
ReturnValue_t LibgpiodTest::performOneShotAction() {
|
||||||
int gpioState;
|
int gpioState;
|
||||||
ReturnValue_t result;
|
ReturnValue_t result;
|
||||||
|
|
||||||
switch(testCase) {
|
switch (testCase) {
|
||||||
case(TestCases::READ): {
|
case (TestCases::READ): {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(TestCases::BLINK): {
|
case (TestCases::BLINK): {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(TestCases::LOOPBACK): {
|
case (TestCases::LOOPBACK): {
|
||||||
result = gpioInterface->pullHigh(gpioIds::TEST_ID_0);
|
result = gpioInterface->pullHigh(gpioIds::TEST_ID_0);
|
||||||
if(result == HasReturnvaluesIF::RETURN_OK) {
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::info << "LibgpiodTest::performOneShotAction: "
|
sif::info << "LibgpiodTest::performOneShotAction: "
|
||||||
"GPIO pulled high successfully for loopback test" << std::endl;
|
"GPIO pulled high successfully for loopback test"
|
||||||
}
|
<< std::endl;
|
||||||
else {
|
} else {
|
||||||
sif::warning << "LibgpiodTest::performOneShotAction: Could not pull GPIO high!"
|
sif::warning << "LibgpiodTest::performOneShotAction: Could not pull GPIO high!"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
result = gpioInterface->readGpio(gpioIds::TEST_ID_1, &gpioState);
|
result = gpioInterface->readGpio(gpioIds::TEST_ID_1, &gpioState);
|
||||||
if(result == HasReturnvaluesIF::RETURN_OK and gpioState == 1) {
|
if (result == HasReturnvaluesIF::RETURN_OK and gpioState == 1) {
|
||||||
sif::info << "LibgpiodTest::performOneShotAction: "
|
sif::info << "LibgpiodTest::performOneShotAction: "
|
||||||
"GPIO state read successfully and is high" << std::endl;
|
"GPIO state read successfully and is high"
|
||||||
}
|
<< std::endl;
|
||||||
else {
|
} else {
|
||||||
sif::warning << "LibgpiodTest::performOneShotAction: GPIO read and is not high!"
|
sif::warning << "LibgpiodTest::performOneShotAction: GPIO read and is not high!"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = gpioInterface->pullLow(gpioIds::TEST_ID_0);
|
result = gpioInterface->pullLow(gpioIds::TEST_ID_0);
|
||||||
if(result == HasReturnvaluesIF::RETURN_OK) {
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
sif::info << "LibgpiodTest::performOneShotAction: "
|
sif::info << "LibgpiodTest::performOneShotAction: "
|
||||||
"GPIO pulled low successfully for loopback test" << std::endl;
|
"GPIO pulled low successfully for loopback test"
|
||||||
}
|
<< std::endl;
|
||||||
result = gpioInterface->readGpio(gpioIds::TEST_ID_1, &gpioState);
|
}
|
||||||
if(result == HasReturnvaluesIF::RETURN_OK and gpioState == 0) {
|
result = gpioInterface->readGpio(gpioIds::TEST_ID_1, &gpioState);
|
||||||
sif::info << "LibgpiodTest::performOneShotAction: "
|
if (result == HasReturnvaluesIF::RETURN_OK and gpioState == 0) {
|
||||||
"GPIO state read successfully and is low" << std::endl;
|
sif::info << "LibgpiodTest::performOneShotAction: "
|
||||||
}
|
"GPIO state read successfully and is low"
|
||||||
else {
|
<< std::endl;
|
||||||
sif::warning << "LibgpiodTest::performOneShotAction: GPIO read and is not low!"
|
} else {
|
||||||
<< std::endl;
|
sif::warning << "LibgpiodTest::performOneShotAction: GPIO read and is not low!"
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
<< std::endl;
|
||||||
}
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
break;
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
@ -1,34 +1,31 @@
|
|||||||
#ifndef TEST_TESTTASKS_LIBGPIODTEST_H_
|
#ifndef TEST_TESTTASKS_LIBGPIODTEST_H_
|
||||||
#define TEST_TESTTASKS_LIBGPIODTEST_H_
|
#define TEST_TESTTASKS_LIBGPIODTEST_H_
|
||||||
|
|
||||||
#include "TestTask.h"
|
|
||||||
#include <fsfw_hal/common/gpio/GpioIF.h>
|
|
||||||
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
|
||||||
#include <fsfw/objectmanager/SystemObject.h>
|
#include <fsfw/objectmanager/SystemObject.h>
|
||||||
|
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
||||||
|
#include <fsfw_hal/common/gpio/GpioIF.h>
|
||||||
|
|
||||||
|
#include "TestTask.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Test for the GPIO read implementation of the LinuxLibgpioIF.
|
* @brief Test for the GPIO read implementation of the LinuxLibgpioIF.
|
||||||
* @author J. Meier
|
* @author J. Meier
|
||||||
*/
|
*/
|
||||||
class LibgpiodTest: public TestTask {
|
class LibgpiodTest : public TestTask {
|
||||||
public:
|
public:
|
||||||
enum TestCases {
|
enum TestCases { READ = 0, LOOPBACK = 1, BLINK };
|
||||||
READ = 0,
|
|
||||||
LOOPBACK = 1,
|
|
||||||
BLINK
|
|
||||||
};
|
|
||||||
|
|
||||||
TestCases testCase;
|
TestCases testCase;
|
||||||
|
|
||||||
LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, GpioCookie* gpioCookie);
|
LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, GpioCookie* gpioCookie);
|
||||||
virtual ~LibgpiodTest();
|
virtual ~LibgpiodTest();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ReturnValue_t performOneShotAction() override;
|
ReturnValue_t performOneShotAction() override;
|
||||||
ReturnValue_t performPeriodicAction() override;
|
ReturnValue_t performPeriodicAction() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GpioIF* gpioInterface;
|
GpioIF* gpioInterface;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* TEST_TESTTASKS_LIBGPIODTEST_H_ */
|
#endif /* TEST_TESTTASKS_LIBGPIODTEST_H_ */
|
||||||
|
@ -1,503 +1,483 @@
|
|||||||
#include "SpiTestClass.h"
|
#include "SpiTestClass.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <fsfw/globalfunctions/arrayprinter.h>
|
||||||
|
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||||
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
|
#include <fsfw/timemanager/Stopwatch.h>
|
||||||
|
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
||||||
|
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
|
||||||
|
#include <fsfw_hal/linux/UnixFileGuard.h>
|
||||||
|
#include <fsfw_hal/linux/utility.h>
|
||||||
|
#include <linux/spi/spidev.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
#include "devices/gpioIds.h"
|
#include "devices/gpioIds.h"
|
||||||
|
|
||||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
SpiTestClass::SpiTestClass(object_id_t objectId, GpioIF *gpioIF)
|
||||||
#include <fsfw/globalfunctions/arrayprinter.h>
|
: TestTask(objectId), gpioIF(gpioIF) {
|
||||||
#include <fsfw/tasks/TaskFactory.h>
|
if (gpioIF == nullptr) {
|
||||||
#include <fsfw/timemanager/Stopwatch.h>
|
sif::error << "SpiTestClass::SpiTestClass: Invalid GPIO ComIF!" << std::endl;
|
||||||
|
}
|
||||||
#include <fsfw_hal/linux/utility.h>
|
testMode = TestModes::MGM_LIS3MDL;
|
||||||
#include <fsfw_hal/linux/UnixFileGuard.h>
|
spiTransferStruct.rx_buf = reinterpret_cast<__u64>(recvBuffer.data());
|
||||||
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
|
spiTransferStruct.tx_buf = reinterpret_cast<__u64>(sendBuffer.data());
|
||||||
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
|
||||||
|
|
||||||
#include <linux/spi/spidev.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <bitset>
|
|
||||||
|
|
||||||
SpiTestClass::SpiTestClass(object_id_t objectId, GpioIF* gpioIF): TestTask(objectId),
|
|
||||||
gpioIF(gpioIF) {
|
|
||||||
if(gpioIF == nullptr) {
|
|
||||||
sif::error << "SpiTestClass::SpiTestClass: Invalid GPIO ComIF!" << std::endl;
|
|
||||||
}
|
|
||||||
testMode = TestModes::MGM_LIS3MDL;
|
|
||||||
spiTransferStruct.rx_buf = reinterpret_cast<__u64>(recvBuffer.data());
|
|
||||||
spiTransferStruct.tx_buf = reinterpret_cast<__u64>(sendBuffer.data());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SpiTestClass::performOneShotAction() {
|
ReturnValue_t SpiTestClass::performOneShotAction() {
|
||||||
switch(testMode) {
|
switch (testMode) {
|
||||||
case(TestModes::NONE): {
|
case (TestModes::NONE): {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(TestModes::MGM_LIS3MDL): {
|
case (TestModes::MGM_LIS3MDL): {
|
||||||
performLis3MdlTest(mgm0Lis3mdlChipSelect);
|
performLis3MdlTest(mgm0Lis3mdlChipSelect);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(TestModes::MGM_RM3100): {
|
case (TestModes::MGM_RM3100): {
|
||||||
performRm3100Test(mgm1Rm3100ChipSelect);
|
performRm3100Test(mgm1Rm3100ChipSelect);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case(TestModes::GYRO_L3GD20H): {
|
case (TestModes::GYRO_L3GD20H): {
|
||||||
performL3gTest(gyro1L3gd20ChipSelect);
|
performL3gTest(gyro1L3gd20ChipSelect);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t SpiTestClass::performPeriodicAction() {
|
ReturnValue_t SpiTestClass::performPeriodicAction() { return HasReturnvaluesIF::RETURN_OK; }
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpiTestClass::performRm3100Test(uint8_t mgmId) {
|
void SpiTestClass::performRm3100Test(uint8_t mgmId) {
|
||||||
/* Configure all SPI chip selects and pull them high */
|
/* Configure all SPI chip selects and pull them high */
|
||||||
acsInit();
|
acsInit();
|
||||||
|
|
||||||
/* Adapt accordingly */
|
/* Adapt accordingly */
|
||||||
if(mgmId != mgm1Rm3100ChipSelect and mgmId != mgm3Rm3100ChipSelect) {
|
if (mgmId != mgm1Rm3100ChipSelect and mgmId != mgm3Rm3100ChipSelect) {
|
||||||
sif::warning << "SpiTestClass::performRm3100Test: Invalid MGM ID!" << std::endl;
|
sif::warning << "SpiTestClass::performRm3100Test: Invalid MGM ID!" << std::endl;
|
||||||
}
|
}
|
||||||
gpioId_t currentGpioId = 0;
|
gpioId_t currentGpioId = 0;
|
||||||
uint8_t chipSelectPin = mgmId;
|
uint8_t chipSelectPin = mgmId;
|
||||||
if(chipSelectPin == mgm1Rm3100ChipSelect) {
|
if (chipSelectPin == mgm1Rm3100ChipSelect) {
|
||||||
currentGpioId = gpioIds::MGM_1_RM3100_CS;
|
currentGpioId = gpioIds::MGM_1_RM3100_CS;
|
||||||
}
|
} else {
|
||||||
else {
|
currentGpioId = gpioIds::MGM_3_RM3100_CS;
|
||||||
currentGpioId = gpioIds::MGM_3_RM3100_CS;
|
}
|
||||||
}
|
uint32_t rm3100speed = 976'000;
|
||||||
uint32_t rm3100speed = 976'000;
|
uint8_t rm3100revidReg = 0x36;
|
||||||
uint8_t rm3100revidReg = 0x36;
|
spi::SpiModes rm3100mode = spi::SpiModes::MODE_3;
|
||||||
spi::SpiModes rm3100mode = spi::SpiModes::MODE_3;
|
|
||||||
|
|
||||||
#ifdef RASPBERRY_PI
|
#ifdef RASPBERRY_PI
|
||||||
std::string deviceName = "/dev/spidev0.0";
|
std::string deviceName = "/dev/spidev0.0";
|
||||||
#else
|
#else
|
||||||
std::string deviceName = "/dev/spidev2.0";
|
std::string deviceName = "/dev/spidev2.0";
|
||||||
#endif
|
#endif
|
||||||
int fileDescriptor = 0;
|
int fileDescriptor = 0;
|
||||||
|
|
||||||
|
UnixFileGuard fileHelper(deviceName, &fileDescriptor, O_RDWR, "SpiComIF::initializeInterface");
|
||||||
|
if (fileHelper.getOpenResult()) {
|
||||||
|
sif::error << "SpiTestClass::performRm3100Test: File descriptor could not be opened!"
|
||||||
|
<< std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setSpiSpeedAndMode(fileDescriptor, rm3100mode, rm3100speed);
|
||||||
|
|
||||||
UnixFileGuard fileHelper(deviceName, &fileDescriptor, O_RDWR,
|
uint8_t revId = readRegister(fileDescriptor, currentGpioId, rm3100revidReg);
|
||||||
"SpiComIF::initializeInterface");
|
sif::info << "SpiTestClass::performRm3100Test: Revision ID 0b" << std::bitset<8>(revId)
|
||||||
if(fileHelper.getOpenResult()) {
|
<< std::endl;
|
||||||
sif::error << "SpiTestClass::performRm3100Test: File descriptor could not be opened!"
|
|
||||||
<< std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setSpiSpeedAndMode(fileDescriptor, rm3100mode, rm3100speed);
|
|
||||||
|
|
||||||
uint8_t revId = readRegister(fileDescriptor, currentGpioId, rm3100revidReg);
|
/* Write configuration to CMM register */
|
||||||
sif::info << "SpiTestClass::performRm3100Test: Revision ID 0b" << std::bitset<8>(revId) <<
|
writeRegister(fileDescriptor, currentGpioId, 0x01, 0x75);
|
||||||
std::endl;
|
uint8_t cmmRegister = readRm3100Register(fileDescriptor, currentGpioId, 0x01);
|
||||||
|
sif::info << "SpiTestClass::performRm3100Test: CMM register value: " << std::hex << "0x"
|
||||||
|
<< static_cast<int>(cmmRegister) << std::dec << std::endl;
|
||||||
|
|
||||||
/* Write configuration to CMM register */
|
/* Read the cycle count registers */
|
||||||
writeRegister(fileDescriptor, currentGpioId, 0x01, 0x75);
|
uint8_t cycleCountsRaw[6];
|
||||||
uint8_t cmmRegister = readRm3100Register(fileDescriptor , currentGpioId, 0x01);
|
readMultipleRegisters(fileDescriptor, currentGpioId, 0x04, cycleCountsRaw, 6);
|
||||||
sif::info << "SpiTestClass::performRm3100Test: CMM register value: " <<
|
|
||||||
std::hex << "0x" << static_cast<int>(cmmRegister) << std::dec << std::endl;
|
|
||||||
|
|
||||||
/* Read the cycle count registers */
|
uint16_t cycleCountX = cycleCountsRaw[0] << 8 | cycleCountsRaw[1];
|
||||||
uint8_t cycleCountsRaw[6];
|
uint16_t cycleCountY = cycleCountsRaw[2] << 8 | cycleCountsRaw[3];
|
||||||
readMultipleRegisters(fileDescriptor, currentGpioId, 0x04, cycleCountsRaw, 6);
|
uint16_t cycleCountZ = cycleCountsRaw[4] << 8 | cycleCountsRaw[5];
|
||||||
|
|
||||||
uint16_t cycleCountX = cycleCountsRaw[0] << 8 | cycleCountsRaw[1];
|
sif::info << "Cycle count X: " << cycleCountX << std::endl;
|
||||||
uint16_t cycleCountY = cycleCountsRaw[2] << 8 | cycleCountsRaw[3];
|
sif::info << "Cycle count Y: " << cycleCountY << std::endl;
|
||||||
uint16_t cycleCountZ = cycleCountsRaw[4] << 8 | cycleCountsRaw[5];
|
sif::info << "Cycle count z: " << cycleCountZ << std::endl;
|
||||||
|
|
||||||
sif::info << "Cycle count X: " << cycleCountX << std::endl;
|
writeRegister(fileDescriptor, currentGpioId, 0x0B, 0x96);
|
||||||
sif::info << "Cycle count Y: " << cycleCountY << std::endl;
|
uint8_t tmrcReg = readRm3100Register(fileDescriptor, currentGpioId, 0x0B);
|
||||||
sif::info << "Cycle count z: " << cycleCountZ << std::endl;
|
sif::info << "SpiTestClass::performRm3100Test: TMRC register value: " << std::hex << "0x"
|
||||||
|
<< static_cast<int>(tmrcReg) << std::dec << std::endl;
|
||||||
writeRegister(fileDescriptor, currentGpioId, 0x0B, 0x96);
|
|
||||||
uint8_t tmrcReg = readRm3100Register(fileDescriptor, currentGpioId, 0x0B);
|
|
||||||
sif::info << "SpiTestClass::performRm3100Test: TMRC register value: " <<
|
|
||||||
std::hex << "0x" << static_cast<int>(tmrcReg) << std::dec << std::endl;
|
|
||||||
|
|
||||||
|
TaskFactory::delayTask(10);
|
||||||
|
uint8_t statusReg = readRm3100Register(fileDescriptor, currentGpioId, 0x34);
|
||||||
|
sif::info << "SpiTestClass::performRm3100Test: Status Register 0b" << std::bitset<8>(statusReg)
|
||||||
|
<< std::endl;
|
||||||
|
/* This means that data is not ready */
|
||||||
|
if ((statusReg & 0b1000'0000) == 0) {
|
||||||
|
sif::warning << "SpiTestClass::performRm3100Test: Data not ready!" << std::endl;
|
||||||
TaskFactory::delayTask(10);
|
TaskFactory::delayTask(10);
|
||||||
uint8_t statusReg = readRm3100Register(fileDescriptor, currentGpioId, 0x34);
|
uint8_t statusReg = readRm3100Register(fileDescriptor, currentGpioId, 0x34);
|
||||||
sif::info << "SpiTestClass::performRm3100Test: Status Register 0b" <<
|
if ((statusReg & 0b1000'0000) == 0) {
|
||||||
std::bitset<8>(statusReg) << std::endl;
|
return;
|
||||||
/* This means that data is not ready */
|
|
||||||
if((statusReg & 0b1000'0000) == 0) {
|
|
||||||
sif::warning << "SpiTestClass::performRm3100Test: Data not ready!" << std::endl;
|
|
||||||
TaskFactory::delayTask(10);
|
|
||||||
uint8_t statusReg = readRm3100Register(fileDescriptor, currentGpioId, 0x34);
|
|
||||||
if((statusReg & 0b1000'0000) == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t rm3100DefaultCycleCout = 0xC8;
|
uint32_t rm3100DefaultCycleCout = 0xC8;
|
||||||
/* Gain scales lineary with cycle count and is 38 for cycle count 100 */
|
/* Gain scales lineary with cycle count and is 38 for cycle count 100 */
|
||||||
float rm3100Gain = rm3100DefaultCycleCout / 100.0 * 38.0;
|
float rm3100Gain = rm3100DefaultCycleCout / 100.0 * 38.0;
|
||||||
float scaleFactor = 1 / rm3100Gain;
|
float scaleFactor = 1 / rm3100Gain;
|
||||||
uint8_t rawValues[9];
|
uint8_t rawValues[9];
|
||||||
readMultipleRegisters(fileDescriptor, currentGpioId, 0x24, rawValues, 9);
|
readMultipleRegisters(fileDescriptor, currentGpioId, 0x24, rawValues, 9);
|
||||||
|
|
||||||
/* The sensor generates 24 bit signed values */
|
/* The sensor generates 24 bit signed values */
|
||||||
int32_t rawX = ((rawValues[0] << 24) | (rawValues[1] << 16) | (rawValues[2] << 8)) >> 8;
|
int32_t rawX = ((rawValues[0] << 24) | (rawValues[1] << 16) | (rawValues[2] << 8)) >> 8;
|
||||||
int32_t rawY = ((rawValues[3] << 24) | (rawValues[4] << 16) | (rawValues[5] << 8)) >> 8;
|
int32_t rawY = ((rawValues[3] << 24) | (rawValues[4] << 16) | (rawValues[5] << 8)) >> 8;
|
||||||
int32_t rawZ = ((rawValues[6] << 24) | (rawValues[7] << 16) | (rawValues[8] << 8)) >> 8;
|
int32_t rawZ = ((rawValues[6] << 24) | (rawValues[7] << 16) | (rawValues[8] << 8)) >> 8;
|
||||||
|
|
||||||
float fieldStrengthX = rawX * scaleFactor;
|
float fieldStrengthX = rawX * scaleFactor;
|
||||||
float fieldStrengthY = rawY * scaleFactor;
|
float fieldStrengthY = rawY * scaleFactor;
|
||||||
float fieldStrengthZ = rawZ * scaleFactor;
|
float fieldStrengthZ = rawZ * scaleFactor;
|
||||||
|
|
||||||
sif::info << "RM3100 measured field strengths in microtesla:" << std::endl;
|
sif::info << "RM3100 measured field strengths in microtesla:" << std::endl;
|
||||||
sif::info << "Field Strength X: " << fieldStrengthX << " uT" << std::endl;
|
sif::info << "Field Strength X: " << fieldStrengthX << " uT" << std::endl;
|
||||||
sif::info << "Field Strength Y: " << fieldStrengthY << " uT" << std::endl;
|
sif::info << "Field Strength Y: " << fieldStrengthY << " uT" << std::endl;
|
||||||
sif::info << "Field Strength Z: " << fieldStrengthZ << " uT" << std::endl;
|
sif::info << "Field Strength Z: " << fieldStrengthZ << " uT" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpiTestClass::performLis3MdlTest(uint8_t lis3Id) {
|
void SpiTestClass::performLis3MdlTest(uint8_t lis3Id) {
|
||||||
/* Configure all SPI chip selects and pull them high */
|
/* Configure all SPI chip selects and pull them high */
|
||||||
acsInit();
|
acsInit();
|
||||||
|
|
||||||
/* Adapt accordingly */
|
/* Adapt accordingly */
|
||||||
if(lis3Id != mgm0Lis3mdlChipSelect and lis3Id != mgm2Lis3mdlChipSelect) {
|
if (lis3Id != mgm0Lis3mdlChipSelect and lis3Id != mgm2Lis3mdlChipSelect) {
|
||||||
sif::warning << "SpiTestClass::performLis3MdlTest: Invalid MGM ID!" << std::endl;
|
sif::warning << "SpiTestClass::performLis3MdlTest: Invalid MGM ID!" << std::endl;
|
||||||
}
|
}
|
||||||
gpioId_t currentGpioId = 0;
|
gpioId_t currentGpioId = 0;
|
||||||
uint8_t chipSelectPin = lis3Id;
|
uint8_t chipSelectPin = lis3Id;
|
||||||
uint8_t whoAmIReg = 0b0000'1111;
|
uint8_t whoAmIReg = 0b0000'1111;
|
||||||
uint8_t whoAmIRegExpectedVal = 0b0011'1101;
|
uint8_t whoAmIRegExpectedVal = 0b0011'1101;
|
||||||
if(chipSelectPin == mgm0Lis3mdlChipSelect) {
|
if (chipSelectPin == mgm0Lis3mdlChipSelect) {
|
||||||
currentGpioId = gpioIds::MGM_0_LIS3_CS;
|
currentGpioId = gpioIds::MGM_0_LIS3_CS;
|
||||||
}
|
} else {
|
||||||
else {
|
currentGpioId = gpioIds::MGM_2_LIS3_CS;
|
||||||
currentGpioId = gpioIds::MGM_2_LIS3_CS;
|
}
|
||||||
}
|
uint32_t spiSpeed = 10'000'000;
|
||||||
uint32_t spiSpeed = 10'000'000;
|
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
|
||||||
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
|
|
||||||
#ifdef RASPBERRY_PI
|
#ifdef RASPBERRY_PI
|
||||||
std::string deviceName = "/dev/spidev0.0";
|
std::string deviceName = "/dev/spidev0.0";
|
||||||
#else
|
#else
|
||||||
std::string deviceName = "/dev/spidev2.0";
|
std::string deviceName = "/dev/spidev2.0";
|
||||||
#endif
|
#endif
|
||||||
int fileDescriptor = 0;
|
int fileDescriptor = 0;
|
||||||
|
|
||||||
UnixFileGuard fileHelper(deviceName, &fileDescriptor, O_RDWR,
|
UnixFileGuard fileHelper(deviceName, &fileDescriptor, O_RDWR, "SpiComIF::initializeInterface");
|
||||||
"SpiComIF::initializeInterface");
|
if (fileHelper.getOpenResult()) {
|
||||||
if(fileHelper.getOpenResult()) {
|
sif::error << "SpiTestClass::performLis3Mdl3100Test: File descriptor could not be opened!"
|
||||||
sif::error << "SpiTestClass::performLis3Mdl3100Test: File descriptor could not be opened!"
|
<< std::endl;
|
||||||
<< std::endl;
|
return;
|
||||||
return;
|
}
|
||||||
}
|
setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
|
||||||
setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
|
spiTransferStruct.delay_usecs = 0;
|
||||||
spiTransferStruct.delay_usecs = 0;
|
|
||||||
|
|
||||||
uint8_t whoAmIRegVal = readStmRegister(fileDescriptor, currentGpioId, whoAmIReg, false);
|
|
||||||
sif::info << "SpiTestClass::performLis3MdlTest: WHO AM I register 0b" <<
|
|
||||||
std::bitset<8>(whoAmIRegVal) << std::endl;
|
|
||||||
if(whoAmIRegVal != whoAmIRegExpectedVal) {
|
|
||||||
sif::warning << "SpiTestClass::performLis3MdlTest: WHO AM I register invalid!"
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
uint8_t whoAmIRegVal = readStmRegister(fileDescriptor, currentGpioId, whoAmIReg, false);
|
||||||
|
sif::info << "SpiTestClass::performLis3MdlTest: WHO AM I register 0b"
|
||||||
|
<< std::bitset<8>(whoAmIRegVal) << std::endl;
|
||||||
|
if (whoAmIRegVal != whoAmIRegExpectedVal) {
|
||||||
|
sif::warning << "SpiTestClass::performLis3MdlTest: WHO AM I register invalid!" << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpiTestClass::performL3gTest(uint8_t l3gId) {
|
void SpiTestClass::performL3gTest(uint8_t l3gId) {
|
||||||
/* Configure all SPI chip selects and pull them high */
|
/* Configure all SPI chip selects and pull them high */
|
||||||
acsInit();
|
acsInit();
|
||||||
|
|
||||||
gpioId_t currentGpioId = 0;
|
gpioId_t currentGpioId = 0;
|
||||||
uint8_t chipSelectPin = l3gId;
|
uint8_t chipSelectPin = l3gId;
|
||||||
uint8_t whoAmIReg = 0b0000'1111;
|
uint8_t whoAmIReg = 0b0000'1111;
|
||||||
uint8_t whoAmIRegExpectedVal = 0b1101'0111;
|
uint8_t whoAmIRegExpectedVal = 0b1101'0111;
|
||||||
|
|
||||||
if(chipSelectPin == gyro1L3gd20ChipSelect) {
|
if (chipSelectPin == gyro1L3gd20ChipSelect) {
|
||||||
currentGpioId = gpioIds::GYRO_1_L3G_CS;
|
currentGpioId = gpioIds::GYRO_1_L3G_CS;
|
||||||
}
|
} else {
|
||||||
else {
|
currentGpioId = gpioIds::GYRO_3_L3G_CS;
|
||||||
currentGpioId = gpioIds::GYRO_3_L3G_CS;
|
}
|
||||||
}
|
uint32_t spiSpeed = 3'900'000;
|
||||||
uint32_t spiSpeed = 3'900'000;
|
spi::SpiModes spiMode = spi::SpiModes::MODE_3;
|
||||||
spi::SpiModes spiMode = spi::SpiModes::MODE_3;
|
|
||||||
#ifdef RASPBERRY_PI
|
#ifdef RASPBERRY_PI
|
||||||
std::string deviceName = "/dev/spidev0.0";
|
std::string deviceName = "/dev/spidev0.0";
|
||||||
#else
|
#else
|
||||||
std::string deviceName = "/dev/spidev2.0";
|
std::string deviceName = "/dev/spidev2.0";
|
||||||
#endif
|
#endif
|
||||||
int fileDescriptor = 0;
|
int fileDescriptor = 0;
|
||||||
|
|
||||||
UnixFileGuard fileHelper(deviceName, &fileDescriptor, O_RDWR,
|
UnixFileGuard fileHelper(deviceName, &fileDescriptor, O_RDWR, "SpiComIF::initializeInterface");
|
||||||
"SpiComIF::initializeInterface");
|
if (fileHelper.getOpenResult()) {
|
||||||
if(fileHelper.getOpenResult()) {
|
sif::error << "SpiTestClass::performLis3Mdl3100Test: File descriptor could not be opened!"
|
||||||
sif::error << "SpiTestClass::performLis3Mdl3100Test: File descriptor could not be opened!"
|
<< std::endl;
|
||||||
<< std::endl;
|
return;
|
||||||
return;
|
}
|
||||||
}
|
setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
|
||||||
setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
|
uint8_t whoAmIRegVal = readStmRegister(fileDescriptor, currentGpioId, whoAmIReg, false);
|
||||||
uint8_t whoAmIRegVal = readStmRegister(fileDescriptor, currentGpioId, whoAmIReg, false);
|
sif::info << "SpiTestClass::performLis3MdlTest: WHO AM I register 0b"
|
||||||
sif::info << "SpiTestClass::performLis3MdlTest: WHO AM I register 0b" <<
|
<< std::bitset<8>(whoAmIRegVal) << std::endl;
|
||||||
std::bitset<8>(whoAmIRegVal) << std::endl;
|
if (whoAmIRegVal != whoAmIRegExpectedVal) {
|
||||||
if(whoAmIRegVal != whoAmIRegExpectedVal) {
|
sif::warning << "SpiTestClass::performL3gTest: Read WHO AM I register invalid!" << std::endl;
|
||||||
sif::warning << "SpiTestClass::performL3gTest: Read WHO AM I register invalid!" <<
|
}
|
||||||
std::endl;
|
|
||||||
|
uint8_t ctrlReg1Addr = 0b0010'0000;
|
||||||
|
{
|
||||||
|
uint8_t commandRegs[5];
|
||||||
|
commandRegs[0] = 0b0000'1111;
|
||||||
|
commandRegs[1] = 0x0;
|
||||||
|
commandRegs[2] = 0x0;
|
||||||
|
/* Configure big endian data format */
|
||||||
|
commandRegs[3] = 0b0100'0000;
|
||||||
|
commandRegs[4] = 0x0;
|
||||||
|
writeMultipleStmRegisters(fileDescriptor, currentGpioId, ctrlReg1Addr, commandRegs,
|
||||||
|
sizeof(commandRegs));
|
||||||
|
uint8_t readRegs[5];
|
||||||
|
readMultipleRegisters(fileDescriptor, currentGpioId, ctrlReg1Addr, readRegs, sizeof(readRegs));
|
||||||
|
for (uint8_t idx = 0; idx < sizeof(readRegs); idx++) {
|
||||||
|
if (readRegs[idx] != commandRegs[0]) {
|
||||||
|
sif::warning << "SpiTestClass::performL3gTest: Read control register "
|
||||||
|
<< static_cast<int>(idx + 1) << " not equal to configured value" << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t ctrlReg1Addr = 0b0010'0000;
|
uint8_t readOutBuffer[14];
|
||||||
{
|
readMultipleStmRegisters(fileDescriptor, currentGpioId, ctrlReg1Addr, readOutBuffer,
|
||||||
uint8_t commandRegs[5];
|
sizeof(readOutBuffer));
|
||||||
commandRegs[0] = 0b0000'1111;
|
|
||||||
commandRegs[1] = 0x0;
|
|
||||||
commandRegs[2] = 0x0;
|
|
||||||
/* Configure big endian data format */
|
|
||||||
commandRegs[3] = 0b0100'0000;
|
|
||||||
commandRegs[4] = 0x0;
|
|
||||||
writeMultipleStmRegisters(fileDescriptor, currentGpioId, ctrlReg1Addr, commandRegs,
|
|
||||||
sizeof(commandRegs));
|
|
||||||
uint8_t readRegs[5];
|
|
||||||
readMultipleRegisters(fileDescriptor, currentGpioId, ctrlReg1Addr, readRegs,
|
|
||||||
sizeof(readRegs));
|
|
||||||
for(uint8_t idx = 0; idx < sizeof(readRegs); idx++) {
|
|
||||||
if(readRegs[idx] != commandRegs[0]) {
|
|
||||||
sif::warning << "SpiTestClass::performL3gTest: Read control register " <<
|
|
||||||
static_cast<int>(idx + 1) << " not equal to configured value" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t readOutBuffer[14];
|
uint8_t statusReg = readOutBuffer[7];
|
||||||
readMultipleStmRegisters(fileDescriptor, currentGpioId, ctrlReg1Addr, readOutBuffer,
|
sif::info << "SpiTestClass::performL3gTest: Status Register 0b" << std::bitset<8>(statusReg)
|
||||||
sizeof(readOutBuffer));
|
<< std::endl;
|
||||||
|
|
||||||
uint8_t statusReg = readOutBuffer[7];
|
uint16_t l3gRange = 245;
|
||||||
sif::info << "SpiTestClass::performL3gTest: Status Register 0b" <<
|
float scaleFactor = static_cast<float>(l3gRange) / INT16_MAX;
|
||||||
std::bitset<8>(statusReg) << std::endl;
|
/* The sensor spits out little endian */
|
||||||
|
int16_t angVelocRawX = (readOutBuffer[8] << 8) | readOutBuffer[9];
|
||||||
|
int16_t angVelocRawY = (readOutBuffer[10] << 8) | readOutBuffer[11];
|
||||||
|
int16_t angVelocRawZ = (readOutBuffer[12] << 8) | readOutBuffer[13];
|
||||||
|
|
||||||
uint16_t l3gRange = 245;
|
float angVelocX = scaleFactor * angVelocRawX;
|
||||||
float scaleFactor = static_cast<float>(l3gRange) / INT16_MAX;
|
float angVelocY = scaleFactor * angVelocRawY;
|
||||||
/* The sensor spits out little endian */
|
float angVelocZ = scaleFactor * angVelocRawZ;
|
||||||
int16_t angVelocRawX = (readOutBuffer[8] << 8) | readOutBuffer[9];
|
|
||||||
int16_t angVelocRawY = (readOutBuffer[10] << 8) | readOutBuffer[11];
|
|
||||||
int16_t angVelocRawZ = (readOutBuffer[12] << 8) | readOutBuffer[13];
|
|
||||||
|
|
||||||
float angVelocX = scaleFactor * angVelocRawX;
|
|
||||||
float angVelocY = scaleFactor * angVelocRawY;
|
|
||||||
float angVelocZ = scaleFactor * angVelocRawZ;
|
|
||||||
|
|
||||||
sif::info << "Angular velocities for the L3GD20H in degrees per second:" << std::endl;
|
|
||||||
sif::info << "X: " << angVelocX << std::endl;
|
|
||||||
sif::info << "Y: " << angVelocY << std::endl;
|
|
||||||
sif::info << "Z: " << angVelocZ << std::endl;
|
|
||||||
|
|
||||||
|
sif::info << "Angular velocities for the L3GD20H in degrees per second:" << std::endl;
|
||||||
|
sif::info << "X: " << angVelocX << std::endl;
|
||||||
|
sif::info << "Y: " << angVelocY << std::endl;
|
||||||
|
sif::info << "Z: " << angVelocZ << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpiTestClass::acsInit() {
|
void SpiTestClass::acsInit() {
|
||||||
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 = new GpiodRegularByChip(rpiGpioName, mgm0Lis3mdlChipSelect, "MGM_0_LIS3", gpio::DIR_OUT,
|
||||||
gpio::DIR_OUT, gpio::HIGH);
|
gpio::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 = new GpiodRegularByChip(rpiGpioName, mgm1Rm3100ChipSelect, "MGM_1_RM3100", gpio::DIR_OUT,
|
||||||
gpio::DIR_OUT, gpio::HIGH);
|
gpio::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 = new GpiodRegularByChip(rpiGpioName, gyro0AdisChipSelect, "GYRO_0_ADIS", gpio::DIR_OUT,
|
||||||
gpio::DIR_OUT, gpio::HIGH);
|
gpio::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 = new GpiodRegularByChip(rpiGpioName, gyro1L3gd20ChipSelect, "GYRO_1_L3G", gpio::DIR_OUT,
|
||||||
gpio::DIR_OUT, gpio::HIGH);
|
gpio::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 = new GpiodRegularByChip(rpiGpioName, gyro3L3gd20ChipSelect, "GYRO_2_L3G", gpio::DIR_OUT,
|
||||||
gpio::DIR_OUT, gpio::HIGH);
|
gpio::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 = new GpiodRegularByChip(rpiGpioName, mgm2Lis3mdlChipSelect, "MGM_2_LIS3", gpio::DIR_OUT,
|
||||||
gpio::DIR_OUT, gpio::HIGH);
|
gpio::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 = new GpiodRegularByChip(rpiGpioName, mgm3Rm3100ChipSelect, "MGM_3_RM3100", gpio::DIR_OUT,
|
||||||
gpio::DIR_OUT, gpio::HIGH);
|
gpio::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 = new GpiodRegularByLineName(q7s::gpioNames::MGM_0_CS, "MGM_0_LIS3", gpio::DIR_OUT,
|
gpio =
|
||||||
gpio::HIGH);
|
new GpiodRegularByLineName(q7s::gpioNames::MGM_0_CS, "MGM_0_LIS3", gpio::DIR_OUT, gpio::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", gpio::DIR_OUT,
|
||||||
gpio::HIGH);
|
gpio::HIGH);
|
||||||
gpioCookie->addGpio(gpioIds::MGM_1_RM3100_CS, gpio);
|
gpioCookie->addGpio(gpioIds::MGM_1_RM3100_CS, gpio);
|
||||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_2_CS, "MGM_2_LIS3", gpio::DIR_OUT,
|
gpio =
|
||||||
gpio::HIGH);
|
new GpiodRegularByLineName(q7s::gpioNames::MGM_2_CS, "MGM_2_LIS3", gpio::DIR_OUT, gpio::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", gpio::DIR_OUT,
|
||||||
gpio::HIGH);
|
gpio::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 = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ADIS_CS, "GYRO_0_ADIS", gpio::DIR_OUT,
|
||||||
gpio::DIR_OUT, gpio::HIGH);
|
gpio::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", gpio::DIR_OUT,
|
||||||
gpio::HIGH);
|
gpio::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 = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ADIS_CS, "GYRO_2_ADIS", gpio::DIR_OUT,
|
||||||
gpio::DIR_OUT, gpio::HIGH);
|
gpio::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", gpio::DIR_OUT,
|
||||||
gpio::HIGH);
|
gpio::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", gpio::DIR_OUT,
|
||||||
gpio::LOW);
|
gpio::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", gpio::DIR_OUT,
|
||||||
gpio::LOW);
|
gpio::LOW);
|
||||||
gpioCookie->addGpio(gpioIds::GYRO_2_ENABLE, gpio);
|
gpioCookie->addGpio(gpioIds::GYRO_2_ENABLE, gpio);
|
||||||
#endif
|
#endif
|
||||||
if (gpioIF != nullptr) {
|
if (gpioIF != nullptr) {
|
||||||
gpioIF->addGpios(gpioCookie);
|
gpioIF->addGpios(gpioCookie);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpiTestClass::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed) {
|
void SpiTestClass::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed) {
|
||||||
int mode_test = SPI_MODE_3;
|
int mode_test = SPI_MODE_3;
|
||||||
int retval = ioctl(spiFd, SPI_IOC_WR_MODE, &mode_test);//reinterpret_cast<uint8_t*>(&mode));
|
int retval = ioctl(spiFd, SPI_IOC_WR_MODE, &mode_test); // reinterpret_cast<uint8_t*>(&mode));
|
||||||
if(retval != 0) {
|
if (retval != 0) {
|
||||||
utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI mode failed!");
|
utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI mode failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = ioctl(spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
|
retval = ioctl(spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
|
||||||
if(retval != 0) {
|
if (retval != 0) {
|
||||||
utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI speed failed!");
|
utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI speed failed!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpiTestClass::writeRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value) {
|
void SpiTestClass::writeRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value) {
|
||||||
spiTransferStruct.len = 2;
|
spiTransferStruct.len = 2;
|
||||||
sendBuffer[0] = reg;
|
sendBuffer[0] = reg;
|
||||||
sendBuffer[1] = value;
|
sendBuffer[1] = value;
|
||||||
|
|
||||||
if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
if (gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||||
gpioIF->pullLow(chipSelect);
|
gpioIF->pullLow(chipSelect);
|
||||||
}
|
}
|
||||||
int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct);
|
int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct);
|
||||||
if(retval < 0) {
|
if (retval < 0) {
|
||||||
utility::handleIoctlError("SpiTestClass::writeRegister: Write failed");
|
utility::handleIoctlError("SpiTestClass::writeRegister: Write failed");
|
||||||
}
|
}
|
||||||
if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
if (gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||||
gpioIF->pullHigh(chipSelect);
|
gpioIF->pullHigh(chipSelect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpiTestClass::writeStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value,
|
void SpiTestClass::writeStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value,
|
||||||
bool autoIncrement) {
|
bool autoIncrement) {
|
||||||
if(autoIncrement) {
|
if (autoIncrement) {
|
||||||
reg |= STM_AUTO_INCR_MASK;
|
reg |= STM_AUTO_INCR_MASK;
|
||||||
}
|
}
|
||||||
writeRegister(fd, chipSelect, reg, value);
|
writeRegister(fd, chipSelect, reg, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpiTestClass::writeMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg,
|
void SpiTestClass::writeMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg,
|
||||||
uint8_t *values, size_t len) {
|
uint8_t *values, size_t len) {
|
||||||
if(values == nullptr) {
|
if (values == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg |= STM_AUTO_INCR_MASK;
|
|
||||||
/* Clear read mask */
|
|
||||||
reg &= ~STM_READ_MASK;
|
|
||||||
writeMultipleRegisters(fd, chipSelect, reg, values, len);
|
|
||||||
|
|
||||||
|
reg |= STM_AUTO_INCR_MASK;
|
||||||
|
/* Clear read mask */
|
||||||
|
reg &= ~STM_READ_MASK;
|
||||||
|
writeMultipleRegisters(fd, chipSelect, reg, values, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpiTestClass::writeMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg,
|
void SpiTestClass::writeMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t *values,
|
||||||
uint8_t *values, size_t len) {
|
size_t len) {
|
||||||
if(values == nullptr) {
|
if (values == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendBuffer[0] = reg;
|
sendBuffer[0] = reg;
|
||||||
std::memcpy(sendBuffer.data() + 1, values, len);
|
std::memcpy(sendBuffer.data() + 1, values, len);
|
||||||
spiTransferStruct.len = len + 1;
|
spiTransferStruct.len = len + 1;
|
||||||
|
|
||||||
if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
if (gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||||
gpioIF->pullLow(chipSelect);
|
gpioIF->pullLow(chipSelect);
|
||||||
}
|
}
|
||||||
int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct);
|
int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct);
|
||||||
if(retval < 0) {
|
if (retval < 0) {
|
||||||
utility::handleIoctlError("SpiTestClass::readRegister: Read failed");
|
utility::handleIoctlError("SpiTestClass::readRegister: Read failed");
|
||||||
}
|
}
|
||||||
if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
if (gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||||
gpioIF->pullHigh(chipSelect);
|
gpioIF->pullHigh(chipSelect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t SpiTestClass::readRm3100Register(int fd, gpioId_t chipSelect, uint8_t reg) {
|
uint8_t SpiTestClass::readRm3100Register(int fd, gpioId_t chipSelect, uint8_t reg) {
|
||||||
return readStmRegister(fd, chipSelect, reg, false);
|
return readStmRegister(fd, chipSelect, reg, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SpiTestClass::readMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg,
|
||||||
void SpiTestClass::readMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t *reply,
|
uint8_t *reply, size_t len) {
|
||||||
size_t len) {
|
reg |= STM_AUTO_INCR_MASK;
|
||||||
reg |= STM_AUTO_INCR_MASK;
|
readMultipleRegisters(fd, chipSelect, reg, reply, len);
|
||||||
readMultipleRegisters(fd, chipSelect, reg, reply, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpiTestClass::readMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t *reply,
|
void SpiTestClass::readMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t *reply,
|
||||||
size_t len) {
|
size_t len) {
|
||||||
if(reply == nullptr) {
|
if (reply == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spiTransferStruct.len = len + 1;
|
spiTransferStruct.len = len + 1;
|
||||||
sendBuffer[0] = reg | STM_READ_MASK;
|
sendBuffer[0] = reg | STM_READ_MASK;
|
||||||
|
|
||||||
for(uint8_t idx = 0; idx < len ; idx ++) {
|
for (uint8_t idx = 0; idx < len; idx++) {
|
||||||
sendBuffer[idx + 1] = 0;
|
sendBuffer[idx + 1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
if (gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||||
gpioIF->pullLow(chipSelect);
|
gpioIF->pullLow(chipSelect);
|
||||||
}
|
}
|
||||||
int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct);
|
int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct);
|
||||||
if(retval < 0) {
|
if (retval < 0) {
|
||||||
utility::handleIoctlError("SpiTestClass::readRegister: Read failed");
|
utility::handleIoctlError("SpiTestClass::readRegister: Read failed");
|
||||||
}
|
}
|
||||||
if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
if (gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||||
gpioIF->pullHigh(chipSelect);
|
gpioIF->pullHigh(chipSelect);
|
||||||
}
|
}
|
||||||
std::memcpy(reply, recvBuffer.data() + 1, len);
|
std::memcpy(reply, recvBuffer.data() + 1, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t SpiTestClass::readStmRegister(int fd, gpioId_t chipSelect, uint8_t reg,
|
uint8_t SpiTestClass::readStmRegister(int fd, gpioId_t chipSelect, uint8_t reg,
|
||||||
bool autoIncrement) {
|
bool autoIncrement) {
|
||||||
reg |= STM_READ_MASK;
|
reg |= STM_READ_MASK;
|
||||||
if(autoIncrement) {
|
if (autoIncrement) {
|
||||||
reg |= STM_AUTO_INCR_MASK;
|
reg |= STM_AUTO_INCR_MASK;
|
||||||
}
|
}
|
||||||
return readRegister(fd, chipSelect, reg);
|
return readRegister(fd, chipSelect, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t SpiTestClass::readRegister(int fd, gpioId_t chipSelect, uint8_t reg) {
|
uint8_t SpiTestClass::readRegister(int fd, gpioId_t chipSelect, uint8_t reg) {
|
||||||
spiTransferStruct.len = 2;
|
spiTransferStruct.len = 2;
|
||||||
sendBuffer[0] = reg;
|
sendBuffer[0] = reg;
|
||||||
sendBuffer[1] = 0;
|
sendBuffer[1] = 0;
|
||||||
|
|
||||||
if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
if (gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||||
gpioIF->pullLow(chipSelect);
|
gpioIF->pullLow(chipSelect);
|
||||||
}
|
}
|
||||||
int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct);
|
int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct);
|
||||||
if(retval < 0) {
|
if (retval < 0) {
|
||||||
utility::handleIoctlError("SpiTestClass::readRegister: Read failed");
|
utility::handleIoctlError("SpiTestClass::readRegister: Read failed");
|
||||||
}
|
}
|
||||||
if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
if (gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||||
gpioIF->pullHigh(chipSelect);
|
gpioIF->pullHigh(chipSelect);
|
||||||
}
|
}
|
||||||
return recvBuffer[1];
|
return recvBuffer[1];
|
||||||
}
|
}
|
||||||
|
@ -13,83 +13,78 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class SpiTestClass: public TestTask {
|
class SpiTestClass : public TestTask {
|
||||||
public:
|
public:
|
||||||
enum TestModes {
|
enum TestModes {
|
||||||
NONE,
|
NONE,
|
||||||
MGM_LIS3MDL,
|
MGM_LIS3MDL,
|
||||||
MGM_RM3100,
|
MGM_RM3100,
|
||||||
GYRO_L3GD20H,
|
GYRO_L3GD20H,
|
||||||
};
|
};
|
||||||
|
|
||||||
TestModes testMode;
|
TestModes testMode;
|
||||||
|
|
||||||
SpiTestClass(object_id_t objectId, GpioIF* gpioIF);
|
SpiTestClass(object_id_t objectId, GpioIF* gpioIF);
|
||||||
|
|
||||||
ReturnValue_t performOneShotAction() override;
|
ReturnValue_t performOneShotAction() override;
|
||||||
ReturnValue_t performPeriodicAction() override;
|
ReturnValue_t performPeriodicAction() override;
|
||||||
private:
|
|
||||||
|
|
||||||
GpioIF* gpioIF;
|
private:
|
||||||
|
GpioIF* gpioIF;
|
||||||
|
|
||||||
std::array<uint8_t, 128> recvBuffer;
|
std::array<uint8_t, 128> recvBuffer;
|
||||||
std::array<uint8_t, 128> sendBuffer;
|
std::array<uint8_t, 128> sendBuffer;
|
||||||
struct spi_ioc_transfer spiTransferStruct = {};
|
struct spi_ioc_transfer spiTransferStruct = {};
|
||||||
|
|
||||||
void performRm3100Test(uint8_t mgmId);
|
void performRm3100Test(uint8_t mgmId);
|
||||||
void performLis3MdlTest(uint8_t lis3Id);
|
void performLis3MdlTest(uint8_t lis3Id);
|
||||||
void performL3gTest(uint8_t l3gId);
|
void performL3gTest(uint8_t l3gId);
|
||||||
|
|
||||||
/* ACS board specific code which pulls all GPIOs high */
|
/* ACS board specific code which pulls all GPIOs high */
|
||||||
void acsInit();
|
void acsInit();
|
||||||
|
|
||||||
/* ACS board specific variables */
|
/* ACS board specific variables */
|
||||||
#ifdef RASPBERRY_PI
|
#ifdef RASPBERRY_PI
|
||||||
uint8_t mgm0Lis3mdlChipSelect = gpio::MGM_0_BCM_PIN;
|
uint8_t mgm0Lis3mdlChipSelect = gpio::MGM_0_BCM_PIN;
|
||||||
uint8_t mgm1Rm3100ChipSelect = gpio::MGM_1_BCM_PIN;
|
uint8_t mgm1Rm3100ChipSelect = gpio::MGM_1_BCM_PIN;
|
||||||
uint8_t mgm2Lis3mdlChipSelect = gpio::MGM_2_BCM_PIN;
|
uint8_t mgm2Lis3mdlChipSelect = gpio::MGM_2_BCM_PIN;
|
||||||
uint8_t mgm3Rm3100ChipSelect = gpio::MGM_3_BCM_PIN;
|
uint8_t mgm3Rm3100ChipSelect = gpio::MGM_3_BCM_PIN;
|
||||||
|
|
||||||
uint8_t gyro0AdisChipSelect = gpio::GYRO_0_BCM_PIN;
|
uint8_t gyro0AdisChipSelect = gpio::GYRO_0_BCM_PIN;
|
||||||
uint8_t gyro1L3gd20ChipSelect = gpio::GYRO_1_BCM_PIN;
|
uint8_t gyro1L3gd20ChipSelect = gpio::GYRO_1_BCM_PIN;
|
||||||
uint8_t gyro2AdisChipSelect = gpio::GYRO_2_BCM_PIN;
|
uint8_t gyro2AdisChipSelect = gpio::GYRO_2_BCM_PIN;
|
||||||
uint8_t gyro3L3gd20ChipSelect = gpio::GYRO_3_BCM_PIN;
|
uint8_t gyro3L3gd20ChipSelect = gpio::GYRO_3_BCM_PIN;
|
||||||
#else
|
#else
|
||||||
uint8_t mgm0Lis3mdlChipSelect = 0;
|
uint8_t mgm0Lis3mdlChipSelect = 0;
|
||||||
uint8_t mgm1Rm3100ChipSelect = 0;
|
uint8_t mgm1Rm3100ChipSelect = 0;
|
||||||
uint8_t gyro0AdisResetLine = 0;
|
uint8_t gyro0AdisResetLine = 0;
|
||||||
uint8_t gyro0AdisChipSelect = 0;
|
uint8_t gyro0AdisChipSelect = 0;
|
||||||
uint8_t gyro1L3gd20ChipSelect = 0;
|
uint8_t gyro1L3gd20ChipSelect = 0;
|
||||||
uint8_t gyro2L3gd20ChipSelect = 0;
|
uint8_t gyro2L3gd20ChipSelect = 0;
|
||||||
uint8_t mgm2Lis3mdlChipSelect = 0;
|
uint8_t mgm2Lis3mdlChipSelect = 0;
|
||||||
uint8_t mgm3Rm3100ChipSelect = 0;
|
uint8_t mgm3Rm3100ChipSelect = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static constexpr uint8_t STM_READ_MASK = 0b1000'0000;
|
static constexpr uint8_t STM_READ_MASK = 0b1000'0000;
|
||||||
static constexpr uint8_t RM3100_READ_MASK = STM_READ_MASK;
|
static constexpr uint8_t RM3100_READ_MASK = STM_READ_MASK;
|
||||||
static constexpr uint8_t STM_AUTO_INCR_MASK = 0b0100'0000;
|
static constexpr uint8_t STM_AUTO_INCR_MASK = 0b0100'0000;
|
||||||
|
|
||||||
void setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed);
|
void setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed);
|
||||||
|
|
||||||
void writeStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value,
|
void writeStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value,
|
||||||
bool autoIncrement);
|
bool autoIncrement);
|
||||||
void writeMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t* values,
|
void writeMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t* values,
|
||||||
size_t len);
|
size_t len);
|
||||||
void writeMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t *values,
|
void writeMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t* values,
|
||||||
size_t len);
|
size_t len);
|
||||||
void writeRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value);
|
void writeRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value);
|
||||||
|
|
||||||
uint8_t readRm3100Register(int fd, gpioId_t chipSelect, uint8_t reg);
|
|
||||||
uint8_t readStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, bool autoIncrement);
|
|
||||||
uint8_t readRegister(int fd, gpioId_t chipSelect, uint8_t reg);
|
|
||||||
void readMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t *reply,
|
|
||||||
size_t len);
|
|
||||||
void readMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg,
|
|
||||||
uint8_t* reply, size_t len);
|
|
||||||
|
|
||||||
|
uint8_t readRm3100Register(int fd, gpioId_t chipSelect, uint8_t reg);
|
||||||
|
uint8_t readStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, bool autoIncrement);
|
||||||
|
uint8_t readRegister(int fd, gpioId_t chipSelect, uint8_t reg);
|
||||||
|
void readMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t* reply,
|
||||||
|
size_t len);
|
||||||
|
void readMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t* reply, size_t len);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* LINUX_BOARDTEST_SPITESTCLASS_H_ */
|
#endif /* LINUX_BOARDTEST_SPITESTCLASS_H_ */
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user