diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ac7a6ac --- /dev/null +++ b/.gitignore @@ -0,0 +1,40 @@ +# Python +**/.idea/* +!**/.idea/runConfigurations +__pycache__ +*.db +venv + +# Eclipse +.cproject +.project +!misc/eclipse/**/.project +!misc/eclipse/**/.cproject +.pydevproject +.settings +.metadata + + +# Build folders +Debug +Debug* +Release +Release* +RelWithDeb +RelWithDeb* +MinSizeRel +MinSizeRel* +/build* + +_dep +_obj +_bin +Makefile* +!**/make/Makefile* + +# GCOV +*.gcno + +# Visual Studio +.vs +out diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..75ba469 --- /dev/null +++ b/NOTICE @@ -0,0 +1,37 @@ +Flight Software Framework Examples + +The initial version of the Flight Software Framework was developed during +the Flying Laptop Project by the Universität Stuttgart in coorporation +with Airbus Defence and Space GmbH. + +The supreme FSFW Logo was designed by Markus Koller and Luise Trilsbach. + +Copyrights in the Flight Software Framework Examples are retained by their contributors. +No copyright assignment is required to contribute to the Flight Software Framework Examples. + +Some files include explicit copyright notices and/or license notices. +For full authorship information, see the version control history. + +Except as otherwise noted (below and/or in individual files), the +Flight Software Framework Example is licensed under the Apache License, Version 2.0. + + +This example uses: + +The Flight Software Framework from egit@irs.uni-stuttgart.de. + +And optional: +The fsfw_hal from egit@irs.uni-stuttgart.de, + +Hardware Abstraction Layers for common OS / Hardware. + +tmtccmd, from https://github.com/rmspacefish/tmtccmd/, + +A python based TM/TC Tool for testing via the PUS Interface. + +rtems-cmake, from https://github.com/rmspacefish/tmtccmd/ + +A project to build RTEMS with cmake. + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..1cdeda7 --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ + + +# FSFW Example Application + +This repository features a demo application. The example has been run successfully on the following +platforms: + + - Linux host machine with the Linux OSAL or the Host OSAL + - Windows with the Host OSAL + - STM32H743ZI-Nucleo with the FreeRTOS OSAL + - Raspberry Pi with the Linux OSAL + - STM32H743ZI-Nucleo with the RTEMS OSAL + +The purpose of this example is to provide a demo of the FSFW capabilities. +However, it can also be used as a starting point to set up a repository for +new flight software. It also aims to provide developers with practical examples +of how the FSFW is inteded to be used and how project using the FSFW should or can be +set up and it might serve as a basic test platform for the FSFW as well to ensure all OSALs +are compiling and running as expected. + +The repository contains a Python TMTC program which can be used to showcase +the TMTC capabilities of the FSFW (currently, using the ECSS PUS packet standard). + +# Configuring the Example + +The build system will copy three configuration files into the build directory: + +1. `commonConfig.h` which contains common configuration parameters +2. `OBSWConfig.h` which can contain machine and architecture specific configuration options +3. `FSFWConfig.h` which contains the configuration for the flight software framework + +These files can be edited manually after `CMake` build generation. + +# Index + +[Getting started with Eclipse for C/C++](https://egit.irs.uni-stuttgart.de/fsfw/fsfw-example-common/src/branch/master/doc/README-eclipse.md)
+[Getting started with CMake](https://egit.irs.uni-stuttgart.de/fsfw/fsfw-example-common/src/branch/master/doc/README-cmake.md)
+ +[Getting started with the Hosted OSAL](#this)
+[Getting started with the FreeRTOS OSAL on a STM32](https://egit.irs.uni-stuttgart.de/fsfw/fsfw-example-stm32h7-freertos)
+[Getting started with the RTEMS OSAL on a STM32](https://egit.irs.uni-stuttgart.de/fsfw/fsfw-example-stm32h7-rtems)
+[Getting started with the Raspberry Pi](https://egit.irs.uni-stuttgart.de/fsfw/fsfw-example-linux-mcu)
+[Getting started with the Beagle Bone Black](https://egit.irs.uni-stuttgart.de/fsfw/fsfw-example-linux-mcu)
+ +# Linux - Enabling RTOS functionalities + +The last chapter in the [Linux README](https://egit.irs.uni-stuttgart.de/fsfw/fsfw-example-linux-mcu) +specifies some steps required to cleanly run the FSFW on a (host) Linux system if +real time functionalities are turned on via `FSFWConfig.h`. + +# Setting up Eclipse for CMake projects + +The separate [Eclipse README](https://egit.irs.uni-stuttgart.de/fsfw/fsfw-example-common/src/branch/master/doc/README-eclipse.md) specifies how to set up Eclipse to build CMake +projects. Separate project files and launch configurations for the MinGW build were provided. +The debug output is colored by default. It is recommended to install the +`ANSI Escape in Console` plugin in Eclipse so the coloring works in the Eclipse console. On Windows, +it is recommended to run the applicaton with the Windows command line for the printout to work +properly. You can do this by simply double-clicking the binary or using `start ` in the +Windows command line + diff --git a/bsp_linux/CMakeLists.txt b/bsp_linux/CMakeLists.txt new file mode 100644 index 0000000..363be99 --- /dev/null +++ b/bsp_linux/CMakeLists.txt @@ -0,0 +1,14 @@ +target_sources(${TARGET_NAME} + PRIVATE + main.cpp +) + +add_subdirectory(core) +add_subdirectory(fsfwconfig) +add_subdirectory(utility) +add_subdirectory(test) + +target_include_directories(${TARGET_NAME} + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} +) \ No newline at end of file diff --git a/bsp_linux/Dockerfile b/bsp_linux/Dockerfile new file mode 100644 index 0000000..28105f4 --- /dev/null +++ b/bsp_linux/Dockerfile @@ -0,0 +1,18 @@ +FROM ubuntu:latest +# FROM alpine:latest + +RUN apt-get update && apt-get install -y cmake g++ +# RUN apk add cmake make g++ + +WORKDIR /usr/src/app +COPY . . + +RUN set -ex; \ + rm -rf build-linux; \ + mkdir build-linux; \ + cd build-linux; \ + cmake -DCMAKE_BUILD_TYPE=Release -DOS_FSFW=linux ..; + +ENTRYPOINT ["cmake", "--build", "build-linux"] +CMD ["-j"] +# CMD ["bash"] diff --git a/bsp_linux/core/CMakeLists.txt b/bsp_linux/core/CMakeLists.txt new file mode 100644 index 0000000..2b124ba --- /dev/null +++ b/bsp_linux/core/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(${TARGET_NAME} + PRIVATE + InitMission.cpp + ObjectFactory.cpp +) \ No newline at end of file diff --git a/bsp_linux/core/InitMission.cpp b/bsp_linux/core/InitMission.cpp new file mode 100644 index 0000000..d74ba45 --- /dev/null +++ b/bsp_linux/core/InitMission.cpp @@ -0,0 +1,241 @@ +#include "InitMission.h" +#include "OBSWConfig.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +void InitMission::createTasks() { + TaskFactory* taskFactory = TaskFactory::instance(); + if(taskFactory == nullptr) { + return; + } + +#if OBSW_ADD_CORE_COMPONENTS == 1 + /* TMTC Distribution */ + PeriodicTaskIF* distributerTask = taskFactory-> + createPeriodicTask("DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, nullptr); + ReturnValue_t result = distributerTask->addComponent(objects::CCSDS_DISTRIBUTOR); + if (result != HasReturnvaluesIF::RETURN_OK) { + task::printInitError("CCSDS distributor", objects::CCSDS_DISTRIBUTOR); + } + result = distributerTask->addComponent(objects::PUS_DISTRIBUTOR); + if (result!=HasReturnvaluesIF::RETURN_OK) { + task::printInitError("PUS distributor", objects::PUS_DISTRIBUTOR); + } + result = distributerTask->addComponent(objects::TM_FUNNEL); + if (result != HasReturnvaluesIF::RETURN_OK) { + task::printInitError("TM funnel", objects::TM_FUNNEL); + } + + /* UDP bridge */ + PeriodicTaskIF* udpBridgeTask = taskFactory->createPeriodicTask( + "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, nullptr); + result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); + if(result != HasReturnvaluesIF::RETURN_OK) { + task::printInitError("UDP bridge", objects::UDP_BRIDGE); + } + /* UDP polling task */ + PeriodicTaskIF* udpPollingTask = taskFactory->createPeriodicTask( + "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.1, nullptr); + result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); + if(result != HasReturnvaluesIF::RETURN_OK) { + task::printInitError("UDP polling", objects::UDP_POLLING_TASK); + } + + PeriodicTaskIF* eventTask = taskFactory->createPeriodicTask( + "EVENT_MGMT", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.1, nullptr); + result = eventTask->addComponent(objects::EVENT_MANAGER); + if(result != HasReturnvaluesIF::RETURN_OK){ + task::printInitError("Event Manager", objects::EVENT_MANAGER); + } +#endif /* OBSW_ADD_CORE_COMPONENTS == 1 */ + +#if OBSW_ADD_TASK_EXAMPLE == 1 + FixedTimeslotTaskIF* timeslotDemoTask = taskFactory->createFixedTimeslotTask + ("PST_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.5, nullptr); + result = pst::pollingSequenceExamples(timeslotDemoTask); + if(result != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "InitMission::createTasks: Timeslot demo task" + <<" initialization failed!" << std::endl; +#else + sif::printError("InitMission::createTasks: Timeslot demo task" + " initialization failed!\n"); +#endif + } + + PeriodicTaskIF* readerTask = taskFactory-> + createPeriodicTask("READER_TASK", 40, + PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr); + result = readerTask->addComponent(objects::TEST_DUMMY_4); + if(result != HasReturnvaluesIF::RETURN_OK) { + task::printInitError("Dummy 4", objects::TEST_DUMMY_4); + } +#endif /* OBSW_ADD_TASK_EXAMPLE == 1 */ + +#if OBSW_ADD_PUS_STACK == 1 + /* PUS Services */ + PeriodicTaskIF* pusVerification = taskFactory->createPeriodicTask( + "PUS_VERIF_1", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, nullptr); + result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); + if(result != HasReturnvaluesIF::RETURN_OK) { + task::printInitError("PUS 1", objects::PUS_SERVICE_1_VERIFICATION); + } + + PeriodicTaskIF* pusHighPrio = taskFactory->createPeriodicTask( + "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, nullptr); + result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); + if (result != HasReturnvaluesIF::RETURN_OK) { + task::printInitError("PUS 2", objects::PUS_SERVICE_2_DEVICE_ACCESS); + } + result = pusHighPrio->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); + if(result != HasReturnvaluesIF::RETURN_OK){ + task::printInitError("PUS 5",objects::PUS_SERVICE_5_EVENT_REPORTING); + } + result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + task::printInitError("PUS 9", objects::PUS_SERVICE_9_TIME_MGMT); + } + + PeriodicTaskIF* pusMedPrio = taskFactory->createPeriodicTask( + "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, nullptr); + result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + task::printInitError("PUS 8", objects::PUS_SERVICE_8_FUNCTION_MGMT); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); + if (result != HasReturnvaluesIF::RETURN_OK) { + task::printInitError("PUS 20", objects::PUS_SERVICE_20_PARAMETERS); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); + if (result != HasReturnvaluesIF::RETURN_OK) { + task::printInitError("PUS 200", objects::PUS_SERVICE_200_MODE_MGMT); + } + + PeriodicTaskIF* pusLowPrio = taskFactory->createPeriodicTask( + "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, nullptr); + result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); + if(result != HasReturnvaluesIF::RETURN_OK) { + task::printInitError("PUS 17", objects::PUS_SERVICE_17_TEST); + } +#endif /* OBSW_ADD_PUS_STACK == 1 */ + +#if OBSW_ADD_DEVICE_HANDLER_DEMO == 1 + FixedTimeslotTaskIF* testDeviceTask = taskFactory->createFixedTimeslotTask( + "PST_TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr); + result = pst::pollingSequenceDevices(testDeviceTask); + if(result != HasReturnvaluesIF::RETURN_OK) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "InitMission::createTasks: Test PST initialization failed!" << std::endl; +#else + sif::printError("InitMission::createTasks: Test PST initialization failed!\n\r"); +#endif + } + PeriodicTaskIF* assemblyTask = taskFactory->createPeriodicTask("ASS_TASK", 30, + PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, nullptr); + if(assemblyTask == nullptr){ + task::printInitError("ASS_TASK", objects::TEST_ASSEMBLY); + } + result = assemblyTask->addComponent(objects::TEST_ASSEMBLY); + if(result != HasReturnvaluesIF::RETURN_OK) { + task::printInitError("ASS_TASK", objects::TEST_ASSEMBLY); + } +#endif /* OBSW_ADD_DEVICE_HANDLER_DEMO == 1 */ + +#if OBSW_ADD_CONTROLLER_DEMO == 1 + PeriodicTaskIF* controllerTask = taskFactory->createPeriodicTask( + "TEST_CTRL", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, nullptr); + result = controllerTask->addComponent(objects::TEST_CONTROLLER); + if(result != HasReturnvaluesIF::RETURN_OK) { + task::printInitError("Controller Task", objects::TEST_CONTROLLER); + } +#endif /* OBSW_ADD_CONTROLLER_DEMO == 1 */ + + PeriodicTaskIF* testTask = taskFactory->createPeriodicTask( + "TEST", 15, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr); + result = testTask->addComponent(objects::TEST_TASK); + if(result != HasReturnvaluesIF::RETURN_OK) { + task::printInitError("Test Task", objects::TEST_TASK); + } + +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "Starting tasks.." << std::endl; +#else + sif::printInfo("Starting tasks..\n"); +#endif + +#if OBSW_ADD_CORE_COMPONENTS == 1 + distributerTask->startTask(); + udpBridgeTask->startTask(); + udpPollingTask->startTask(); + eventTask->startTask(); +#endif /* OBSW_ADD_CORE_COMPONENTS == 1 */ + +#if OBSW_ADD_PUS_STACK == 1 + pusVerification->startTask(); + pusHighPrio->startTask(); + pusMedPrio->startTask(); + pusLowPrio->startTask(); +#endif /* OBSW_ADD_PUS_STACK == 1 */ + +#if OBSW_ADD_TASK_EXAMPLE == 1 + timeslotDemoTask->startTask(); + readerTask->startTask(); +#endif /* OBSW_ADD_TASK_EXAMPLE == 1 */ + +#if OBSW_ADD_DEVICE_HANDLER_DEMO == 1 + testDeviceTask->startTask(); + assemblyTask->startTask(); +#endif /* OBSW_ADD_DEVICE_HANDLER_DEMO == 1 */ + +#if OBSW_ADD_CONTROLLER_DEMO == 1 + controllerTask->startTask(); +#endif /* OBSW_ADD_CONTROLLER_DEMO == 1 */ + + testTask->startTask(); + +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "Tasks started.." << std::endl; +#else + sif::printInfo("Tasks started..\n"); +#endif + + +#if OBSW_ADD_DEVICE_HANDLER_DEMO + HasModesIF* assembly = ObjectManager::instance()->get(objects::TEST_ASSEMBLY); + if (assembly == nullptr){ + return; + } +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "Waiting 5 Seconds and then command Test Assembly to Normal, Dual" << std::endl; +#else + sif::printInfo("Waiting 5 Seconds and then command Test Assembly to Normal, Dual \n"); +#endif + + TaskFactory::delayTask(5000); + CommandMessage modeMessage; + ModeMessage::setModeMessage(&modeMessage, ModeMessage::CMD_MODE_COMMAND, + DeviceHandlerIF::MODE_NORMAL, TestAssembly::submodes::DUAL); +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "Commanding Test Assembly to Normal, Dual" << std::endl; +#else + sif::printInfo("Commanding Test Assembly to Normal, Dual \n"); +#endif + MessageQueueSenderIF::sendMessage(assembly->getCommandQueue(), &modeMessage, + MessageQueueIF::NO_QUEUE); +#endif /* OBSW_ADD_DEVICE_HANDLER_DEMO */ +} diff --git a/bsp_linux/core/InitMission.h b/bsp_linux/core/InitMission.h new file mode 100644 index 0000000..8c4788d --- /dev/null +++ b/bsp_linux/core/InitMission.h @@ -0,0 +1,8 @@ +#ifndef MISSION_CORE_INITMISSION_H_ +#define MISSION_CORE_INITMISSION_H_ + +namespace InitMission { +void createTasks(); +}; + +#endif /* MISSION_CORE_INITMISSION_H_ */ diff --git a/bsp_linux/core/ObjectFactory.cpp b/bsp_linux/core/ObjectFactory.cpp new file mode 100644 index 0000000..6a1fe59 --- /dev/null +++ b/bsp_linux/core/ObjectFactory.cpp @@ -0,0 +1,57 @@ +#include "OBSWConfig.h" + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +void ObjectFactory::produce(void* args) { + /* Located inside the GenericFactory source file */ + Factory::setStaticFrameworkObjectIds(); + +#if OBSW_ADD_CORE_COMPONENTS == 1 + { + LocalPool::LocalPoolConfig poolCfg = { + {16, 100},{32, 50}, {64, 25}, {128,15}, {1024, 5} + }; + new PoolManager(objects::TC_STORE, poolCfg); + } + + { + LocalPool::LocalPoolConfig poolCfg = { + {16, 100},{32, 50}, {64, 25}, {128,15}, {1024, 5} + }; + new PoolManager(objects::TM_STORE, poolCfg); + } + + { + LocalPool::LocalPoolConfig poolCfg = { + {16, 100},{32, 50}, {64, 25}, {128,15}, {1024, 5} + }; + new PoolManager(objects::IPC_STORE, poolCfg); + } + + /* TMTC Reception via UDP socket */ + auto tmtcBridge = new UdpTmTcBridge(objects::UDP_BRIDGE, objects::CCSDS_DISTRIBUTOR); + tmtcBridge->setMaxNumberOfPacketsStored(20); + new UdpTcPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); +#endif /* OBSW_ADD_CORE_COMPONENTS == 1 */ + + ObjectFactory::produceGenericObjects(); + new TestTask(objects::TEST_TASK, false); +} diff --git a/bsp_linux/core/ObjectFactory.h b/bsp_linux/core/ObjectFactory.h new file mode 100644 index 0000000..1151a9e --- /dev/null +++ b/bsp_linux/core/ObjectFactory.h @@ -0,0 +1,10 @@ +#ifndef MISSION_CORE_OBJECTFACTORY_H_ +#define MISSION_CORE_OBJECTFACTORY_H_ + + +namespace ObjectFactory { + void setStatics(); + void produce(void* args); +}; + +#endif /* MISSION_CORE_OBJECTFACTORY_H_ */ diff --git a/bsp_linux/fsfwconfig/CMakeLists.txt b/bsp_linux/fsfwconfig/CMakeLists.txt new file mode 100644 index 0000000..a81b34d --- /dev/null +++ b/bsp_linux/fsfwconfig/CMakeLists.txt @@ -0,0 +1,22 @@ +target_sources(${TARGET_NAME} PRIVATE + ipc/missionMessageTypes.cpp +) + +# Add include paths for the executable +target_include_directories(${TARGET_NAME} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} +) + +# If a special translation file for object IDs exists, compile it. +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/objects/translateObjects.cpp") + target_sources(${TARGET_NAME} PRIVATE + objects/translateObjects.cpp + ) +endif() + +# If a special translation file for events exists, compile it. +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/objects/translateObjects.cpp") + target_sources(${TARGET_NAME} PRIVATE + events/translateEvents.cpp + ) +endif() diff --git a/bsp_linux/fsfwconfig/FSFWConfig.h.in b/bsp_linux/fsfwconfig/FSFWConfig.h.in new file mode 100644 index 0000000..bd128ad --- /dev/null +++ b/bsp_linux/fsfwconfig/FSFWConfig.h.in @@ -0,0 +1,72 @@ +#ifndef CONFIG_FSFWCONFIG_H_ +#define CONFIG_FSFWCONFIG_H_ + +#include +#include + +//! Used to determine whether C++ ostreams are used which can increase +//! the binary size significantly. If this is disabled, +//! the C stdio functions can be used alternatively +#define FSFW_CPP_OSTREAM_ENABLED 1 + +//! More FSFW related printouts depending on level. Useful for development. +#define FSFW_VERBOSE_LEVEL 1 + +//! Can be used to completely disable printouts, even the C stdio ones. +#if FSFW_CPP_OSTREAM_ENABLED == 0 && FSFW_VERBOSE_LEVEL == 0 + #define FSFW_DISABLE_PRINTOUT 0 +#endif + +#define FSFW_USE_PUS_C_TELEMETRY 1 + +//! Can be used to disable the ANSI color sequences for C stdio. +#define FSFW_COLORED_OUTPUT 1 + +//! If FSFW_OBJ_EVENT_TRANSLATION is set to one, +//! additional output which requires the translation files translateObjects +//! and translateEvents (and their compiled source files) +#define FSFW_OBJ_EVENT_TRANSLATION 1 + +#if FSFW_OBJ_EVENT_TRANSLATION == 1 +//! Specify whether info events are printed too. +#define FSFW_DEBUG_INFO 1 +#include "objects/translateObjects.h" +#include "events/translateEvents.h" +#else +#endif + +//! When using the newlib nano library, C99 support for stdio facilities +//! will not be provided. This define should be set to 1 if this is the case. +#define FSFW_NO_C99_IO 1 + +//! Specify whether a special mode store is used for Subsystem components. +#define FSFW_USE_MODESTORE 0 + +//! Defines if the real time scheduler for linux should be used. +//! If set to 0, this will also disable priority settings for linux +//! as most systems will not allow to set nice values without privileges +//! For embedded linux system set this to 1. +//! If set to 1 the binary needs "cap_sys_nice=eip" privileges to run +#define FSFW_USE_REALTIME_FOR_LINUX 0 + +namespace fsfwconfig { + +//! Default timestamp size. The default timestamp will be an seven byte CDC short timestamp. +static constexpr uint8_t FSFW_MISSION_TIMESTAMP_SIZE = 7; + +//! Configure the allocated pool sizes for the event manager. +static constexpr size_t FSFW_EVENTMGMR_MATCHTREE_NODES = 240; +static constexpr size_t FSFW_EVENTMGMT_EVENTIDMATCHERS = 120; +static constexpr size_t FSFW_EVENTMGMR_RANGEMATCHERS = 120; + +//! Defines the FIFO depth of each commanding service base which +//! also determines how many commands a CSB service can handle in one cycle +//! simultaneously. This will increase the required RAM for +//! each CSB service ! +static constexpr uint8_t FSFW_CSB_FIFO_DEPTH = 6; + +static constexpr size_t FSFW_PRINT_BUFFER_SIZE = 124; + +} + +#endif /* CONFIG_FSFWCONFIG_H_ */ diff --git a/bsp_linux/fsfwconfig/OBSWConfig.h.in b/bsp_linux/fsfwconfig/OBSWConfig.h.in new file mode 100644 index 0000000..d90a917 --- /dev/null +++ b/bsp_linux/fsfwconfig/OBSWConfig.h.in @@ -0,0 +1,25 @@ +/** + * @brief This file can be used to add preprocessor define for conditional + * code inclusion exclusion or various other project constants and + * properties in one place. + */ +#ifndef FSFWCONFIG_OBSWCONFIG_H_ +#define FSFWCONFIG_OBSWCONFIG_H_ + +#include + +#ifdef __cplusplus + +#include "events/subsystemIdRanges.h" +#include "objects/systemObjectList.h" + +namespace config { +#endif + +/* Add mission configuration flags here */ + +#ifdef __cplusplus +} +#endif + +#endif /* FSFWCONFIG_OBSWCONFIG_H_ */ diff --git a/bsp_linux/fsfwconfig/events/subsystemIdRanges.h b/bsp_linux/fsfwconfig/events/subsystemIdRanges.h new file mode 100644 index 0000000..5d1fe3b --- /dev/null +++ b/bsp_linux/fsfwconfig/events/subsystemIdRanges.h @@ -0,0 +1,12 @@ +#ifndef FSFWCONFIG_TMTC_SUBSYSTEMIDRANGES_H_ +#define FSFWCONFIG_TMTC_SUBSYSTEMIDRANGES_H_ + +#include "commonSubsystemIds.h" + +namespace SUBSYSTEM_ID { +enum subsystemId: uint8_t { + SUBSYSTEM_ID_START = COMMON_SUBSYSTEM_ID_END +}; +} + +#endif /* FSFWCONFIG_TMTC_SUBSYSTEMIDRANGES_H_ */ diff --git a/bsp_linux/fsfwconfig/events/translateEvents.cpp b/bsp_linux/fsfwconfig/events/translateEvents.cpp new file mode 100644 index 0000000..49d993b --- /dev/null +++ b/bsp_linux/fsfwconfig/events/translateEvents.cpp @@ -0,0 +1,249 @@ +/** + * @brief Auto-generated event translation file. Contains 78 translations. + * @details + * Generated on: 2021-05-28 18:21:48 + */ +#include "translateEvents.h" + +const char *STORE_SEND_WRITE_FAILED_STRING = "STORE_SEND_WRITE_FAILED"; +const char *STORE_WRITE_FAILED_STRING = "STORE_WRITE_FAILED"; +const char *STORE_SEND_READ_FAILED_STRING = "STORE_SEND_READ_FAILED"; +const char *STORE_READ_FAILED_STRING = "STORE_READ_FAILED"; +const char *UNEXPECTED_MSG_STRING = "UNEXPECTED_MSG"; +const char *STORING_FAILED_STRING = "STORING_FAILED"; +const char *TM_DUMP_FAILED_STRING = "TM_DUMP_FAILED"; +const char *STORE_INIT_FAILED_STRING = "STORE_INIT_FAILED"; +const char *STORE_INIT_EMPTY_STRING = "STORE_INIT_EMPTY"; +const char *STORE_CONTENT_CORRUPTED_STRING = "STORE_CONTENT_CORRUPTED"; +const char *STORE_INITIALIZE_STRING = "STORE_INITIALIZE"; +const char *INIT_DONE_STRING = "INIT_DONE"; +const char *DUMP_FINISHED_STRING = "DUMP_FINISHED"; +const char *DELETION_FINISHED_STRING = "DELETION_FINISHED"; +const char *DELETION_FAILED_STRING = "DELETION_FAILED"; +const char *AUTO_CATALOGS_SENDING_FAILED_STRING = "AUTO_CATALOGS_SENDING_FAILED"; +const char *GET_DATA_FAILED_STRING = "GET_DATA_FAILED"; +const char *STORE_DATA_FAILED_STRING = "STORE_DATA_FAILED"; +const char *DEVICE_BUILDING_COMMAND_FAILED_STRING = "DEVICE_BUILDING_COMMAND_FAILED"; +const char *DEVICE_SENDING_COMMAND_FAILED_STRING = "DEVICE_SENDING_COMMAND_FAILED"; +const char *DEVICE_REQUESTING_REPLY_FAILED_STRING = "DEVICE_REQUESTING_REPLY_FAILED"; +const char *DEVICE_READING_REPLY_FAILED_STRING = "DEVICE_READING_REPLY_FAILED"; +const char *DEVICE_INTERPRETING_REPLY_FAILED_STRING = "DEVICE_INTERPRETING_REPLY_FAILED"; +const char *DEVICE_MISSED_REPLY_STRING = "DEVICE_MISSED_REPLY"; +const char *DEVICE_UNKNOWN_REPLY_STRING = "DEVICE_UNKNOWN_REPLY"; +const char *DEVICE_UNREQUESTED_REPLY_STRING = "DEVICE_UNREQUESTED_REPLY"; +const char *INVALID_DEVICE_COMMAND_STRING = "INVALID_DEVICE_COMMAND"; +const char *MONITORING_LIMIT_EXCEEDED_STRING = "MONITORING_LIMIT_EXCEEDED"; +const char *MONITORING_AMBIGUOUS_STRING = "MONITORING_AMBIGUOUS"; +const char *FUSE_CURRENT_HIGH_STRING = "FUSE_CURRENT_HIGH"; +const char *FUSE_WENT_OFF_STRING = "FUSE_WENT_OFF"; +const char *POWER_ABOVE_HIGH_LIMIT_STRING = "POWER_ABOVE_HIGH_LIMIT"; +const char *POWER_BELOW_LOW_LIMIT_STRING = "POWER_BELOW_LOW_LIMIT"; +const char *SWITCH_WENT_OFF_STRING = "SWITCH_WENT_OFF"; +const char *HEATER_ON_STRING = "HEATER_ON"; +const char *HEATER_OFF_STRING = "HEATER_OFF"; +const char *HEATER_TIMEOUT_STRING = "HEATER_TIMEOUT"; +const char *HEATER_STAYED_ON_STRING = "HEATER_STAYED_ON"; +const char *HEATER_STAYED_OFF_STRING = "HEATER_STAYED_OFF"; +const char *TEMP_SENSOR_HIGH_STRING = "TEMP_SENSOR_HIGH"; +const char *TEMP_SENSOR_LOW_STRING = "TEMP_SENSOR_LOW"; +const char *TEMP_SENSOR_GRADIENT_STRING = "TEMP_SENSOR_GRADIENT"; +const char *COMPONENT_TEMP_LOW_STRING = "COMPONENT_TEMP_LOW"; +const char *COMPONENT_TEMP_HIGH_STRING = "COMPONENT_TEMP_HIGH"; +const char *COMPONENT_TEMP_OOL_LOW_STRING = "COMPONENT_TEMP_OOL_LOW"; +const char *COMPONENT_TEMP_OOL_HIGH_STRING = "COMPONENT_TEMP_OOL_HIGH"; +const char *TEMP_NOT_IN_OP_RANGE_STRING = "TEMP_NOT_IN_OP_RANGE"; +const char *FDIR_CHANGED_STATE_STRING = "FDIR_CHANGED_STATE"; +const char *FDIR_STARTS_RECOVERY_STRING = "FDIR_STARTS_RECOVERY"; +const char *FDIR_TURNS_OFF_DEVICE_STRING = "FDIR_TURNS_OFF_DEVICE"; +const char *MONITOR_CHANGED_STATE_STRING = "MONITOR_CHANGED_STATE"; +const char *VALUE_BELOW_LOW_LIMIT_STRING = "VALUE_BELOW_LOW_LIMIT"; +const char *VALUE_ABOVE_HIGH_LIMIT_STRING = "VALUE_ABOVE_HIGH_LIMIT"; +const char *VALUE_OUT_OF_RANGE_STRING = "VALUE_OUT_OF_RANGE"; +const char *SWITCHING_TM_FAILED_STRING = "SWITCHING_TM_FAILED"; +const char *CHANGING_MODE_STRING = "CHANGING_MODE"; +const char *MODE_INFO_STRING = "MODE_INFO"; +const char *FALLBACK_FAILED_STRING = "FALLBACK_FAILED"; +const char *MODE_TRANSITION_FAILED_STRING = "MODE_TRANSITION_FAILED"; +const char *CANT_KEEP_MODE_STRING = "CANT_KEEP_MODE"; +const char *OBJECT_IN_INVALID_MODE_STRING = "OBJECT_IN_INVALID_MODE"; +const char *FORCING_MODE_STRING = "FORCING_MODE"; +const char *MODE_CMD_REJECTED_STRING = "MODE_CMD_REJECTED"; +const char *HEALTH_INFO_STRING = "HEALTH_INFO"; +const char *CHILD_CHANGED_HEALTH_STRING = "CHILD_CHANGED_HEALTH"; +const char *CHILD_PROBLEMS_STRING = "CHILD_PROBLEMS"; +const char *OVERWRITING_HEALTH_STRING = "OVERWRITING_HEALTH"; +const char *TRYING_RECOVERY_STRING = "TRYING_RECOVERY"; +const char *RECOVERY_STEP_STRING = "RECOVERY_STEP"; +const char *RECOVERY_DONE_STRING = "RECOVERY_DONE"; +const char *RF_AVAILABLE_STRING = "RF_AVAILABLE"; +const char *RF_LOST_STRING = "RF_LOST"; +const char *BIT_LOCK_STRING = "BIT_LOCK"; +const char *BIT_LOCK_LOST_STRING = "BIT_LOCK_LOST"; +const char *FRAME_PROCESSING_FAILED_STRING = "FRAME_PROCESSING_FAILED"; +const char *CLOCK_SET_STRING = "CLOCK_SET"; +const char *CLOCK_SET_FAILURE_STRING = "CLOCK_SET_FAILURE"; +const char *TEST_STRING = "TEST"; + +const char * translateEvents(Event event) { + switch( (event & 0xffff) ) { + case(2200): + return STORE_SEND_WRITE_FAILED_STRING; + case(2201): + return STORE_WRITE_FAILED_STRING; + case(2202): + return STORE_SEND_READ_FAILED_STRING; + case(2203): + return STORE_READ_FAILED_STRING; + case(2204): + return UNEXPECTED_MSG_STRING; + case(2205): + return STORING_FAILED_STRING; + case(2206): + return TM_DUMP_FAILED_STRING; + case(2207): + return STORE_INIT_FAILED_STRING; + case(2208): + return STORE_INIT_EMPTY_STRING; + case(2209): + return STORE_CONTENT_CORRUPTED_STRING; + case(2210): + return STORE_INITIALIZE_STRING; + case(2211): + return INIT_DONE_STRING; + case(2212): + return DUMP_FINISHED_STRING; + case(2213): + return DELETION_FINISHED_STRING; + case(2214): + return DELETION_FAILED_STRING; + case(2215): + return AUTO_CATALOGS_SENDING_FAILED_STRING; + case(2600): + return GET_DATA_FAILED_STRING; + case(2601): + return STORE_DATA_FAILED_STRING; + case(2800): + return DEVICE_BUILDING_COMMAND_FAILED_STRING; + case(2801): + return DEVICE_SENDING_COMMAND_FAILED_STRING; + case(2802): + return DEVICE_REQUESTING_REPLY_FAILED_STRING; + case(2803): + return DEVICE_READING_REPLY_FAILED_STRING; + case(2804): + return DEVICE_INTERPRETING_REPLY_FAILED_STRING; + case(2805): + return DEVICE_MISSED_REPLY_STRING; + case(2806): + return DEVICE_UNKNOWN_REPLY_STRING; + case(2807): + return DEVICE_UNREQUESTED_REPLY_STRING; + case(2808): + return INVALID_DEVICE_COMMAND_STRING; + case(2809): + return MONITORING_LIMIT_EXCEEDED_STRING; + case(2810): + return MONITORING_AMBIGUOUS_STRING; + case(4201): + return FUSE_CURRENT_HIGH_STRING; + case(4202): + return FUSE_WENT_OFF_STRING; + case(4204): + return POWER_ABOVE_HIGH_LIMIT_STRING; + case(4205): + return POWER_BELOW_LOW_LIMIT_STRING; + case(4300): + return SWITCH_WENT_OFF_STRING; + case(5000): + return HEATER_ON_STRING; + case(5001): + return HEATER_OFF_STRING; + case(5002): + return HEATER_TIMEOUT_STRING; + case(5003): + return HEATER_STAYED_ON_STRING; + case(5004): + return HEATER_STAYED_OFF_STRING; + case(5200): + return TEMP_SENSOR_HIGH_STRING; + case(5201): + return TEMP_SENSOR_LOW_STRING; + case(5202): + return TEMP_SENSOR_GRADIENT_STRING; + case(5901): + return COMPONENT_TEMP_LOW_STRING; + case(5902): + return COMPONENT_TEMP_HIGH_STRING; + case(5903): + return COMPONENT_TEMP_OOL_LOW_STRING; + case(5904): + return COMPONENT_TEMP_OOL_HIGH_STRING; + case(5905): + return TEMP_NOT_IN_OP_RANGE_STRING; + case(7101): + return FDIR_CHANGED_STATE_STRING; + case(7102): + return FDIR_STARTS_RECOVERY_STRING; + case(7103): + return FDIR_TURNS_OFF_DEVICE_STRING; + case(7201): + return MONITOR_CHANGED_STATE_STRING; + case(7202): + return VALUE_BELOW_LOW_LIMIT_STRING; + case(7203): + return VALUE_ABOVE_HIGH_LIMIT_STRING; + case(7204): + return VALUE_OUT_OF_RANGE_STRING; + case(7301): + return SWITCHING_TM_FAILED_STRING; + case(7400): + return CHANGING_MODE_STRING; + case(7401): + return MODE_INFO_STRING; + case(7402): + return FALLBACK_FAILED_STRING; + case(7403): + return MODE_TRANSITION_FAILED_STRING; + case(7404): + return CANT_KEEP_MODE_STRING; + case(7405): + return OBJECT_IN_INVALID_MODE_STRING; + case(7406): + return FORCING_MODE_STRING; + case(7407): + return MODE_CMD_REJECTED_STRING; + case(7506): + return HEALTH_INFO_STRING; + case(7507): + return CHILD_CHANGED_HEALTH_STRING; + case(7508): + return CHILD_PROBLEMS_STRING; + case(7509): + return OVERWRITING_HEALTH_STRING; + case(7510): + return TRYING_RECOVERY_STRING; + case(7511): + return RECOVERY_STEP_STRING; + case(7512): + return RECOVERY_DONE_STRING; + case(7900): + return RF_AVAILABLE_STRING; + case(7901): + return RF_LOST_STRING; + case(7902): + return BIT_LOCK_STRING; + case(7903): + return BIT_LOCK_LOST_STRING; + case(7905): + return FRAME_PROCESSING_FAILED_STRING; + case(8900): + return CLOCK_SET_STRING; + case(8901): + return CLOCK_SET_FAILURE_STRING; + case(9700): + return TEST_STRING; + default: + return "UNKNOWN_EVENT"; + } + return 0; +} diff --git a/bsp_linux/fsfwconfig/events/translateEvents.h b/bsp_linux/fsfwconfig/events/translateEvents.h new file mode 100644 index 0000000..9034dcf --- /dev/null +++ b/bsp_linux/fsfwconfig/events/translateEvents.h @@ -0,0 +1,8 @@ +#ifndef FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_ +#define FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_ + +#include + +const char * translateEvents(Event event); + +#endif /* FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_ */ diff --git a/bsp_linux/fsfwconfig/fsfwconfig.mk b/bsp_linux/fsfwconfig/fsfwconfig.mk new file mode 100644 index 0000000..4577ab6 --- /dev/null +++ b/bsp_linux/fsfwconfig/fsfwconfig.mk @@ -0,0 +1,8 @@ +CXXSRC += $(wildcard $(CURRENTPATH)/datapool/*.cpp) +CXXSRC += $(wildcard $(CURRENTPATH)/events/*.cpp) +CXXSRC += $(wildcard $(CURRENTPATH)/ipc/*.cpp) +CXXSRC += $(wildcard $(CURRENTPATH)/objects/*.cpp) +CXXSRC += $(wildcard $(CURRENTPATH)/pollingsequence/*.cpp) + +INCLUDES += $(CURRENTPATH) +INCLUDES += $(CURRENTPATH)/events \ No newline at end of file diff --git a/bsp_linux/fsfwconfig/ipc/missionMessageTypes.cpp b/bsp_linux/fsfwconfig/ipc/missionMessageTypes.cpp new file mode 100644 index 0000000..5fca594 --- /dev/null +++ b/bsp_linux/fsfwconfig/ipc/missionMessageTypes.cpp @@ -0,0 +1,11 @@ +#include "missionMessageTypes.h" +#include +#include + +void messagetypes::clearMissionMessage(CommandMessage* message) { + switch((message->getMessageType())) { + default: + message->setCommand(CommandMessage::CMD_NONE); + break; + } +} diff --git a/bsp_linux/fsfwconfig/ipc/missionMessageTypes.h b/bsp_linux/fsfwconfig/ipc/missionMessageTypes.h new file mode 100644 index 0000000..9733220 --- /dev/null +++ b/bsp_linux/fsfwconfig/ipc/missionMessageTypes.h @@ -0,0 +1,19 @@ +#ifndef FSFWCONFIG_IPC_MISSIONMESSAGETYPES_H_ +#define FSFWCONFIG_IPC_MISSIONMESSAGETYPES_H_ + +#include + +class CommandMessage; + +namespace messagetypes { +/* First type must have number MESSAGE_TYPE::FW_MESSAGES_COUNT! */ +/* Remember to add new message types to the clearMissionMessage function below! */ +enum MISSION_MESSAGE_TYPE { + COSTUM_MESSAGE = FW_MESSAGES_COUNT, +}; + +void clearMissionMessage(CommandMessage* message); + +} + +#endif /* FSFWCONFIG_IPC_MISSIONMESSAGETYPES_H_ */ diff --git a/bsp_linux/fsfwconfig/objects/systemObjectList.h b/bsp_linux/fsfwconfig/objects/systemObjectList.h new file mode 100644 index 0000000..b273edf --- /dev/null +++ b/bsp_linux/fsfwconfig/objects/systemObjectList.h @@ -0,0 +1,17 @@ +#ifndef FSFWCONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ +#define FSFWCONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ + +#include + +namespace objects { +enum mission_objects: object_id_t { + /* 0x62 ('b') Board and mission specific objects */ + UDP_BRIDGE = 0x62000300, + UDP_POLLING_TASK = 0x62000400, + /* Generic name for FSFW static ID setter */ + DOWNLINK_DESTINATION = UDP_BRIDGE, + LINUX_SPI_COM_IF = 0x63000001, +}; +} + +#endif /* FSFWCONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ */ diff --git a/bsp_linux/fsfwconfig/objects/translateObjects.cpp b/bsp_linux/fsfwconfig/objects/translateObjects.cpp new file mode 100644 index 0000000..734e67a --- /dev/null +++ b/bsp_linux/fsfwconfig/objects/translateObjects.cpp @@ -0,0 +1,127 @@ +/** + * @brief Auto-generated object translation file. + * @details + * Contains 37 translations. + * Generated on: 2021-05-28 18:12:48 + */ +#include "translateObjects.h" + +const char *TEST_ASSEMBLY_STRING = "TEST_ASSEMBLY"; +const char *TEST_CONTROLLER_STRING = "TEST_CONTROLLER"; +const char *TEST_DEVICE_HANDLER_0_STRING = "TEST_DEVICE_HANDLER_0"; +const char *TEST_DEVICE_HANDLER_1_STRING = "TEST_DEVICE_HANDLER_1"; +const char *TEST_ECHO_COM_IF_STRING = "TEST_ECHO_COM_IF"; +const char *FSFW_OBJECTS_START_STRING = "FSFW_OBJECTS_START"; +const char *PUS_SERVICE_1_VERIFICATION_STRING = "PUS_SERVICE_1_VERIFICATION"; +const char *PUS_SERVICE_2_DEVICE_ACCESS_STRING = "PUS_SERVICE_2_DEVICE_ACCESS"; +const char *PUS_SERVICE_3_HOUSEKEEPING_STRING = "PUS_SERVICE_3_HOUSEKEEPING"; +const char *PUS_SERVICE_5_EVENT_REPORTING_STRING = "PUS_SERVICE_5_EVENT_REPORTING"; +const char *PUS_SERVICE_8_FUNCTION_MGMT_STRING = "PUS_SERVICE_8_FUNCTION_MGMT"; +const char *PUS_SERVICE_9_TIME_MGMT_STRING = "PUS_SERVICE_9_TIME_MGMT"; +const char *PUS_SERVICE_17_TEST_STRING = "PUS_SERVICE_17_TEST"; +const char *PUS_SERVICE_20_PARAMETERS_STRING = "PUS_SERVICE_20_PARAMETERS"; +const char *PUS_SERVICE_200_MODE_MGMT_STRING = "PUS_SERVICE_200_MODE_MGMT"; +const char *PUS_SERVICE_201_HEALTH_STRING = "PUS_SERVICE_201_HEALTH"; +const char *HEALTH_TABLE_STRING = "HEALTH_TABLE"; +const char *MODE_STORE_STRING = "MODE_STORE"; +const char *EVENT_MANAGER_STRING = "EVENT_MANAGER"; +const char *INTERNAL_ERROR_REPORTER_STRING = "INTERNAL_ERROR_REPORTER"; +const char *TC_STORE_STRING = "TC_STORE"; +const char *TM_STORE_STRING = "TM_STORE"; +const char *IPC_STORE_STRING = "IPC_STORE"; +const char *TIME_STAMPER_STRING = "TIME_STAMPER"; +const char *FSFW_OBJECTS_END_STRING = "FSFW_OBJECTS_END"; +const char *UDP_BRIDGE_STRING = "UDP_BRIDGE"; +const char *UDP_POLLING_TASK_STRING = "UDP_POLLING_TASK"; +const char *CCSDS_DISTRIBUTOR_STRING = "CCSDS_DISTRIBUTOR"; +const char *PUS_DISTRIBUTOR_STRING = "PUS_DISTRIBUTOR"; +const char *TM_FUNNEL_STRING = "TM_FUNNEL"; +const char *TEST_DUMMY_1_STRING = "TEST_DUMMY_1"; +const char *TEST_DUMMY_2_STRING = "TEST_DUMMY_2"; +const char *TEST_DUMMY_3_STRING = "TEST_DUMMY_3"; +const char *TEST_DUMMY_4_STRING = "TEST_DUMMY_4"; +const char *TEST_DUMMY_5_STRING = "TEST_DUMMY_5"; +const char *TEST_TASK_STRING = "TEST_TASK"; +const char *NO_OBJECT_STRING = "NO_OBJECT"; + +const char* translateObject(object_id_t object) { + switch( (object & 0xFFFFFFFF) ) { + case 0x4100CAFE: + return TEST_ASSEMBLY_STRING; + case 0x4301CAFE: + return TEST_CONTROLLER_STRING; + case 0x4401AFFE: + return TEST_DEVICE_HANDLER_0_STRING; + case 0x4402AFFE: + return TEST_DEVICE_HANDLER_1_STRING; + case 0x4900AFFE: + return TEST_ECHO_COM_IF_STRING; + case 0x53000000: + return FSFW_OBJECTS_START_STRING; + case 0x53000001: + return PUS_SERVICE_1_VERIFICATION_STRING; + case 0x53000002: + return PUS_SERVICE_2_DEVICE_ACCESS_STRING; + case 0x53000003: + return PUS_SERVICE_3_HOUSEKEEPING_STRING; + case 0x53000005: + return PUS_SERVICE_5_EVENT_REPORTING_STRING; + case 0x53000008: + return PUS_SERVICE_8_FUNCTION_MGMT_STRING; + case 0x53000009: + return PUS_SERVICE_9_TIME_MGMT_STRING; + case 0x53000017: + return PUS_SERVICE_17_TEST_STRING; + case 0x53000020: + return PUS_SERVICE_20_PARAMETERS_STRING; + case 0x53000200: + return PUS_SERVICE_200_MODE_MGMT_STRING; + case 0x53000201: + return PUS_SERVICE_201_HEALTH_STRING; + case 0x53010000: + return HEALTH_TABLE_STRING; + case 0x53010100: + return MODE_STORE_STRING; + case 0x53030000: + return EVENT_MANAGER_STRING; + case 0x53040000: + return INTERNAL_ERROR_REPORTER_STRING; + case 0x534f0100: + return TC_STORE_STRING; + case 0x534f0200: + return TM_STORE_STRING; + case 0x534f0300: + return IPC_STORE_STRING; + case 0x53500010: + return TIME_STAMPER_STRING; + case 0x53ffffff: + return FSFW_OBJECTS_END_STRING; + case 0x62000300: + return UDP_BRIDGE_STRING; + case 0x62000400: + return UDP_POLLING_TASK_STRING; + case 0x63000000: + return CCSDS_DISTRIBUTOR_STRING; + case 0x63000001: + return PUS_DISTRIBUTOR_STRING; + case 0x63000002: + return TM_FUNNEL_STRING; + case 0x74000001: + return TEST_DUMMY_1_STRING; + case 0x74000002: + return TEST_DUMMY_2_STRING; + case 0x74000003: + return TEST_DUMMY_3_STRING; + case 0x74000004: + return TEST_DUMMY_4_STRING; + case 0x74000005: + return TEST_DUMMY_5_STRING; + case 0x7400CAFE: + return TEST_TASK_STRING; + case 0xFFFFFFFF: + return NO_OBJECT_STRING; + default: + return "UNKNOWN_OBJECT"; + } + return 0; +} diff --git a/bsp_linux/fsfwconfig/objects/translateObjects.h b/bsp_linux/fsfwconfig/objects/translateObjects.h new file mode 100644 index 0000000..dbf5b46 --- /dev/null +++ b/bsp_linux/fsfwconfig/objects/translateObjects.h @@ -0,0 +1,8 @@ +#ifndef FSFWCONFIG_OBJECTS_TRANSLATEOBJECTS_H_ +#define FSFWCONFIG_OBJECTS_TRANSLATEOBJECTS_H_ + +#include + +const char* translateObject(object_id_t object); + +#endif /* FSFWCONFIG_OBJECTS_TRANSLATEOBJECTS_H_ */ diff --git a/bsp_linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp b/bsp_linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp new file mode 100644 index 0000000..e94b472 --- /dev/null +++ b/bsp_linux/fsfwconfig/pollingsequence/pollingSequenceFactory.cpp @@ -0,0 +1,5 @@ +/** + * Add polling sequence initialization which are not common to every BSP here. + */ +#include "pollingSequenceFactory.h" + diff --git a/bsp_linux/fsfwconfig/pollingsequence/pollingSequenceFactory.h b/bsp_linux/fsfwconfig/pollingsequence/pollingSequenceFactory.h new file mode 100644 index 0000000..b696b78 --- /dev/null +++ b/bsp_linux/fsfwconfig/pollingsequence/pollingSequenceFactory.h @@ -0,0 +1,14 @@ +#ifndef POLLINGSEQUENCE_POLLINGSEQUENCFACTORY_H_ +#define POLLINGSEQUENCE_POLLINGSEQUENCFACTORY_H_ + +#include "OBSWConfig.h" +#include + +class FixedTimeslotTaskIF; + +namespace pst { +ReturnValue_t pollingSequenceExamples(FixedTimeslotTaskIF *thisSequence); +ReturnValue_t pollingSequenceDevices(FixedTimeslotTaskIF* thisSequence); +} + +#endif /* POLLINGSEQUENCE_POLLINGSEQUENCFACTORY_H_ */ diff --git a/bsp_linux/fsfwconfig/returnvalues/classIds.h b/bsp_linux/fsfwconfig/returnvalues/classIds.h new file mode 100644 index 0000000..c0eba73 --- /dev/null +++ b/bsp_linux/fsfwconfig/returnvalues/classIds.h @@ -0,0 +1,16 @@ +#ifndef FSFWCONFIG_RETURNVALUES_CLASSIDS_H_ +#define FSFWCONFIG_RETURNVALUES_CLASSIDS_H_ + +#include "commonClassIds.h" + +namespace CLASS_ID { +enum classIds: uint8_t { + CLASS_ID_START = COMMON_CLASS_ID_END, + LINUX_LIBGPIO_IF, //GPIO + LINUX_SPI_COM_IF, //LSPI + CLASS_ID_END // [EXPORT] : [END] +}; +} + + +#endif /* FSFWCONFIG_RETURNVALUES_CLASSIDS_H_ */ diff --git a/bsp_linux/fsfwconfig/tmtc/apid.h b/bsp_linux/fsfwconfig/tmtc/apid.h new file mode 100644 index 0000000..eecc485 --- /dev/null +++ b/bsp_linux/fsfwconfig/tmtc/apid.h @@ -0,0 +1,11 @@ +#ifndef FSFWCONFIG_TMTC_APID_H_ +#define FSFWCONFIG_TMTC_APID_H_ + +#include +#include + +namespace apid { +static const uint16_t APID = COMMON_APID; +}; + +#endif /* FSFWCONFIG_TMTC_APID_H_ */ diff --git a/bsp_linux/fsfwconfig/tmtc/pusIds.h b/bsp_linux/fsfwconfig/tmtc/pusIds.h new file mode 100644 index 0000000..13b59c7 --- /dev/null +++ b/bsp_linux/fsfwconfig/tmtc/pusIds.h @@ -0,0 +1,6 @@ +#ifndef FSFWCONFIG_TMTC_PUSIDS_H_ +#define FSFWCONFIG_TMTC_PUSIDS_H_ + +#include + +#endif /* FSFWCONFIG_TMTC_PUSIDS_H_ */ diff --git a/bsp_linux/main.cpp b/bsp_linux/main.cpp new file mode 100644 index 0000000..4696be2 --- /dev/null +++ b/bsp_linux/main.cpp @@ -0,0 +1,73 @@ +#include +#include + +#include +#include +#include + +#include +#include +#include + +#if defined(RASPBERRY_PI) +static const char* COMPILE_PRINTOUT = "Raspberry Pi"; +#elif defined(BEAGLE_BONE_BLACK) +static const char* COMPILE_PRINTOUT = "Beagle Bone Black"; +#elif defined(LINUX) +static const char* COMPILE_PRINTOUT = "Host"; +#else +static const char* COMPILE_PRINTOUT = "Unknown device"; +#endif + +#if FSFW_CPP_OSTREAM_ENABLED == 1 +/* On Linux, no carriage return is added. */ +ServiceInterfaceStream sif::debug("DEBUG"); +ServiceInterfaceStream sif::info("INFO"); +ServiceInterfaceStream sif::warning("WARNING"); +ServiceInterfaceStream sif::error("ERROR", false, false, true); +#endif + +ObjectManagerIF *objectManager = nullptr; + +int main() { + + utility::commonInitPrint("Linux", COMPILE_PRINTOUT); + +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "Producing system objects.." << std::endl; +#else + sif::printInfo("Producing system objects..\n"); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ + + ObjectManager* objManager = ObjectManager::instance(); + objManager->setObjectFactoryFunction(ObjectFactory::produce, nullptr); + +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "Objects created successfully.." << std::endl; + sif::info << "Initializing objects.." << std::endl; +#else + sif::printInfo("Objects created successfully..\n"); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ + + objManager->initialize(); + +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::info << "Creating tasks.." << std::endl; +#else + sif::printInfo("Creating tasks..\n"); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ + + InitMission::createTasks(); + + MutexExample::example(); + PusPacketCreator::createPusPacketAndPrint(); + + + + /* Permanent loop. */ + for(;;) { + /* Sleep main thread, not needed anymore. */ + TaskFactory::delayTask(5000); + } + return 0; +} diff --git a/bsp_linux/test/CMakeLists.txt b/bsp_linux/test/CMakeLists.txt new file mode 100644 index 0000000..4bebec2 --- /dev/null +++ b/bsp_linux/test/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${TARGET_NAME} + PUBLIC + SpiTest.cpp +) + + + diff --git a/bsp_linux/test/SpiTest.cpp b/bsp_linux/test/SpiTest.cpp new file mode 100644 index 0000000..0ddfc45 --- /dev/null +++ b/bsp_linux/test/SpiTest.cpp @@ -0,0 +1,4 @@ +#include "SpiTest.h" + +SpiTest::SpiTest(object_id_t objectId): SystemObject(objectId) { +} diff --git a/bsp_linux/test/SpiTest.h b/bsp_linux/test/SpiTest.h new file mode 100644 index 0000000..edce067 --- /dev/null +++ b/bsp_linux/test/SpiTest.h @@ -0,0 +1,15 @@ +#ifndef BSP_LINUX_TEST_SPITEST_H_ +#define BSP_LINUX_TEST_SPITEST_H_ + +#include +#include + +class SpiTest: public ExecutableObjectIF, SystemObject { +public: + SpiTest(object_id_t objectId); +private: + +}; + + +#endif /* BSP_LINUX_TEST_SPITEST_H_ */ diff --git a/bsp_linux/utility/CMakeLists.txt b/bsp_linux/utility/CMakeLists.txt new file mode 100644 index 0000000..721ba1c --- /dev/null +++ b/bsp_linux/utility/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${TARGET_NAME} + PUBLIC + printChar.c +) + + + diff --git a/bsp_linux/utility/printChar.c b/bsp_linux/utility/printChar.c new file mode 100644 index 0000000..2f34675 --- /dev/null +++ b/bsp_linux/utility/printChar.c @@ -0,0 +1,12 @@ +#include +#include + + +void printChar(const char* character, bool errStream) { + if(errStream) { + fprintf( stderr, "%c", *character); + } else { + printf("%c", *character); + } +} + diff --git a/doc/images/FSFW_Logo_V3_bw.png b/doc/images/FSFW_Logo_V3_bw.png new file mode 100644 index 0000000..99b9b4f Binary files /dev/null and b/doc/images/FSFW_Logo_V3_bw.png differ diff --git a/doc/images/bbb/beagleboard-logo.png b/doc/images/bbb/beagleboard-logo.png new file mode 100644 index 0000000..e215738 Binary files /dev/null and b/doc/images/bbb/beagleboard-logo.png differ diff --git a/doc/images/build_cfg_mingw.PNG b/doc/images/build_cfg_mingw.PNG new file mode 100644 index 0000000..a233c5e Binary files /dev/null and b/doc/images/build_cfg_mingw.PNG differ diff --git a/doc/images/cmake.png b/doc/images/cmake.png new file mode 100644 index 0000000..b4f5711 Binary files /dev/null and b/doc/images/cmake.png differ diff --git a/doc/images/eclipse/eclipse-cross-compile-linux.png b/doc/images/eclipse/eclipse-cross-compile-linux.png new file mode 100644 index 0000000..637276e Binary files /dev/null and b/doc/images/eclipse/eclipse-cross-compile-linux.png differ diff --git a/doc/images/eclipse/eclipse-cross-compile-win.png b/doc/images/eclipse/eclipse-cross-compile-win.png new file mode 100644 index 0000000..306b325 Binary files /dev/null and b/doc/images/eclipse/eclipse-cross-compile-win.png differ diff --git a/doc/images/eclipse/eclipse-indexer.png b/doc/images/eclipse/eclipse-indexer.png new file mode 100644 index 0000000..b403ffe Binary files /dev/null and b/doc/images/eclipse/eclipse-indexer.png differ diff --git a/doc/images/eclipse/eclipse-rpi.png b/doc/images/eclipse/eclipse-rpi.png new file mode 100644 index 0000000..90a07a5 Binary files /dev/null and b/doc/images/eclipse/eclipse-rpi.png differ diff --git a/doc/images/eclipse/rpi-win-environment.PNG b/doc/images/eclipse/rpi-win-environment.PNG new file mode 100644 index 0000000..cf55193 Binary files /dev/null and b/doc/images/eclipse/rpi-win-environment.PNG differ diff --git a/doc/images/eclipse_cfg.PNG b/doc/images/eclipse_cfg.PNG new file mode 100644 index 0000000..1417a2b Binary files /dev/null and b/doc/images/eclipse_cfg.PNG differ diff --git a/doc/images/eclipse_logo_colour.png b/doc/images/eclipse_logo_colour.png new file mode 100644 index 0000000..8c0f14c Binary files /dev/null and b/doc/images/eclipse_logo_colour.png differ diff --git a/doc/images/rpi/RPi-Logo-Landscape-Reg-PRINT.png b/doc/images/rpi/RPi-Logo-Landscape-Reg-PRINT.png new file mode 100644 index 0000000..7be4ccd Binary files /dev/null and b/doc/images/rpi/RPi-Logo-Landscape-Reg-PRINT.png differ