46.1 选项字节与读写保护
1.1 选项字节的内容
选项字节是一段特殊的 FLASH 空间,STM32 芯片会根据它的内容进行读写保护配置,选项字节的构成见表选项字节的构成
STM32F103 系列芯片的选项字节有 8 个配置项,即上表中的 USER、RDP、DATA0/1 及 WRP0/1/2/3,而表中带 n 的同类项是该项的反码,即 nUSER 的值等于 (~USER)、nRDP 的值等于 (~RDP),STM32利用反码来确保选项字节内容的正确性。
选项字节的 8 个配置项具体的数据位配置说明见表选项字节具体的数据位配置说明 。
1.2 RDP 读保护
修改选项字节的 RDP 位的值可设置内部 FLASH 为以下保护级别:
• 0xA5:无保护
• 其它值:使能读保护
• 解除保护
芯片被配置成读保护后根据不同的使用情况,访问权限不同,总结
1.3 WRP 写保护
使用选项字节的 WRP0/1/2/3 可以设置主 FLASH 的写保护,防止它存储的程序内容被修改。
• 设置写保护
• 解除写保护
46.2 修改选项字节的过程
- 解除 FLASH_CR 寄存器的访问限制
• 往 FPEC 键寄存器 FLASH_KEYR 中写入 KEY1 = 0x45670123
• 再往 FPEC 键寄存器 FLASH_KEYR 中写入 KEY2 = 0xCDEF89AB
- 解除对选项字节的访问限制
• 往 FLASH_OPTKEYR 中写入 KEY1 = 0x45670123
• 再往 FLASH_OPTKEYR 中写入 KEY2 = 0xCDEF89AB
-
配置 FLASH_CR 的 OPTPG 位,准备修改选项字节
-
直接使用指针操作修改选项字节的内容,根据需要修改 RDP、WRP 等内容
-
对于读保护的解除,由于它会擦除 FLASH 的内容,所以需要检测状态寄存器标志位以确认FLASH 擦除操作完成。
-
若是设置读保护及其解除,需要给芯片重新上电复位,以使新配置的选项字节生效;对于设置写保护及其解除,需要给芯片进行系统复位,以使新配置的选项字节生效。
46.3 操作选项字节的库函数
3.1 选项字结构体定义
3.2 设置写保护及解除
3.3 设置读保护及解除
注意:
函数 FLASH_ReadOutProtection 来设置 FLASH 的读保护及解除和函数FLASH_EnableWriteProtection 可用于设置写保护及解除同样有对 FLASH_CR 寄存器的访问,但并没有进行解锁操作,所以调用本函数前,同样需要先使用 FLASH_Unlock 函数解锁。
46.4 实验:设置读写保护及解除
4.1 硬件设计
本实验完全针对内部 FLASH 的操作,对外部硬件无特殊要求。即使是在 SRAM 调试模式下,由于是使用Debug 强制加载 PC 和 SP 指针,所以也无需设置 BOOT0 和 BOOT1 的引脚。
4.2 软件设计
4.2.1 代码分析
(1)设置写保护及解除
(2)设置读保护及解除
(3)main 函数
RAM.sct
;若RAM版本工程提示找不到sct文件,把本文件改名为“RAM版本.sct”复制至Output目录即可
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x20000000 0x00008000 { ; load region size_region
ER_IROM1 0x20000000 0x00008000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20008000 0x00008000 { ; RW data
.ANY (+RW +ZI)
}
}
flash.sct
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x08000000 0x00080000 { ; load region size_region
ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
RW_IRAM1 0x20000000 0x00010000 { ; RW data
.ANY (+RW +ZI)
}
}
main.c
#include "stm32f10x.h"
#include "./usart/bsp_usart.h"
#include "./key/bsp_key.h"
#include "./led/bsp_led.h"
#include "./protect/bsp_readWriteProtect.h"
// 函数原型声明
void Delay(__IO uint32_t nCount);
//【 !!】注意事项:
//1.当芯片处于读写保护状态时,均无法下载新的程序,需要先解除保护状态后再下载
//2.本工程包含两个版本,可在MDK的“Load”下载按钮旁边的下拉框选择:
// FLASH版本: 接上串口调试助手后,直接点击MDK的“Load”按钮把程序下载到STM32的FLASH中,
// 复位运行,串口会输出当前芯片的保护状态,可使用KEY1和KEY2切换。切换写保护
// 状态时,芯片会自动复位,程序重新执行;切换读保护状态时,按键后需要重新给
// 开发板上电复位,配置才会有效(断电时,串口与电脑的连接会断开,所以上电后
// 注意重新打开串口调试助手),若是执行解除读保护过程,运行后芯片FLASH中自身
// 的代码都会消失,所以要重新给开发板下载程序。
// RAM版本 : 若无SRAM调试程序的经验,请先学习前面的《SRAM调试》章节。接上串口调试助手后,
// 只能使用MDK的“Debug”按钮把程序下载到STM32的内部SRAM中,然后点击全速运行,
// 可在串口查看调试输出。由于SRAM调试状态下,复位会使芯片程序乱飞,所以每次切
// 换状态后,都要重新点击“Debug”按钮下载SRAM程序,再全速运行查看输出。
//3.若自己修改程序导致使芯片处于读写保护状态而无法下载,
// 且 FALSH程序自身又不包含自解除状态的程序,可以使用本工程的“RAM版本”解除,解除即可重新下载。
/*
* 函数名:main
* 描述 :主函数
* 输入 :无
* 输出 :无
*/
int main(void)
{
/*初始化USART,配置模式为 115200 8-N-1*/
USART_Config();
LED_GPIO_Config();
Key_GPIO_Config();
LED_BLUE;
//芯片自动复位后,串口可能有小部分异常输出,如输出一个“?”号
printf("\r\n欢迎使用野火 STM32 开发板。\r\n");
printf("这是读写保护测试实验\r\n");
/* 获取写保护寄存器的值进行判断,寄存器位为0表示有保护,为1表示无保护 */
/* 若不等于0xFFFFFFFF,则说明有部分页被写保护了 */
if(FLASH_GetWriteProtectionOptionByte() !=0xFFFFFFFF )
{
printf("\r\n目前芯片处于写保护状态,按Key1键解除保护\r\n");
printf("写保护寄存器的值:WRPR=0x%x\r\n",FLASH_GetWriteProtectionOptionByte());
}
else //无写保护
{
printf("\r\n目前芯片无 写 保护,按 Key1 键可设置成 写 保护\r\n");
printf("写保护寄存器的值:WRPR=0x%x\r\n",FLASH_GetWriteProtectionOptionByte());
}
/* 若等于SET,说明处于读保护状态 */
if(FLASH_GetReadOutProtectionStatus () == SET )
{
printf("\r\n目前芯片处于读保护状态,按Key2键解除保护\r\n");
}
else
{
printf("\r\n目前芯片无 读 保护,按 Key2 键可设置成 读 保护\r\n");
}
while(1)
{
if( Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON )
{
LED1_TOGGLE;
WriteProtect_Toggle();
}
if( Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == KEY_ON )
{
LED2_TOGGLE;
ReadProtect_Toggle();
}
}
}
void Delay(__IO uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
/*********************************************END OF FILE**********************/
其他配置:
4.3 下载测试
本工程包含两个版本,可在 MDK 的“Load”下载按钮旁边的下拉框选择:
• FLASH 版本:
接上串口调试助手后,直接点击 MDK 的“Load”按钮把程序下载到 STM32的 FLASH 中,复位运行,串口会输出当前芯片的保护状态,可使用 KEY1 和 KEY2 切换。切换写保护状态时,芯片会自动复位,程序重新执行;切换读保护状态时,按键后需要重新给开发板上电复位,配置才会有效(断电时,串口与电脑的连接会断开,所以上电后注意重新打开串口调试助手),若是执行解除读保护过程,运行后芯片 FLASH 中自身的代码都会消失,所以要重新给开发板下载程序。
• RAM 版本:
若无 SRAM 调试程序的经验,请先学习前面的《SRAM 调试》章节。接上串口调试助手后,只能使用 MDK 的“Debug”按钮把程序下载到 STM32 的内部 SRAM 中,然后点击全速运行,可在串口查看调试输出。由于 SRAM 调试状态下,复位会使芯片程序乱飞,所以每次切换状态复位后,都要重新点击“Debug”按钮下载 SRAM 程序,再全速运行才能正常查看输出。