跳转至

在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.

alt text alt text

    FLASH_Unlock();

    FLASH_EraseOptionBytes();

    //解除读保护
    FLASH_ProgramOptionHalfWord(0x1FFFF800, 0x5AA5);
    FLASH_WaitForLastOperation(EraseTimeout);

    //配置 nBOOT1 为 0
    FLASH_ProgramOptionHalfWord(0x1FFFF802, 0x00EF);
    FLASH_WaitForLastOperation(EraseTimeout);

    FLASH_Lock();

MDK工程配置

alt text
alt text

更改中断向量表指向地址

    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();