stm32专题二十九:Flash 读写保护

设置Flash的读写保护,其实就是操作内部Flash的选项字节

RDP 读保护 

修改选项字节的 RDP 位的值可设置内部 FLASH 为以下保护级别: 

读保护的解除,必须要上电复位才可以。 

 WRP 写保护

1 设置写保护

       写保护的配置一般以 4K 字节为单位,除 WRP3 的最后一位比较特殊外,每个WRP 选项字节的一位用于控制 4K 字节的写访问权限, 把对应 WRP 的位置 0 即可把它匹配的空间加入写保护。被设置成写保护后,主 FLASH 中的内容使用任何方式都不能被擦除和写入,写保护不会影响读访问权限,读访问权限完全由前面介绍的读保护设置限制。

2 解除写保护

       解除写保护是逆过程,把对应 WRP 的位置 1 即可把它匹配的空间解除写保护。解除写保护后,主 FLASH 中的内容不会像解读保护那样丢失,它会被原样保留。

修改选项字节的过程 

Flash_CR寄存器,操作选项字节的位描述: 

 操作选项字节的库函数:

结构体和宏定义: 

/** 
  * @brief Option Bytes Registers
  */
  
typedef struct
{
  __IO uint16_t RDP;
  __IO uint16_t USER;
  __IO uint16_t Data0;
  __IO uint16_t Data1;
  __IO uint16_t WRP0;
  __IO uint16_t WRP1;
  __IO uint16_t WRP2;
  __IO uint16_t WRP3;
} OB_TypeDef;
 
#define OB                  ((OB_TypeDef *) OB_BASE) 
#define OB_BASE               ((uint32_t)0x1FFFF800)    /*!< Flash Option Bytes base address */

设置Flash写保护使能函数:

/* 掩码 */
#define RDPRT_Mask ((uint32_t)0x00000002)
#define WRP0_Mask ((uint32_t)0x000000FF)
#define WRP1_Mask ((uint32_t)0x0000FF00)
#define WRP2_Mask ((uint32_t)0x00FF0000)
#define WRP3_Mask ((uint32_t)0xFF000000)

/* 大容量产品页保护的宏定义,每位控制 4K 字节(2 页) */
#define FLASH_WRProt_Pages0to1 ((uint32_t)0x00000001)
 #define FLASH_WRProt_Pages2to3 ((uint32_t)0x00000002)
 #define FLASH_WRProt_Pages4to5 ((uint32_t)0x00000004)
 #define FLASH_WRProt_Pages6to7 ((uint32_t)0x00000008)
 /*..部分省略*/
 /*!< 特殊位,最后一位,页 62 至 511 */
 #define FLASH_WRProt_Pages62to511 ((uint32_t)0x80000000)
 /*保护所有页*/
 #define FLASH_WRProt_AllPages ((uint32_t)0xFFFFFFFF)


 /**
 * @brief 对指定的页设置写保护
 * @param FLASH_Pages: 指定要设置写保护的页.
 * 可输入参数:
 * STM32 大容量产品: FLASH_WRProt_Pages0to1 至 FLASH_WRProt_Pages60to61
 * 或 FLASH_WRProt_Pages62to255 和 FLASH_WRProt_AllPages

 * @retval FLASH Status:
 * 可能的返回值: FLASH_ERROR_PG, FLASH_ERROR_WRP,
 FLASH_COMPLETE or FLASH_TIMEOUT.
 */
 FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages)
 {
	 uint16_t WRP0_Data = 0xFFFF, WRP1_Data = 0xFFFF,
	P2_Data = 0xFFFF, WRP3_Data = 0xFFFF;

	 FLASH_Status status = FLASH_COMPLETE;

	 /* 检查参数 */
	 assert_param(IS_FLASH_WRPROT_PAGE(FLASH_Pages));
	 /*根据输入计算要设置的值*/
	 FLASH_Pages = (uint32_t)(~FLASH_Pages);
	 WRP0_Data = (uint16_t)(FLASH_Pages & WRP0_Mask);
	 WRP1_Data = (uint16_t)((FLASH_Pages & WRP1_Mask) >> 8);
	 WRP2_Data = (uint16_t)((FLASH_Pages & WRP2_Mask) >> 16);
	 WRP3_Data = (uint16_t)((FLASH_Pages & WRP3_Mask) >> 24);

	 /* 等待上一次操作完毕 */
	 status = FLASH_WaitForLastOperation(ProgramTimeout);

	 if (status == FLASH_COMPLETE) {
	 /* 对选项字节进行解锁 */
	 FLASH->OPTKEYR = FLASH_KEY1;
	 FLASH->OPTKEYR = FLASH_KEY2;
	 FLASH->CR |= CR_OPTPG_Set; //准备写入选项字节
		 if (WRP0_Data != 0xFF) {
		 OB->WRP0 = WRP0_Data;
		 /* 等待上一次操作完毕 */
		 status = FLASH_WaitForLastOperation(ProgramTimeout);
		 }
		 if ((status == FLASH_COMPLETE) && (WRP1_Data != 0xFF)) {
		 OB->WRP1 = WRP1_Data;
		 status = FLASH_WaitForLastOperation(ProgramTimeout);
		 }
		 if ((status == FLASH_COMPLETE) && (WRP2_Data != 0xFF)) {
		 OB->WRP2 = WRP2_Data;
		 status = FLASH_WaitForLastOperation(ProgramTimeout);
		 }
		 if ((status == FLASH_COMPLETE)&& (WRP3_Data != 0xFF)) {
		 OB->WRP3 = WRP3_Data;
		 status = FLASH_WaitForLastOperation(ProgramTimeout);
		 }
		 if (status != FLASH_TIMEOUT) {
		 /* 若写入完成, 对选项字节重新上锁 */
		 FLASH->CR &= CR_OPTPG_Reset;
		 }
	}
 /* 返回设置结果 */
 return status;
}

 

 设置读保护及解除

#define RDP_Key ((uint16_t)0x00A5)


/**
* @brief 使能或关闭读保护
* @note 若芯片本身有对选项字节进行其它操作,
请先读出然后再重新写入,因为本函数会擦除所有选项字节的内容

 * @param Newstate: 使能(ENABLE)或关闭(DISABLE)
 * @retval FLASH Status: 可能的返回值: FLASH_ERROR_PG,
 * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
 */
 FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState)
{
	 FLASH_Status status = FLASH_COMPLETE;
	 /* 检查参数 */
	 assert_param(IS_FUNCTIONAL_STATE(NewState));
	 status = FLASH_WaitForLastOperation(EraseTimeout);
	 if (status == FLASH_COMPLETE) {
		 /* 写入选项字节解锁码 */
		 FLASH->OPTKEYR = FLASH_KEY1;
		 FLASH->OPTKEYR = FLASH_KEY2;
		 FLASH->CR |= CR_OPTER_Set; //擦除选项字节
		 FLASH->CR |= CR_STRT_Set; //开始擦除
		 /* 等待上一次操作完毕 */
		 status = FLASH_WaitForLastOperation(EraseTimeout);
		29 if (status == FLASH_COMPLETE) {
		 /* 若擦除操作完成,复位 OPTER 位 */
		 FLASH->CR &= CR_OPTER_Reset;
		 /* 准备写入选项字节 */
		 FLASH->CR |= CR_OPTPG_Set;
		 if (NewState != DISABLE) {
			 OB->RDP = 0x00;//写入非 0xA5 值,进行读保护
		 } else {
			 OB->RDP = RDP_Key; //写入 0xA5,解除读保护
		 }
		 /* 等待上一次操作完毕 */
		 status = FLASH_WaitForLastOperation(EraseTimeout);

		 if (status != FLASH_TIMEOUT) {
			 /* 若操作完毕,复位 OPTPG 位 */
			 FLASH->CR &= CR_OPTPG_Reset;
		 }
		} else {
		 if (status != FLASH_TIMEOUT) {
			 /* 复位 OPTER 位 */
			 FLASH->CR &= CR_OPTER_Reset;
		 }
		}
	}
		 /* 返回设置结果 */
		 return status;
}

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F103内部FLASH读写保护设置流程如下: 1. 在系统时钟配置中,使能FLASH读写保护时钟。 2. 编函数来设置FLASH读写保护。可以使用以下代码: ```c void FLASH_If_WriteProtectionConfig(uint32_t protectionstate) { FLASH_OBProgramInitTypeDef OBInit; HAL_StatusTypeDef result = HAL_OK; HAL_FLASH_Unlock(); /* Clear OPTVERR bit set on virgin samples */ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR); /* Get the Dual boot configuration status */ HAL_FLASHEx_OBGetConfig(&OBInit); /* The user is allowed to change the protection status */ if ((OBInit.USERConfig & FLASH_OPTR_WRP_SECTOR) != protectionstate) { /* Modify the parameter data */ if (protectionstate == FLASH_PROTECTION_DISABLE) { OBInit.OptionType = OPTIONBYTE_WRP; OBInit.WRPSector = FLASH_WRPSector_AllPages; OBInit.WRPState = OB_WRPSTATE_DISABLE; } else { OBInit.OptionType = OPTIONBYTE_WRP; OBInit.WRPSector = FLASH_WRPSector_AllPages; OBInit.WRPState = OB_WRPSTATE_ENABLE; } /* Launch the option byte loading */ result = HAL_FLASHEx_OBProgram(&OBInit); /* Check if the option byte loading has succeeded */ if (result == HAL_OK) { /* Check if the programmed data is OK */ if ((OBInit.USERConfig & FLASH_OPTR_WRP_SECTOR) != protectionstate) { /* Error occurred while writing data in Flash memory */ result = HAL_ERROR; } } } /* Locks the FLASH */ HAL_FLASH_Lock(); /* Return the protection operation status */ if (result == HAL_OK) { return FLASHIF_OK; } else { return FLASHIF_FAIL; } } ``` 3. 在主函数中调用该函数,以设置FLASH读写保护。例如,要禁用FLASH读写保护,请使用以下代码: ```c FLASH_If_WriteProtectionConfig(FLASH_PROTECTION_DISABLE); ``` 4. 在编译和下载代码之前,确保将选项字节设置为与应用程序兼容的值。 以上就是STM32F103内部FLASH读写保护设置的流程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值