在SRAM中调试MM32程序¶
以 MM32SPIN0280 为例,记录在 SRAM 中调试代码的方法和步骤。
引言¶
MM32SPIN0280 的读保护,除了 UM 手册中指明的方法外,还有一种读保护形式,我们姑且叫它读保护2。
使能读保护2后,0x080000C0 之前的地址内容可以读出,其内容是中断向量表。0x080000C0 之后的地址内容读的时候全为 0xFFFFFFFF。
但是在读保护2模式下,程序可以正常下载、运行、调试。
读保护2设置步骤¶
- 设置FLASH_AR地址为0x1FFFF800,执行该选项字节区块擦除
- 按选项字节区块编程方式,按流程写0x5AA5到对应地址
- 设置FLASH_AR地址为0x1FFE0000,执行该选项字节区块擦除
- 按选项字节区块编程方式,按流程写0x7F80到0x1FFE0000
- 按选项字节区块编程方式,按流程写0xFF00到0x1FFE0002
读保护2解除步骤¶
- 设置FLASH_AR地址为0x1FFFF800,执行该选项字节区块擦除
- 按选项字节区块编程方式,按流程写0x5AA5到对应地址
- 对0x0800000地址执行全片擦除
- 设置FLASH_AR地址为0x1FFE0000,执行该选项字节区块擦除,确保0x1FFE0000和0x1FFE0002地址的数据都为0xFFFF
为了测试读保护2,设置使能读保护2的时候,测试程序可以在 Flash 中运行,但是在解除时,需要全片擦除 Flash,程序就没有办法在 Flash 中运行了。下面介绍如何在 SRAM 中运行程序解除读保护2.
读保护2设置代码¶
以上节所述步骤,使用以下代码编程 0x1FFE0000。
FLASH_Unlock();
FLASH_EraseOptionBytes();
//解除读保护
FLASH_ProgramOptionHalfWord(0x1FFFF800, 0x5AA5);
FLASH_WaitForLastOperation(EraseTimeout);
//擦除0x1FFE0000区间
FLASH_OPTB_Enable();
FLASH->AR = 0x1FFE0000;
FLASH->CR |= (FLASH_CR_OPTER | FLASH_CR_STRT);
FLASH_WaitForLastOperation(EraseTimeout);
//设置芯片第二种读保护
FLASH_ProgramOptionHalfWord(0x1FFE0000, 0x7F80);
FLASH_WaitForLastOperation(EraseTimeout);
FLASH_ProgramOptionHalfWord(0x1FFE0002, 0xFF00);
FLASH_WaitForLastOperation(EraseTimeout);
FLASH_Lock();
SRAM启动配置¶
如 UM 手册所述,要想从 SRAM 中启动,除了 BOOT0 引脚要拉高外,选项字节中还需要配置 nBOOT1 为 0.

FLASH_Unlock();
FLASH_EraseOptionBytes();
//解除读保护
FLASH_ProgramOptionHalfWord(0x1FFFF800, 0x5AA5);
FLASH_WaitForLastOperation(EraseTimeout);
//配置 nBOOT1 为 0
FLASH_ProgramOptionHalfWord(0x1FFFF802, 0x00EF);
FLASH_WaitForLastOperation(EraseTimeout);
FLASH_Lock();
MDK工程配置¶


更改中断向量表指向地址¶
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
SYSCFG->CFGR |= 0x3;
完整测试代码¶
FLASH_Unlock();
FLASH_EraseOptionBytes();
//解除读保护
FLASH_ProgramOptionHalfWord(0x1FFFF800, 0x5AA5);
FLASH_WaitForLastOperation(EraseTimeout);
//擦除0x1FFE0000区间
FLASH_OPTB_Enable();
FLASH->AR = 0x1FFE0000;
FLASH->CR |= (FLASH_CR_OPTER | FLASH_CR_STRT);
FLASH_WaitForLastOperation(EraseTimeout);
//设置芯片第二种读保护
FLASH_ProgramOptionHalfWord(0x1FFE0000, 0x7F80);
FLASH_WaitForLastOperation(EraseTimeout);
FLASH_ProgramOptionHalfWord(0x1FFE0002, 0xFF00);
FLASH_WaitForLastOperation(EraseTimeout);
FLASH_Lock();
//以下是解除读保护2设置
RCC_APB2PeriphClockCmd(RCC_APB2ENR_SYSCFG, ENABLE);
SYSCFG->CFGR |= 0x3;
FLASH_Unlock();
FLASH_EraseOptionBytes();
//解除读保护
FLASH_ProgramOptionHalfWord(0x1FFFF800, 0x5AA5);
FLASH_WaitForLastOperation(EraseTimeout);
//配置 nBOOT1 为 0
FLASH_ProgramOptionHalfWord(0x1FFFF802, 0x00EF);
FLASH_WaitForLastOperation(EraseTimeout);
FLASH_EraseAllPages();
FLASH_OPTB_Enable();
FLASH->AR = 0x1FFe0000;
FLASH->CR |= (FLASH_CR_OPTER | FLASH_CR_STRT);
FLASH_WaitForLastOperation(EraseTimeout);
FLASH_Lock();