/** ****************************************************************************** * @file User\Driver\flash_config.c * @author 路淮 * @version v0.1 * @date 2026-05-21 * @brief Flash读写配置 ****************************************************************************** */ #include "flash_config.h" #include "stm32h7xx_hal.h" #include "FreeRTOS.h" #include "task.h" /** * @brief stmflash_read_data:读取Flash数据 * @note none * @param pbuf:数据缓冲区指针 * @param addr:Flash地址 * @param datalen:数据长度 * @retval none */ void stmflash_read_data(uint8_t *pbuf, uint32_t addr, uint16_t datalen) { if (pbuf == NULL || datalen == 0) { return; } memcpy(pbuf, (const void *)addr, datalen); } /* ============================================================ * 写 Flash * 函数指针原型: void (*write_flash)(uint8_t *pbuf, uint32_t addr, uint16_t datalen) * * H743 写入规则: * - 每次必须写 32字节 (FLASH_TYPEPROGRAM_FLASHWORD) * - 写入地址必须 32字节对齐 * - 不满 32字节的部分用 0xFF 填充 * ============================================================ */ void stmflash_write_data(uint8_t *pbuf, uint32_t addr, uint16_t datalen) { if (pbuf == NULL || datalen == 0) { return; } /* 地址必须32字节对齐 */ if ((addr % 32) != 0) { return; } /* 计算对齐后的长度 */ uint16_t aligned_len = (datalen + 31) & ~31U; /* 构建对齐缓冲区, 多余部分填 0xFF */ uint8_t buf[aligned_len]; memset(buf, 0xFF, aligned_len); memcpy(buf, pbuf, datalen); HAL_FLASH_Unlock(); uint32_t address = addr; uint8_t *writePtr = buf; uint16_t remain = aligned_len; while (remain >= 32) { if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, address, (uint32_t)writePtr) != HAL_OK) { /* 写入失败,退出 */ break; } address += 32; writePtr += 32; remain -= 32; } HAL_FLASH_Lock(); } /* ============================================================ * 擦除 Flash Sector * 函数指针原型: uint8_t (*erase_sector)(uint32_t addr) * * H743 参数: * - Bank2, Sector0 起始地址 0x08100000 * - 每个 Sector = 128KB * - VoltageRange = FLASH_VOLTAGE_RANGE_3 (2.7V ~ 3.6V) * ============================================================ */ uint8_t flash_sector_erase(uint32_t addr) { FLASH_EraseInitTypeDef EraseInitStruct = {0}; uint32_t SECTORError = 0; /* 根据地址计算 Sector 编号 */ /* Bank2: 0x08100000 ~ 0x081FFFFF, 共8个Sector, 每个128KB */ uint32_t sector = (addr - 0x08100000) / (128 * 1024); if (sector > 7) { return 0; } HAL_FLASH_Unlock(); EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS; EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3; EraseInitStruct.Banks = FLASH_BANK_2; EraseInitStruct.Sector = sector; EraseInitStruct.NbSectors = 1; if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK) { HAL_FLASH_Lock(); return 0; } HAL_FLASH_Lock(); return 1; } flash_manage_t stm_flash_manage = {0}; void stm_flash_init(void) { stm_flash_manage.align_num = 32; stm_flash_manage.flash_write_mode = FLASH_OVERWRITING_MODE; stm_flash_manage.flash_read_mode = FLASH_NO_CLEAR_MODE; stm_flash_manage.flash_start_address = 0x08180000; stm_flash_manage.manage_sector_num = 1; stm_flash_manage.sector_size = 128 * 1024; stm_flash_manage.open_flash = NULL; stm_flash_manage.close_flash = NULL; stm_flash_manage.read_flash = stmflash_read_data; stm_flash_manage.write_flash = stmflash_write_data; stm_flash_manage.erase_sector = flash_sector_erase; // stm_flash_manage.open_flash(); flash_manage_init(&stm_flash_manage); } int8_t stm_flash_read(uint8_t *pbuf, uint8_t frame_type) { taskENTER_CRITICAL(); int8_t flag = flash_manage_read(&stm_flash_manage, pbuf, frame_type); taskEXIT_CRITICAL(); return flag; } int8_t stm_flash_write(uint8_t *pbuf, uint16_t size, uint8_t frame_type) { taskENTER_CRITICAL(); int8_t flag = flash_manage_write(&stm_flash_manage, pbuf, size, frame_type); taskEXIT_CRITICAL(); return flag; }