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

Posted

技术标签:

【中文标题】ARM (Cortex M3) 的应用内编程如何工作?【英文标题】:How does the in-application programming for ARM (Cortex M3) work? 【发布时间】:2011-12-21 03:11:53 【问题描述】:

我正在开发基于 Cortex-M3 的定制设备,我需要实现应用内编程 (IAP) 机制,以便可以在没有 JTAG 的情况下更新设备固件(我们将使用 TFTP 或 HTTP反而)。虽然 ST Microelectronics 提供的与 IAP 相关的代码示例对我来说已经足够清楚,但我并不真正了解重新刷新的工作原理。

据我了解,指令是由 CPU 通过 ICode 总线(当然还有预取块)从闪存中获取的。所以,这是我的一个非常愚蠢的问题:为什么正在运行的程序在重新刷新自身(即更改运行它的闪存)时不会损坏?

【问题讨论】:

【参考方案1】:

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

当然,刷固件时这个小区域是不会被覆盖的,只能通过其他方式(比如JTAG)来完成。因此,请确保此闪烁程序一开始就可以正常工作。 :)

【讨论】:

啊哈...没错,我在研究代码时错过了那部分! 是的,但是在许多设备上,还需要在对闪存进行编程时实际从 ram 运行,因此必须将一小段编程代码复制到 RAM 并调用以进行实际编程,即使如果整个过程由闪存保留部分中的代码管理。 您需要考虑许多故障情况,否则,您最终可能会阻塞系统。 IAP 是固件开发的基石,特别是在有损网络上正确执行此操作可能会很棘手。【参考方案2】:

我不熟悉 STM 的实现,但在 NXP 芯片中,IAP 例程存储在单独的保留 ROM 区域中,用户代码无法擦除该区域。

如果您通过直接使用硬件寄存器自己实现闪存写入代码,您需要确保它不会触及它正在运行的扇区或从 RAM 运行。

【讨论】:

【参考方案3】:

现在很多微控制器都支持 IAP,可以在同一闪存中执行程序的同时对其闪存进行编程。

对于 IAP,flash 中的程序存储器可以分为两部分,一个可执行部分和其他备份部分。

通常我们通过固件版本为 0.01 的 JTAG 在某个位置(例如第 1 部分)对闪存进行编程。对于IAP,即在代码执行时对另一部分(part-2)的flash进行编程,固件版本0.01应提供相应的API,这有助于对flash part-2进行编程,编程成功后固件版本将是更新为 0.02。处理器重启后,程序执行通过在初始化时检查固件版本跳转到最新固件。

固件正在执行的部分称为可执行部分,其他部分称为备份。为什么叫备份是指,假设烧写过程中固件损坏,固件版本不会更新,重启后,程序控制检查版本号后会自动跳回备份固件。

【讨论】:

【参考方案4】:

另一个好方法是使用定制的引导加载程序。但是 STM IAP 不存储在 Flash 中,所以它不能被它自己覆盖。通常人们所做的是将flash分成两部分溢出,一个是为定制的Bootloader保留的,另一个是用于应用程序的。引导加载程序确保它不会写入自己分配的区域。引导加载程序可以通过 JTAG 进行编程,以后的应用程序可以利用引导加载程序自行编程。

【讨论】:

【参考方案5】:

据我了解,指令是由 CPU 通过 ICode 总线(当然还有预取块)从闪存中获取的。所以,这是我的一个非常愚蠢的问题:为什么正在运行的程序在重新刷新自身(即更改运行它的闪存)时不会损坏?

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

查看this,了解有关实施 IAP 的一些想法。

【讨论】:

以上是关于ARM (Cortex M3) 的应用内编程如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

如何展开ARM Cortex M3堆栈

ARM Cortex M4(或M3)上的周期计数器?

(ARM-Cortex M3)Boot以及App下载方法

优化 ARM Cortex M3 代码

单片机行业经常提到的M0 M1 M2 M3 M4 M7指的是啥

ARM基础教程 | 深入 Cortex‐M3 的 Faults异常