文章目录
- 注意
- 1. `Option Byte`的定义
- 2. 读取`Option Byte`
- 3. `MCU Flash`读保护/写保护的配置
- 4. `Option Byte`的数据字段
- 5. `Option Byte`的配置字段
注意
在
STM32F103
上经过反复测试,有如下问题及疑问(测试代码):
- 设置读保护时,数据字段可以通过备份后再保存的方式维持原来的数据,但之前设置的写保护设置都将丢失(恢复成默认值:所有页面的写保护都未开启)(不正常);而且必须上电复位后才能运行;(应对方案:在需要读保护时,先使能读保护,再设置写保护)
- 清除读保护时,整个固件都将被擦除,必须重新烧录;(正常)
- 写数据字段时,读保护设置可以维持,写保护设置将恢复到默认值(不正常),需复位;
- 设置写保护时,读保护设置可以维持,数据字段可以维持;可以使能指定页的写保护,需复位;(正常)
- 清除写保护时,读保护设置可以维持,数据字段可以维持;只能一次性清除所有页的写保护设置(不正常),需复位;
1. Option Byte
的定义
// stm32f1xx_hal_flash_ex.h
/**
* @brief FLASH Options bytes program structure definition
*/
typedef struct
{
uint32_t OptionType; /*!< OptionType: Option byte to be configured.
This parameter can be a value of @ref FLASHEx_OB_Type */
uint32_t WRPState; /*!< WRPState: Write protection activation or deactivation.
This parameter can be a value of @ref FLASHEx_OB_WRP_State */
uint32_t WRPPage; /*!< WRPPage: specifies the page(s) to be write protected
This parameter can be a value of @ref FLASHEx_OB_Write_Protection */
uint32_t Banks; /*!< Select banks for WRP activation/deactivation of all sectors.
This parameter must be a value of @ref FLASHEx_Banks */
uint8_t RDPLevel; /*!< RDPLevel: Set the read protection level..
This parameter can be a value of @ref FLASHEx_OB_Read_Protection */
#if defined(FLASH_BANK2_END)
uint8_t USERConfig; /*!< USERConfig: Program the FLASH User Option Byte:
IWDG / STOP / STDBY / BOOT1
This parameter can be a combination of @ref FLASHEx_OB_IWatchdog, @ref FLASHEx_OB_nRST_STOP,
@ref FLASHEx_OB_nRST_STDBY, @ref FLASHEx_OB_BOOT1 */
#else
uint8_t USERConfig; /*!< USERConfig: Program the FLASH User Option Byte:
IWDG / STOP / STDBY
This parameter can be a combination of @ref FLASHEx_OB_IWatchdog, @ref FLASHEx_OB_nRST_STOP,
@ref FLASHEx_OB_nRST_STDBY */
#endif /* FLASH_BANK2_END */
uint32_t DATAAddress; /*!< DATAAddress: Address of the option byte DATA to be programmed
This parameter can be a value of @ref FLASHEx_OB_Data_Address */
uint8_t DATAData; /*!< DATAData: Data to be stored in the option byte DATA
This parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF */
} FLASH_OBProgramInitTypeDef;
2. 读取Option Byte
FLASH_OBProgramInitTypeDef OBInit;
HAL_FLASHEx_OBGetConfig(&OBInit);
// 以下都回来的值并不是每个都有意义,根据需要使用即可
LOG_DBG("OptionType: [0x%08X]\n", OBInit.OptionType); // 需要修改OptionByte时才使用
LOG_DBG("USERConfig: [0x%02X]\n", OBInit.USERConfig); // 当前MCU的一些配置信息,后面详细说
LOG_DBG("RDPLevel: [0x%02X]\n", OBInit.RDPLevel); // 表示当前MCU Flash的读保护状态
LOG_DBG("Banks: [0x%08X]\n", OBInit.Banks); // 这三个一起表示了当前MCU Flash的写保护状态
LOG_DBG("WRPPage: [0x%08X]\n", OBInit.WRPPage);
LOG_DBG("WRPState: [0x%08X]\n", OBInit.WRPState);
LOG_DBG("DATA0: [0x%02X]\n", HAL_FLASHEx_OBGetUserData(OB_DATA_ADDRESS_DATA0)); // 获取数据字段值
LOG_DBG("DATA1: [0x%02X]\n", HAL_FLASHEx_OBGetUserData(OB_DATA_ADDRESS_DATA1))
3. MCU Flash
读保护/写保护的配置
参考STM32_RDP_WRP_SRAM
4. Option Byte
的数据字段
- 这个用户字段在
F1
系列只有两个字节(非连续),用于存储一些掉电也可以保存的状态、标志位;至于需要怎么用,看用户自己的需求,个人目前感觉最大的用处就是用于固件升级时保存一下升级的标志位;(参考:STM32固件更新)
5. Option Byte
的配置字段
USERConfig
可设置的选项如下:
// @defgroup FLASHEx_OB_IWatchdog Option Byte IWatchdog
#define OB_IWDG_SW ((uint16_t)0x0001) /*!< Software IWDG selected */ // MCU 复位后 IWDG 需要软件配置后才启动(默认值)
#define OB_IWDG_HW ((uint16_t)0x0000) /*!< Hardware IWDG selected */ // MCU 复位后 IWDG 直接生效,不需要软件配置
// @defgroup FLASHEx_OB_nRST_STOP Option Byte nRST STOP
#define OB_STOP_NO_RST ((uint16_t)0x0002) /*!< No reset generated when entering in STOP */ // 进入STOP模式后不产生复位(默认值)
#define OB_STOP_RST ((uint16_t)0x0000) /*!< Reset generated when entering in STOP */ // 进入STOP模式后产生复位(这个有什么用呢?每次进入STOP后,就复位,又恢复到正常模式从新开始运行了啊)
// @defgroup FLASHEx_OB_nRST_STDBY Option Byte nRST STDBY
#define OB_STDBY_NO_RST ((uint16_t)0x0004) /*!< No reset generated when entering in STANDBY */ // 同上
#define OB_STDBY_RST ((uint16_t)0x0000) /*!< Reset generated when entering in STANDBY */ // 通过这个配置产生的复位不会设置PWR_FLAG_SB位,即MCU不会认为此次复位是由唤醒Standby模式产生的
USERConfig
的默认值为0x07
(OB_IWDG_SW | OB_STOP_NO_RST | OB_STDBY_NO_RST
);- 关于
OB_STOP_RST
配置的验证,可以参考STM32低功耗例程;