- 嵌入式
- 系统编程
【免费下载链接】fprime
F´ - A flight software and embedded systems framework
本文是一份面向 F´(F Prime)飞行软件与嵌入式系统框架的平台移植(Porting)实操指南。它围绕框架官方移植文档展开,讲解将 F´ 迁移到新硬件平台所需的四个核心开发部分——CMake 工具链与平台文件、Fw::Types数值类型与配置、硬件驱动、OSAL(操作系统抽象层)支持,并深入结合仓库源码(如 cmake/platform、cmake/toolchain、Fw/Types、Os)给出可复制、可运行的具体实现。读完本文,你将掌握为 F´ 编写平台文件、交叉编译工具链、PlatformTypes.hpp类型头文件以及为裸机(baremetal)系统提供 OSAL 实现的完整技术方案。
F´ 被设计为与硬件基本无关的框架:绝大多数飞行软件代码只依赖一套明确定义的接口与抽象,只有少量"平台相关"部分需要为新硬件单独开发。根据 docs/UsersGuide/dev/porting-guide.md,将 F´ 移植到新平台需要完成以下四个部分:
- CMake Toolchain 与 F´ platform 文件:指定编译器等构建工具的路径与编译选项,供 CMake 为给定平台编译 F´。
Fw::Types与配置:当硬件需要不同于默认设置时,可能需要提供Fw::Types头文件及相应配置。- 硬件驱动:超出框架自带 Linux Driver 包范围的驱动,需针对硬件特定接口自行开发。
- OSAL 支持:若平台需要非 Linux 操作系统,则需开发 OSAL 支持文件(详见 docs/UsersGuide/dev/os-docs.md)。
以上四个部分全部实现后,用户即可在新的系统或平台上运行 F´。下文将逐一展开,并给出仓库内可直接对照的源码证据。
一、CMake Toolchain 与 F´ platform 文件
F´ 的 CMake 构建系统将"工具链(toolchain)"与"平台(platform)"两个概念分开:
- Toolchain 文件(
cmake/toolchain/):指定目标系统名称、C/C++ 交叉编译器路径、查找根路径等,解决"用什么工具编译"的问题; - Platform 文件(
cmake/platform/):设置 F´ 特有的构建选项,如全局头文件包含目录、编译器宏定义(如TGT_OS_TYPE_*)、线程库等,解决"为这个 OS/平台编译成什么样"的问题。
1.1 平台文件的加载规则
根据 cmake/platform/platform.cmake.template,平台文件的加载遵循以下规则,用户很少需要直接指定:
- 若指定了 CMake Toolchain 文件,则平台文件为
${CMAKE_SYSTEM_NAME}.cmake。CMAKE_SYSTEM_NAME在工具链文件中设置,通常为Linux、Darwin这类通用名称,如需更细分也可取更具体的名字; - 否则CMake 将
CMAKE_SYSTEM_NAME自动设为宿主机系统名,并使用对应平台文件。例如在 Linux 上构建时使用Linux.cmake。
仓库中 cmake/platform/platform.cmake 的加载逻辑证实了这一点:它遍历FPRIME_PROJECT_ROOT、FPRIME_LIBRARY_LOCATIONS、FPRIME_FRAMEWORK_PATH三个搜索位置,依次查找${ROOT}/cmake/platform/${CMAKE_SYSTEM_NAME}.cmake,找到即include并停止;若最终仍未找到,则报错并提示创建${CMAKE_SYSTEM_NAME}.cmake:
foreach(ROOT ${FPRIME_PROJECT_ROOT};${FPRIME_LIBRARY_LOCATIONS};${FPRIME_FRAMEWORK_PATH} ) set(EXPECTED_PLATFORM_FILE "${ROOT}/cmake/platform/${CMAKE_SYSTEM_NAME}.cmake") if (EXISTS "${EXPECTED_PLATFORM_FILE}") message(STATUS "Including ${EXPECTED_PLATFORM_FILE}") include("${EXPECTED_PLATFORM_FILE}") break() endif() endforeach() if (NOT EXISTS "${EXPECTED_PLATFORM_FILE}") message(FATAL_ERROR "\n[F-PRIME] No platform config for '${CMAKE_SYSTEM_NAME}'. Please create: '${CMAKE_SYSTEM_NAME}.cmake'\n") endif()因此,新平台文件应放在项目(或库、框架)的cmake/platform/目录下,并以系统名称命名,例如MyOS.cmake。同时可看到输出目录也按工具链名组织(lib/${TOOLCHAIN_NAME}、bin/${TOOLCHAIN_NAME}),便于同一部署为多平台产出不同的构建产物。
1.2 编写 Platform 文件(platform.cmake.template)
cmake/platform/platform.cmake.template 是官方提供的平台文件模板,按照其中的步骤填写即可生成一个可用的平台文件。核心要点:
- STEP 1(必做):删除模板开头的
message(FATAL_ERROR ...)失效保护行——这是防止未填写的原始模板被当作有效平台文件加载的保险丝; - STEP 2:指定 OS 类型宏,例如
add_definitions(-DTGT_OS_TYPE_<PLATFORM-NAME>)(实际各平台文件使用LINUX、DARWIN、RTEMS等值); - STEP 3:设置 C/C++ 编译标志,注意不要清空已有标志,应追加:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} <ADD-C-FLAGS-HERE>") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} <ADD-CXX-FLAGS-HERE>") - STEP 4:声明是否需要线程包。使用
FPRIME_USE_BAREMETAL_SCHEDULER区分裸机调度(无线程)与线程化系统:if (NOT DEFINED FPRIME_USE_BAREMETAL_SCHEDULER) set(FPRIME_USE_BAREMETAL_SCHEDULER OFF) message(STATUS "Requiring thread library") FIND_PACKAGE ( Threads REQUIRED ) endif()若使用裸机调度器则不要设置该变量为 OFF,从而跳过
FIND_PACKAGE(Threads); - STEP 5:指定包含
PlatformTypes.hpp及系统头文件的目录。模板注释明确建议:通常Linux目录是不错的选择,因为它从<cstdint>获取标准类型:include_directories(SYSTEM "${FPRIME_FRAMEWORK_PATH}/Fw/Types/Linux")
模板还特别说明:如果目标系统与 Linux 相似,可包含已有的*-common.cmake(Linux 相关公共设置)以节省时间;编译器的路径等 CMake 工具链设置则应交给 toolchain 文件处理(见 cmake/toolchain/toolchain.cmake.template)。
1.3 仓库内现有平台文件对照
仓库 cmake/platform 目录下已有三个平台文件,可作为移植时的参照:
- cmake/platform/Linux.cmake:标准 Linux 目标。设置
FPRIME_USE_BAREMETAL_SCHEDULER OFF并要求Threads包;添加-DTGT_OS_TYPE_LINUX宏;设置FPRIME_USE_POSIX ON;把平台头文件目录cmake/platform/types加入系统包含路径。 - cmake/platform/Darwin.cmake:macOS 目标。设置
-DTGT_OS_TYPE_DARWIN、FPRIME_USE_POSIX ON;默认开启FPRIME_USE_STUBBED_DRIVERS(使用桩驱动);同样包含cmake/platform/types目录(Darwin 可兼容使用 Linux/Posix 类型的PlatformTypes.hpp)。 - cmake/platform/rtems5.cmake:RTEMS 5 实时操作系统目标,是"非 Linux POSIX 系统"移植的范例。它设置
-DTGT_OS_TYPE_RTEMS与FPRIME_USE_POSIX ON,加入 RTEMS 的头文件路径(${RTEMS_INCLUDE_DIRS}、${RTEMS_BSP_INCLUDE_DIRS}等)、编译选项与链接选项,并追加__rtems__、_POSIX_THREADS编译宏定义。
这三个文件共同展示了平台文件需要回答的问题:OS 类型宏、POSIX/裸机选择、线程需求、系统头文件路径、编译器/链接器附加选项。
1.4 编写 Toolchain 文件(toolchain.cmake.template)
当需要交叉编译(cross-compile)时,需要编写工具链文件。官方模板 cmake/toolchain/toolchain.cmake.template 的步骤与示例:
- STEP 1(必做):删除
message(FATAL_ERROR ...)失效保护行; - STEP 2:设置目标系统名:
set(CMAKE_SYSTEM_NAME "<NAME-OF-TARGET-SYSTEM>"); - STEP 3:指定 C/C++ 交叉编译器路径:
set(CMAKE_C_COMPILER "<PATH-TO-C-CROSS-COMPILER") set(CMAKE_CXX_COMPILER "<PATH-TO-CXX-CROSS-COMPILER>") - STEP 4:设置工具链包根路径,供查找库、可执行文件等使用:
set(CMAKE_FIND_ROOT_PATH "<PATH-TO-TOOLCHAIN-ROOT>") - 不要编辑以下查找模式设置(F´ 的交叉编译约定):
# F prime 从宿主机查找程序,而不是交叉编译工具链 set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # 交叉编译时从工具链中查找库、头文件与包 set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
模板中给出的 Raspberry Pi 示例片段是理解这一流程的最佳案例:
CMAKE_SYSTEM_NAME "RaspberryPI" # 指定交叉编译器 set(CMAKE_C_COMPILER "/opt/rpi/bin/arm-linux-gnueabihf-gcc") set(CMAKE_CXX_COMPILER "/opt/rpi/bin/arm-linux-gnueabihf-g++") # 目标环境在哪里 set(CMAKE_FIND_ROOT_PATH "/opt/rpi")仓库中提供了完整的 Raspberry Pi 工具链实现 cmake/toolchain/raspberrypi.cmake,它是真实可用的交叉编译配置:设置CMAKE_SYSTEM_NAME Linux、CMAKE_SYSTEM_PROCESSOR arm,通过find_program查找arm-linux-gnueabihf-gcc、arm-linux-gnueabihf-g++、arm-linux-gnueabihf-ar、arm-linux-gnueabihf-objcopy、arm-linux-gnueabihf-objdump等工具,并支持通过环境变量RPI_TOOLCHAIN_DIR或CMAKE_SYSROOT指定工具链位置。其注释说明宿主机上可通过sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf gdb-multiarch安装交叉编译器。
使用方法(在部署目录下,通过fprime-util或 CMake 传递):
# 通过 fprime-util 使用工具链(示例) fprime-util build --toolchain <路径>/cmake/toolchain/raspberrypi.cmake # 或直接传递给 CMake cmake -DCMAKE_TOOLCHAIN_FILE=<路径>/cmake/toolchain/raspberrypi.cmake ...二、Fw::Types与配置:为平台提供数值类型定义
F´ 的数值类型体系是"平台无关代码 + 平台相关定义"的关键分界。移植时,平台开发者需要提供PlatformTypes.hpp头文件,并视需要调整配置。
2.1PlatformTypes.hpp的职责
根据 cmake/platform/types/PlatformTypes.hpp(Linux/Darwin 系统使用的平台类型头文件)的文件头注释,PlatformTypes.hpp由平台开发者发布,用于定义 F´ 可用的标准算术类型。该 Linux/Darwin 版本面向运行在 x86/x86_64 上、使用系统自带 gcc/clang 的标准发行版。
其内容结构如下:
- Section 0:C 标准类型。F´ 依赖
intN_t/uintN_t及对应的 min/max 值。平台开发者必须要么定义这些类型,要么包含定义了这些类型的头文件。同时通过开关控制各类型宽度是否可用:#define FW_HAS_64_BIT 1 //!< 架构支持 64 位整数 #define FW_HAS_32_BIT 1 //!< 架构支持 32 位整数 #define FW_HAS_16_BIT 1 //!< 架构支持 16 位整数 #define FW_HAS_F64 1 //!< 架构支持 64 位浮点数F´ 消费这些信息并生成代码中常见的
UN、IN、FN系列类型。 - Section 1:逻辑类型(Logical Types)。F´ 要求平台实现者定义形如
Platform*的逻辑类型(完整清单见 docs/Design/numerical-types.md),例如:typedef int PlatformIntType; #define PRI_PlatformIntType "d" typedef unsigned int PlatformUIntType; #define PRI_PlatformUIntType "u" typedef PlatformIntType PlatformIndexType; #define PRI_PlatformIndexType PRI_PlatformIntType typedef PlatformUIntType PlatformSizeType;头文件还定义了这些类型的 min/max 常量(供
FpLimits继承使用),并以注释说明使用 C++ struct 静态常量的两个原因:静态上下文引用不占用存储(无需优化)、可被私有继承传递给派生类型。
2.2 逻辑类型与框架类型的分层
docs/Design/numerical-types.md 详细阐述了数值类型的设计哲学:
- 固定宽度类型(Fixed Width Types):
I8/I16/I32/I64、U8/U16/U32/U64、F32/F64,映射到 C 标准类型;编译器不支持的宽度可通过将 config/FpConfig.hpp 中的FW_HAS_*字段置0关闭(默认全部开启)。 - 平台配置的逻辑类型:
PlatformIndexType(端口索引)、PlatformSizeType(尺寸)、PlatformPointerCastType(以整数存储的指针)、PlatformAssertArgType(FW_ASSERT参数)、以及已废弃的PlatformIntType/PlatformUIntType。每个类型都必须提供PRI_*格式说明符,并在PlatformLimits结构体中定义<type>_MIN/<type>_MAX静态常量:typedef int32_t PlatformIndexType; #define PRI_PlatformIndexType PRId32 struct PlatformLimits { static const PlatformIndexType PlatformIndexType_MIN = 0; static const PlatformIndexType PlatformIndexType_MAX = INT32_MAX; }; - 可配置的框架类型(Configurable Integer Types):项目可通过自定义
FpConfig.hpp配置框架使用的类型。默认配置直接复用平台类型:typedef PlatformIndexType FwIndexType; #define PRI_FwIndexType PRI_PlatformIndexType typedef PlatformSizeType FwSizeType; #define PRI_FwSizeType PRI_PlatformSizeType typedef PlatformAssertArgType FwAssertArgType; #define PRI_FwAssertArgType PRI_PlatformAssertArgType上述即 config/FpConfig.hpp 中真实存在的定义。此外,GDS(地面数据系统)相关类型如
FwBuffSizeType、FwEnumStoreType、FwOpcodeType、FwChanIdType、FwEventIdType、FwPacketDescriptorType等在FpConfig.hpp中默认基于平台无关的固定宽度类型(U16/I32/U32 等)。
2.3 备用默认实现:DefaultTypes.hpp
若平台文件的头文件搜索路径未找到自定义PlatformTypes.hpp,仓库在 Fw/Types/default/DefaultTypes.hpp 提供了基于 x86_64 Linux 的回退默认实现。它使用#ifndef PLATFORM_*_TYPE_DEFINED守卫:只有当平台头文件未定义对应类型时才填充默认 typedef 与PRI_*宏。其中PlatformPointerCastType的默认实现通过__SIZEOF_POINTER__判断指针宽度(8/4/2 字节分别映射uint64_t/uint32_t/uint16_t,否则退化为uint8_t),若编译器不支持该宏则直接#error。移植时,平台开发者应自行定义并置位这些PLATFORM_*_TYPE_DEFINED守卫,或直接提供完整头文件覆盖默认值。
2.4 打印与约束
平台逻辑类型在printf家族中使用PRI_*宏格式化(依赖字符串常量拼接),例如:
PlatformIndexType index = 3; printf("Index %" PRI_PlatformIndexType " is bound by %" PRI_PlatformIndexType, index, FpLimits::PlatformIndexType_MIN);另一个关键约束是:为保证无警告编译,平台类型必须是 C 标准整数集合的元素(int8_t、int16_t、int32_t、int64_t或其无符号对应)。在int/unsigned int不属于该集合的编译器上,PlatformIntType与PlatformUIntType必须被设置为某个固定宽度类型。
类型定义链可继续追溯:Fw/Types/BasicTypes.hpp 以#include <PlatformTypes.hpp>开头,并在FW_HAS_*开关控制下定义I8/I16/I32/I64、U8/U16/U32/U64、F32/F64,以及NATIVE_INT_TYPE、NATIVE_UINT_TYPE、POINTER_CAST等别名——这正是PlatformTypes.hpp定义的逻辑类型进入框架代码的入口。
三、硬件驱动:为平台特定接口开发驱动
F´ 的驱动层位于 Drv 目录,包含BlockDriver、LinuxGpioDriver、LinuxI2cDriver、LinuxSpiDriver、LinuxUartDriver、TcpClient/TcpServer/Udp、Ip网络套接字等。移植指南明确指出:任何超出框架自带 Linux Driver 包范围的驱动,都需要针对新硬件开发。
编写硬件驱动时的要点(结合仓库现有驱动结构可以推断):
- 端口定义(.fpp / .fppi):驱动通过 FPP(F´ 原语描述语言)声明对外端口,例如 Drv/GpioDriverPorts/GpioDriverPorts.fpp、Drv/SpiDriverPorts/SpiDriverPorts.fpp 定义了驱动与组件之间的端口契约;
- 组件实现类:以 Drv/LinuxGpioDriver/LinuxGpioDriverComponentImpl.cpp 为代表的
*ComponentImpl类实现端口回调函数,具体操作底层硬件; - 桩驱动机制:CMake 选项
FPRIME_USE_STUBBED_DRIVERS(见 cmake/options.cmake)允许使用桩驱动替代完整实现,适用于尚无驱动或仅需验证编译的移植阶段。该选项默认值由平台文件设定(如 Darwin 平台默认 ON)。完整实现需要驱动与 OS 支持(OFF)。
对于 Linux 之外的平台,驱动层需要与 OSAL 结合:例如 Os/Linux、Os/Posix 提供系统调用封装,而裸机平台则需自行实现寄存器操作与中断处理。
四、OSAL 支持:为操作系统提供抽象实现
若新平台运行非 Linux 操作系统,必须开发 OSAL(操作系统抽象层)支持文件。详见 docs/UsersGuide/dev/os-docs.md。
4.1 OSAL 提供的服务
OSAL 通过薄封装(thin wrappers)抽象真实操作系统(RTEMS、VxWorks、Azure ThreadX、QNX、FreeRTOS、Zephyr 等实时系统,或 Linux、macOS 等非实时系统)的公共功能,共六大类服务:
- 带优先级的任务(多任务)管理;
- 同步(互斥);
- 文件管理;
- 消息队列;
- 通信;
- 超时(定时)。
OSAL 的存在使 F´ 组件可以在开发工作站上独立于具体 OS 开发与测试,显著降低系统间迁移成本。仓库中 OSAL 头文件集中在 Os 目录,已提供 Unix(POSIX)与 Mac OS 变体的实现;新操作系统通过补充新实现即可完成移植。
4.2 需要实现的关键类(按文档与源码)
OS 移植文档 docs/UsersGuide/dev/os-docs.md 逐一说明了各服务的接口:
- 任务(Tasks):接口在 Os/Task.hpp。
start()的参数包括任务名、用户选择的唯一整型标识符、优先级(0 最低,255 最高)、栈大小(字节)、任务例程函数、传入参数,以及 SMP 系统中的cpuAffinity(-1 表示不指定核)。其他方法包括delay()(毫秒级挂起)、suspend()/resume()/isSuspended()、getIdentifier()、getOsIdentifier()、getRawHandle()、registerTaskRegistry()等。Active(主动)组件依赖任务实现其特性。 - 任务注册表(Task Registry):用于跟踪系统中所有任务实例,可遍历并对其执行操作。基类提供
addTask()/removeTask()纯虚函数,开发者需派生自己的注册表实现。 - 互斥锁(Mutexes):接口在 Os/Mutex.hpp,提供
lock()/unlock()。 - 消息队列(Message Queues):接口在 Os/Queue.hpp。
create()参数为队列名、深度(超过即丢消息)、消息最大尺寸、是否阻塞标志;send()/receive()各有两个重载(SerializeBufferBase引用版本与字节指针版本),后者需要容量、实际大小与优先级参数;getNumQueues()返回系统中创建的队列数。 - 间隔定时器(Interval Timer):接口在 Os/IntervalTimer.hpp。不是到期定时器,而是测量时间间隔的工具:
start()/stop()记录起止时间,getDiffUsec()返回微秒差,getRawTime()用于事件时间戳。 - 看门狗定时器(Watchdog Timer):接口在 Os/WatchdogTimer.hpp。一次性定时器,到期回调;
startTicks()/startMs()指定延时与回调函数、参数,restart()用原值重启,cancel()取消。文档注明并非所有 OS 适配都要求实现。 - 中断锁(Interrupt Lock):接口在 Os/InterruptLock.hpp。
lock()/unlock()阻止中断抢占,可作为轻量互斥;锁定区间的代码应极短。getKey()返回中断锁键(通常不需要)。 - 文件(File):接口在 Os/File.hpp。抽象常见文件操作:
open()、isOpen()、seek()(absolute参数控制相对文件头还是当前位置)、read()(waitForFull控制是否等待读满,遇 EOF 提前返回)、write()、flush()、close()、getLastError()/getLastErrorString()(抽象errno/strerror())、calculateCRC32()。 - 文件系统(File System):接口在 Os/FileSystem.hpp,包含创建/删除目录等辅助调用;另有 Os/Directory.hpp 支持流式读取目录。
- 日志(Log):接口在 Os/Log.hpp,抽象系统日志设施,是
Fw::Logger的子类,构造后需注册;将 Os/LogDefault.cpp 编译进部署会自动创建并注册Os::Log。logMsg()接受格式串与最多 6 个POINTER_CAST参数。
4.3 仓库中的 OSAL 实现布局
仓库 Os 目录展示了多套实现,是移植时的直接参考:
- Os/Posix:POSIX 实现(
Task.cpp、Mutex.cpp、Queue.cpp、IPCQueue.cpp、IntervalTimer.cpp、LocklessQueue.cpp、TaskId.cpp); - Os/Linux:Linux 特有实现(
File.cpp、FileSystem.cpp、Directory.cpp、SystemResources.cpp、InterruptLock.cpp、WatchdogTimer.cpp); - Os/Baremetal:裸机实现(
Task.cpp、Mutex.cpp、Queue.cpp、SystemResources.cpp、File.cpp、FileSystem.cpp、IntervalTimer.cpp及TaskRunner/子目录)——这是无 OS 平台移植的核心参考; - Os/MacOs、Os/X86:平台微调实现;
- Os/Stubs:桩实现。
移植时,为每个头文件(Task、Mutex、Queue等)提供对应平台的.cpp实现,并在平台文件中加入编译即可。
五、裸机平台的移植:无 OS 场景的 F´
移植指南与 docs/UsersGuide/dev/baremetal-multicore.md 表明,F´ 同样支持裸机(无操作系统)平台,此时由 F´ 自身提供文件系统、线程调度等基础服务。裸机移植需要特别注意以下几点:
- 优先使用 Passive(被动)组件:裸机系统应尽量避免 Active 组件,因为其需要准异步执行上下文(线程)。若系统可完全由 Passive 组件构成,则每个端口调用都是同步的。
- 选择执行上下文:由于没有 OS 调度,实现者必须保证有某个调用驱动所有组件运行。典型做法是把系统组合成由速率组(rate group)驱动的结构,全部执行源于速率组驱动这一单一来源,从而把问题简化为"以设定速率向速率组驱动提供执行上下文"。主程序典型结构为:
setup(); while (true) { execute(); // 以固定间隔触发速率组驱动 }间隔判定可通过自旋等待硬件时钟信号、读取时钟寄存器、
sleep()或定时器中断(ISR)实现;文档特别提醒:ISR 不应直接执行速率组,而应置标志或排队启动消息,由主循环while(true)检测后启动速率组。 - 裸机调度器与线程虚拟化:仓库在 Os/Baremetal 下实现了顺序调度器——Os/Baremetal/TaskRunner/TaskRunner.hpp 是"任务注册表 + 任务运行器"的组合,
addTask()/removeTask()维护最多TASK_REGISTRY_CAP(100)个任务,run()在主循环中一次遍历运行所有任务。其原理是把每个 Active 组件线程的"阻塞等待消息"循环改造成非阻塞的run_once()切片(探测是否有消息、有则分发、随后返回),再在主循环中依次调用所有组件的run_once(),实现"虚拟化并行"(protothreading 技术)。FPRIME_USE_BAREMETAL_SCHEDULER(见 cmake/options.cmake)为 ON 时启用该替代实现,可限制为单线程执行或用于在 PC 上测试裸机调度器。使用线程虚拟化时,自定义任务函数必须:不循环、绝不阻塞、每次只执行"一片"后返回。
六、移植完成后的验证与运行
四个部分实现完成后,可通过以下路径验证移植成果:
- 平台文件加载验证:配置 CMake 时观察
platform.cmake输出的Target build toolchain/platform: <name>/<system>与Including ...消息,确认新平台文件被正确加载; - 数值类型验证:检查 Fw/Types 与 config/FpConfig.hpp 的编译是否通过、
PRI_*宏格式化输出是否符合预期; - 构建与单元测试:框架的
Fw/Types模块带单元测试(Fw/Types/test/ut/TypesTest.cpp),OSAL 各实现可结合 Os/test/ut 的测试用例验证任务、队列、互斥、定时器等行为; - 部署运行:参照仓库中的部署示例(如 Ref、RPI)构建目标部署,在目标硬件上启动并观察遥测、事件与命令流是否正常。
总结
F´ 的平台移植是一项有清晰边界的工作:CMake 工具链与平台文件负责构建系统适配,PlatformTypes.hpp与FpConfig.hpp负责数值类型适配,驱动层负责硬件接口适配,OSAL 负责操作系统服务适配。四者相互配合,使得"平台无关"的 F´ 核心代码可以在新硬件上运行。以 cmake/platform/platform.cmake.template、cmake/toolchain/toolchain.cmake.template、cmake/platform/types/PlatformTypes.hpp、Os/Baremetal 为起点,对照仓库内已有的 Linux、Darwin、RTEMS、Raspberry Pi 实现,开发者可以在最短时间内完成从"有 OS 的 POSIX 系统"到"裸机嵌入式系统"的完整移植。
- 嵌入式
- 系统编程
【免费下载链接】fprime
F´ - A flight software and embedded systems framework
相关推荐
F´ (F Prime) 飞行软件框架中的 Svc::ActiveRateGroup 速率组调度组件详解
F´ F Prime 飞行软件框架中的 Svc::ActiveRateGroup 速率组调度组件详解 Svc::ActiveRateGroup 是 F´ 飞行软
嵌入式系统编程F´ 新平台移植指南:Toolchain、平台文件、Fw::Types、硬件驱动与 OSAL 五步移植法
F´ 新平台移植指南:Toolchain、平台文件、Fw::Types、硬件驱动与 OSAL 五步移植法 F´(F Prime)是一个面向飞行软件与嵌入式系统的
嵌入式系统编程F´ (F Prime) 入门指南:组件驱动的飞行软件框架与首个应用搭建
F´ F Prime 入门指南:组件驱动的飞行软件框架与首个应用搭建 F´(F Prime)是一个组件驱动的软件框架,面向航天飞行软件及各类嵌入式应用的快速开发
嵌入式系统编程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考