better missed deadline handling

This commit is contained in:
Robin Müller 2021-02-22 18:46:45 +01:00
parent b03420c706
commit e9ffa930de
19 changed files with 136 additions and 227 deletions

View File

@ -30,7 +30,7 @@ ServiceInterfaceStream sif::error("ERROR", true, false, true);
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 = new ObjectManager(ObjectFactory::produce); objectManager = new ObjectManager(ObjectFactory::produce);
@ -41,7 +41,7 @@ void InitMission::initMission() {
initTasks(); initTasks();
} }
void InitMission::initTasks(){ void initmission::initTasks(){
/* TMTC Distribution */ /* TMTC Distribution */
PeriodicTaskIF* TmTcDistributor = TaskFactory::instance()-> PeriodicTaskIF* TmTcDistributor = TaskFactory::instance()->
createPeriodicTask("DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, createPeriodicTask("DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE,

View File

@ -1,7 +1,7 @@
#ifndef BSP_LINUX_INITMISSION_H_ #ifndef BSP_LINUX_INITMISSION_H_
#define BSP_LINUX_INITMISSION_H_ #define BSP_LINUX_INITMISSION_H_
namespace InitMission { namespace initmission {
void initMission(); void initMission();
void initTasks(); void initTasks();
}; };

View File

@ -24,7 +24,7 @@ int main(void)
<< SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << std::endl; << SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << 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.

View File

@ -30,7 +30,7 @@ ServiceInterfaceStream sif::error("ERROR", true, false, true);
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 = new ObjectManager(ObjectFactory::produce); objectManager = new ObjectManager(ObjectFactory::produce);
@ -41,96 +41,102 @@ void InitMission::initMission() {
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
void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline;
#else
void (*missedDeadlineFunc) (void) = nullptr;
#endif
/* TMTC Distribution */ /* TMTC Distribution */
PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask( PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
"DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, nullptr); "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) {
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);
} }
/* UDP bridge */ /* UDP bridge */
PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask(
"UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, nullptr); "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); result = udpBridgeTask->addComponent(objects::UDP_BRIDGE);
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
InitMission::printAddObjectError("UDP_BRIDGE", objects::UDP_BRIDGE); initmission::printAddObjectError("UDP_BRIDGE", objects::UDP_BRIDGE);
} }
PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask( PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask(
"UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, nullptr); "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK);
if(result != HasReturnvaluesIF::RETURN_OK) { if(result != HasReturnvaluesIF::RETURN_OK) {
InitMission::printAddObjectError("UDP_POLLING", objects::UDP_POLLING_TASK); initmission::printAddObjectError("UDP_POLLING", objects::UDP_POLLING_TASK);
} }
/* PUS Services */ /* PUS Services */
PeriodicTaskIF* pusVerification = factory->createPeriodicTask( PeriodicTaskIF* pusVerification = factory->createPeriodicTask(
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); "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) {
InitMission::printAddObjectError("PUS_VERIF", objects::PUS_SERVICE_1_VERIFICATION); initmission::printAddObjectError("PUS_VERIF", objects::PUS_SERVICE_1_VERIFICATION);
} }
PeriodicTaskIF* pusEvents = factory->createPeriodicTask( PeriodicTaskIF* pusEvents = factory->createPeriodicTask(
"PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); "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("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING); initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING);
} }
PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask( PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask(
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); "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);
} }
PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask( PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask(
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, nullptr); "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_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);
} }
PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask( PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask(
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, nullptr); "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);
} }
//TODO: Add handling of missed deadlines //TODO: Add handling of missed deadlines
/* Polling Sequence Table Default */ /* Polling Sequence Table Default */
FixedTimeslotTaskIF * pollingSequenceTableTaskDefault = factory->createFixedTimeslotTask( FixedTimeslotTaskIF * pollingSequenceTableTaskDefault = factory->createFixedTimeslotTask(
"PST_TASK_DEFAULT", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, nullptr); "PST_TASK_DEFAULT", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0,
missedDeadlineFunc);
result = pst::pollingSequenceInitDefault(pollingSequenceTableTaskDefault); result = pst::pollingSequenceInitDefault(pollingSequenceTableTaskDefault);
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;
@ -139,7 +145,7 @@ void InitMission::initTasks() {
#if TE0720 == 0 #if TE0720 == 0
FixedTimeslotTaskIF* gomSpacePstTask = factory-> FixedTimeslotTaskIF* gomSpacePstTask = factory->
createFixedTimeslotTask("GS_PST_TASK", 50, createFixedTimeslotTask("GS_PST_TASK", 50,
PeriodicTaskIF::MINIMUM_STACK_SIZE*8, 3.0, nullptr); PeriodicTaskIF::MINIMUM_STACK_SIZE*8, 3.0, missedDeadlineFunc);
result = pst::gomspacePstInit(gomSpacePstTask); result = pst::gomspacePstInit(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;
@ -147,17 +153,17 @@ void InitMission::initTasks() {
#endif #endif
PeriodicTaskIF* testTask = factory->createPeriodicTask( PeriodicTaskIF* testTask = factory->createPeriodicTask(
"GPIOD_TEST", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, nullptr); "GPIOD_TEST", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, 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 */
#if TE0720 == 1 && TEST_LIBGPIOD == 1 #if TE0720 == 1 && 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 /* TE0720 == 1 && TEST_LIBGPIOD == 1 */ #endif /* TE0720 == 1 && TEST_LIBGPIOD == 1 */

View File

@ -1,7 +1,7 @@
#ifndef BSP_Q7S_INITMISSION_H_ #ifndef BSP_Q7S_INITMISSION_H_
#define BSP_Q7S_INITMISSION_H_ #define BSP_Q7S_INITMISSION_H_
namespace InitMission { namespace initmission {
void initMission(); void initMission();
void initTasks(); void initTasks();
}; };

View File

@ -13,15 +13,15 @@
int main(void) int main(void)
{ {
std::cout << "-- EIVE OBSW --" << std::endl; std::cout << "-- EIVE OBSW --" << std::endl;
std::cout << "-- Compiled for Linux " << " --" << std::endl; std::cout << "-- Compiled for Linux (Xiphos Q7S) --" << std::endl;
std::cout << "-- Software version " << SW_NAME << " v" << SW_VERSION << "." std::cout << "-- Software version " << SW_NAME << " v" << SW_VERSION << "."
<< SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << std::endl; << SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << 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);
} }
} }

View File

@ -9,7 +9,7 @@
#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/ServiceInterface.h>
#include <fsfw/objectmanager/ObjectManager.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>
@ -24,7 +24,7 @@ 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 = new ObjectManager(ObjectFactory::produce); objectManager = new ObjectManager(ObjectFactory::produce);
@ -35,11 +35,21 @@ void InitMission::initMission() {
initTasks(); initTasks();
} }
void InitMission::initTasks(){ void initmission::initTasks() {
TaskFactory* factory = TaskFactory::instance();
if(factory == nullptr) {
/* Should never happen ! */
return;
}
#if OBSW_PRINT_MISSED_DEADLINES == 1
void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline;
#else
void (*missedDeadlineFunc) (void) = nullptr;
#endif
/* TMTC Distribution */ /* TMTC Distribution */
PeriodicTaskIF* tmTcDistributor = TaskFactory::instance()-> PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
createPeriodicTask("DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
0.100, nullptr);
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){
@ -55,95 +65,85 @@ void InitMission::initTasks(){
} }
/* UDP bridge */ /* UDP bridge */
PeriodicTaskIF* udpBridgeTask = TaskFactory::instance()->createPeriodicTask( PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask(
"UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
0.2, nullptr);
result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); result = udpBridgeTask->addComponent(objects::UDP_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* udpPollingTask = TaskFactory::instance()-> PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask(
createPeriodicTask("UDP_POLLING", 80, "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, nullptr);
result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); result = udpPollingTask->addComponent(objects::UDP_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 = TaskFactory::instance()-> PeriodicTaskIF* pusVerification = factory->createPeriodicTask(
createPeriodicTask("PUS_VERIF", 40, "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr);
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 = TaskFactory::instance()-> PeriodicTaskIF* pusEvents = factory->createPeriodicTask(
createPeriodicTask("PUS_EVENTS", 60, "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr);
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 = TaskFactory::instance()-> PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask(
createPeriodicTask("PUS_HIGH_PRIO", 50, "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
PeriodicTaskIF::MINIMUM_STACK_SIZE,
0.200, nullptr);
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 = TaskFactory::instance()-> PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask(
createPeriodicTask("PUS_HIGH_PRIO", 40, "PUS_HIGH_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
PeriodicTaskIF::MINIMUM_STACK_SIZE,
0.8, nullptr);
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 = TaskFactory::instance()-> PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask(
createPeriodicTask("PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
1.6, nullptr);
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 = TaskFactory::instance()-> PeriodicTaskIF* testTask = factory->createPeriodicTask(
createPeriodicTask("SPI_TEST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, "TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
2.0, nullptr);
#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 */
#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 */

View File

@ -1,7 +1,7 @@
#ifndef BSP_LINUX_INITMISSION_H_ #ifndef BSP_LINUX_INITMISSION_H_
#define BSP_LINUX_INITMISSION_H_ #define BSP_LINUX_INITMISSION_H_
namespace InitMission { namespace initmission {
void initMission(); void initMission();
void initTasks(); void initTasks();
}; };

View File

@ -1,5 +1,4 @@
#include "ObjectFactory.h" #include "ObjectFactory.h"
#include <bsp_rpi/boardtest/SpiTest.h>
#include <bsp_rpi/gpio/GPIORPi.h> #include <bsp_rpi/gpio/GPIORPi.h>
#include <objects/systemObjectList.h> #include <objects/systemObjectList.h>
@ -8,18 +7,21 @@
#include <tmtc/apid.h> #include <tmtc/apid.h>
#include <tmtc/pusIds.h> #include <tmtc/pusIds.h>
#include <linux/boardtest/LibgpiodTest.h>
#include <linux/boardtest/SpiTestClass.h>
#include <linux/gpio/GpioCookie.h>
#include <linux/gpio/LinuxLibgpioIF.h>
#include <mission/core/GenericFactory.h>
#include <mission/utility/TmFunnel.h>
#include <fsfw/datapoollocal/LocalDataPoolManager.h> #include <fsfw/datapoollocal/LocalDataPoolManager.h>
#include <fsfw/tmtcservices/CommandingServiceBase.h> #include <fsfw/tmtcservices/CommandingServiceBase.h>
#include <fsfw/tmtcservices/PusServiceBase.h> #include <fsfw/tmtcservices/PusServiceBase.h>
#include <fsfw/osal/linux/TmTcUnixUdpBridge.h> #include <fsfw/osal/linux/TmTcUnixUdpBridge.h>
#include <fsfw/tmtcpacket/pus/TmPacketStored.h> #include <fsfw/tmtcpacket/pus/TmPacketStored.h>
#include <fsfw/osal/linux/TcUnixUdpPollingTask.h> #include <fsfw/osal/linux/TcUnixUdpPollingTask.h>
#include <linux/boardtest/LibgpiodTest.h> #include <fsfw/tasks/TaskFactory.h>
#include <linux/gpio/GpioCookie.h>
#include <linux/gpio/LinuxLibgpioIF.h>
#include <mission/core/GenericFactory.h>
#include <mission/utility/TmFunnel.h>
void Factory::setStaticFrameworkObjectIds() { void Factory::setStaticFrameworkObjectIds() {
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
@ -52,7 +54,7 @@ void ObjectFactory::produce(){
new LinuxLibgpioIF(objects::GPIO_IF); new LinuxLibgpioIF(objects::GPIO_IF);
#if RPI_ADD_SPI_TEST == 1 #if RPI_ADD_SPI_TEST == 1
new SpiTest(objects::SPI_TEST); new SpiTestClass(objects::SPI_TEST);
#endif #endif
#if RPI_LOOPBACK_TEST_GPIO == 1 #if RPI_LOOPBACK_TEST_GPIO == 1

View File

@ -1,5 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE target_sources(${TARGET_NAME} PRIVATE
SpiTest.cpp
) )

View File

@ -1,61 +0,0 @@
#include "SpiTest.h"
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <fcntl.h>
#include <sys/ioctl.h>
SpiTest::SpiTest(object_id_t objectId): SystemObject(objectId) {
sif::info << "Setting up Raspberry Pi WiringPi library." << std::endl;
// wiringPiSetupGpio();
// pinMode(SS_MGM_0_LIS3, OUTPUT);
// pinMode(SS_MGM_1_RM, OUTPUT);
// pinMode(SS_GYRO_0_ADIS, OUTPUT);
// pinMode(SS_GYRO_1_L3G, OUTPUT);
// pinMode(SS_GYRO_2_L3G, OUTPUT);
// pinMode(SS_MGM_2_LIS3, OUTPUT);
// pinMode(SS_MGM_3_RM, OUTPUT);
//
// digitalWrite(SS_MGM_0_LIS3, HIGH);
// digitalWrite(SS_MGM_1_RM, HIGH);
// digitalWrite(SS_GYRO_0_ADIS, HIGH);
// digitalWrite(SS_GYRO_1_L3G, HIGH);
// digitalWrite(SS_GYRO_2_L3G, HIGH);
// digitalWrite(SS_MGM_2_LIS3, HIGH);
// digitalWrite(SS_MGM_3_RM, HIGH);
int spiFd = open(spiDeviceName.c_str(), O_RDWR);
if (spiFd < 0){
sif::error << "Could not open SPI device!" << std::endl;
}
spiMode = SPI_MODE_3;
int ret = ioctl(spiFd, SPI_IOC_WR_MODE, &spiMode);
if(ret < 0) {
sif::error << "Could not set write mode!" << std::endl;
}
/* Datenrate setzen */
ret = ioctl(spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed);
if(ret < 0) {
sif::error << "Could not SPI speed!" << std::endl;
}
}
ReturnValue_t SpiTest::performOperation(uint8_t opCode) {
if(oneShot) {
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t SpiTest::initialize() {
//transferHandle.rx_buf = reinterpret_cast<__u64>(receiveBuffer);
//transferHandle.tx_buf = reinterpret_cast<__u64>(sendBuffer);
//transferHandle.speed_hz = 976000;
//transferHandle.len = 2;
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -1,45 +0,0 @@
#ifndef BSP_LINUX_TEST_SPITEST_H_
#define BSP_LINUX_TEST_SPITEST_H_
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <linux/spi/spidev.h>
#include <string>
class SpiTest:
public SystemObject,
public ExecutableObjectIF {
public:
SpiTest(object_id_t objectId);
ReturnValue_t performOperation(uint8_t opCode) override;
ReturnValue_t initialize() override;
private:
// These chip selects (BCM number) will be pulled high if not used
// ACS board specific.
enum SpiChipSelects {
SS_MGM_0_LIS3 = 0, //!< MGM 0, LIS3MDLTR, U6, A side
SS_MGM_1_RM = 1, //!< MGM 1, RM3100, U7, A side
SS_GYRO_0_ADIS = 2, //!< Gyro 0, ADIS16485, U3, A side
SS_GYRO_1_L3G = 3, //!< Gyro 1, L3GD20H, U4, A side
SS_GYRO_2_L3G = 4, //!< Gyro 2, L3GD20h, U5, B side
SS_MGM_2_LIS3 = 17, //!< MGM 2, LIS3MDLTR, U8, B side
SS_MGM_3_RM = 27, //!< MGM 3, RM3100, U9, B side
};
const std::string spiDeviceName = "/dev/spidev0.0";
int spiFd = 0;
uint8_t spiMode = SPI_MODE_3;
uint32_t spiSpeed = 976000;
uint8_t sendBuffer[32];
uint8_t receiveBuffer[32];
struct spi_ioc_transfer transferHandle;
bool oneShot = true;
};
#endif /* BSP_LINUX_TEST_SPITEST_H_ */

View File

@ -1,12 +1,10 @@
#include "InitMission.h" #include "InitMission.h"
#include <OBSWVersion.h> #include <OBSWVersion.h>
#include <fsfw/tasks/TaskFactory.h> #include <fsfw/tasks/TaskFactory.h>
#include <iostream> #include <iostream>
#include <unistd.h>
/** /**
* @brief This is the main program for the target hardware. * @brief This is the main program for the target hardware.
* @return * @return
@ -14,15 +12,15 @@
int main(void) int main(void)
{ {
std::cout << "-- EIVE OBSW --" << std::endl; std::cout << "-- EIVE OBSW --" << std::endl;
std::cout << "-- Compiled for Linux " << " --" << std::endl; std::cout << "-- Compiled for Linux (Raspberry Pi) --" << std::endl;
std::cout << "-- Software version " << SW_NAME << " v" << SW_VERSION << "." std::cout << "-- Software version " << SW_NAME << " v" << SW_VERSION << "."
<< SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << std::endl; << SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << 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);
} }
} }

2
fsfw

@ -1 +1 @@
Subproject commit c28398257b68facbabb19d7228b045f1388305df Subproject commit 144375827441b80a601579fe4395e3bbc19df92c

View File

@ -13,16 +13,17 @@
/* These defines should be disabled for mission code but are useful for /* These defines should be disabled for mission code but are useful for
debugging. */ debugging. */
#define OBSW_VERBOSE_LEVEL 1 #define OBSW_VERBOSE_LEVEL 1
#define OBSW_ADD_TEST_CODE 1 #define OBSW_PRINT_MISSED_DEADLINES 1
#define TEST_LIBGPIOD 0 #define OBSW_ADD_TEST_CODE 1
#define TEST_LIBGPIOD 0
#define TE0720 0 #define TE0720 0
#define P60DOCK_DEBUG 0 #define P60DOCK_DEBUG 0
#define PDU1_DEBUG 0 #define PDU1_DEBUG 0
#define PDU2_DEBUG 0 #define PDU2_DEBUG 0
#define ACU_DEBUG 1 #define ACU_DEBUG 1
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -3,6 +3,7 @@
#include <fsfwconfig/devices/gpioIds.h> #include <fsfwconfig/devices/gpioIds.h>
#include <fsfw/serviceinterface/ServiceInterfaceStream.h> #include <fsfw/serviceinterface/ServiceInterfaceStream.h>
#include <fsfw/objectmanager/ObjectManagerIF.h> #include <fsfw/objectmanager/ObjectManagerIF.h>
#include <fsfw/tasks/TaskFactory.h>
LibgpiodTest::LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, LibgpiodTest::LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId,
GpioCookie* gpioCookie): GpioCookie* gpioCookie):
@ -75,6 +76,22 @@ ReturnValue_t LibgpiodTest::performOneShotAction() {
<< std::endl; << std::endl;
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
result = gpioInterface->pullLow(gpioIds::TEST_ID_0);
if(result == HasReturnvaluesIF::RETURN_OK) {
sif::info << "LibgpiodTest::performOneShotAction:"
"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) {
sif::info << "LibgpiodTest::performOneShotAction:"
"GPIO state read successfully and is low" << std::endl;
}
else {
sif::warning << "LibgpiodTest::performOneShotAction: GPIO read and is not low!"
<< std::endl;
return HasReturnvaluesIF::RETURN_OK;
}
break; break;
} }
} }

View File

@ -4,7 +4,7 @@
#include <fsfw/objectmanager/SystemObjectIF.h> #include <fsfw/objectmanager/SystemObjectIF.h>
#include <fsfw/serviceinterface/ServiceInterface.h> #include <fsfw/serviceinterface/ServiceInterface.h>
namespace InitMission { namespace initmission {
void printAddObjectError(const char* name, object_id_t objectId) { void printAddObjectError(const char* name, object_id_t objectId) {
#if FSFW_CPP_OSTREAM_ENABLED == 1 #if FSFW_CPP_OSTREAM_ENABLED == 1
@ -14,7 +14,7 @@ void printAddObjectError(const char* name, object_id_t objectId) {
#else #else
sif::printError("InitMission::printAddError: Adding object %s with object ID 0x%08x failed!\n" , sif::printError("InitMission::printAddError: Adding object %s with object ID 0x%08x failed!\n" ,
name, objectId); name, objectId);
#endif #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
} }
} }

View File

@ -8,14 +8,9 @@
#include <array> #include <array>
#include <cstring> #include <cstring>
bool TestTask::oneShotAction = true;
MutexIF* TestTask::testLock = nullptr;
TestTask::TestTask(object_id_t objectId_): TestTask::TestTask(object_id_t objectId_):
SystemObject(objectId_), testMode(testModes::A) { SystemObject(objectId_), testMode(testModes::A) {
if(testLock == nullptr) {
testLock = MutexFactory::instance()->createMutex();
}
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE); IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
} }
@ -24,19 +19,17 @@ TestTask::~TestTask() {
ReturnValue_t TestTask::performOperation(uint8_t operationCode) { ReturnValue_t TestTask::performOperation(uint8_t operationCode) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
sif::info << "Hallo EIVE!" << std::endl;
testLock ->lockMutex(MutexIF::TimeoutType::WAITING, 20);
if(oneShotAction) { if(oneShotAction) {
// Add code here which should only be run once /* Add code here which should only be run once */
performOneShotAction(); performOneShotAction();
oneShotAction = false; oneShotAction = false;
} }
testLock->unlockMutex();
// Add code here which should only be run once per performOperation /* Add code here which should only be run once per performOperation */
performPeriodicAction(); performPeriodicAction();
// Add code here which should only be run on alternating cycles. /* Add code here which should only be run on alternating cycles. */
if(testMode == testModes::A) { if(testMode == testModes::A) {
performActionA(); performActionA();
testMode = testModes::B; testMode = testModes::B;
@ -49,7 +42,7 @@ ReturnValue_t TestTask::performOperation(uint8_t operationCode) {
} }
ReturnValue_t TestTask::performOneShotAction() { ReturnValue_t TestTask::performOneShotAction() {
// Everything here will only be performed once. /* Everything here will only be performed once. */
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -61,12 +54,12 @@ ReturnValue_t TestTask::performPeriodicAction() {
ReturnValue_t TestTask::performActionA() { ReturnValue_t TestTask::performActionA() {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
// Add periodically executed code here /* Add periodically executed code here */
return result; return result;
} }
ReturnValue_t TestTask::performActionB() { ReturnValue_t TestTask::performActionB() {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
// Add periodically executed code here /* Add periodically executed code here */
return result; return result;
} }

View File

@ -48,8 +48,7 @@ protected:
private: private:
// Actually, to be really thread-safe, a mutex should be used as well // Actually, to be really thread-safe, a mutex should be used as well
// Let's keep it simple for now. // Let's keep it simple for now.
static bool oneShotAction; bool oneShotAction = true;
static MutexIF* testLock;
StorageManagerIF* IPCStore; StorageManagerIF* IPCStore;
}; };