再上一篇:16.4 跟踪组件:嵌入式跟踪宏单元
上一篇:16.5 跟踪组件:跟踪端口接口单元(TPIU)
主页
下一篇:16.7 AHB 访问端口
再下一篇:16.8 ROM 表
文章列表

16.6 闪存地址重载及断点单元(FPB)

《Cortex-M3 权威指南》,嵌入式处理器开发教程。

FPB有两项功能:

 硬件断点支持。产生一个断点事件,从而使处理器进入调试模式(停机或调试监视器异常)
 把代码地址空间中对指令或字面值(literal data)的加载,重载到SRAM的地址空间中。

FPB有8个比较器,分别是:

 6个指令比较器
 2个字面值比较器

什么是“字面值加载”?

当我们使用汇编写程序时,常常需要往寄存器中加载立即数据。当立即数的值很大 时,加载操作就无法用单一指令完成,例如:

LDR R0, =0xE000E400

因为没有任何指令能接收32位立即数,我们需要把这个立即数预先安置到另一个存 储器空间中,通常放到程序代码区的后面,然后就可以使用一条相对PC的加载指令,来 读取这个立即数到对应的寄存器中。因此,上条代码的汇编结果可以如下所示:

LDR R0, [PC, #<immed_8>*4]

; immed_8 = (字面值地址 – PC)/4

...

; 文字池

...

DCD 0xE000E400

...

上面的LDR也可以是Thumb-2提供的32位版本:

LDR.W R0, [PC, #+/-<offset_12>]

; offset_12 = 字面值地址-PC

...

; 文字池

...

DCD 0xE000E400

...

在实际使用中我们经常需要在代码中使用多个字面值,汇编器或编译器就会在代码 区中开出一块地址范围,来集合字面值,这个块就是所谓的“文字池”。在CM3中,从文 字池的数据加载通常使用D-Code总线,但比较另类的实现也可以把文字池放到RAM区中, 从而使用系统总线加载。

在FPB中有一个闪存地址重载控制寄存器,它包含了FPB的使能位。此外,每个比较器在它自己
的控制寄存器中,都还有各自的使能位——前者是总开关。两种使能位必须都为1时才能启用比较 器。
可以通过编程比较器,把指令空间的地址重载(重映射)到SRAM地址空间中。当使用此功能时, 需要编程REMAP寄存器,以提供需要重映射内容的基址。REMAP寄存器的最高3位[31:29]被硬线连 接成0b001,因此限定了重映射后的地址范围在0x2000_0000-0x3FFF_FF80之间,这段地址正好落 在SRAM地址空间中。
当指令地址或字面值地址与比较器中的数值发生匹配命中时,读访问就会根据REMAP的设置被 重映射。
使用这个重映射功能,可以创建一些“如果...将会…”(what if)形式的测试——通过把原 始指令或字面值取代成另一个来实现。并且即使是在ROM或flash中运行的代码,也能够参与此种测 试。另一种用法在本质上与这种用法相同,但被取代的是跳转指令,因此行为很像“狸猫换太子”: 对于某个位于flash中的子程序,在SRAM中提供一个冒充它的。通过闪存地址重载,使得在执行到 调用该子程序的指令(BL)时,实际上执行的是被“调包”过的,位于SRAM中的BL,后者则跳转到
“狸猫”中。这种机制使得基于ROM的设备也可以调试(修改过的子程序暂时放到SRAM中)。 下图演示了重映射的效果

图16.3 闪存地址重载:对指令及字面值的重映射
除了地址重载,指令地址比较器的另一项功能,就是用于产生硬件断点(共6个),当地址匹配 时使处理器进入调试模式。