我目前正在从事一个涉及 Cortex-M 微控制器 (NXP RT1175) 固件开发的项目。我的开发堆栈包括 FreeRTOS、LittleFS 和 gcc-arm-none-eabi 工具链。我希望在此固件中实现“插件”功能,我的客户可以编写自己的算法并独立部署它们。
我面临的主要挑战是设计一个系统,其中这些插件可以动态加载(仅在启动时一次)并由固件执行。插件应该能够与固件提供的现有功能(API 和函数)进行交互。以下是一些具体内容:
我对此设置有一些疑问:
任何指导、建议或类似实现的参考都将不胜感激。
动态加载通常是操作系统的一项功能,而 FreeRTOS 本身并不支持该功能。
VxWorks 是一个可以动态加载和链接对象模块的 RTOS 示例。这些模块是通过“部分链接”生成的,其中生成的对象带有一些未解析的外部符号。在这种情况下,VxWorks 有一个动态加载器,它将加载对象中的外部链接解析为目标上的现有代码。 要实现该目标,需要提供完整的符号表。这不利于占用空间非常小的系统 - 特别是如果您支持链接 C++ 代码。 VxWorks 命令 shell 中使用相同的符号表来运行加载的或静态的代码。本质上,任何具有外部链接的函数都会成为入口点,因此例如在命令 shell 中键入
printf "hello"
完全符合您的预期。您只需要一个命名约定,例如
pluginMain()
。 VxWorks 有一种搜索符号表的方法,您可以使用模式匹配来查找插件。但是我不会推荐任何这些。将链接任意代码加载到核心二进制文件从根本上来说是不安全的。
更安全、更简单、更可靠的解决方案是嵌入脚本语言解释器,例如
Lua或 MicroPython。我曾经开发过一个产品,我们使用 Forth 启用了最终用户定制(尽管我不太愿意推荐它!)。然后,您可以仅公开您希望最终用户能够使用的接口,而不是在整个代码中有效地让他们自由支配。