提问人:mastupristi 提问时间:11/13/2023 更新时间:11/13/2023 访问量:28
使用 FreeRTOS、LittleFS 和 gcc-arm-none-eabi 在固件中实现插件功能
Implementing Plugin Functionality in Firmware using FreeRTOS, LittleFS, and gcc-arm-none-eabi
问:
我目前正在从事一个涉及Cortex-M微控制器(NXP RT1175)固件开发的项目。我的开发堆栈包括 FreeRTOS、LittleFS 和 gcc-arm-none-eabi 工具链。我希望在这个固件中实现一个“插件”功能,我的客户可以编写自己的算法并独立部署它们。
我面临的主要挑战是设计一个系统,在这个系统中,这些插件可以动态加载(在启动时仅加载一次)并由固件执行。插件应该能够与固件提供的现有功能(API 和函数)进行交互。以下是一些细节:
- 固件基础:固件当前未编译为位置无关代码 (PIC),我正在使用 FreeRTOS 和 LittleFS 等各种框架。
- 插件要求:这个想法是让客户端使用相同的工具链(gcc-arm-none-eabi)单独编译他们的插件。插件需要调用固件中定义的函数,这意味着它们需要知道这些函数的入口点。
- 当前方法:我正在考虑使用文件系统方法(通过 LittleFS),其中固件将在特定目录中查找插件文件并将它们加载到 RAM 中执行。插件可以编译为 PIC。
关于此设置,我有几个问题:
- 插件文件格式的最佳实践:考虑到当前的工具链和框架,这些插件的合适文件格式是什么?我正在考虑需要在不同的RAM地址加载的代码和数据存储器。
- 处理函数入口点:由于固件当前未编译为 PIC,并且函数地址可能会随着每次编译而更改,因此让插件了解这些函数入口点的最佳方法是什么?
- 安全稳定:在加载和执行第三方插件时,如何保证系统的安全性和稳定性?
任何指导、建议或对类似实现的引用将不胜感激。
答:
动态加载通常是操作系统的一项功能,而 FreeRTOS 本身不支持动态加载。
VxWorks 是 RTOS 的一个示例,它可以动态加载和链接对象模块。这些模块是通过部分链接生成的,其中对象是用一些未解析的外部符号生成的。在本例中,VxWorks 具有一个动态加载器,该加载器将加载对象中的外部链接解析为目标上的现有代码。
要实现此目的,目标需要存在完整的符号表。这不利于非常小的占用空间系统 - 特别是当您支持链接 C++ 代码时。在 VxWorks 命令行界面中使用相同的符号表来运行加载的代码或静态代码。从本质上讲,任何具有外部链接的函数都会成为入口点,因此,例如,在命令 shell 中键入的内容完全符合您的预期。您只需要一个命名约定,例如 .VxWorks 具有搜索符号表的方法,您可以使用模式匹配来查找插件。printf "hello"
pluginMain()
但是,我不推荐任何一个。从根本上说,将链接任意代码加载到核心二进制文件是不安全的。
一个更安全、更简单、更有保障的解决方案是嵌入脚本语言解释器,如 Lua 或 MicroPython。我曾经做过一个产品,我们使用 Forth 实现了最终用户定制(尽管我不愿意推荐!),或者你可以实现你自己的专有脚本语言(有趣,但不平凡)。然后,您可以只公开您希望最终用户能够使用的接口,而不能有效地在整个代码中赋予他们自由支配权。
评论