stm32三种boot模式的差异
boot(启动)模式
STM32三种启动模式对应的存储介质均是芯片内置的,它们是:
- 用户闪存:芯片内置的Flash。
- SRAM:芯片内置的RAM 区,就是内存啦。
- 系统存储器:芯片内部一块特定的区域,芯片出厂时在这个区域预置了一段Bootloader,就是通常说的ISP程序。这个区域的内容在芯片出厂后没有人能够修改或擦除,即它是一个ROM 区。
在每个STM32的芯片上都有两个管脚BOOT0和BOOT1,这两个管脚在芯片复位时的电平状态决定了芯片复位后从哪个区域开始执行程序。
在系统复位后,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存。用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启动模式。
在从待机模式退出时,BOOT引脚的值将被被重新锁存;因此,在待机模式下BOOT引脚应保持为需要的启动配置。
在启动延迟之后,CPU从地址0x0000 0000获取堆栈顶的地址,并从启动存储器的0x0000 0004指示的地址开始执行代码。
根据选定的启动模式,主闪存存储器、系统存储器或内置SRAM可以按照以下方式访问:
● 从主闪存存储器启动:主闪存存储器被映射到启动空间(0x0000 0000),但仍然能够在它原有的地址(0x0800 0000)访问它,即flash memory的内容可以在两个地址区域访问,0x0000 0000或0x0800 0000。
● 从系统存储器启动:系统存储器被映射到启动空间(0x0000 0000),但仍然能够在它原有的地址(互联型产品原有地址为0x1FFF B000,其它产品原有地址为0x1FFF F000)访问它。
● 从内置SRAM启动:只能在0x2000 0000开始的地址区访问SRAM。
注意: 当从内置SRAM启动,在应用程序的初始化代码中,必须使用NVIC的异常表和偏移寄存器,从新映射向量表之SRAM中。
实例分析
野火开发板stm32f103
从主闪存存储器启动(仿真器下载)
- keil直接编写,这里借用之前c程序的内存分配的代码, 使用下载器(这里用st-link)烧录
#include <stdio.h>
#include <stdlib.h>
int k1 = 1;
int k2;
static int k3 = 2;
static int k4;
int main( )
{ static int m1=2, m2;
int i = 1;
char *p;
char str[10] = "hello";
char *var1 = "123456";
char *var2 = "abcdef";
int *p1=malloc(4);
int *p2=malloc(4);
free(p1);
free(p2);
printf("栈区-变量地址\n");
printf(" i:%p\n", &i);
printf(" p:%p\n", &p);
printf(" str:%p\n", str);
printf("\n堆区-动态申请地址\n");
printf(" %p\n", p1);
printf(" %p\n", p2);
printf("\n.bss段\n");
printf("全局外部无初值 k2:%p\n", &k2);
printf("静态外部无初值 k4:%p\n", &k4);
printf("静态内部无初值 m2:%p\n", &m2);
printf("\n.data段\n");
printf("全局外部有初值 k1:%p\n", &k1);
printf("静态外部有初值 k3:%p\n", &k3);
printf("静态内部有初值 m1:%p\n", &m1);
printf("\n常量区\n");
printf("文字常量地址 :%p\n",var1);
printf("文字常量地址 :%p\n",var2);
printf("\n代码区\n");
printf("程序区地址 :%p\n",&main);
return 0;
}
从系统存储器启动(ISP下载)
操作方法:
①将BOOT0设置为1,BOOT1设置为0,然后按下复位键,从系统存储器启动BootLoader
②通过串口下载程序到Flash中
③程序下载完成后,将BOOT0设置为GND,手动复位。
所幸此次采用的野火开发板在芯片中嵌入了BootLoad程序,将做串口转SPI通信,就不需要那么麻烦的操作。
下载一个isp下载器mcuisp,绿色开源,无需安装
执行下列操作
打开野火的多功能调试助手
参考+总结
不太理解得是两种烧录方式的结果并没有什么差别。第一种从主闪存存储器启动方式是我们用的最多,也比较容易的方式,第二种则比较麻烦。