123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- /* includes ----------------------------------------------------------*/
- #include "flash.h"
- /* typedef -----------------------------------------------------------*/
- /* define ------------------------------------------------------------*/
- /* macro -------------------------------------------------------------*/
- /* variables ---------------------------------------------------------*/
- param_boot s_param_boot = {
- .jumpAddr = 0x8040C00U,
- };
- /* function prototypes -----------------------------------------------*/
- /**
- * @brief flash读数据
- * @param address:读数据的起始地址
- read_buf:数据存储区
- length:读取的数据长度
- * @return HAL_StatusTypeDef
- */
- void FLASH_Read(uint32_t address, uint32_t *read_buf, uint32_t length)
- {
- for (uint32_t i = 0; i < length; i++)
- {
- read_buf[i] = *(volatile uint32_t*)(address + (i * 4)); // 以字(32位)为单位读取
- }
- }
- /**
- * @brief flash按页擦除
- * @param app_address address to jump
- number_of_pages:擦除页的页数
- * @return HAL_StatusTypeDef
- */
- HAL_StatusTypeDef FLASH_Erase(uint32_t start_address, uint32_t number_of_pages)
- {
- HAL_StatusTypeDef status = HAL_ERROR;
- FLASH_EraseInitTypeDef EraseInitStruct;
- uint32_t PageError = 0;
- // 解锁Flash
- HAL_FLASH_Unlock();
- // 设置擦除参数
- EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
- EraseInitStruct.PageAddress = start_address;
- EraseInitStruct.NbPages = number_of_pages;
- // 擦除Flash
- status = HAL_FLASHEx_Erase(&EraseInitStruct, &PageError);
- // 锁定Flash
- HAL_FLASH_Lock();
- return status; // 返回擦除操作的状态
- }
- /**
- * @brief flash按字写入
- * @param address:写入地址
- data:数据
- length:长度
- * @return HAL_StatusTypeDef
- */
- HAL_StatusTypeDef FLASH_Write(uint32_t address, uint32_t *data, uint32_t length)
- {
- HAL_StatusTypeDef status = HAL_OK;
- // 进入临界区 挂起所有任务
- vTaskSuspendAll();
- // 解锁Flash
- HAL_FLASH_Unlock();
- // 逐个字节写入数据
- for (uint32_t i = 0; i < length; i++)
- {
- if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data[i]) == HAL_OK)
- {
- // 验证写入的数据
- if (*(uint32_t*)address != data[i])
- {
- status = HAL_ERROR;
- break;
- }
- address += 4; // 更新地址(一个字的大小)
- }
- else
- {
- status = HAL_ERROR;
- break;
- }
- }
- // 锁定Flash
- HAL_FLASH_Lock();
- // 退出临界区 恢复任务调度
- xTaskResumeAll();
- return status; // 返回写入操作的状态
- }
- /**
- * @brief 写参数区跳转地址数据
- * @param none
- * @return HAL_StatusTypeDef
- */
- void Write_paramArea(void){
- // 擦除和写入参数
- uint32_t start_address = PARAM_ADDRESS; // Flash起始地址
- uint32_t number_of_pages = 1; // 假设我们只擦除1页
- // 调用擦除函数
- if (FLASH_Erase(start_address, number_of_pages) != HAL_OK) {
- // 擦除失败的处理
- }
- // 调用写入函数
- if (FLASH_Write(start_address, (uint32_t*)&s_param_boot, (FLASH_PAGE_SIZE / sizeof(uint32_t))) != HAL_OK) {
- // 写入失败的处理
- }
- }
- /**
- * @brief 参数区数据读取
- * @param NONE
- * @return HAL_StatusTypeDef
- */
- void Read_ParamArea(void) {
- // 读取参数区的所有数据
- FLASH_Read(PARAM_ADDRESS, (uint32_t*)&s_param_boot, sizeof(param_boot) / sizeof(uint32_t));
- }
- /**
- * @brief 向量重映射
- * @param NONE
- * @return HAL_StatusTypeDef
- */
- void Remap_Vector_Table(void) {
-
- __disable_irq();
- // 设置向量表到程序运行区
- SCB->VTOR = APP1_ADDRESS;
- __enable_irq();
- }
- /**
- * @brief 读取96位(或者说是3个32位的字)的唯一ID
- * @param id: 指向三个uint32_t元素数组的指针作为参数,用来存储读取的唯一设备ID
- * @return
- * @note
- */
- void GetUniqueID(uint32_t* id) {
- if (id != NULL) {
- for (int i = 0; i < 3; i++) {
- *id++ = *(UNIQUE_ID_ADDR + i);
- }
- }
- }
|