151 lines
4.2 KiB
C
151 lines
4.2 KiB
C
|
|
#include "flash_config.h"
|
|||
|
|
#include "stm32h7xx_hal.h"
|
|||
|
|
#include "FreeRTOS.h"
|
|||
|
|
#include "task.h"
|
|||
|
|
|
|||
|
|
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};
|
|||
|
|
|
|||
|
|
/* demo */
|
|||
|
|
// stm_flash_read(data[0], 1);
|
|||
|
|
// stm_flash_read(data[1], 0);
|
|||
|
|
// stm_flash_read(data[0], 1);
|
|||
|
|
// stm_flash_read(data[1], 0);
|
|||
|
|
// stm_flash_write("12345678912345678912345678912345678912345", 41, 1);
|
|||
|
|
// stm_flash_write("abcdef", 6, 0);
|
|||
|
|
// stm_flash_write("12345678912345678912345678912345678912345", 41, 1);
|
|||
|
|
// stm_flash_write("abcdef", 6, 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;
|
|||
|
|
}
|