ARM(Cortex M3)的应用程序编程是如何工作的?

16
我正在开发一个基于Cortex-M3的定制设备,需要实现应用程序内编程(IAP)机制,以便能够在没有JTAG的情况下更新设备固件(我们将使用TFTP或HTTP)。虽然ST Microelectronics提供的与IAP相关的代码示例对我来说已经足够清晰,但我并不真正理解重新刷写是如何工作的。
据我所了解,指令是通过ICode总线(当然还有预取块)从Flash中由CPU获取的。那么,这就是我的一个相当愚蠢的问题:为什么在重新刷写自身时(即更改正在运行的程序所在的Flash存储器),运行中的程序不会被破坏呢?
5个回答

10

常见的解决方案是在闪存中保留一个小的预留区域,用于存储实际的刷写程序。当下载新固件后,只需跳转到此区域中的代码。

当然,在刷写固件时,不会覆盖这个小区域,只能通过其他方式(如JTAG)来进行修改。因此,请确保此刷写程序一开始就能够正常工作。 :)


啊哈...没错,我在学习代码时漏掉了那部分! - Roman Dmitrienko
1
是的,然而在许多设备上,除了在编程闪存时实际运行时还需要从 RAM 运行,因此必须将一小段编程代码复制到 RAM 并调用以进行实际编程,即使整个过程由保留部分的闪存中的代码管理。 - Chris Stratton
有许多故障场景需要考虑,否则,您可能会使系统变得无法使用。IAP是固件开发的基石,特别是在不稳定的网络环境下正确地执行可能会很棘手。 - Amit

6
我不熟悉STM实现,但在NXP芯片中,IAP例程存储在一个单独的、保留的ROM区域中,用户代码无法擦除该区域。
如果你自己实现闪存编写代码,通过直接使用硬件寄存器,你需要确保它不会触及正在运行的扇区,或从RAM中运行。

1
现在许多微控制器支持IAP,这意味着可以在程序执行时编程其闪存。对于IAP,闪存中的程序存储器可能分为两个部分,一个是可执行部分,另一个是备份部分。通常我们通过JTAG在某个位置(例如part-1)编程闪存,其固件版本为0.01。对于IAP,即在代码执行时在另一部分(part-2)中编程闪存,在固件版本0.01中应提供相应的API,以帮助编程flash part-2。成功编程完成后,固件版本将更新为0.02。在处理器重新启动时,通过检查初始化时的固件版本,程序执行跳转到最新的固件。正在执行固件的部分称为可执行部分,而其他部分称为备份。为什么它被称为备份?因为假设在编程过程中存在任何固件损坏,固件版本将不会更新,并且在检查版本号后,程序控制将自动跳回备份固件。

0
据我所知,CPU通过ICode总线(当然还有预取块)从Flash中获取指令。因此,这是我的一个非常愚蠢的问题:为什么在重新刷新自身(即更改正在运行的程序所在的Flash存储器)时,运行中的程序不会被破坏?

这是因为,在一般情况下,当您从Flash内读取(即执行代码)时,不允许对其进行写入/编程。

请查看this以获取有关实现IAP的一些想法。


0
另一种好的方法是使用定制的引导加载程序。然而,STM IAP 不存储在 Flash 中,因此无法被自身覆盖。通常人们会将闪存分为两部分,一部分保留给定制的引导加载程序,另一部分用于应用程序。引导加载程序确保不会写入其自己分配的区域。引导加载程序可以通过 JTAG 编程,后来应用程序可以利用引导加载程序来对自身进行编程。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接