diff --git a/docs/how-to/data-products.md b/docs/how-to/develop/data-products.md similarity index 99% rename from docs/how-to/data-products.md rename to docs/how-to/develop/data-products.md index 35dd6b97414..6041a40dfe6 100644 --- a/docs/how-to/data-products.md +++ b/docs/how-to/develop/data-products.md @@ -1,4 +1,4 @@ -# How-To: Generate Data Products +# Generate Data Products This How-To describes **when to use data products**, **how to generate them in flight software**, **how to test them**, and provides guidance for **topology integration** and **ground decoding**. It is intended for engineers who are comfortable with F Prime components and want to add structured, store-and-forward mission data to their system. diff --git a/docs/how-to/define-state-machines.md b/docs/how-to/develop/define-state-machines.md similarity index 99% rename from docs/how-to/define-state-machines.md rename to docs/how-to/develop/define-state-machines.md index 00febacb6f4..a2c0df5e82b 100644 --- a/docs/how-to/define-state-machines.md +++ b/docs/how-to/develop/define-state-machines.md @@ -1,4 +1,4 @@ -# How-To: Define State Machines in F Prime +# Define State Machines in F Prime This guide shows how to define and use state machines in F Prime using the F Prime Modeling Language (FPP). State machines help capture component behavior by modeling modes (states) and transitions explicitly, making complex logic easier to implement, test, and maintain. FPP provides autocoding capabilities to allow users to quickly implement state-defined behavior. diff --git a/docs/how-to/develop-device-driver.md b/docs/how-to/develop/develop-device-driver.md similarity index 96% rename from docs/how-to/develop-device-driver.md rename to docs/how-to/develop/develop-device-driver.md index 1c2de80a376..4e811b94422 100644 --- a/docs/how-to/develop-device-driver.md +++ b/docs/how-to/develop/develop-device-driver.md @@ -19,7 +19,7 @@ Before starting, you should have: A "device driver" traditionally refers to the entire stack of software that manages a hardware device. In F´, the driver-manager pattern splits this in two components: the device manager component and the bus driver component. The bus driver handles the platform-specific implementation of communications on a specific bus (e.g., LinuxI2cDriver, LinuxUartDriver). The device manager handles the operations and logic for a specific device. This enhances modularity and reusability: for example the same device manager can be ported to different platforms by switching the bus driver component. -Please refer to the [Application Manager Driver pattern documentation](../user-manual/design-patterns/app-man-drv.md) for more details on the design pattern used in F Prime for device drivers. +Please refer to the [Application Manager Driver pattern documentation](../../user-manual/design-patterns/app-man-drv.md) for more details on the design pattern used in F Prime for device drivers. ### Example and reference @@ -65,7 +65,7 @@ Use `fprime-util new --component` to create a new component for your device mana This component will translate device-specific operations into bus transactions. Identify the bus type (I2C, SPI, UART, etc.) and the operations needed (read, write, configure, etc.). These should be reflected in the component's ports by mirroring the bus driver's interface. -For our `ImuManager` component, we are using an I2C bus, therefore we need to define ports that mirror the `Drv.I2c` interface (see [Drv/Interfaces/I2c.fpp](../../Drv/Interfaces/I2c.fpp)). +For our `ImuManager` component, we are using an I2C bus, therefore we need to define ports that mirror the `Drv.I2c` interface (see [Drv/Interfaces/I2c.fpp](../../../Drv/Interfaces/I2c.fpp)). For example, a `Drv.I2c` component provides an ***input*** port of type `Drv.I2cWriteRead`, so we need to define an ***output*** port of that type in our component in order to connect to a bus driver component. We mirror each Bus Driver port that we need to use in our Device Manager. ```python @@ -280,7 +280,7 @@ We learn the following: ### Step 2 - Define the Bus Driver Component -Use `fprime-util new --component` to create a new component for your bus driver. The set of ports that a bus driver needs to expose depends on the bus communication protocol (I2C, SPI, UART, etc.). F Prime provides standard interfaces for common bus types in the `Drv/Interfaces/` directory. For I2C, we can use the existing `Drv.I2c` interface (see [Drv/Interfaces/I2c.fpp](../../Drv/Interfaces/I2c.fpp)). +Use `fprime-util new --component` to create a new component for your bus driver. The set of ports that a bus driver needs to expose depends on the bus communication protocol (I2C, SPI, UART, etc.). F Prime provides standard interfaces for common bus types in the `Drv/Interfaces/` directory. For I2C, we can use the existing `Drv.I2c` interface (see [Drv/Interfaces/I2c.fpp](../../../Drv/Interfaces/I2c.fpp)). ```python # In: ZephyrI2cDriver.fpp @@ -292,7 +292,7 @@ passive component ZephyrI2cDriver { ``` > [!TIP] -> Our I2C bus driver will only be responding to read/write requests from a device manager, therefore we define it as a `passive component` and the `Drv.I2c` ports are sufficient. If your bus driver needs to perform scheduled tasks (e.g., polling, timeouts, etc.), you may consider adding a scheduling port (`Svc.Sched`) to hook to a [Svc.RateGroup](../../Svc/ActiveRateGroup/docs/sdd.md), and potentially switching to an `active` component. `queued` components can also be used but need careful design to ensure messages are dispatched. +> Our I2C bus driver will only be responding to read/write requests from a device manager, therefore we define it as a `passive component` and the `Drv.I2c` ports are sufficient. If your bus driver needs to perform scheduled tasks (e.g., polling, timeouts, etc.), you may consider adding a scheduling port (`Svc.Sched`) to hook to a [Svc.RateGroup](../../../Svc/ActiveRateGroup/docs/sdd.md), and potentially switching to an `active` component. `queued` components can also be used but need careful design to ensure messages are dispatched. Run `fprime-util impl` to generate the component C++, including the port handler to fill out. In our case, we will need to implement the `write`, `read`, and `writeRead` port handlers. @@ -405,9 +405,9 @@ void configureTopology() { ## Additional Resources -- [Application Manager Driver Pattern](../user-manual/design-patterns/app-man-drv.md) +- [Application Manager Driver Pattern](../../user-manual/design-patterns/app-man-drv.md) - [fprime-sensors Repository](https://github.com/fprime-community/fprime-sensors) - A collection of ready-to-use device managers for specific devices - [fprime-sensors-reference Repository](https://github.com/fprime-community/fprime-sensors-reference) - Reference project that uses sensors defined in fprime-sensors -- [F´ core Linux Bus Drivers](../../Drv/) +- [F´ core Linux Bus Drivers](../../../Drv) - [fprime-zephyr package](https://github.com/fprime-community/fprime-zephyr) - F Prime support for Zephyr RTOS, including common bus drivers for Zephyr diff --git a/docs/how-to/develop-fprime-libraries.md b/docs/how-to/develop/develop-fprime-libraries.md similarity index 99% rename from docs/how-to/develop-fprime-libraries.md rename to docs/how-to/develop/develop-fprime-libraries.md index 6cb9f7ae707..93f790696fe 100644 --- a/docs/how-to/develop-fprime-libraries.md +++ b/docs/how-to/develop/develop-fprime-libraries.md @@ -59,7 +59,7 @@ add_fprime_subdirectory("${CURRENT_CMAKE_LIST_DIR}/MyLibrary/MyTopology") F´ libraries share F´ code through modules. These module directories are created by `fprime-util new --component` or by hand and may include any F´ code (Components, Ports, Topologies, Data Types, etc.). These types are made available to users of the library by ensuring that they are added to the `library.cmake` file. The only restriction is that these component should be placed under a namespacing directory for the library (e.g. `MyLibrary`) to avoid collisions with other libraries and F´ code. -Developing component, ports, topologies, etc. are the subject of our [tutorials](../tutorials/index.md). +Developing component, ports, topologies, etc. are the subject of our [tutorials](../../tutorials/index.md). ## Optional: Toolchain Folder and Toolchain Files diff --git a/docs/how-to/develop-subtopologies.md b/docs/how-to/develop/develop-subtopologies.md similarity index 98% rename from docs/how-to/develop-subtopologies.md rename to docs/how-to/develop/develop-subtopologies.md index b37af460a19..790e8ac86af 100644 --- a/docs/how-to/develop-subtopologies.md +++ b/docs/how-to/develop/develop-subtopologies.md @@ -1,13 +1,13 @@ # Develop a Subtopology -Subtopologies are topologies for smaller chunks of behavior in F Prime. It allows for grouping bits of topology architecture that fit together, to then be imported into a base deployment's topology. The use case for this is seen when working with shareable components, specifically in the form of [libraries](./develop-fprime-libraries.md). +Subtopologies are topologies for smaller chunks of behavior in F Prime. It allows for grouping bits of topology architecture that fit together, to then be imported into a base deployment's topology. The use case for this is seen when working with shareable components, specifically in the form of [libraries](develop-fprime-libraries.md). *Contents* 1. [Subtopology Structure](#subtopology-structure) 2. [Individual File Contents](#individual-file-contents) 1. [Example Scenario](#example-scenario) 3. [Integration into a "Main" Deployment](#integration-into-a-main-deployment) -4. [Subtopology Autocoder](#the-subtopology-autocoder) +4. [Adding Subtopology Configuration](#adding-subtopology-configuration) 5. [Conclusion](#conclusion) ## Subtopology Structure diff --git a/docs/how-to/implement-radio-manager.md b/docs/how-to/develop/implement-radio-manager.md similarity index 80% rename from docs/how-to/implement-radio-manager.md rename to docs/how-to/develop/implement-radio-manager.md index 1da1e3a3db5..c71160e3723 100644 --- a/docs/how-to/implement-radio-manager.md +++ b/docs/how-to/develop/implement-radio-manager.md @@ -1,6 +1,6 @@ -# How-To: Implement a Radio Manager Component +# Implement a Radio Manager Component -This guide provides step-by-step instructions for implementing a radio manager component using the [Svc.Com Communications Adapter Interface](../reference/communication-adapter-interface.md). A radio manager handles communication with radio hardware, managing both outgoing transmissions (downlink) and incoming receptions (uplink). +This guide provides step-by-step instructions for implementing a radio manager component using the [Svc.Com Communications Adapter Interface](../../reference/communication-adapter-interface.md). A radio manager handles communication with radio hardware, managing both outgoing transmissions (downlink) and incoming receptions (uplink). --- @@ -11,13 +11,13 @@ Before starting, you should have: - Completed the [LedBlinker Tutorial](https://fprime.jpl.nasa.gov/latest/tutorials-led-blinker/docs/led-blinker/). - A general understanding of [FPP component modeling](https://nasa.github.io/fpp/fpp-users-guide.html). - Experience creating commands, events, and telemetry in FPP. -- Read the [Communication Adapter Interface](../reference/communication-adapter-interface.md) reference documentation. +- Read the [Communication Adapter Interface](../../reference/communication-adapter-interface.md) reference documentation. --- ## Overview -A radio manager component bridges the F´ communication stack and radio hardware. To integrate with F´ standard uplink and downlink components, the radio manager must implement the [Communications Adapter Interface](../reference/communication-adapter-interface.md). +A radio manager component bridges the F´ communication stack and radio hardware. To integrate with F´ standard uplink and downlink components, the radio manager must implement the [Communications Adapter Interface](../../reference/communication-adapter-interface.md). A common approach is to use an intermediate driver component (e.g., `Drv.ByteStreamDriver`) to communicate with radio hardware. This provides modularity and allows the same radio manager to work across different platforms by swapping the underlying driver. @@ -26,7 +26,7 @@ A common approach is to use an intermediate driver component (e.g., `Drv.ByteStr ## Step 0 - Read the Reference Documentation -Before starting, read the [Communication Adapter Interface](../reference/communication-adapter-interface.md) reference documentation. This How-To Guide is essentially walking through the implementation of the interface, and much of the information we are going to cover is explained at length in the reference documentation. +Before starting, read the [Communication Adapter Interface](../../reference/communication-adapter-interface.md) reference documentation. This How-To Guide is essentially walking through the implementation of the interface, and much of the information we are going to cover is explained at length in the reference documentation. ## Step 1 - Component Definition @@ -45,7 +45,7 @@ module MyProject { } ``` -See [`Svc.ComStub`](../../Svc/ComStub/ComStub.fpp) for a complete reference implementation. +See [`Svc.ComStub`](../../../Svc/ComStub/ComStub.fpp) for a complete reference implementation. --- @@ -57,8 +57,8 @@ Run `fprime-util impl` to generate the component implementation files. Implement This port is receiving data from the communication stack and sending it to the hardware for outgoing communications. When done sending the data: -- the input buffer **must** be returned through the `dataReturnOut` port (for memory ownership, see [Design Pattern: Return-To-Sender](../user-manual/framework/memory-management/buffer-pool.md#design-pattern-return-to-sender)) -- a status **must** be sent via `comStatusOut`. Only a `Fw::Success::SUCCESS` value will trigger the ComQueue to send new outgoing data. `Fw::Success::SUCCESS` is valid in three contexts: (1) at start-up to initiate data flow, (2) in response to a successful transmission, and (3) after a previous `Fw::Success::FAILURE` to indicate recovery. See [Communication Adapter Protocol](../reference/communication-adapter-interface.md#communication-adapter-protocol) for more detail. +- the input buffer **must** be returned through the `dataReturnOut` port (for memory ownership, see [Design Pattern: Return-To-Sender](../../user-manual/framework/memory-management/buffer-pool.md#design-pattern-return-to-sender)) +- a status **must** be sent via `comStatusOut`. Only a `Fw::Success::SUCCESS` value will trigger the ComQueue to send new outgoing data. `Fw::Success::SUCCESS` is valid in three contexts: (1) at start-up to initiate data flow, (2) in response to a successful transmission, and (3) after a previous `Fw::Success::FAILURE` to indicate recovery. See [Communication Adapter Protocol](../../reference/communication-adapter-interface.md#communication-adapter-protocol) for more detail. **Example:** @@ -116,7 +116,7 @@ void RadioManager::dataReturnIn_handler(FwIndexType portNum, Fw::Buffer& fwBuffe ### Initiate downlink data flow -As detailed in the [Communication Adapter Protocol](../reference/communication-adapter-interface.md#communication-adapter-protocol), the F´ downlink stack expects to receive an initial `Fw::Success::SUCCESS` message via our Com Adapter component's `comStatusOut` port to initiate data flow. This initial SUCCESS is not in response to any data — it tells `Svc::ComQueue` that the adapter is ready to accept its first message. Similarly, after a `Fw::Success::FAILURE`, the adapter must eventually emit a recovery `Fw::Success::SUCCESS` to resume data flow. Projects may implement this as is relevant for their specific radio. +As detailed in the [Communication Adapter Protocol](../../reference/communication-adapter-interface.md#communication-adapter-protocol), the F´ downlink stack expects to receive an initial `Fw::Success::SUCCESS` message via our Com Adapter component's `comStatusOut` port to initiate data flow. This initial SUCCESS is not in response to any data — it tells `Svc::ComQueue` that the adapter is ready to accept its first message. Similarly, after a `Fw::Success::FAILURE`, the adapter must eventually emit a recovery `Fw::Success::SUCCESS` to resume data flow. Projects may implement this as is relevant for their specific radio. In our example, we will leverage the ByteStreamDriver's `ready` port, which signals when the driver is ready to receive data. @@ -129,7 +129,7 @@ void RadioManager::drvConnected_handler(const FwIndexType portNum) { } ``` -Refer to [`Svc.ComStub` implementation](../../Svc/ComStub/ComStub.cpp) for detailed examples of each handler +Refer to [`Svc.ComStub` implementation](../../../Svc/ComStub/ComStub.cpp) for detailed examples of each handler --- @@ -140,7 +140,7 @@ As discussed in the Overview, new deployments are by default created with a `Svc ### Remove ComStub -First, we need to take out ComStub of our topology. This is done by using the `ComCcsds.FramingSubtopology` instead of the default `ComCcsds.Subtopology`. Refer to the [ComCcsds definition](../../Svc/Subtopologies/ComCcsds/ComCcsds.fpp) for more detail +First, we need to take out ComStub of our topology. This is done by using the `ComCcsds.FramingSubtopology` instead of the default `ComCcsds.Subtopology`. Refer to the [ComCcsds definition](../../../Svc/Subtopologies/ComCcsds/ComCcsds.fpp) for more detail ```diff # ---------------------------------------------------------------------- @@ -228,17 +228,17 @@ void teardownTopology(const TopologyState& state) { ### Asynchronous Transmission -For asynchronous byte stream drivers, use the async send ports and store the context for the callback. See [`Svc.ComStub` async implementation](../../Svc/ComStub/ComStub.cpp) for a complete example. +For asynchronous byte stream drivers, use the async send ports and store the context for the callback. See [`Svc.ComStub` async implementation](../../../Svc/ComStub/ComStub.cpp) for a complete example. ### Retry Logic -Implement retry logic for transient failures. See [`Svc.ComStub::handleSynchronousSend`](../../Svc/ComStub/ComStub.cpp) for an example with retry limits +Implement retry logic for transient failures. See [`Svc.ComStub::handleSynchronousSend`](../../../Svc/ComStub/ComStub.cpp) for an example with retry limits --- ## Best Practices -- **Follow the protocol**: Review the [Communication Adapter Protocol](../reference/communication-adapter-interface.md#communication-adapter-protocol) requirements carefully. +- **Follow the protocol**: Review the [Communication Adapter Protocol](../../reference/communication-adapter-interface.md#communication-adapter-protocol) requirements carefully. - **Return buffers promptly**: Return ownership via `*Return*` ports immediately after transmission. @@ -247,7 +247,7 @@ Implement retry logic for transient failures. See [`Svc.ComStub::handleSynchrono ## Additional Resources -- Reference: [Svc.ComStub](../../Svc/ComStub/docs/sdd.md) - Com Adapter implementation passing through data from a ByteStreamDriver +- Reference: [Svc.ComStub](../../../Svc/ComStub/docs/sdd.md) - Com Adapter implementation passing through data from a ByteStreamDriver - Reference: [XBeeManager](https://github.com/fprime-community/fprime-sensors/tree/devel/fprime-sensors/XBee/Components/XBeeManager) - Com Adapter implementation for a [XBee radio](https://www.digi.com/products/embedded-systems/digi-xbee/rf-modules) -- [Communication Adapter Interface Reference](../reference/communication-adapter-interface.md) - Complete protocol specification -- [Byte Stream Driver Model](../../Drv/ByteStreamDriverModel/docs/sdd.md) - Driver interface documentation +- [Communication Adapter Interface Reference](../../reference/communication-adapter-interface.md) - Complete protocol specification +- [Byte Stream Driver Model](../../../Drv/ByteStreamDriverModel/docs/sdd.md) - Driver interface documentation diff --git a/docs/how-to/python-development.md b/docs/how-to/develop/python-development.md similarity index 98% rename from docs/how-to/python-development.md rename to docs/how-to/develop/python-development.md index 900a7b05d95..cc193e5018d 100644 --- a/docs/how-to/python-development.md +++ b/docs/how-to/develop/python-development.md @@ -1,4 +1,4 @@ -# How-To: Develop Components in Python +# Develop Components in Python This guide is a starting point for developing Python-based F Prime applications by constructing select components using Python. @@ -15,8 +15,8 @@ For a working reference project, see the [F Prime Python Reference](https://gith - [Prerequisites](#prerequisites) - [Python in F Prime](#python-in-f-prime) - [Modeling](#modeling) -- [Project Structure](#project-structure) -- [Development Environment](#development-environment) +- [Project Setup](#project-setup) +- [Modeling](#modeling) - [Development Workflow](#development-workflow) - [Testing](#testing) - [Packaging and Distribution](#packaging-and-distribution) diff --git a/docs/how-to/index.md b/docs/how-to/index.md index 356433ee950..8c7a89ff816 100644 --- a/docs/how-to/index.md +++ b/docs/how-to/index.md @@ -7,137 +7,49 @@ hide: How-To guides offer step-by-step instructions for specific development tasks in F Prime. +> [!TIP] +> **← Navigation pane** +> Use the navigation pane on the left to explore the different chapters of the How-To documentation. If the navigation pane is not visible, click on the menu icon (three horizontal lines) at the top left corner of the page. The navigation pane is hidden on narrow screens or if zoomed in. -
+## Table of Contents -- __F´ GDS Plugin Development__ +
+Develop — Learn how to develop components, libraries, and other F´ artifacts. - --- +- [Generate Data Products](develop/data-products.md) +- [Define State Machines in F Prime](develop/define-state-machines.md) +- [Develop a Device Driver](develop/develop-device-driver.md) +- [Develop an F´ Library](develop/develop-fprime-libraries.md) +- [Develop a Subtopology](develop/develop-subtopologies.md) +- [Implement a Radio Manager Component](develop/implement-radio-manager.md) +- [Develop Components in Python](develop/python-development.md) - This guide will walk you through the process of developing GDS plugins. +
- [View Develop F´ GDS Plugins](develop-gds-plugins.md){ .md-button .md-button--primary } +
+Integrate — Learn how to integrate F´ with external libraries and platforms. -- __F´ Library Development__ +- [Implement a Framing Protocol](integrate/custom-framing.md) +- [Implement an OS Abstraction Layer](integrate/implement-osal.md) +- [Integrate a Third-Party Library](integrate/integrate-external-libraries.md) +- [Porting to new platforms](integrate/porting-guide.md) - --- +
- This how to will walk you through the structure and best practices in developing an F´ library. +
+Operate — Learn how to operate F´ applications and the Ground Data System. - [View Develop F´ Libraries](develop-fprime-libraries.md){ .md-button .md-button--primary } +- [Create Ground-Derived Channels in F Prime GDS](operate/derive-channels-on-ground.md) +- [Develop a GDS Plugin](operate/develop-gds-plugins.md) +- [Load Parameters in Batch](operate/prm-write-how-to.md) -- __Integrating Third-Party Libraries__ +
- --- +
+Test — Learn how to test F´ components and applications. - This how to will walk you through how to integrate non-F´ libraries into your F´ project. It - will cover multiple approaches based on examples with [OpenCV](https://github.com/opencv/opencv), [OpenSSL](https://github.com/openssl/openssl) and [ETL](https://github.com/etlcpp/etl). +- [Write Rule-Based Tests for F Prime Components](test/rule-based-testing.md) +- [Test-Driven Development in F Prime (F´)](test/test-driven-development.md) - [View Integrating Third-Party Libraries](integrate-external-libraries.md){ .md-button .md-button--primary } +
-- __Porting F´ To a New Platform__ - - --- - - This how to will walk you through porting F´ to a new platform. - - [View Porting Guide](porting-guide.md){ .md-button .md-button--primary } - - -- __Implement a Framing Protocol__ - - --- - - This guide shows you how to implement a custom framing protocol in F Prime flight software and integrate it with the F Prime GDS. - - [View Implement a Framing Protocol](custom-framing.md){ .md-button .md-button--primary } - -- __Generate Data Products__ - - --- - - This guide shows you when to use data products, how to generate them, how to test them, and how to integrate them into your topology and ground system. - - [View Generate Data Products](data-products.md){ .md-button .md-button--primary } - -- __Define State Machines__ - - --- - - This guide shows you how to define and use state machines in F Prime with FPP so complex component behavior is explicit, testable, and maintainable. - - [View Define State Machines](define-state-machines.md){ .md-button .md-button--primary } - -- __Create Ground-Derived Channels__ - - --- - - This guide shows you how to compute telemetry-derived values on the ground and publish them through the F Prime GDS plugin system. - - [View Create Ground-Derived Channels](derive-channels-on-ground.md){ .md-button .md-button--primary } - -- __Develop a Device Driver__ - - --- - - This guide shows you how to build a new device driver in F Prime using the application-manager-driver pattern. - - [View Develop a Device Driver](develop-device-driver.md){ .md-button .md-button--primary } - -- __Develop a Subtopology__ - - --- - - This guide shows you how to organize reusable topology architecture into subtopologies that can be imported into deployments. - - [View Develop a Subtopology](develop-subtopologies.md){ .md-button .md-button--primary } - -- __Implement an OS Abstraction Layer__ - - --- - - This guide shows you how to implement a new OS Abstraction Layer for F´ so the framework can run on another operating system. - - [View Implement an OS Abstraction Layer](implement-osal.md){ .md-button .md-button--primary } - -- __Implement a Radio Manager Component__ - - --- - - This guide shows you how to implement a radio manager component using the communications adapter interface. - - [View Implement a Radio Manager Component](implement-radio-manager.md){ .md-button .md-button--primary } - -- __Develop Components in Python__ - - --- - - This guide shows you how to develop Python-based F Prime applications and integrate Python components into a larger system. - - [View Develop Components in Python](python-development.md){ .md-button .md-button--primary } - -- __Write Rule-Based Tests__ - - --- - - This guide shows you how to write rule-based unit tests for F Prime components using the RuleDemo example component. - - [View Write Rule-Based Tests](rule-based-testing.md){ .md-button .md-button--primary } - -- __Test-Driven Development__ - - --- - - This guide shows you a practical test-driven development loop for building an F´ component from model to implementation. - - [View Test-Driven Development](test-driven-development.md){ .md-button .md-button--primary } - -- __Import Parameters in Batch__ - - --- - - This guide covers two methods of updating parameters: through a `.dat` file that PrmDb loads directly, or by generating a command sequence (`.seq` file) to dispatch a series of commands. - - [View Import Parameters in Batch](prm-write-how-to.md){ .md-button .md-button--primary } - -
\ No newline at end of file diff --git a/docs/how-to/custom-framing.md b/docs/how-to/integrate/custom-framing.md similarity index 91% rename from docs/how-to/custom-framing.md rename to docs/how-to/integrate/custom-framing.md index 82eab4d27b0..49d00a590a6 100644 --- a/docs/how-to/custom-framing.md +++ b/docs/how-to/integrate/custom-framing.md @@ -2,7 +2,7 @@ This How-To Guide provides a step-by-step guide to implementing a custom framing protocol in F Prime Flight Software. -Modern F´ deployments use the CCSDS protocol by default via the `Svc.ComCcsds` subtopology. The lightweight [F Prime Protocol](../../Svc/FprimeProtocol/docs/sdd.md) (available via `Svc.ComFprime`) is also available as an alternative low-overhead communications protocol that the [F Prime GDS](https://github.com/nasa/fprime-gds) understands. However, some projects choose to implement another framing protocol that fits their mission requirements. This document provides an overview of how to implement a custom framing protocol in F Prime Flight Software, and how to integrate it with the F Prime GDS. +Modern F´ deployments use the CCSDS protocol by default via the `Svc.ComCcsds` subtopology. The lightweight [F Prime Protocol](../../../Svc/FprimeProtocol/docs/sdd.md) (available via `Svc.ComFprime`) is also available as an alternative low-overhead communications protocol that the [F Prime GDS](https://github.com/nasa/fprime-gds) understands. However, some projects choose to implement another framing protocol that fits their mission requirements. This document provides an overview of how to implement a custom framing protocol in F Prime Flight Software, and how to integrate it with the F Prime GDS. ## Overview @@ -28,7 +28,7 @@ To implement custom framing protocols, you will typically need to: 2. **Manually import components**: Copy the relevant topology code from the subtopology into your main topology so you can modify the component connections as needed, and remove the old `import Svc.ComCcsds` statement. 3. **Replace standard components**: Substitute the default framer/deframer components with your custom implementations -For more information on working with subtopologies, see the [Subtopologies Guide](../user-manual/design-patterns/subtopologies.md). This understanding is essential before proceeding with custom framing implementation. +For more information on working with subtopologies, see the [Subtopologies Guide](../../user-manual/design-patterns/subtopologies.md). This understanding is essential before proceeding with custom framing implementation. ## Flight Software Implementation @@ -41,7 +41,7 @@ To implement a custom framing protocol in F´, will need to implement the follow > [!TIP] > When creating framer/deframer components using `fprime-util new --component`, the recommended settings are to use passive components with events enabled. -The following examples will walk through the implementation of a custom framer and deframer for a hypothetical **MyCustomProtocol** protocol. Implementation details are left to the reader, but examples of such implementations can be found in the [fprime-examples repository](https://github.com/nasa/fprime-examples/tree/devel/FlightExamples/CustomFraming), or within the F´ codebase itself ([Svc.FprimeFramer](../../Svc/FprimeFramer/docs/sdd.md) and [Svc.FprimeDeframer](../../Svc/FprimeDeframer/docs/sdd.md)). +The following examples will walk through the implementation of a custom framer and deframer for a hypothetical **MyCustomProtocol** protocol. Implementation details are left to the reader, but examples of such implementations can be found in the [fprime-examples repository](https://github.com/nasa/fprime-examples/tree/devel/FlightExamples/CustomFraming), or within the F´ codebase itself ([Svc.FprimeFramer](../../../Svc/FprimeFramer/docs/sdd.md) and [Svc.FprimeDeframer](../../../Svc/FprimeDeframer/docs/sdd.md)). ### Pitfalls and Best Practices @@ -173,7 +173,7 @@ Before implementing, consider these best practices: - TCP connections (stream-based, no inherent message boundaries) - UART/serial connections (e.g. UART radios such as XBee) - F Prime provides this capability with the [Svc.FrameAccumulator](../../Svc/FrameAccumulator/docs/sdd.md) component, which uses a circular buffer and a helper `FrameDetector` to identify complete frames in the data stream. + F Prime provides this capability with the [Svc.FrameAccumulator](../../../Svc/FrameAccumulator/docs/sdd.md) component, which uses a circular buffer and a helper `FrameDetector` to identify complete frames in the data stream. > [!NOTE] > The `FrameDetector` is a C++ helper class, not an FPP component. It does not have an `.fpp` definition and is used internally by `Svc.FrameAccumulator`. @@ -215,7 +215,7 @@ Before implementing, consider these best practices: ## F´ GDS Implementation -To support your custom protocol in the F´ GDS, implement a GDS framing plugin. The GDS plugin system allows you to customize GDS behavior with user-provided code. For new framing protocols, you will need to implement a plugin that extends the `FramerDeframer`. This is further documented in the [How-To Develop a GDS Plugin Guide](./develop-gds-plugins.md) and [F Prime GDS Framing Plugin reference](../reference/gds-plugins/framing.md). +To support your custom protocol in the F´ GDS, implement a GDS framing plugin. The GDS plugin system allows you to customize GDS behavior with user-provided code. For new framing protocols, you will need to implement a plugin that extends the `FramerDeframer`. This is further documented in the [How-To Develop a GDS Plugin Guide](../operate/develop-gds-plugins.md) and [F Prime GDS Framing Plugin reference](../../reference/gds-plugins/framing.md). For example, in Python: @@ -239,7 +239,7 @@ class MyCustomFramerDeframer(FramerDeframer): return "MyCustomProtocol" ``` -Make sure to [package and install the plugin in your virtual environment](./develop-gds-plugins.md#packaging-and-testing-plugins) for the GDS to be able to load it, then run it: +Make sure to [package and install the plugin in your virtual environment](../operate/develop-gds-plugins.md#packaging-and-testing-plugins) for the GDS to be able to load it, then run it: ``` fprime-gds --framing-selection MyCustomProtocol @@ -249,7 +249,7 @@ fprime-gds --framing-selection MyCustomProtocol - [C++ CustomFraming Example](https://github.com/nasa/fprime-examples/tree/devel/FlightExamples/CustomFraming) - [GDS Plugin Example](https://github.com/nasa/fprime-examples/tree/devel/GdsExamples/gds-plugins/src/framing) -- [F Prime GDS Framing Plugin](../reference/gds-plugins/framing.md) -- [F Prime Communication Adapter Interface](../reference/communication-adapter-interface.md) +- [F Prime GDS Framing Plugin](../../reference/gds-plugins/framing.md) +- [F Prime Communication Adapter Interface](../../reference/communication-adapter-interface.md) - [F Prime GDS Plugin Development](https://fprime.jpl.nasa.gov/devel/docs/how-to/develop-gds-plugins/) diff --git a/docs/how-to/implement-osal.md b/docs/how-to/integrate/implement-osal.md similarity index 89% rename from docs/how-to/implement-osal.md rename to docs/how-to/integrate/implement-osal.md index 0f47a672f0b..7a9bec8356c 100644 --- a/docs/how-to/implement-osal.md +++ b/docs/how-to/integrate/implement-osal.md @@ -1,6 +1,6 @@ -# How-To: Implement an OS Abstraction Layer +# Implement an OS Abstraction Layer -This guide provides step-by-step instructions for implementing a new OS Abstraction Layer (OSAL) for F´. The F´ OSAL provides a uniform interface to operating system services, allowing F´ to run on multiple operating systems without modification to the source code. For more information on the architecture and design of the OSAL, refer to the [OSAL Software Design Document](../../Os/docs/sdd.md). +This guide provides step-by-step instructions for implementing a new OS Abstraction Layer (OSAL) for F´. The F´ OSAL provides a uniform interface to operating system services, allowing F´ to run on multiple operating systems without modification to the source code. For more information on the architecture and design of the OSAL, refer to the [OSAL Software Design Document](../../../Os/docs/sdd.md). --- @@ -8,16 +8,16 @@ This guide provides step-by-step instructions for implementing a new OS Abstract Before starting, you should have: -* An understanding of the [OSAL architecture](../../Os/docs/sdd.md#5-implementation-architecture), specifically the [delegate pattern](../../Os/docs/sdd.md#51-delegate-pattern). +* An understanding of the [OSAL architecture](../../../Os/docs/sdd.md#5-implementation-architecture), specifically the [delegate pattern](../../../Os/docs/sdd.md#51-delegate-pattern). * A working F´ build environment for testing. -* Familiarity with [F´ libraries](develop-fprime-libraries.md) and [F´ platform files](develop-fprime-libraries.md#optional-platform-folder-and-platform-files). +* Familiarity with [F´ libraries](../develop/develop-fprime-libraries.md) and [F´ platform files](../develop/develop-fprime-libraries.md#optional-platform-folder-and-platform-files). * Knowledge of your target OS APIs (e.g., mutex, task creation, file I/O). --- ## Overview -The OSAL uses a delegate pattern to decouple F´ application code from platform-specific OS calls. Each OSAL _service_ (Mutex, File, Task, etc.) has three layers: an **interface class** defining the contract, a **wrapper class** (e.g., `Os::Mutex`) that application code uses, and a **platform-specific implementation** that the wrapper delegates to. The build system selects the implementation at link time. Before proceeding, read the [OSAL Software Design Document](../../Os/docs/sdd.md) — in particular the [delegate pattern](../../Os/docs/sdd.md#51-delegate-pattern) and [implementation architecture](../../Os/docs/sdd.md#5-implementation-architecture) sections — as this guide assumes familiarity with those concepts. +The OSAL uses a delegate pattern to decouple F´ application code from platform-specific OS calls. Each OSAL _service_ (Mutex, File, Task, etc.) has three layers: an **interface class** defining the contract, a **wrapper class** (e.g., `Os::Mutex`) that application code uses, and a **platform-specific implementation** that the wrapper delegates to. The build system selects the implementation at link time. Before proceeding, read the [OSAL Software Design Document](../../../Os/docs/sdd.md) — in particular the [delegate pattern](../../../Os/docs/sdd.md#51-delegate-pattern) and [implementation architecture](../../../Os/docs/sdd.md#5-implementation-architecture) sections — as this guide assumes familiarity with those concepts. This guide walks through implementing an OSAL for a hypothetical OS called **"MyOs"**, and walks through the implementation of the `Os::Mutex` service as the example. The same process applies for all other OSAL services. Reference implementations are linked in the [Additional Resources](#additional-resources) section below. @@ -25,7 +25,7 @@ This guide walks through implementing an OSAL for a hypothetical OS called **"My ## Step 1 — Set Up the Library -An OSAL implementation is packaged as an [F´ library](develop-fprime-libraries.md). Create the following directory structure: +An OSAL implementation is packaged as an [F´ library](../develop/develop-fprime-libraries.md). Create the following directory structure: ``` fprime-my-os/ @@ -98,7 +98,7 @@ class MyOsMutex : public MutexInterface { ``` > [!TIP] -> Look at each interface header in `Os/` (e.g., `Os/Mutex.hpp`, `Os/File.hpp`, `Os/Task.hpp`) to see the exact set of pure virtual methods that need to be implemented for each. Each interface also defines a `Status` enum — your implementation must return the appropriate [status values](../../Os/docs/sdd.md#24-error-handling). +> Look at each interface header in `Os/` (e.g., `Os/Mutex.hpp`, `Os/File.hpp`, `Os/Task.hpp`) to see the exact set of pure virtual methods that need to be implemented for each. Each interface also defines a `Status` enum — your implementation must return the appropriate [status values](../../../Os/docs/sdd.md#24-error-handling). ### 2.2 — Implement the Methods @@ -238,7 +238,7 @@ The process described above for `Os::Mutex` is the same for every OSAL module. F > [!NOTE] > F´ provides `Os_Generic_PriorityQueue`, a platform-independent queue implementation that most platforms use. You do not need to write an OS-specific queue unless the generic one is unsuitable for your target. -The full set of [OSAL modules](../../Os/docs/sdd.md#2-core-services) that can be implemented is: +The full set of [OSAL modules](../../../Os/docs/sdd.md#2-core-services) that can be implemented is: | Module | Interface | Key Methods | |---|---|---| @@ -272,7 +272,7 @@ The bottom line is that to use your new OSAL implementation, you need to add the ## Best Practices -- **Start with Stubs.** Only implement the modules you need. The [Stub backend](../../Os/Stub) returns `NOT_SUPPORTED` for unimplemented services, allowing you to bring up an OSAL incrementally. +- **Start with Stubs.** Only implement the modules you need. The [Stub backend](../../../Os/Stub) returns `NOT_SUPPORTED` for unimplemented services, allowing you to bring up an OSAL incrementally. - **Map error codes consistently.** Create a shared error-translation module (like `Os/Posix/error.hpp`) that converts your OS's native error codes to the F´ Os `Status` enums. This keeps error handling centralized and testable. - **Watch the handle size.** Each implementation object must fit in the fixed-size handle storage. If your native OS primitives are large, override `FW_MUTEX_HANDLE_MAX_SIZE` (or equivalent) in your platform configuration. - **Use other implementations as references.** The `Os/Posix/` directory is the most complete OSAL implementation in F´ and serves as the canonical example for all modules. Other implementations exist (see links above, or in the resources below) @@ -282,8 +282,8 @@ The bottom line is that to use your new OSAL implementation, you need to add the ## Additional Resources -- [OSAL Software Design Document](../../Os/docs/sdd.md) — Architecture details and design rationale. -- [Develop an F´ Library](develop-fprime-libraries.md) — Library structure, toolchain, and platform files. +- [OSAL Software Design Document](../../../Os/docs/sdd.md) — Architecture details and design rationale. +- [Develop an F´ Library](../develop/develop-fprime-libraries.md) — Library structure, toolchain, and platform files. - [Porting Guide](porting-guide.md) — High-level checklist for porting F´ to a new platform. - [Posix OSAL implementation](https://github.com/nasa/fprime/tree/devel/Os/Posix) — Reference implementation for POSIX systems. - [fprime-zephyr](https://github.com/fprime-community/fprime-zephyr) — OSAL implementation for Zephyr RTOS. diff --git a/docs/how-to/integrate-external-libraries.md b/docs/how-to/integrate/integrate-external-libraries.md similarity index 100% rename from docs/how-to/integrate-external-libraries.md rename to docs/how-to/integrate/integrate-external-libraries.md diff --git a/docs/how-to/porting-guide.md b/docs/how-to/integrate/porting-guide.md similarity index 100% rename from docs/how-to/porting-guide.md rename to docs/how-to/integrate/porting-guide.md diff --git a/docs/how-to/derive-channels-on-ground.md b/docs/how-to/operate/derive-channels-on-ground.md similarity index 95% rename from docs/how-to/derive-channels-on-ground.md rename to docs/how-to/operate/derive-channels-on-ground.md index 73c28cd2eb2..823d8cf8cda 100644 --- a/docs/how-to/derive-channels-on-ground.md +++ b/docs/how-to/operate/derive-channels-on-ground.md @@ -143,7 +143,7 @@ First this code filters out unwanted channels. Then it performs a translation on ## Running It -Install the plugin as directed in the plugin development How-To section [packaging and testing plugins ](./develop-gds-plugins.md#packaging-and-testing-plugins). Next we need to merge our dictionaries and run it. This is accomplished by running the merge dictionary command, and then supplying the output to the `--dictionary` flag of the GDS. +Install the plugin as directed in the plugin development How-To section [packaging and testing plugins ](develop-gds-plugins.md#packaging-and-testing-plugins). Next we need to merge our dictionaries and run it. This is accomplished by running the merge dictionary command, and then supplying the output to the `--dictionary` flag of the GDS. **Merging Dictionaries** ```bash diff --git a/docs/how-to/develop-gds-plugins.md b/docs/how-to/operate/develop-gds-plugins.md similarity index 98% rename from docs/how-to/develop-gds-plugins.md rename to docs/how-to/operate/develop-gds-plugins.md index a9def4fa9de..d6ac111119d 100644 --- a/docs/how-to/develop-gds-plugins.md +++ b/docs/how-to/operate/develop-gds-plugins.md @@ -37,11 +37,11 @@ category is summarized in the table below. | Category | Type | Description | Reference | |---------------|---------------|--------------------------------------------------------------------------|------------------------------------------------------------------------------| -| framing | SELECTION | Implement a framer/deframer pair to handle serialized data | [Framing Plugin Reference](../reference/gds-plugins/framing.md) | -| communication | SELECTION | Implement a communication adapter for flight software communication | [Communication Plugin Reference](../reference/gds-plugins/communications.md) | -| data-handler | FEATURE | Implement custom data item handling (for channels, events, etc) | [Data Handler Plugin](../reference/gds-plugins/data-handler.md) | -| gds-app | FEATURE | Implement a new GDS application isolated to a separate process | [Gds Application Plugin](../reference/gds-plugins/gds-app.md) | -| gds-function | FEATURE | (Advanced) Implement new GDS functionality with control over the process | [Gds Function Plugin](../reference/gds-plugins/gds-function.md) | +| framing | SELECTION | Implement a framer/deframer pair to handle serialized data | [Framing Plugin Reference](../../reference/gds-plugins/framing.md) | +| communication | SELECTION | Implement a communication adapter for flight software communication | [Communication Plugin Reference](../../reference/gds-plugins/communications.md) | +| data-handler | FEATURE | Implement custom data item handling (for channels, events, etc) | [Data Handler Plugin](../../reference/gds-plugins/data-handler.md) | +| gds-app | FEATURE | Implement a new GDS application isolated to a separate process | [Gds Application Plugin](../../reference/gds-plugins/gds-app.md) | +| gds-function | FEATURE | (Advanced) Implement new GDS functionality with control over the process | [Gds Function Plugin](../../reference/gds-plugins/gds-function.md) | Plugins should define a function called `register__plugin` that return a concrete subclass of the category's diff --git a/docs/how-to/prm-write-how-to.md b/docs/how-to/operate/prm-write-how-to.md similarity index 99% rename from docs/how-to/prm-write-how-to.md rename to docs/how-to/operate/prm-write-how-to.md index 4092b013cec..b87e5c67160 100644 --- a/docs/how-to/prm-write-how-to.md +++ b/docs/how-to/operate/prm-write-how-to.md @@ -1,4 +1,4 @@ -# How-To: Load Parameters in Batch +# Load Parameters in Batch ## Overview diff --git a/docs/how-to/rule-based-testing.md b/docs/how-to/test/rule-based-testing.md similarity index 99% rename from docs/how-to/rule-based-testing.md rename to docs/how-to/test/rule-based-testing.md index db2edc36a93..83db1cfc43c 100644 --- a/docs/how-to/rule-based-testing.md +++ b/docs/how-to/test/rule-based-testing.md @@ -1,4 +1,4 @@ -# How-To: Write Rule-Based Tests for F Prime Components +# Write Rule-Based Tests for F Prime Components This guide shows how to write Rule-Based Testing (RBT) unit tests for an F Prime component. diff --git a/docs/how-to/test-driven-development.md b/docs/how-to/test/test-driven-development.md similarity index 99% rename from docs/how-to/test-driven-development.md rename to docs/how-to/test/test-driven-development.md index 2f71ad067df..16d15f4db59 100644 --- a/docs/how-to/test-driven-development.md +++ b/docs/how-to/test/test-driven-development.md @@ -1,4 +1,4 @@ -# How-To: Test-Driven Development in F Prime (F´) +# Test-Driven Development in F Prime (F´) This guide shows a practical, repeatable test-driven development loop for building an F´ component. You’ll model behavior first in FPP, stub the implementation, write tests that fail, then implement the component until the tests pass—iterating as needed. diff --git a/docs/local-website-build.sh b/docs/local-website-build.sh old mode 100644 new mode 100755 index 2a5bc608e41..00efb79a0d2 --- a/docs/local-website-build.sh +++ b/docs/local-website-build.sh @@ -32,7 +32,7 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" VENV_DIR="$SCRIPT_DIR/docs-venv" # mkdocs.yml sets docs_dir to the fprime/ root, so site_dir must be outside it. -SITE_DIR="$REPO_ROOT/../fprime-docs-site-local" +SITE_DIR="./site" PORT=8000 echo -e "${BLUE}========================================${NC}" @@ -72,10 +72,11 @@ python -m pip install \ echo -e "${GREEN}Building nested docs website only...${NC}" rm -rf "$SITE_DIR" + # Temporarily disable custom_dir since overrides/ doesn't exist in standalone fprime/ checkout -sed 's/custom_dir:/#custom_dir:/' "$SCRIPT_DIR/mkdocs.yml" > "$SCRIPT_DIR/mkdocs.local.yml" +sed 's/custom_dir:/#custom_dir:/' "$REPO_ROOT/mkdocs.yml" > "$REPO_ROOT/mkdocs.local.yml" -mkdocs build --clean --config-file "$SCRIPT_DIR/mkdocs.local.yml" --site-dir "$SITE_DIR" +mkdocs build --clean --config-file "$REPO_ROOT/mkdocs.local.yml" if [ $? -ne 0 ]; then echo -e "${RED}Error: Documentation build failed${NC}" diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 47e4c86a63b..7e45e626fa1 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -147,10 +147,147 @@ markdown_extensions: # Custom navigation is set in the fprime/.nav.yml file # Must keep a copy of just the tutorials nav here to let multirepo know to import them, this does not act as a nav nav: + - Home: https://fprime.jpl.nasa.gov/ + - Documentation: index.md + - Getting Started: + - Getting Started: getting-started/index.md + - Installing F´: getting-started/installing-fprime.md + - F´ Features: getting-started/features.md - Tutorials: - Tutorials Index: docs/tutorials/index.md - - 'Hello World': tutorials-hello-world/docs/hello-world.md - - 'LED Blinker': tutorials-led-blinker/docs/led-blinker.md - - 'MathComponent': tutorials-math-component/docs/math-component.md - - 'Cross-Compilation Setup': docs/tutorials/cross-compilation.md - - 'Arduino LED Blinker': tutorials-arduino-led-blinker/docs/arduino-led-blinker.md + - Hello World: ../../tutorials/tutorials-hello-world/docs/hello-world.md + - LED Blinker: ../../tutorials/tutorials-led-blinker/docs/led-blinker.md + - MathComponent: ../../tutorials/tutorials-math-component/docs/math-component.md + - Cross-Compilation Setup: docs/tutorials/cross-compilation.md + - Arduino LED Blinker: ../..//tutorials-arduino-led-blinker/docs/arduino-led-blinker.md + - User Manual: + - User Manual: user-manual/index.md + - Framework: + - Supported Platforms: user-manual/framework/supported-platforms.md + - F´ Autocoded Functions and Component Classes: user-manual/framework/autocoded-functions.md + - F´ on Baremetal Systems: user-manual/framework/run-baremetal.md + - Selecting Component, Port, and Command Kinds: user-manual/framework/component-and-port-selection.md + - State Machines: user-manual/framework/state-machines.md + - Memory Management: + - Memory Management: user-manual/framework/memory-management/index.md + - Memory Allocation with Fw::MemAllocator: user-manual/framework/memory-management/memory-allocation.md + - Buffer Pools with Svc.BufferManager: user-manual/framework/memory-management/buffer-pool.md + - Data Products: user-manual/framework/data-products.md + - Ground Interface Architecture and Customization: user-manual/framework/ground-interface.md + - F´ on Multi-Core Systems: user-manual/framework/run-multi-core.md + - Configuring F´: user-manual/framework/configuring-fprime.md + - Asserts in F: user-manual/framework/assert.md + - Constructing the F´ Topology: user-manual/framework/building-topology.md + - Security: + - Software Bill Of Materials Generation: user-manual/security/software-bill-of-materials.md + - Design Patterns: + - Application-Manager-Driver Architecture: user-manual/design-patterns/app-man-drv.md + - Health Checking Pattern: user-manual/design-patterns/health-checking.md + - Rate Groups and Timeliness: user-manual/design-patterns/rate-group.md + - The Manager/Worker Pattern: user-manual/design-patterns/manager-worker.md + - Subtopologies: user-manual/design-patterns/subtopologies.md + - A Quick Look at the Hub Pattern: user-manual/design-patterns/hub-pattern.md + - Common Port Design Patterns: user-manual/design-patterns/common-port-patterns.md + - GDS: + - GDS Integration Test API: user-manual/gds/gds-test-api-guide.md + - The F´ GDS CLI: user-manual/gds/gds-cli.md + - Sequencing In F´: user-manual/gds/seqgen.md + - GDS Developer's Guide: user-manual/gds/gds-dev-guide.md + - GDS Dashboard Component Reference: user-manual/gds/gds-dashboard-reference.md + - The GDS Dashboard: user-manual/gds/gds-custom-dashboards.md + - Reusable Integration Tests: user-manual/gds/reusable-integration-tests.md + - Overview: + - 'Core Constructs: Ports, Components, and Topologies': user-manual/overview/03-port-comp-top.md + - F´ Development Process: user-manual/overview/development-practice.md + - Projects and Deployments: user-manual/overview/proj-dep.md + - The F´ Ground Data System: user-manual/overview/gds-introduction.md + - Data Structures and Types: user-manual/overview/05-enum-arr-ser.md + - Introduction To F´: user-manual/overview/01-full-intro.md + - F´ Software Architecture: user-manual/overview/02-fprime-architecture.md + - A Tour of the Source Tree: user-manual/overview/source-tree.md + - Unit Testing in F´: user-manual/overview/unit-testing.md + - 'Data Constructs: Commands, Events, Channels, and Parameters': user-manual/overview/04-cmd-evt-chn-prm.md + - Build System: + - CMake Toolchain Files: user-manual/build-system/cmake-toolchains.md + - '`settings.ini`: Build Settings Configuration': user-manual/build-system/settings.md + - CMake Implementations: user-manual/build-system/cmake-implementations.md + - CMake Customization: user-manual/build-system/cmake-customization.md + - CMake API Reference: user-manual/build-system/cmake-api.md + - Targets: user-manual/build-system/cmake-targets.md + - F´ CMake Build System: user-manual/build-system/01-cmake-intro.md + - CMake Build System Unit Tests: user-manual/build-system/cmake-uts.md + - F´ and CMake Platforms: user-manual/build-system/cmake-platforms.md + - How-To: + - How-To: how-to/index.md + - Develop: + - Define State Machines in F Prime: how-to/develop/define-state-machines.md + - Develop a Device Driver: how-to/develop/develop-device-driver.md + - Develop Components in Python: how-to/develop/python-development.md + - Implement a Radio Manager Component: how-to/develop/implement-radio-manager.md + - Develop an F´ Library: how-to/develop/develop-fprime-libraries.md + - Generate Data Products: how-to/develop/data-products.md + - Develop a Subtopology: how-to/develop/develop-subtopologies.md + - Test: + - Test-Driven Development in F Prime (F´): how-to/test/test-driven-development.md + - Write Rule-Based Tests for F Prime Components: how-to/test/rule-based-testing.md + - Integrate: + - Implement an OS Abstraction Layer: how-to/integrate/implement-osal.md + - Porting to new platforms: how-to/integrate/porting-guide.md + - Integrate a Third-Party Library: how-to/integrate/integrate-external-libraries.md + - Implement a Framing Protocol: how-to/integrate/custom-framing.md + - Operate: + - Develop a GDS Plugin: how-to/operate/develop-gds-plugins.md + - Load Parameters in Batch: how-to/operate/prm-write-how-to.md + - Create Ground-Derived Channels in F Prime GDS: how-to/operate/derive-channels-on-ground.md + - Reference: + - Reference: reference/index.md + - FPP JSON Dictionary Specification: reference/fpp-json-dict.md + - GDS Plugins: + - App Plugin: reference/gds-plugins/gds-app.md + - Framing Plugin: reference/gds-plugins/framing.md + - Communication Plugin: reference/gds-plugins/communications.md + - Data Handler Plugin: reference/gds-plugins/data-handler.md + - GDS Function Plugin: reference/gds-plugins/gds-function.md + - Nomenclature: reference/nomenclature.md + - Communication Adapter Interface: reference/communication-adapter-interface.md + - F Prime Translation Guide: reference/fprime-translations.md + - System Functional Documentation: + - System Functional Documentation: reference/system-functional/index.md + - Communication Stack Functionality: reference/system-functional/communication.md + - Operating System Abstraction Layer (OSAL): reference/system-functional/osal.md + - Parameter Management Functionality: reference/system-functional/parameters.md + - ComLoggerTee Subtopology: reference/system-functional/subtopology-com-logger-tee.md + - System Services Functionality: reference/system-functional/system-services.md + - ComFprime Subtopology: reference/system-functional/subtopology-com-fprime.md + - File Management Functionality: reference/system-functional/file-management.md + - Sequencing Functionality: reference/system-functional/sequencing.md + - ComCcsds Subtopology: reference/system-functional/subtopology-com-ccsds.md + - File Handling Subtopology: reference/system-functional/subtopology-file-handling.md + - Health Monitoring Functionality: reference/system-functional/health-monitoring.md + - Hardware Driver Functionality: reference/system-functional/hardware-drivers.md + - Data Products Subtopology: reference/system-functional/subtopology-data-products.md + - Time Services Functionality: reference/system-functional/time-services.md + - Dictionary Capabilities: reference/system-functional/dictionary.md + - Event Management Functionality: reference/system-functional/event-management.md + - CCSDS Protocol Functionality: reference/system-functional/ccsds-protocol.md + - Buffer Management Functionality: reference/system-functional/buffer-management.md + - Rate Group Scheduling Functionality: reference/system-functional/rate-group-scheduling.md + - Data Products Functionality: reference/system-functional/data-products.md + - Command Dispatch Functionality: reference/system-functional/command-dispatch.md + - Framework Functionality: reference/system-functional/framework.md + - Telemetry Channel Storage Functionality: reference/system-functional/telemetry-chan.md + - Telemetry Packetizer Functionality: reference/system-functional/telemetry-packetizer.md + - CDH Core Subtopology: reference/system-functional/subtopology-cdh-core.md + - F´ Numerical Types: reference/numerical-types.md +# watch: # if this path changes, a full site rebuild is triggered, but this is causing zensical serve to stall +# - / + +validation: # warning messages at build time + unresolved_references: false + unresolved_footnotes: false + unused_definitions: false + unused_footnotes: false + shadowed_definitions: false + shadowed_footnotes: false + invalid_links: false + invalid_link_anchors: false \ No newline at end of file diff --git a/docs/reference/fprime-translations.md b/docs/reference/fprime-translations.md index 4e7cb75e4a9..a2ce463eae6 100644 --- a/docs/reference/fprime-translations.md +++ b/docs/reference/fprime-translations.md @@ -1,4 +1,4 @@ -# F Prime Translation Guide: Software Engineering Terminology to F Prime Nomenclature +# F Prime Translation Guide This guide provides a mapping between common software engineering concepts and their equivalent implementations in the F´ framework. It serves as a reference for developers new to F´ development. diff --git a/docs/reference/index.md b/docs/reference/index.md index 6abd1e0d6bf..430458e266f 100644 --- a/docs/reference/index.md +++ b/docs/reference/index.md @@ -5,42 +5,63 @@ hide: # Reference -Technical reference for the F Prime C++ API, CMake API, FPP language specification and more. +Reference documentation for F Prime APIs and components. + +> [!TIP] +> **← Navigation pane** +> Use the navigation pane on the left to explore the different chapters of the Reference documentation. If the navigation pane is not visible, click on the menu icon (three horizontal lines) at the top left corner of the page. The navigation pane is hidden on narrow screens or if zoomed in. + +## Table of Contents + +- [**Communication Adapter Interface**](communication-adapter-interface.md) + +- [**FPP JSON Dictionary Specification**](fpp-json-dict.md) + +- [**F Prime Translation Guide**](fprime-translations.md) + +
+GDS Plugins + +- [Communication Plugin](gds-plugins/communications.md) +- [Data Handler Plugin](gds-plugins/data-handler.md) +- [Framing Plugin](gds-plugins/framing.md) +- [App Plugin](gds-plugins/gds-app.md) +- [GDS Function Plugin](gds-plugins/gds-function.md) + +
+ +- [**Nomenclature**](nomenclature.md) + +- [**F´ Numerical Types**](numerical-types.md) + +
+System Functional Documentation + +- [Buffer Management Functionality](system-functional/buffer-management.md) +- [CCSDS Protocol Functionality](system-functional/ccsds-protocol.md) +- [Command Dispatch Functionality](system-functional/command-dispatch.md) +- [Communication Stack Functionality](system-functional/communication.md) +- [Data Products Functionality](system-functional/data-products.md) +- [Dictionary Capabilities](system-functional/dictionary.md) +- [Event Management Functionality](system-functional/event-management.md) +- [File Management Functionality](system-functional/file-management.md) +- [Framework Functionality](system-functional/framework.md) +- [Hardware Driver Functionality](system-functional/hardware-drivers.md) +- [Health Monitoring Functionality](system-functional/health-monitoring.md) +- [Operating System Abstraction Layer (OSAL)](system-functional/osal.md) +- [Parameter Management Functionality](system-functional/parameters.md) +- [Rate Group Scheduling Functionality](system-functional/rate-group-scheduling.md) +- [Sequencing Functionality](system-functional/sequencing.md) +- [CDH Core Subtopology](system-functional/subtopology-cdh-core.md) +- [ComCcsds Subtopology](system-functional/subtopology-com-ccsds.md) +- [ComFprime Subtopology](system-functional/subtopology-com-fprime.md) +- [ComLoggerTee Subtopology](system-functional/subtopology-com-logger-tee.md) +- [Data Products Subtopology](system-functional/subtopology-data-products.md) +- [File Handling Subtopology](system-functional/subtopology-file-handling.md) +- [System Services Functionality](system-functional/system-services.md) +- [Telemetry Channel Storage Functionality](system-functional/telemetry-chan.md) +- [Telemetry Packetizer Functionality](system-functional/telemetry-packetizer.md) +- [Time Services Functionality](system-functional/time-services.md) + +
- -
- -- __C++ Documentation__ - - --- - - This is the F´ automatically generated documentation for C++. - - [View C++ Documentation](./api/cpp/html/index.html){ .md-button .md-button--primary } - -- __F´ Components SDDs__ - - --- - - Software Design Documents (SDD) capture the design of the F´ core components. - - Please use the left navigation panel to browse the SDDs. - -- __FPP Language Specification__ - - --- - - This document describes F Prime Prime, also known as FPP or F Double Prime. - - [View FPP Language Spec](https://nasa.github.io/fpp/fpp-spec.html){ .md-button .md-button--primary } - -- __CMake User API__ - - --- - - This section of the documentation captures step by step how tos for various F´ development tasks. - - [View CMake User API Documentation](./api/cmake/API.md){ .md-button .md-button--primary } - - -
\ No newline at end of file diff --git a/docs/tutorials/sync_tutorial_docs.py b/docs/tutorials/sync_tutorial_docs.py new file mode 100644 index 00000000000..3f42aef57f6 --- /dev/null +++ b/docs/tutorials/sync_tutorial_docs.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +"""At website runtime, git clone tutorials markdown files into fprime/docs/tutorials. +This was initially written for Zensical integration. +""" + +from __future__ import annotations + +import shutil +import subprocess +from pathlib import Path + + +def tutorials() -> None: + # Get the tutorials directory (fprime/docs/tutorials/) + script_dir = Path(__file__).parent + + # Define the repository URLs and their target directories + repos = { + "tutorials-hello-world": "https://github.com/fprime-community/fprime-tutorial-hello-world.git", + "tutorials-led-blinker": "https://github.com/fprime-community/fprime-workshop-led-blinker.git", + "tutorials-math-component": "https://github.com/fprime-community/fprime-tutorial-math-component.git", + "tutorials-arduino-led-blinker": "https://github.com/fprime-community/fprime-tutorial-arduino-blinker.git", + } + + for target_dir, repo_url in repos.items(): + target_path = script_dir / target_dir + + # Remove existing directory if it exists + if target_path.exists(): + shutil.rmtree(target_path) + + # Clone the repository + print(f"Cloning {repo_url} into {target_path}...") + subprocess.run(["git", "clone", repo_url, str(target_path)], check=True) + + # Remove the .git directory to avoid nested repo issues with mike + git_dir = target_path / ".git" + if git_dir.exists(): + shutil.rmtree(git_dir) + print(f"Removed .git directory from {target_path}") + + +if __name__ == "__main__": + tutorials() diff --git a/docs/user-manual/build-system/cmake-api.md b/docs/user-manual/build-system/cmake-api.md index 9214e1da391..fd58eb7ecd6 100644 --- a/docs/user-manual/build-system/cmake-api.md +++ b/docs/user-manual/build-system/cmake-api.md @@ -1,3 +1,5 @@ +# CMake API Reference + ## User API Documentation These links point to documentation needed by most users of the CMake system. The API link diff --git a/docs/user-manual/build-system/cmake-customization.md b/docs/user-manual/build-system/cmake-customization.md index 9567315d3bd..a7bb711da65 100644 --- a/docs/user-manual/build-system/cmake-customization.md +++ b/docs/user-manual/build-system/cmake-customization.md @@ -43,4 +43,4 @@ Alternatively, `ExternalProject_Add` can be used if the external library require version control, and building steps. For a guide on integrating with another build system see: -[How To: Integrate External Libraries](../../how-to/integrate-external-libraries.md). \ No newline at end of file +[How To: Integrate External Libraries](../../how-to/integrate/integrate-external-libraries.md). \ No newline at end of file diff --git a/docs/user-manual/design-patterns/app-man-drv.md b/docs/user-manual/design-patterns/app-man-drv.md index 09fd280e661..d303509c8ab 100644 --- a/docs/user-manual/design-patterns/app-man-drv.md +++ b/docs/user-manual/design-patterns/app-man-drv.md @@ -77,7 +77,7 @@ know what I2C hardware it is talking to. ## How-To Guide -A detailed How-To guide for implementing the Manager-Driver pattern can be found here: [How-To Implement a Device Driver](../../how-to/develop-device-driver.md) +A detailed How-To guide for implementing the Manager-Driver pattern can be found here: [How-To Implement a Device Driver](../../how-to/develop/develop-device-driver.md) ## Conclusion diff --git a/docs/user-manual/index.md b/docs/user-manual/index.md index d63eb30ce3c..8cb9c78644e 100644 --- a/docs/user-manual/index.md +++ b/docs/user-manual/index.md @@ -5,22 +5,93 @@ hide: # User Manual -The User Manual dives into F Prime concepts and usage, providing a deep understanding of how the framework operates. The different chapters are listed below. +The User Manual provides comprehensive documentation for understanding and using F Prime. > [!TIP] > **← Navigation pane** -> Use the navigation pane on the left to explore the different chapters of the User Manual. If the navigation pane is not visible, click on the menu icon (three horizontal lines) at the top left corner of the page. The navigation pane is hidden on narrow screens or if zoomed in. +> Use the navigation pane on the left to explore the different chapters of the User Manual documentation. If the navigation pane is not visible, click on the menu icon (three horizontal lines) at the top left corner of the page. The navigation pane is hidden on narrow screens or if zoomed in. -- __Overview__ - Technical overview of the F´ ecosystem. +## Table of Contents -- __Framework__ - Learn concepts and mechanisms needed to build and use an F´ application. +
+Overview — Technical overview of the F´ ecosystem. -- __FPP User's Guide__ - In-depth user guide for F Prime Prime (FPP), the F´ modeling language. +- [Introduction To F´](overview/01-full-intro.md) +- [F´ Software Architecture](overview/02-fprime-architecture.md) +- [Core Constructs: Ports, Components, and Topologies](overview/03-port-comp-top.md) +- [Data Constructs: Commands, Events, Channels, and Parameters](overview/04-cmd-evt-chn-prm.md) +- [Data Structures and Types](overview/05-enum-arr-ser.md) +- [F´ Development Process](overview/development-practice.md) +- [The F´ Ground Data System](overview/gds-introduction.md) +- [Projects and Deployments](overview/proj-dep.md) +- [A Tour of the Source Tree](overview/source-tree.md) +- [Unit Testing in F´](overview/unit-testing.md) -- __F´ GDS__ - Learn how to use the F Prime Ground Data System, and how it can be used to test F´ applications. +
-- __Design Patterns__ - Learn about common design patterns used in F´ applications. +
+Framework — Learn concepts and mechanisms needed to build and use an F´ application. -- __Build System__ - Learn about the F´ build system and how to customize it. +- [Asserts in F](framework/assert.md) +- [F´ Autocoded Functions and Component Classes](framework/autocoded-functions.md) +- [Constructing the F´ Topology](framework/building-topology.md) +- [Selecting Component, Port, and Command Kinds](framework/component-and-port-selection.md) +- [Configuring F´](framework/configuring-fprime.md) +- [Data Products](framework/data-products.md) +- [Ground Interface Architecture and Customization](framework/ground-interface.md) +- [Memory Management](framework/memory-management/index.md) +- [F´ on Baremetal Systems](framework/run-baremetal.md) +- [F´ on Multi-Core Systems](framework/run-multi-core.md) +- [State Machines](framework/state-machines.md) +- [Supported Platforms](framework/supported-platforms.md) + +
+ +
+GDS — Learn how to use the F Prime Ground Data System, and how it can be used to test F´ applications. + +- [The F´ GDS CLI](gds/gds-cli.md) +- [The GDS Dashboard](gds/gds-custom-dashboards.md) +- [GDS Dashboard Component Reference](gds/gds-dashboard-reference.md) +- [GDS Developer's Guide](gds/gds-dev-guide.md) +- [GDS Integration Test API](gds/gds-test-api-guide.md) +- [Reusable Integration Tests](gds/reusable-integration-tests.md) +- [Sequencing In F´](gds/seqgen.md) + +
+ +
+Design Patterns — Learn about common design patterns used in F´ applications. + +- [Application-Manager-Driver Architecture](design-patterns/app-man-drv.md) +- [Common Port Design Patterns](design-patterns/common-port-patterns.md) +- [Health Checking Pattern](design-patterns/health-checking.md) +- [A Quick Look at the Hub Pattern](design-patterns/hub-pattern.md) +- [The Manager/Worker Pattern](design-patterns/manager-worker.md) +- [Rate Groups and Timeliness](design-patterns/rate-group.md) +- [Subtopologies](design-patterns/subtopologies.md) + +
+ +
+Build System — Learn about the F´ build system and how to customize it. + +- [F´ CMake Build System](build-system/01-cmake-intro.md) +- [CMake API Reference](build-system/cmake-api.md) +- [CMake Customization](build-system/cmake-customization.md) +- [CMake Implementations](build-system/cmake-implementations.md) +- [F´ and CMake Platforms](build-system/cmake-platforms.md) +- [Targets](build-system/cmake-targets.md) +- [CMake Toolchain Files](build-system/cmake-toolchains.md) +- [CMake Build System Unit Tests](build-system/cmake-uts.md) +- [`settings.ini`: Build Settings Configuration](build-system/settings.md) + +
+ +
+Security — Security considerations when designing and developing F´ applications. + +- [Software Bill Of Materials Generation](security/software-bill-of-materials.md) + +
-- __Security__ - Security considerations when designing and developing F´ applications. diff --git a/scripts/docs_nav_tree.py b/scripts/docs_nav_tree.py new file mode 100644 index 00000000000..9330200d0eb --- /dev/null +++ b/scripts/docs_nav_tree.py @@ -0,0 +1,198 @@ +import os +from pathlib import Path +import yaml +import re # for reg expression matching of nav: block in mkdocs.yml + +# Get the directory where this script is located +SCRIPT_DIR = Path(__file__).parent.parent + +MKDOCS_YML = SCRIPT_DIR / "docs/mkdocs.yml" +output_file = "mkdocs_nav.yml" +root = str(SCRIPT_DIR / "docs") +excluded_folders = { + "Home", + "docs-venv", + "doxygen", + "index", + "INSTALL", + "tutorials-hello-world", + "tutorials-led-blinker", + "tutorials-arduino-led-blinker", + "tutorials-math-component", +} + +tab_order = ["getting-started", "tutorials", "user-manual", "how-to", "reference"] + + +def build_nav_tree(path): + nav = [] + entries = sorted( + os.listdir(path), + key=lambda x: tab_order.index(x) if x in tab_order else len(tab_order), + ) + + # Detect folder index.md first + index_md_path = os.path.join(path, "index.md") + folder_index_title = None + if os.path.isfile(index_md_path): + folder_index_title = read_h1(Path(index_md_path)) + + for entry in entries: + if ( + entry == "fprime" + ): # Entire fprime repo is copied, but only want to nav fprime/docs + entry = "fprime/docs" + full_path = os.path.join(path, entry) + + # Include only markdown files (but skip index.md here; we add it separately as the folder root link) + if ( + os.path.isfile(full_path) + and entry.endswith(".md") + and not entry.endswith("index.md") + ): + # Check if the file stem (filename without .md) is excluded + file_stem = Path(entry).stem + if file_stem in excluded_folders: + continue + title = read_h1(Path(full_path)) + title = reformat_entry(title) + if title in excluded_folders: + continue + nav.append({title: os.path.relpath(full_path, root)}) + + # Process folders only if they contain .md files inside + elif os.path.isdir(full_path): + if entry in excluded_folders: + continue + + if ( + entry.lower() == "tutorials" + ): # manually defines tutorial tree since its links are external + nav.append(build_tutorials()) + continue + + children = build_nav_tree(full_path) + + if children: + # If folder has index.md, use that as title + index_file = os.path.join(full_path, "index.md") + if os.path.isfile(index_file): + folder_title = read_h1(Path(index_file)) + folder_title = reformat_entry(folder_title) + if folder_title in excluded_folders: + continue + nav.append({folder_title: children}) + else: + entry = reformat_entry(entry) + if entry in excluded_folders: + continue + nav.append({entry: children}) + + # If this folder has index.md at the root level, prefix it to the folder’s nav list so it becomes the “folder level” link + if folder_index_title: + formatted_title = reformat_entry(folder_index_title) + if formatted_title not in excluded_folders: + nav.insert(0, {formatted_title: os.path.relpath(index_md_path, root)}) + + return nav + + +# If entry title starts with a lowercase letter, make uppercase and replace '-' with spaces +def reformat_entry(entry): + if entry.startswith("How-To: "): + return entry.replace("How-To: ", "") + if entry.startswith("Getting Started with F Prime"): + return entry.replace("Getting Started with F Prime", "Getting Started") + elif entry.islower(): + entry = entry.replace("-", " ") + entry = entry.title() + entry = entry.replace("Gds", "GDS") + return entry + else: + return entry + + +def read_h1(md_file: Path) -> str: + """Return the first '# Heading' (or Title) line from a markdown file, or the + filename stem if no H1 is present. This mirrors awesome-nav's + behavior of titling pages by their first heading.""" + if not md_file.exists(): + return md_file.stem + for line in md_file.read_text().splitlines(): + if line.startswith("# "): + return line[2:].strip() + elif line.startswith("Title: ") or line.startswith("title: "): + return line[7:].strip() + return md_file.stem + + +def write_mkdocs_nav(root_path, output_file="mkdocs_nav.yml"): + print("Found root directory", root_path) + nav_tree = build_nav_tree(root_path) + yaml_output = yaml.dump( + nav_tree, sort_keys=False, default_flow_style=False, allow_unicode=True + ) + + with open(output_file, "w") as f: + f.write(yaml_output) + + print(f"Wrote YAML navigation to {output_file}") + + return yaml_output + + +def write_nav_into_mkdocs(nav: list) -> None: + """Replace the body of the existing `nav:` block in mkdocs.yml. + Everything else in the file is untouched.""" + text = MKDOCS_YML.read_text() + lines = text.splitlines(keepends=True) + + # Find the line that starts the top-level `nav:` block. + start = next((i for i, ln in enumerate(lines) if re.match(r"^nav:\s*$", ln)), None) + if start is None: + raise SystemExit(f"No top-level `nav:` block found in {MKDOCS_YML}.") + + # Find where it ends — the next non-blank line at column 0 + # (i.e., the next top-level key like `theme:` or `plugins:`). + end = len(lines) + for i in range(start + 1, len(lines)): + if lines[i].strip() and not lines[i].startswith((" ", "\t")): + end = i + break + + body = Path("mkdocs_nav.yml").read_text() + + # Indent everything by two spaces + body = "".join(" " + ln for ln in body.splitlines(keepends=True)) + + # Prepend the Home link to the nav body + nav_body = " - Home: https://fprime.jpl.nasa.gov/\n" + body + + MKDOCS_YML.write_text("".join(lines[: start + 1]) + nav_body + "".join(lines[end:])) + print(f"Wrote YAML navigation to mkdocs.yml nav: block") + + +def build_tutorials(): + return { + "Tutorials": [ + {"Tutorials Index": "docs/tutorials/index.md"}, + { + "Hello World": "../../tutorials/tutorials-hello-world/docs/hello-world.md" + }, + { + "LED Blinker": "../../tutorials/tutorials-led-blinker/docs/led-blinker.md" + }, + { + "MathComponent": "../../tutorials/tutorials-math-component/docs/math-component.md" + }, + {"Cross-Compilation Setup": "docs/tutorials/cross-compilation.md"}, + { + "Arduino LED Blinker": "../..//tutorials-arduino-led-blinker/docs/arduino-led-blinker.md" + }, + ] + } + + +if __name__ == "__main__": # cleaner way to write this, just testing for now + nav_block = write_mkdocs_nav(root, output_file) + write_nav_into_mkdocs(nav_block) diff --git a/scripts/gen_indexes.py b/scripts/gen_indexes.py new file mode 100644 index 00000000000..93321e25f48 --- /dev/null +++ b/scripts/gen_indexes.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python3 +""" +Generates docs/
/index.md from the filesystem structure. +""" + +# Run before docs_nav_tree.py so index.md are properly included in the nav tree + +from pathlib import Path + +# Get the directory where this script is located +SCRIPT_DIR = Path(__file__).parent.parent + +# Source of truth: filesystem walk of docs/
/ +SOURCE_DIRS = [ + SCRIPT_DIR / "docs" / "user-manual", + SCRIPT_DIR / "docs" / "how-to", + SCRIPT_DIR / "docs" / "reference", +] + +# Section blurbs shown next to each top-level entry. Keys are section directory names. +SECTION_DESCRIPTIONS = { # note: these are not automated, new sections will be populated without descriptions unless defined below + "user-manual": { + "overview": "Technical overview of the F´ ecosystem.", + "framework": "Learn concepts and mechanisms needed to build and use an F´ application.", + "fpp": "In-depth user guide for F Prime Prime (FPP), the F´ modeling language.", + "gds": "Learn how to use the F Prime Ground Data System, and how it can be used to test F´ applications.", + "design-patterns": "Learn about common design patterns used in F´ applications.", + "build-system": "Learn about the F´ build system and how to customize it.", + "security": "Security considerations when designing and developing F´ applications.", + }, + "how-to": { + "develop": "Learn how to develop components, libraries, and other F´ artifacts.", + "integrate": "Learn how to integrate F´ with external libraries and platforms.", + "operate": "Learn how to operate F´ applications and the Ground Data System.", + "test": "Learn how to test F´ components and applications.", + }, + "reference": { + "software-design-documents": "Software Design Documents (SDD) capture the design of the F´ core components.", + "fpp-language-specification": "This document describes F Prime Prime, also known as FPP or F Double Prime." + }, +} + +# Section metadata: title and description for each main section +SECTION_METADATA = { + "user-manual": { + "title": "User Manual", + "description": "The User Manual provides comprehensive documentation for understanding and using F Prime.", + }, + "how-to": { + "title": "How-To", + "description": "How-To guides offer step-by-step instructions for specific development tasks in F Prime.", + }, + "reference": { + "title": "Reference", + "description": "Reference documentation for F Prime APIs and components.", + }, +} + + +def read_h1(md_file: Path) -> str | None: + """Return the first H1 (header) line in a markdown file, skipping YAML frontmatter.""" + text = md_file.read_text(encoding="utf-8") + if text.startswith("---\n"): + end = text.find("\n---\n", 4) + if end != -1: + text = text[end + 5 :] + for line in text.splitlines(): + stripped = line.strip() + if stripped.startswith("# "): + return stripped[2:].strip() + return None + + +def list_pages(section_dir: Path): + """Yield (title, url) for each page in a section. Url is relative to the parent directory.""" + for entry in sorted(section_dir.iterdir()): + if entry.name.startswith((".", "_")) or entry.name == "index.md": + continue + if entry.is_dir(): + sub_index = entry / "index.md" + if sub_index.exists(): + title = read_h1(sub_index) + title = reformat_entry(title) + yield title, f"{section_dir.name}/{entry.name}/index.md" + # else: probably an asset dir (img/, _includes/, etc.) — skip + elif entry.suffix == ".md": + title = read_h1(entry) + title = reformat_entry(title) + yield title, f"{section_dir.name}/{entry.name}" + + +def get_section_title(section_dir: Path) -> str: + """Get the title for a section from its index.md file, or fallback to directory name.""" + index_file = section_dir / "index.md" + if index_file.exists(): + title = read_h1(index_file) + title = reformat_entry(title) + if title: + return title + # Fallback: capitalize directory name + return reformat_entry(section_dir.name) + + +def get_sections(source_dir: Path): + """Yield (section_path, title, is_file) for each section in the given directory.""" + section_name = source_dir.name + desired_order = list(SECTION_DESCRIPTIONS.get(section_name, {}).keys()) + + def sort_key(entry): + if entry.name in desired_order: + return (0, desired_order.index(entry.name)) + else: + return (1, entry.name) # unlisted items go last, alphabetically + + for entry in sorted(source_dir.iterdir(), key=sort_key): + if ( + entry.name.startswith((".", "_")) + or entry.name == "index.md" + or entry.suffix == ".py" + ): + continue + if entry.is_dir(): + yield entry, get_section_title(entry), False + elif entry.suffix == ".md": + title = read_h1(entry) + if title: + yield entry, reformat_entry(title), True + + +# If entry title starts with a lowercase letter, make uppercase and replace '-' with spaces +def reformat_entry(entry): + if entry.startswith("How-To: "): + return entry.replace("How-To: ", "") + elif entry.islower(): + entry = entry.replace("-", " ") + entry = entry.title() + entry = entry.replace("Gds", "GDS") + entry = entry.replace("Api", "API") + return entry + else: + return entry + + +def generate_index_for_section(source_dir: Path): + """Generate the index page for a given documentation section.""" + section_name = source_dir.name + metadata = SECTION_METADATA.get(section_name, {}) + section_title = metadata.get("title", section_name.replace("-", " ").title()) + section_description = metadata.get("description", "") + + # Get section-specific descriptions + subsection_descriptions = SECTION_DESCRIPTIONS.get(section_name, {}) + + # Generate the markdown content + content = [] + content.append("---\nhide:\n - toc\n---\n\n") + content.append(f"# {section_title}\n\n") + + if section_description: + content.append(f"{section_description}\n\n") + + content.append( + "> [!TIP]\n" + "> **← Navigation pane** \n" + "> Use the navigation pane on the left to explore the different chapters of the " + f"{section_title} documentation. " + "If the navigation pane is not visible, click on the menu icon (three horizontal lines) at the top left corner of the page. " + "The navigation pane is hidden on narrow screens or if zoomed in.\n\n" + ) + content.append("## Table of Contents\n\n") + + for section_path, title, is_file in get_sections(source_dir): + description = subsection_descriptions.get(section_path.name, "") + suffix = f" — {description}" if description else "" + + if is_file: + # Standalone markdown file — simple bullet point link + file_url = section_path.name + content.append(f"- [**{title}**]({file_url}){suffix}\n\n") + else: + # Directory section — collect all pages + pages = list(list_pages(section_path)) + + if pages: + # Directory with children — collapsible
box + content.append('
\n') + content.append( + f"{title}{suffix}\n\n" + ) + for page_title, page_url in pages: + content.append(f"- [{page_title}]({page_url})\n") + content.append("\n
\n\n") + else: + # Empty directory or only has index.md — simple bullet point link + index_url = f"{section_path.name}/index.md" + content.append(f"- [**{title}**]({index_url}){suffix}\n\n") + + # Write to output file + output_file = source_dir / "index.md" + output_file.write_text("".join(content), encoding="utf-8") + print(f"Generated {output_file.relative_to(SCRIPT_DIR)}") + + +def main(): + """Generate index pages for all documentation sections.""" + for source_dir in SOURCE_DIRS: + if source_dir.exists(): + generate_index_for_section(source_dir) + else: + print(f"Warning: {source_dir} does not exist, skipping...") + + +if __name__ == "__main__": + main()