ARM Cortex-M3 从 RAM 初始状态启动
ARM Cortex-M3 boot from RAM initial state
我有两个 ARM Cortex-M3 芯片:STMF103C8T6 和 STM32F103VET6.
当设置为从RAM启动时,STMF103C8T6PC
寄存器的初始状态为0x20000108
; 0x200001e0
用于 STM32F103VET6。
我无法在数据表中找到有关这些地址的信息。为什么它们以这种方式启动,我在哪里可以找到相关信息?
编辑:
澄清一下。当芯片设置为从闪存启动时,PC
寄存器指向复位处理程序的位置。该地址在地址 0x0 处的复位向量 table 中提供。但是当芯片设置为从 RAM 启动时,PC
指向常量地址,如上所述。
编辑 2:
STMF103C8T6反汇编:
20000000 <Vectors>:
20000000: 20005000 andcs r5, r0, r0
20000004: 2000010f andcs r0, r0, pc, lsl #2
20000008: 2000010d andcs r0, r0, sp, lsl #2
2000000c: 2000010d andcs r0, r0, sp, lsl #2
20000010: 2000010d andcs r0, r0, sp, lsl #2
20000014: 2000010d andcs r0, r0, sp, lsl #2
20000018: 2000010d andcs r0, r0, sp, lsl #2
...
20000108: f000 b801 b.w 2000010e <Reset_Handler>
2000010c <HardFault_Handler>:
2000010c: e7fe b.n 2000010c <HardFault_Handler>
2000010e <Reset_Handler>:
...
STM32F103VET6反汇编:
20000000 <Vectors>:
20000000: 20005000 andcs r5, r0, r0
20000004: 200001e7 andcs r0, r0, r7, ror #3
20000008: 200001e5 andcs r0, r0, r5, ror #3
2000000c: 200001e5 andcs r0, r0, r5, ror #3
20000010: 200001e5 andcs r0, r0, r5, ror #3
20000014: 200001e5 andcs r0, r0, r5, ror #3
20000018: 200001e5 andcs r0, r0, r5, ror #3
...
200001e0: f000 b801 b.w 200001e6 <Reset_Handler>
200001e4 <HardFault_Handler>:
200001e4: e7fe b.n 200001e4 <HardFault_Handler>
200001e6 <Reset_Handler>:
...
I am unable to find and information about these addresses in the datasheets. Why are they booted this way and where I can find some information about it?
据我所知,ST 没有官方文档提及 这种行为,更不用说详细解释了。 The STM32F1 family reference manual 在第 3.4 节 ("Boot Configuration") 中含糊地说:
Due to its fixed memory map, the code area starts from address 0x0000 0000 (accessed through the ICode/DCode buses) while the data area (SRAM) starts from address 0x2000 0000 (accessed through the system bus). The Cortex®-M3 CPU always fetches the reset vector on the ICode bus, which implies to have the boot space available only in the code area (typically, Flash memory). STM32F10xxx microcontrollers implement a special mechanism to be able to boot also from SRAM and not only from main Flash memory and System memory.
唯一引用这些地址和值的地方是在它们的一些模板启动文件中——即便如此,也不是全部。为 ARM 和 IAR 工具链提供的 SPL 启动文件不支持 BootRAM;此功能仅包含在 GCC 和 TrueSTUDIO 工具链的启动文件中。
总之。这是我对情况的最佳分析。
当 STM32F1 部件复位时,从 0x00000000 开始的内存块根据 BOOT 引脚的配置进行映射。当设置为从闪存启动时,该块被别名为闪存;当它从引导加载程序设置为 运行 时,该块被别名为内部 ROM 块(大约或略低于 0x1FFFF000)。但是,当它设置为从 RAM 启动时,会发生一些非常奇怪的事情。
不像您期望的那样将该内存块别名为 SRAM,而是将该内存块别名为一个微型(16 字节!)ROM。在 STM32F103C8(中密度)部件上,此 ROM 的内容为:
20005000 20000109 20000004 20000004
此数据被解释为向量 table:
第一个字导致堆栈指针初始化为 0x20005000,位于 RAM 的顶部。
第二个字是复位向量,设置为0x20000108(低位设置为启用Thumb模式)。该地址也在 RAM 中,位于向量 table 末尾的几个字之外,您应该在此处放置 "magic" 值 0xF108F85F。这实际上是指令 ldr.w pc, [pc, #-480]
,它从 RAM 中加载真正的复位向量并跳转到它。
第三个和第四个字是NMI和硬故障向量。它们没有设置低位,因此如果在 VTOR 仍为零时发生这些异常中的任何一个,处理器将出现双重故障。令人困惑的是,PC 将指向 RAM 中的向量 table。
此 ROM 的确切内容因部分而略有不同。例如,F107(连接线)具有 ROM 内容:
20005000 200001e1 20000004 20000004
初始SP相同,初始PC不同。这是因为这部分有一个更大的向量table,而中密度地址会在它的向量table内。
使用的位置和值的完整列表是:
- Low/medium密度:0x0108(值:0xF108F85F)
- Low/medium密度值线:0x01CC(值:0xF1CCF85F)
注意: ST 的示例文件给出与 low/medium 密度部件相同的值。我很确定这是错误的,并已在此处更正,但我没有这种类型的任何部件可以测试。我很感激反馈以确认这是否有效。
- 所有其他:0x01E0(值:0xF1E0F85F)
谢天谢地,这种行为似乎在很大程度上是 F103/5/7 家族所独有的。较新的部分使用不同的方法来控制启动,这些方法更加一致。
我有两个 ARM Cortex-M3 芯片:STMF103C8T6 和 STM32F103VET6.
当设置为从RAM启动时,STMF103C8T6PC
寄存器的初始状态为0x20000108
; 0x200001e0
用于 STM32F103VET6。
我无法在数据表中找到有关这些地址的信息。为什么它们以这种方式启动,我在哪里可以找到相关信息?
编辑:
澄清一下。当芯片设置为从闪存启动时,PC
寄存器指向复位处理程序的位置。该地址在地址 0x0 处的复位向量 table 中提供。但是当芯片设置为从 RAM 启动时,PC
指向常量地址,如上所述。
编辑 2:
STMF103C8T6反汇编:
20000000 <Vectors>:
20000000: 20005000 andcs r5, r0, r0
20000004: 2000010f andcs r0, r0, pc, lsl #2
20000008: 2000010d andcs r0, r0, sp, lsl #2
2000000c: 2000010d andcs r0, r0, sp, lsl #2
20000010: 2000010d andcs r0, r0, sp, lsl #2
20000014: 2000010d andcs r0, r0, sp, lsl #2
20000018: 2000010d andcs r0, r0, sp, lsl #2
...
20000108: f000 b801 b.w 2000010e <Reset_Handler>
2000010c <HardFault_Handler>:
2000010c: e7fe b.n 2000010c <HardFault_Handler>
2000010e <Reset_Handler>:
...
STM32F103VET6反汇编:
20000000 <Vectors>:
20000000: 20005000 andcs r5, r0, r0
20000004: 200001e7 andcs r0, r0, r7, ror #3
20000008: 200001e5 andcs r0, r0, r5, ror #3
2000000c: 200001e5 andcs r0, r0, r5, ror #3
20000010: 200001e5 andcs r0, r0, r5, ror #3
20000014: 200001e5 andcs r0, r0, r5, ror #3
20000018: 200001e5 andcs r0, r0, r5, ror #3
...
200001e0: f000 b801 b.w 200001e6 <Reset_Handler>
200001e4 <HardFault_Handler>:
200001e4: e7fe b.n 200001e4 <HardFault_Handler>
200001e6 <Reset_Handler>:
...
I am unable to find and information about these addresses in the datasheets. Why are they booted this way and where I can find some information about it?
据我所知,ST 没有官方文档提及 这种行为,更不用说详细解释了。 The STM32F1 family reference manual 在第 3.4 节 ("Boot Configuration") 中含糊地说:
Due to its fixed memory map, the code area starts from address 0x0000 0000 (accessed through the ICode/DCode buses) while the data area (SRAM) starts from address 0x2000 0000 (accessed through the system bus). The Cortex®-M3 CPU always fetches the reset vector on the ICode bus, which implies to have the boot space available only in the code area (typically, Flash memory). STM32F10xxx microcontrollers implement a special mechanism to be able to boot also from SRAM and not only from main Flash memory and System memory.
唯一引用这些地址和值的地方是在它们的一些模板启动文件中——即便如此,也不是全部。为 ARM 和 IAR 工具链提供的 SPL 启动文件不支持 BootRAM;此功能仅包含在 GCC 和 TrueSTUDIO 工具链的启动文件中。
总之。这是我对情况的最佳分析。
当 STM32F1 部件复位时,从 0x00000000 开始的内存块根据 BOOT 引脚的配置进行映射。当设置为从闪存启动时,该块被别名为闪存;当它从引导加载程序设置为 运行 时,该块被别名为内部 ROM 块(大约或略低于 0x1FFFF000)。但是,当它设置为从 RAM 启动时,会发生一些非常奇怪的事情。
不像您期望的那样将该内存块别名为 SRAM,而是将该内存块别名为一个微型(16 字节!)ROM。在 STM32F103C8(中密度)部件上,此 ROM 的内容为:
20005000 20000109 20000004 20000004
此数据被解释为向量 table:
第一个字导致堆栈指针初始化为 0x20005000,位于 RAM 的顶部。
第二个字是复位向量,设置为0x20000108(低位设置为启用Thumb模式)。该地址也在 RAM 中,位于向量 table 末尾的几个字之外,您应该在此处放置 "magic" 值 0xF108F85F。这实际上是指令
ldr.w pc, [pc, #-480]
,它从 RAM 中加载真正的复位向量并跳转到它。第三个和第四个字是NMI和硬故障向量。它们没有设置低位,因此如果在 VTOR 仍为零时发生这些异常中的任何一个,处理器将出现双重故障。令人困惑的是,PC 将指向 RAM 中的向量 table。
此 ROM 的确切内容因部分而略有不同。例如,F107(连接线)具有 ROM 内容:
20005000 200001e1 20000004 20000004
初始SP相同,初始PC不同。这是因为这部分有一个更大的向量table,而中密度地址会在它的向量table内。
使用的位置和值的完整列表是:
- Low/medium密度:0x0108(值:0xF108F85F)
- Low/medium密度值线:0x01CC(值:0xF1CCF85F)
注意: ST 的示例文件给出与 low/medium 密度部件相同的值。我很确定这是错误的,并已在此处更正,但我没有这种类型的任何部件可以测试。我很感激反馈以确认这是否有效。 - 所有其他:0x01E0(值:0xF1E0F85F)
谢天谢地,这种行为似乎在很大程度上是 F103/5/7 家族所独有的。较新的部分使用不同的方法来控制启动,这些方法更加一致。