1.STM32的启动过程模式
1.1 根据boot引脚决定三种启动模式
-
复位后,在 SYSCLK 的第四个上升沿锁存 BOOT 引脚的值。BOOT0 为专用引脚,而 BOOT1 则与 GPIO 引脚共用。一旦完成对 BOOT1 的采样,相应 GPIO 引脚即进入空闲状态,可用于其它用途。BOOT0与BOOT1引脚的不同值指向了三种启动方式:
- 从主Flash启动。主Flash指的是STM32的内置Flash。选择该启动模式后,内置Flash的起始地址将被重映射到0x00000000地址,代码将在该处开始执行。一般我们使用JTAG或者SWD模式下载调试程序时,就是下载到这里面,重启后也直接从这启动。
- 从系统存储器启动。系统储存器指的是STM32的内置ROM,选择该启动模式后,内置ROM的起始地址0x1FFF0000,将被重映射到0x00000000地址,代码在此处开始运行。ROM中有一段出厂预置的代码,这段代码起到一个桥的作用,允许外部通过UART/CAN或USB等将代码写入STM32的内置Flash中。这段代码也被称为ISP(In System Programing)代码,这种烧录代码的方式也被称为ISP烧录。关于ISP、ICP和IAP之间的区别将在后续章节中介绍。
- 从嵌入式SRAM中启动,选择该启动模式后,内置SRAM的起始地址0x20000000将被重映射到0x00000000地址,代码在此处开始运行。这种模式由于烧录程序过程中不需要擦写Flash,因此速度较快,适合调试,但是掉电丢失。
-
总结:不同的配置决定了,MCU将何处映射到0x00000000。从这里又可以看到一点,MCU眼里只有0x00000000。至于为啥可以从Flash(0x08000000)启动,就是因为MCU内部做了映射。从其他位置启动时同理,如第一列,从Flash启动时,原本储存在0x0800000的程序映射到0x000000位置,,如下图是STM32F4xx中文参考手册中的图,可以看到类似的表述。同时,在下图中也展示了STM32F4xx中统一编址下,各内存的地址分配,注意一点,即使相应的内存被映射到了0x00000000起始的地址,通过其原来地址依然是可以访问的。
1.2 内存空间解释
- 上电序列或系统复位后,ARM处理器先从0x0000 0000地址获取栈顶值,再从0x0000 0004地址获得引导代码的基地址,然后从引导代码的基地址开始执行程序。所选引导源对应的存储空间会被映射到引导存储空间,即从0x0000 0000开始的地址空间。
- 如果片上SRAM(开始于0x2000 0000的存储空间)被选为引导源,用户必须在应用程序初始化代码中通过修改NVIC异常向量表和偏移地址将向量表重置到SRAM中。
- 当主FLASH存储器被选择作为引导源,从0x0800 0000开始的存储空间会被映射到引导存储空间。由于主FLASH存储器的Bank0或Bank1均可映射到地址0x0800 0000(通过配置SYSCFG_CFG0寄存器的FMC_SWP控制位),所以,微控制器可以使用该方法从Bank0或Bank1中启动。
- 为了使能引导块功能,选项字节中的BB控制位需要被置位。当该控制位被置位并且主FLASH存储器被选择作为引导源,微控制器从引导装载程序中启动并且引导装载程序跳至主FLASH存储器的Bank1中执行代码。在应用程序初始化代码中,用户必须通过修改NVIC异常向量表和偏移地址将向量表重置到Bank1基地址。
1.3 启动后bootloader做了什么?
- 根据BOOT引脚确定了启动方式后,处理器进行的第二大步就是开始从0x00000000地址处开始执行代码,而该处存放的代码正是bootloader即.s启动文件,名为startup_xxxx.s,在.s启动文件中指明了向量表,默认在0x08000000处,栈顶是一个栈顶指针,之后就是Reset_handler复位中断入口向量地址等等中断服务函数向量地址,每个地址4字节,所以是从MSP偏移0x00004字节处取出Reset_Handler。
- bootloader,也可以叫启动文件,每一种微控制器(处理器)都必须有启动文件,启动文件的作用便是负责执行微