AGM*_*AGM 3 c embedded arm cortex-m
是否可以在ARM Cortex-M4架构(例如STM32 F4)上分离基本FW和应用程序代码.我想做的是从外部闪存运行应用程序和从内部闪存基础FW.应用程序都实现相同的"API"(单头文件),但功能不同.
想法是基础FW提供驱动程序,引擎和UI,并且可以作为独立工作.应用程序将在需要时为FW提供额外的功能.由于所有应用程序的总代码大小对于内部闪存而言太大,因此无法在内部闪存上刷新所有应用程序.另一个原因是我们想要在不重新刷新设备的情况下即时更新/添加应用程序.
所以,到目前为止我几乎没有想法如何做到这一点,但这些是否可行或有其他选择吗?
所有提示,提示和示例代码均受到赞赏!
编辑:谢谢你的答案,需要一些时间来消化这些.
此试验的主要原因是允许在不刷新基本FW的情况下更新设备功能,而不是保存SRAM /内部闪存.一种插件架构,提供简单的界面来扩展系统功能,而无需改变底层系统.如果我无法从外部闪存(SD卡,NAND)构建系统执行代码,我将尝试首先将应用程序加载到SRAM /内部闪存.但我也会深入挖掘emcraft解决方案.
没有必要坚持STM芯片,我恰好在我的桌子上有他们的devkits.最终目标是从SD卡或NAND内存加载应用程序,所以在这一点上我不想限制实现仅适用于NOR闪存.
我将通过使用STM32 F4 devkit开始使用最少的实现.首先,我需要在其上包装一些NAND/SD卡.我将尝试将应用程序加载到SRAM和内部闪存的两个选项,以查看它们的工作原理以及对性能的影响.正如Clifford所说,在链接,构建和工具集设置方面将面临更多挑战.即使是强硬的我也可以强迫应用程序在内存中始终保持相同的位置,功能将在不同的地方,需要弄清楚如何处理这个问题.示例/演示将有所帮助.
我最小化实现的规范.
Project 1: Base FW
Driver for accessing applications from external flash
Minimal filesystem to write and read applications to/from external flash
UART commands -- Write applications to external flash -- Load applications from external flash to SRAM/Internal flash -- Execute application and print result to UART
Interface.h
int functionWrapper(int functionNumber)
bool initApplication()
int executeMathOperation1(int a, int b)
int executeMathOperation2(int a, int b)
Project 2: Application 1
MathOp1: Sums up two values
MathOp2: Multiply up two values
Project 3: Application 2
MathOp1: Subtracts two values
MathOp2: Divide two values
Run Code Online (Sandbox Code Playgroud)
我没有想到最终的操作系统,但最有可能是Free/OpenRTOS
问题不在于处理器; 在不同的内存空间中执行代码是一个适当构建,链接和加载代码的问题,这在很大程度上是一个工具链问题,而不是芯片选择问题.
第一个问题是选择实际具有内存映射的外部存储器接口的设备.在这种情况下,例如,诸如NAND闪存的串行存储器设备或诸如SD卡的大容量存储设备是不合适的.它必须是系统地址/数据总线上的NOR闪存.
其次,在大多数情况下,外部存储器接口必须配置正确的存储器类型,总线宽度和时序等,以便可寻址.这意味着您无法直接启动外部存储器上的软件,因为必须运行软件才能执行配置.
第三,通常你的工具链会编译并将你的应用程序链接到一个单一的monotithic应用程序 - 将它分成BIOS/OS和应用程序并不简单,对于裸机目标(即没有运行完整的操作系统,如带有加载/执行的Linux)内置的动态链接等)没有标准的方法 - 你必须自己做饭.
对于启动引导加载程序,加载应用程序并运行它的情况,它可能很简单,因为一旦应用程序运行,引导加载程序就不再发挥作用 - 引导加载程序只需要知道应用程序的起始地址.但是在您的情况下,您需要单独编译和链接两个单独的软件实体,并让应用程序能够访问您的BIOS/OS代码,因此应用程序实体需要知道独立链接的BIOS/OS的例程入口点地址.一种方法是生成BIOS/OS的链接映射(特定于工具链),并从中生成一个入口点查找表(本质上是函数指针数组),您可以与每个应用程序链接,这样您的应用程序将具有回调BIOS/OS的方法.
但是您可能不需要这样做,您可以将应用程序链接到不相交的内存地址区域并单独编程内部和外部存储器设备(有时称为"分散加载").这样链接器负责解析内部和外部地址并且可以在任一方向调用.当然,您需要确保配置外部存储器的启动代码在内部存储器中,但是可以指示链接器将特定代码放在特定存储器中或让它决定何时不要紧.
重新刷新代码的需要本身并不需要您描述的架构,您可以简单地实现一个引导加载程序(占用内部闪存的保留页面),可以从某些来源加载数据,如SD卡,USB,串行或NAND闪存,并将其写入适当的内部或外部闪存页面; 如果加载的数据是例如英特尔格式的Hex文件,它将包含将告诉引导加载程序在何处写入数据的地址信息.在这种方法中,唯一的永久代码是引导加载程序(必须配置外部存储器),并且您的BIOS/OS和应用程序可以是单片的,并且可以跨内部和外部闪存"分散加载".
但需要注意的是,Cortex-M器件经过优化,可以通过不同的总线执行代码和加载数据.在STM32上,内部闪存和内部SRAM位于不同的总线上,允许并行进行指令和数据读取.当从外部存储器运行代码时,你必须意识到不仅总线可能更慢,外部存储器的指令和数据取出也将被序列化.因此,性能可能会受到重创.
cortex-m4 与你所说的无关,cortex-m4 与所有 arm 处理器内核一样只是一个处理器内核而已,arm 制造 IP 而不是芯片。您必须查看芯片供应商的实现,他们中的任何一个都提供在外部闪存接口上执行代码的能力。我认为不会,就像很难找到从外部 RAM 执行的微控制器,但它们比闪存更常见。几乎所有您都可以复制并运行或闪存并运行,在内部芯片资源上运行的代码将代码从外部资源复制到内部资源(ROM / RAM),然后在那里运行它,该代码可以再次复制并跳转或返回到主片上固件以复制并加载下一个覆盖层。
芯片供应商应该能够告诉您闪存的使用寿命、闪存磨损、设计用于定期/不断擦除和写入闪存的代码会在几天、几周或几个月内磨损该部件,具体取决于您惩罚的严重程度闪光。当断电时,将状态保存到舞会或闪烁,例如,车辆上的里程表读数,可以是一天一次或几次,也可能是每隔几年一次,但可以保存十分之一英里会在车辆使用寿命之前磨损该部件。
m4 很难称为具有所有功能(浮点、缓存、mmu 之类的东西等)的微控制器,并且与 cortex-m0 兄弟姐妹相比,它们往往拥有大量 RAM 和闪存。所以你最好的选择就是买一个有更多内存的,然后复制和跳跃。应该有很多部分适合您......