目录
概述
本篇文章介绍如何使用STM32HAL库,针对芯片读写保护实现防篡改、破解功能(详解),本案例还包含内部FLASH读写数据,本质就是操作Flash。
硬件:STM32F401CEU6最小系统板(内部Flash : 512Kbytes,SARM : 96 Kbytes)
软件:Keil 5.29 + STM32CubeMX6.8.0

一、使用方法
通过参阅《STM32中文参考手册》得知,不同型号的芯片对应FLASH大小不一样。
Flash地址映射表:

想更详细的了解,请阅读《STM32中文参考手册》,自行上网查找资料下载。
二、STM32CubeMx配置


三、Examples
-
打开STM32CubeMx生成的keil工程,新建bsp文件夹,同时分别新建bsp_flash.c与bsp_flash.h文件,并把这两个文件,添加keil工程中来即可。

-
添加头文件路径

-
bsp_flash.h文件
#ifndef __BSP_FLASH_H
#define __BSP_FLASH_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
#define DATASTOREADDR 0x08008000//数据存放地址
typedef enum {
FALSE = 0,
TRUE,
}bool;
typedef enum {
PS_DISABLE = 0,
PS_ENABLE,
}Protection_Status;
typedef enum {
APPLICATION_NORMAL = 0, // APP能正常稳定运行
APPLICATION_UPDATED, // APP刚更新完成,等待测试启动
APPLICATION_ERROR, // APP错误,不能正常工作
}Application_Status_t;
typedef __PACKED_STRUCT{
uint32_t Device_id; // 设备号
uint32_t Hardware_Version; // 硬件版本信息
uint32_t Application_Version; // APP软件版本
uint32_t Application_Status; // APP的状态. @Application_Status_t
uint32_t SystemParamCRC;
}SystemParamTypeDef;
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Base address of the Flash sectors */
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbyte */
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbyte */
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbyte */
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbyte */
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbyte */
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbyte */
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbyte */
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbyte */
/* Error code */
enum
{
FLASHIF_OK = 0,
FLASHIF_ERASEKO,
FLASHIF_WRITINGCTRL_ERROR,
FLASHIF_WRITING_ERROR,
};
enum{
FLASHIF_PROTECTION_NONE = 0,
FLASHIF_PROTECTION_PCROPENABLED = 0x1,
FLASHIF_PROTECTION_WRPENABLED = 0x2,
FLASHIF_PROTECTION_RDPENABLED = 0x4,
};
/* End of the Flash address */
#define APPLICATION_ADDRESS (uint32_t)0x08010000
#define USER_FLASH_END_ADDRESS 0x0807FFFF
/* Define the user application size */
/* Define the address from where user application will be loaded.
Note: the 1st sector 0x08000000-0x08003FFF is reserved for the IAP code */
/* Define bitmap representing user flash area that could be write protected (check restricted to pages 8-39). */
#define FLASH_SECTOR_TO_BE_PROTECTED (OB_WRP_SECTOR_0 | OB_WRP_SECTOR_1 | OB_WRP_SECTOR_2 | OB_WRP_SECTOR_3 |\
OB_WRP_SECTOR_4 | OB_WRP_SECTOR_5 | OB_WRP_SECTOR_6 | OB_WRP_SECTOR_7 )
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void FLASH_If_Init(void);
uint32_t FLASH_If_Erase(uint32_t StartSector);
uint32_t FLASH_If_Write(uint32_t FlashAddress, uint32_t* Data, uint32_t DataLength);
uint32_t FLASH_If_Write_ex(uint32_t FlashAddress, uint32_t* Data, uint32_t DataLength);
uint32_t FLASH_If_WriteByte(uint32_t FlashAddress, uint8_t* Data ,uint32_t DataLength);
uint32_t FLASH_If_Read(uint32_t FlashAddress, uint32_t* Data ,uint32_t DataLength);
uint32_t FLASH_If_Read_ex(uint32_t FlashAddress, uint32_t* Data ,uint32_t DataLength);
uint32_t FLASH_If_ReadByte(uint32_t FlashAddress, uint8_t* Data ,uint32_t DataLength);
uint16_t FLASH_If_GetWriteProtectionStatus(void);
HAL_StatusTypeDef FLASH_If_WriteProtectionConfig(uint32_t modifier);
void Flash_Test(void);
#ifdef __cplusplus
}
#endif
#endif
-
bsp_flash.c文件
/* Includes ------------------------------------------------------------------*/
#include "bsp_flash.h"
#include "stdio.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
static uint32_t GetSector(uint32_t Address);
/* Private functions ----