Flight Software Design

Introduction

As of Fall 2023, flight software will be utilizing Zephyr RTOS as its primary platform instead of launch-core. Several benefits of this include greater hardware and platform independence, as well as better software support and reliability by leveraging an open-source community.

Although using a RTOS may be considered overkill for our purposes, we can better utilize our chips' resources (similar to launch-core's scheduler but with less headaches) and provide valuable learning experiences for members to talk about with prospective employers in the embedded industry.

This page serves as a way of communicating general philosophies when designing flight software for various hardware components including but not limited to backplane modules, extension boards and payload flight computers.

This page also serves as place to standardize how data should be communicated within a board and across different boards.

These pages may change as time goes on and the team learns of better practices when designing software around a RTOS.

General Software Guidelines

  • All flight software will go under the FSW repo for now

    • This allows us to unify all flight software instead of having scattered repos

    • The trade-off is that all software needs to be using the same Zephyr version. This could have long term impacts if Zephyr decides to change features that certain board firmware may use, leading to increased maintenance in the future.

  • Since all flight software is unified on one repository, shared functionality is expected to go under the lib folder to enforce DRY principles. This includes but is not limited to

    • Networking

    • File System

    • Telemetry

  • Data logging should be a buffered operation! Constantly logging telemetry means constant I/O operations which can negatively impact performance.

  • Multiple tasks should not write to global variables! 

    • In general global variables should be frowned upon. Especially in a multi threaded environment.

    • Multiple threads writing to global data means there is a good chance of race conditions occurring. 

      • Why not use a mutex? This leads to tasks competing for access to data which could also incur performance costs and there are better tools for the job

    • Utilize thread safe queues which a good RTOS should provide. (see below software design)

  • There's probably more I can't list off the top of my head at the moment and this will eventually be expanded.

General Software Design

  • Software should follow an event driven architecture. This leads to better decoupling of software components and greater responsiveness to certain events 

    •   This means following a producer-consumer pattern where some tasks will produce data and other tasks will consume that data

      • i.e Sensor telemetry tasks produce data for a logging task to consume and store data

    • Data should be put on a thread-safe queue by producers for other consumers to use

    • Certain tasks should be triggered based on certain events.

      • For example, if a module detects that the rocket has launched, it should start logging data and notify other modules to do the same 

  • Closely related application functionality shall be grouped under one RTOS task instead of split across multiple tasks.

    • For example, if there are a few sensors reading data at 100 Hz, they should be grouped under one task instead of a sensor per task

    • When developing embedded software, you need to be aware of your limited hardware resources. Each task needs its own stack space which means you're eating up RAM.

  • Although you should limit the number of tasks you have, tasks shall not be overloaded as well

    • Goldilocks principle.

      • Large tasks = Overly complex tasks and violation of single responsibility. Run the risk of timing critical events not being serviced in time.  

      • Many tasks = Unnecessary wastage of memory

    • Some software requirements may include servicing asynchronous reads from communication interfaces like Ethernet and LoRa

      • Those may need to be serviced quickly in time for the next read and that data could impact how a certain module should behave

Individual Board Software Design



Ethernet Communication Standards

  • The first 3 numbers in an IP address represent the network ID and therefore must be the same across modules.

  • All communication between modules over Ethernet will be done over UDP.

  • To maintain simplicity, at this point in time all packets will be broadcasted to the network.

  • It is up to each individual module to handle packets on specific ports.

  • Each module can reserve a range of ports for various purposes.

  • Port purposes will be specified in individual board software design pages

  • Port assignments should be defined in a header file under the lib folder to reduce code defects and reduce work if standards change 

    • Port assignments should be specified under an enum with naming following the pattern (MODULE NAME)_(PURPOSE NAME)_PORT

      • i.e SENSOR_HUNDRED_HZ_TELEMETRY_PORT or RADIO_LIFTOFF_PORT

  • Port 9999 will be reserved for notifying other modules of flight events including liftoff, apogee and landing 

Module

Port Range

Module

Port Range

Autopilot

10,000 - 10,999

Power 

11,000 - 11,999

Radio

12,000 - 12,999

Sensor

13,000 - 13,999



RS-485 Communication Standards

  • Currently, the team has no experience with communicating with boards using the RS-232 interface and this section will be adjusted as we learn more

  • UART is the expected communication protocol over RS-485. To frame data for proper interpretation and ease of debugging, the SLIP protocol will be used

  • Non-backplane boards should constantly transmit an identifier until it receives acknowledgment from a parent device before transmitting its data

    • Unknown if this is necessary at this point

    • The idea is to not hard-code extension board functionality into module software

    • Functionality for responding to data from extension boards may be required to be put under lib to increase software flexibility