目录
1. 在RAM中调试代码
2. STM32的三种存储方式
3. STM32的启动方式
4. 实验过程
通过上一节的学习,我们已经了解了SRAM静态存储器;
1. 在RAM中调试代码
一般情况下,我们在MDK中编写工程应用后,调试时都是把程序下载到芯片内部FLASH运行测试的,代码的CODE及RW-data的内容被写入到内部FLASH中存储。但是某些应用场合下却不希望或者不能修改内部FLASH的内容,这时就可以使用RAM调试功能,它的本质是把原来存储在内部FLASH的代码(CODE及RW-data的内容)改为存储到SRAM中(内部SRAM或者外部SDRAM均可),芯片复位后从SRAM中加载代码并运行。
在RAM中调试程序有以下的优势:
我们通常都是使用 MDK 的 Build 和 DownLoad 来下载程序到 Flash,但是通过这种方式下载到 FLASH 中是有擦除和写入的过程,当代码比较长时,这种方式是比较费时间的。
写入到 RAM 存储器中,下载速度比内部 FLASH 要快的多,而且没有擦除过程,因此在 RAM 中调试程序时程序几乎是秒下的,对于那些大型程序,并且需要频繁更改的程序,能节省很多时间。并且通过 RAM 不会改写内部 FLASH 的原有程序。对于内部 FLASH 被锁定的芯片,可以把解锁程序下载到 RAM 上,进行解锁。
在RAM中调试程序最大的缺点是:
RAM中存储程序会掉电丢失。不能像FLASH那样保存。
RAM中存储空间比较小,不像FLASH那样存储空间比较大。
2. STM32的三种存储方式
BOOT 引脚:
可以去仔细的看自己的开发板:
开发板在出厂的时候:对于上述的 BOOT 3*2插针 ,默认是通过跳线帽将 BOOT0 和 GND连接;将 BOOT1 和 GND连接;默认就是将 MDK编译好的程序下载到Flash 中;
开发板在设计的时候,对于 BOOT插针 的设置,是有 3.3V 高电平1 的,也就是说设计师在设计开发板的时候,不仅仅是希望我们只是将程序下载到Flash中看看现象的;更多的是希望我们通过跳线帽灵活的配置程序下载到三种不同的存储方式中。
3. STM32的启动方式
M4内核在离开复位状态后会从映射的地址中取值给栈指针MSP以及程序指针PC,然后执行指令,一般以存储器的类型来区分自举过程,例如内部FLASH启动方式、内部SRAM启动方式以及系统存储器启动方式。
内部Flash启动过程:
当芯片被上电采样BOOT0引脚为低电平时,0x00000000和0x00000004的地址会被映射到内部Flash的0x08000000和0x08000004地址。当M4内核离开系统复位命令以后,读取0x08000000地址的内容会被赋值给栈指针MSP,作为栈顶地址。读取0x08000004地址的内容赋值给程序指针PC,作为将要执行的第一个指令所在的地址。
具备这两个条件以后,M4内核就可以开始从PC指向的地址中读取指令执行了。
内部SRAM启动方法:
类似的,当芯片被上电采样到BOOT0和BOOT1引脚均为高电平时,0x00000000和0x000000004地址会被映射到内部SRAM的首地址0x200000000和0x20000004,内核从SRAM空间获取内容进行自举。
在实际的应用中,由启动文件startup_stm32f40_41xxx.s决定了0x00000000和0x00000004地址中存储了什么内容,链接时,由分散加载文件(sct)决定这些内容的绝对地址,也就是分配到内部Flash还是内部SRAM;
系统存储器启动方式:
当芯片上电后采样到BOOT0引脚为高电平,BOOT1引脚为低电平时,内核将从系统存储器的0x1FFFF000及0x1FFFF004获取MSP及PC值进行自举。系统存储器是一段特殊的空间,用户是不能访问的。ST公司在芯片出厂前就在系统存储器中固化了一段代码。因此使用系统存储器启动方式时,内核会执行该代码,该代码运行时,会为ISP提供支持(In System Program),如检测USART1/3、CAN2及USB通讯接口传输过来的信息,并根据这些信息更新自己内部Flash的内容,达到升级产品应用程序的目的,因此这种启动方式也称为ISP启动方式。
系统存储器的存储方式等同于使用FlyMcu APP进行下载程序到芯片内部Flash。
4. 实验过程
本实验将会程序写入到内部SRAM中;
有两种方式可以验证程序的正确性,一种是直接下载到 Flash 中,一种是在 SRAM 中跑。但是要注意程序在 SRAM 中运行掉电会消失,不过他也有他的优点,避免了每次擦写 FALSH,毕竟 FLASH的擦写次数是有限的,在 SRAM 中验证程序没有问题后,可以再烧录在 FLASH 中。
给 SRAM 分区
M4 处理器的 Flash 的初始地址为 0x80000000,而 SRAM 的起始地址为 0x20000000。首先将 SRAM 空间均分,一部分构造成 ROM,一部分构造成 RAM。注意ROM的地址是紧跟着RAM的。这里构造的目的是假装从 ROM 启动,这样不需要在硬件上变更 BOOT0、BOOT1 的值。
增加 SRAM 向量表
对应的还要在 main 文件中加入 NVIC_SetVectorTable(NVIC_VectTab_RAM,0x0);这样才能找到 SRAM 的入口地址。否则入口地址总是在 0x00000000
int main(void)
{
NVIC_SetVectorTable(NVIC_VectorTab_RAM,0x0);
}
增加初始化文件
//ini文档的地址为:PACK\Keil\STM32F4xx_DFP\2.15.0\MDK\Boards\ST\32F469IDISCOVERY\Blinky\Debug_RAM.ini
/*
FUNC void Setup (void) {
SP = _RDWORD(0x20000000); // Setup Stack Pointer
PC = _RDWORD(0x20000004); // Setup Program Counter
//这里注意SP指针和PC指针的指向;
//关于这两个指针在上述已经进行了清楚的介绍
XPSR = 0x01000000; // Set Thumb bit
_WDWORD(0xE000ED08, 0x20000000); // Setup Vector Table Offset Register
}
LOAD %L INCREMENTAL // Download to RAM
Setup();
*/
选择不擦出 FLASH
不要勾选 updata target before debugging ,简单来说就是不下载到 Flash 中;
运行 SRAM
点击按键,进入调试模式,就可以进入 SRAM 中调试代码啦,然后退出 debug 的界面,在 MDK 中运行程序仍然是 SRAM 的程序。