Main / Nasacfs
Introhttps://github.com/nasa/CFS-101 A test environment and a good introduction to cFS https://github.com/nasa/cFS The NASA repo has some documentation linked in its README that may be helpful. Build documentation: https://github.com/nasa/cFE/blob/main/cmake/README.md Training HTML docs: https://software.nasa.gov/software/MSC-26323-1 This has links for various CFS applications as well. Some advice for practical CFS use: https://flightsoftware.jhuapl.edu/files/2018/Day-1/007_Brown-Fleming-LessonsLearned_cFSonLinuxRTEMS.pdf https://flightsoftware.jhuapl.edu/files/2017/cFS-Day/cFS17-C3-cfe-cmake-build-2017-workshop.pdf Training slides: https://ntrs.nasa.gov/api/citations/20210022378/downloads/NASA TM 20205000691 REV 2 Final.pdf So CFS runs on top of Linux? But provides an “executive API” used by all applications? The executive services and API are called cFE. The cFS framework includes the cFE and OSAL and platform support packages. “cFS Distribution” created by augmenting the NASA cFS Framework with components (platforms, apps, and tools) to create an operational system.
Each module in cFS is an application (task) that more or less must follow the same pattern (registration, blocking call on msg rx, process ccsds msg). Library is a collection of utilities for use by apps. OS abstraction API = OSAL OS abstraction layer which sounds like it allows an application to be rather OS agnostic cFE Executive Services is a layer that incorporates the OS Abstraction Layer (OSAL) API. The OSAL API was originally developed with the intent to provide a common interface for all Applications regardless of which RTOS the Application was running on. The OSAL is a software library that isolates the upper layers of the cFS from the Real-time Operating System. When I’m running the "cFS" on our target, what am I running? Just the CFS? The CFE? Both. It looks like the CFE is a component of the CFS. CFS = tools + OSAL + CFE(with it’s API) + apps CFS-GroundSystem ToolPyQt5 is required and I did not have this installed. This command seemed to work but need to verify: sudo apt-get install python3-pyqt5 PyZMQ is required and I did not have this installed. This command seemed to work but need to verify: sudo apt-get install python-zmq Apparently this is the default for connecting the GS: CI_LAB listening on UDP port: 1234 Quick reference build steps 9. Rebuild the cFS. make clean make prep make make install 10. Run the cFE cd build/exe/cpu1 ./core-cpu1 CDS = critical data stores, data preserved through reset What is this Caelum thing? Appears to be version name, equated with 7.0 You run applications (and name libraries) with help from the ./build/exe/cpu1/cf/cfe_es_startup.scr file, ASCII text that contains parameters. Feels almost like a run configuration file, specifying the names and priorities of desired applications. What is HK housekeeping? Requests handled by the scheduler. In build/exe/cpu1/cf you find a .so for each application named. Are these the defaults? Oh ok, sample applications ci_lab = Command Ingest to_lab = Telemetry Output sch_lab = Scheduler these are the three keys to the “runtime context” tailored for an app’s environment and are considered to be part of the CFS Framework fm = File Manager cf = CFDP CI LAB tells you on start which port it’s listening to for CCSDS telecommands: 1980-012-15:16:53.21496 CI_LAB listening on TCP port: 1234 This is interesting, wonder how it works: SW components can be switched in and out at runtime, without rebooting or rebuilding the system SW. Might be using the ES START and STOP commands CFE_ES_STOP_APP_CC #define CFE_ES_STOP_APP_CC 5 Name Stop and Unload Application CFE_ES_START_APP_CC #define CFE_ES_START_APP_CC 4 Name Load and Start an Application Every thing you need to use these commands properly can be found in the startup script, ./sample_defs/cpu1_cfe_es_startup.scr Note that the single argument for STOP is the “Application” which is simply the CFE Name (like MY_APP). Definitions
ApplicationsApplications For the different provided applications, there are configuration .h header files in the cFS/apps/<name>/config/ folders. Code lives in /fsw/ Anatomy of an application files folder: apps ├── ci_lab │ ├── arch_build.cmake │ ├── CHANGELOG.md │ ├── CMakeLists.txt │ ├── config │ │ ├── default_ci_lab_fcncodes.h │ │ ├── default_ci_lab_interface_cfg.h │ │ ├── default_ci_lab_internal_cfg.h . . . │ ├── CONTRIBUTING.md │ ├── fsw │ │ ├── inc │ │ │ └── ci_lab_eventids.h │ │ └── src │ │ ├── ci_lab_app.c │ │ ├── ci_lab_app.h │ │ ├── ci_lab_cmds.c │ │ ├── ci_lab_cmds.h . . . │ ├── LICENSE │ ├── mission_build.cmake │ ├── README.md │ └── SECURITY.md The .so, .scr, .bin, and .tbl files end up in /build/exe/cpu1/cf/ .tbl files are binary Table parameter files (but are these generated from .json files?) How can I run a sample application? https://github.com/nasa/sample_app/ Described as “non-flight” what does that mean? How is this new application added to the build? well, it’s part of build/native/default_cpu1/CMakeFiles/TargetDirectories.txt but not clear if that’s auto-generated. A compile command line? /usr/bin/cc -fPIC -g -shared -o sample_app.so CMakeFiles/sample_app.dir/fsw/src/sample_app.c.o CMakeFiles/sample_app.dir/fsw/src/sample_app_cmds.c.o CMakeFiles/sample_app.dir/fsw/src/sample_app_dispatch.c.o CMakeFiles/sample_app.dir/fsw/src/sample_app_utils.c.o Application Design Practices• Allocate resources during initialization to help keep run loop deterministic • Use a lower priority child task for long operations like a memory dump – Create child tasks during initialization • Register with EVS immediately after registering app so local event log can be used instead of system log • NOOP command sends an informational event message with app’s version number • Use SCH app to periodically send a “send housekeeping” message – Housekeeping data includes command counters and general app status – 3 to 5 seconds is a common interval – Attitude Determination and Control apps don’t typically use this pattern Difference between local event log and system log?Can point EVS output (time stamped text messages) to local event log Local event log – If enabled, events are written to a local buffer – Log “mode” can be set to overwrite or discard – Serves as backup to onboard-recorder during initialization or error scenarios – Suitable for multi-processor architectures – Command to write log to file My own new applicationHere is a video walk through of creating a new application: https://www.youtube.com/watch?v=hW8V33ZjikM Flight System Application Tutorial (from https://flightsoftware.org, the Flight Software Workshop) https://www.youtube.com/watch?v=-_gUwzQahH4 sample_defsWhen you create a new application, you must add its name to the sample_defs/targets.cmake file: list(APPEND MISSION_GLOBAL_APPLIST sample_app sample_lib) becomes list(APPEND MISSION_GLOBAL_APPLIST sample_app my_app sample_lib) When you create a new application, you must add an entry to the startup script at sample_defs/cpu1_cfe_es_startup.scr CFE_APP, my_app, MY_APP_Main, MY_APP, 50, 16384, 0x0, 0; In the startup script file, note that the Priority column is used by the core system and not the scheduler. apparently these do NOT need to be unique. • If you copied an application to create this, you must also change the my_app/CmakeLists.txt file to reflect the new name. • Change all the file names within your new my_app folder that have *sample_app* to *my_app*. • Edit the apps/my_app/mission_build.cmake file to update the app names. • Edit the apps/my_app/arch_build.cmake file to update the app names. • Edit the apps/my_app/fsw/src/ .c files code to update the app name. • Edit all the .h header files in apps/my_app/fsw/ subfolders to update app name. • Edit all the .h header files in apps/my_app/config/ subfolders to update app name. • Edit all the .c files in apps/my_app/fsw/tables/ to update the app name. Why don’t I have to edit this line? Why no sample_app, which is running in the APPLIST? SET(cpu1_APPLIST ci_lab to_lab sch_lab) I guess because they are in the other APPLIST, rather than being assigned specifically to one CPU?
What is .scr file? as in sample_defs/cpu1_cfe_es_startup.scr? Appears to be some kind of boot or more accurately startup script, in the stype of the Uboot boot.scr scripts maybe? https://docs.xilinx.com/r/en-US/ug1144-petalinux-tools-reference-guide/Configuring-U-Boot-Boot-Script-boot.scr There is NO platform_inc or mission_inc folder, just inc, is that the old way? Now combined? The documentation developers guide describes four types of header file: interface, platform, mission, fsw. ll apps/my_app/config/ -rw-rw-r-- 1 tyler tyler 1656 Dec 19 16:41 default_my_app_fcncodes.h -rw-rw-r-- 1 tyler tyler 1799 Dec 19 16:42 default_my_app_interface_cfg.h -rw-rw-r-- 1 tyler tyler 1872 Dec 19 14:49 default_my_app_internal_cfg.h -rw-rw-r-- 1 tyler tyler 1175 Dec 19 16:44 default_my_app_topicids.h . . . Per the developers guide, these header files can be superseded by creating a _defs directory and copying the .h file over to it and removing the default_ prefix in the file name. HOWEVER, that doesn’t actually work. Instead, you must put the edited copy of the .h file in the sample_defs/ folder. How can I learn more about or manipulate the runtime environment for my application?The runtime is supposedly set up by the Executive Services module but is also described in one tutorial as a “core set of apps” in CI, TO, SCH but perhaps also file management and transfer. ES owns the Performance Identifiers, or perfids. Some CFE perfids to observe are in ./sample_defs/sample_perfids.h Each performance id is used to identify something that needs to be * measured. Performance ids are limited to the range of 0 to * CFE_MISSION_ES_PERF_MAX_IDS - 1. Any performance ids outside of this range * will be ignored and will be flagged as an error. Note that * performance ids 0-31 are reserved for the cFE Core.
So 0-31 are used in this sample_perfids.h file. That’s funny that the CFE ID set is in this file titles sample_. There’s also a check to make sure the value is not less than 32. Here’s an example of something CFE wants to measure:
Can these be shared or must they be unique? I don’t see any complaints in the log when using the same one for SAMPLE_APP and MY_APP, but… Each PerfID is a tag for a segment of code to monitor for performance, so add a unique one for each code segment, so a single app can monitor multiple segments. Where is the Perf Log? How do I read it? The function docs say PeftLogAdd “Adds a new entry to the data buffer” but how do I read this data buffer? Seen in code, but no apparent file being written. Can’t find any source for the references to this so-called “Software Performance Analysis Tool.” Found some new documentation https://ntrs.nasa.gov/api/citations/20140017040/downloads/20140017040.pdf talking about Development Tools - Productivity / Interoperability – Performance Monitoring / Profiling Tool (Linux/Java) Performance utility, is this it? https://github.com/nasa/perfutils-java Apparently not, totally empty repo. There is a reference to “external tools” which I apparently cannot locate: an external post processing tool has been developed to calculate CPU utilization, trace interrupts, track task CPU usage. In addition, other external tools can ingest data and provides a graphical display of the software timing based on the markers. So courtesty of cfe-usersguide.pdf we found “Performance Analyzer” start and stop commands in the ES module. Oh Look, ES also writes to a system log: CFE_ES_WriteToSysLog This function is used in place of printf
The function acts just like a standard 'C' printf function and records the ASCII string to a buffer that is preserved during resets. WHAT BUFFER WHERE????? To explore: Volatile vs NVM 1980-012-14:03:26.09273 CFE_ES_StartApplications: Cannot Open Volatile Startup file: /ram/cfe_es_startup.scr, Trying Nonvolatile. 1980-012-14:03:26.09276 CFE_ES_StartApplications: Opened ES App Startup file: /cf/cfe_es_startup.scr What is EDS? electronic data sheet formal spec of a device/system/SW interface in a machine format CCSDS spec format? Somehow it can be used to generated C header files for use by FSW, and Python bindings? In the example I saw, the eds/ folder is a sibling to the app fsw/ folder. i.e. app-name/ |- eds/ |- fsw/ and the EDS files are just .xml files. What is OSK? open sat kit, a framwork for applications, an object-based design written in C Software BusThis is the messaging system between CFS apps. At its core is a CCSDS packet header. It uses CCSDS Command and Telemetry packets. /** \brief Software Bus generic message */ typedef union CFE_SB_Msg { CFE_MSG_Message_t Msg; /**< \brief Base message type without enforced alignment */ long long int LongInt; /**< \brief Align to support Long Integer */ long double LongDouble; /**< \brief Align to support Long Double */ } CFE_SB_Buffer_t; ** * \brief cFS generic base message * * This provides the definition of CFE_MSG_Message_t */ union CFE_MSG_Message { CCSDS_SpacePacket_t CCSDS; /**< \brief CCSDS Header (Pri or Pri + Ext) */ uint8 Byte[sizeof(CCSDS_SpacePacket_t)]; /**< \brief Byte level acces*/ }; /** * \brief Full CCSDS header */ typedef struct { CCSDS_PrimaryHeader_t Pri; /**< \brief CCSDS Primary Header */ } CCSDS_SpacePacket_t; If this SB buffer definition only has a header and not data, how do you send data? For an Application to send an SB Message, it must first create it. The Application shall define the data structure of the SB Message, allocate memory for it (instantiate it), initialize it with the appropriate SB Message Header information and fill the rest of the structure with appropriate data. The current version of the cFE supports only CCSDS, however, the implementation of the message structure can be changed without affecting the rest of cFS as long as the APIs meet the required behavior identified in the related documentation. So you can “overwrite” the CCSDS structure if you want. If you are using the default (MISSION_MSG_V1), MsgID maps directly to the CCSDS Stream ID. default Message ID values for commands are of the format 0x18xx and telemetry is 0x08xx In the CCSDS implementation, the command and telemetry headers share the same CCSDS primary header structure but have different secondary header structures. Note that all messages must have a secondary header, a message containing just a CFE_MSG_Message_t is invalid per the CCSDS standard. Is secondary header the same thing as the extended header in the code? I don’t necessarily think it is… A CommandHeader is made of a Message_t (CCSDS part) and a CommandSecondaryHeader_t. Different. The CommandSecondaryHeader_t has it’s own .h file and consists of a function code and checksum, but CCSDS spec refers to it’s own extended header option. It is common practice for an application to have a single "CMD_MID" to capture all commands and then to differentiate those commands using a command code. In other words, leave these alone: _app_msgids.h add cmd codes here: _app_msg.h So I’m beginning to think the data is just attached after the MSG_CommandHeader. You use CFE_MSG_SetSize to declare total message length. That is what we define in _app_msg.h, we create a new composite structure that consists of the CommandHeader_t (or TelemetryHeader_t) plus the data format for whatever we want to send. SB Transmit and Receive APIs are generally the largest performance bottlenecks on mission. Changes in cFS since previous flight heritage missions have significantly decreased performance due to additional SB Lock calls (implemented to improve the modularity of the code, but without consideration for performance impacts). https://github.com/nasa/cFE/issues/2460 One improvement to performance is using the zero-copy CFE_SB_TransmitBuffer() function in the API instead of the copying CFE_SB_TransmitMsg() function for high-rate messages. A second that I have not tested, but is mentioned in the CFE documentation, would be an effort to reduce the fragmentation in the heap by more carefully curating buffer allocation sizes for the transmit functions already mentioned. This is known as “SB Msg Alignment”. Best Practices for using Software BusThe following are recommended "best practices" for applications using SB.
System Privileges (esp on Linux)https://flightsoftware.jhuapl.edu/files/2018/Day-1/007_Brown-Fleming-LessonsLearned_cFSonLinuxRTEMS.pdf This slide set says CFS on Linux often run as root to enable real-time threads and thread priorities CFS (POSIX OSAL) assumes root is needed Will not try to set priorities if geteuid() != 0 Apparently you cannot assign different privileges to different threads of a process, so you probably can’t do that with CFS applications. On EIDsThese are numbers representing event IDs which are defined in the appname_app_events.h file in src/ and are unique to the app. There is a set of standard, common ones apparently and then the app author can the IDs as needed. The ID is given as an argument to the SendEvent function. libgpiod-devBuild error: In file included from /home/tyler/hd/sandbox/p3build/reap_pcu_cfs/apps/power/fsw/src/power_control.cpp:7: /home/tyler/hd/sandbox/p3build/reap_pcu_cfs/apps/power/fsw/src/gpio_pin.hpp:7:10: fatal error: gpiod.h: No such file or directory 7 | #include <gpiod.h> | ^~~~~~~~~ This header file is part of ligpiod. Cmake BuildsThe best way to add Cmake control variables is to set them in the mission_defines/p3_defs/targets.cmake file. For example, to get Boost found I added the line: set (Boost_INCLUDE_DIRS /mnt/newHHD/lt_gitlab/Ponderosa/lasercat/sockets_proto/boost_1_82_0) Message and APIDBoth the message and APIDs are defined in the platform_inc/ _msgids.h file. The apid is the last 2 bytes of the msg id The msg id includeds the telemetry bit of the main cfs header But each apid may have several command codes associated with it. Telemetry typesHousekeeping is actually one of the CFS apps, but is not part of the “CFS Framework”. So it’s sibling to Checksum, Health/Safety, Scheduler, File Manager rather than TO Lab or CI Lab Housekeeping “collects and repackages telemetry from other applications” |