Files
BR_YKC/Core/User/Driver/drv_flash.c
2026-05-21 12:19:01 +08:00

208 lines
8.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
******************************************************************************
* @file User\Driver\drv_flash.c
* @author 路淮
* @version v0.1
* @date 2026-05-21
* @brief Flash驱动
******************************************************************************
*/
#include "drv_flash.h"
/* flash数据帧格式 */
/* 帧头, 同时表示当前帧状态 */
/* 整帧大小, 5~65536 */
/* 帧类型, 用于区分不同存储数据, 0~255*/
/* 帧数据 */
/* 帧尾, 同时表示当前帧状态 */
/* 可读帧表,存放不同帧类型的第一个可读帧的地址与大小 */
type_readable_frame_t data_form[255] = {0};
/* 首个可写地址 */
uint32_t writeable_addr = 0;
uint8_t erase_flag = 0;
/* 地址对齐向高地址取整 */
#define ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1))
uint32_t i = 0;
/**
* @brief flash_manage_init初始化flash管理函数
* @note none
* @param flash_manage 指向flash管理结构体的指针
* @retval none
*/
int8_t flash_manage_init(flash_manage_t *flash_manage)
{
uint8_t buff[4] = {0}; /* 存放帧头,帧大小,帧类型 */
if (flash_manage->manage_sector_num == 0 || flash_manage->sector_size == 0 || flash_manage->read_flash == 0 ||
flash_manage->write_flash == 0 || flash_manage->erase_sector == 0) {
return -1;
}
/* 遍历管理的空间以更新地址 */
for (; i < flash_manage->manage_sector_num * flash_manage->sector_size; ) {
/* 取出帧信息 */
flash_manage->read_flash(buff, ALIGN_UP(flash_manage->flash_start_address + i, flash_manage->align_num), 4);
/* 只获取该类帧类型的首个可读帧地址 */
if (buff[0] == FLASH_READABLE_HEAD) {
if (data_form[buff[3]].state == 0) {
uint8_t frame_tail = 0;
flash_manage->read_flash(&frame_tail, ALIGN_UP(flash_manage->flash_start_address + i, flash_manage->align_num) + (buff[2] << 8 | buff[1]) - 1, 1);
if (frame_tail == FLASH_READABLE_TAIL) {
/* 只有帧头帧尾均为可读, 才把对齐后的地址填入 */
data_form[buff[3]].addr = ALIGN_UP(flash_manage->flash_start_address + i, flash_manage->align_num);
/* 帧大小按小端排列 */
data_form[buff[3]].size = buff[2] << 8 | buff[1];
data_form[buff[3]].state = 1;
}
}
i = i + ALIGN_UP(buff[2] << 8 | buff[1], flash_manage->align_num);
} else if ((buff[0] & buff[1] & buff[2] & buff[3]) == FLASH_WRITABLE) {
/* 遍历提前结束 */
writeable_addr = ALIGN_UP(flash_manage->flash_start_address + i, flash_manage->align_num);
return 1;
} else {
i += flash_manage->align_num;
}
}
erase_flag = 1;
return 1;
}
/**
* @brief update_readable_frame更新可读帧表函数
* @note none
* @param flash_manage 指向flash管理结构体的指针
* @param addr 可读帧地址 可读帧地址
* @param frame_type 可读帧类型 可读帧类型
* @retval none
*/
void update_readable_frame(flash_manage_t *flash_manage, uint32_t addr, uint8_t frame_type)
{
uint8_t buff[4] = {0}; /* 存放帧头,帧大小,帧类型 */
/* 从当前位置遍历剩余空间 */
for (uint32_t i = 0; i < flash_manage->manage_sector_num * flash_manage->sector_size - (addr - flash_manage->flash_start_address);) {
/* 取出帧信息 */
flash_manage->read_flash(buff, ALIGN_UP(addr + i, flash_manage->align_num), 4);
/* 寻找相同类型的帧数据 */
if (buff[0] == FLASH_READABLE_HEAD) {
if (buff[3] == frame_type) {
uint8_t frame_tail = 0;
flash_manage->read_flash(&frame_tail, ALIGN_UP(addr + i, flash_manage->align_num) + (buff[2] << 8 | buff[1]) - 1, 1);
if (frame_tail == FLASH_READABLE_TAIL) {
/* 只有帧头帧尾均为可读, 才把地址填入 */
data_form[buff[3]].addr = ALIGN_UP(addr + i, flash_manage->align_num);
data_form[buff[3]].size = buff[2] << 8 | buff[1];
data_form[buff[3]].state = 1;
return;
}
}
i += ALIGN_UP(buff[2] << 8 | buff[1], flash_manage->align_num);
} else if ((buff[0] | buff[1] | buff[2] | buff[3]) == FLASH_WRITABLE) {
return;
} else {
i += flash_manage->align_num;
}
}
}
/**
* @brief flash_manage_read读取flash函数
* @note none
* @param flash_manage 指向flash管理结构体的指针
* @param pbuf 指向要读取数据的指针
* @param frame_type 要读取数据的类型
* @retval none
*/
int8_t flash_manage_read(flash_manage_t *flash_manage, uint8_t *pbuf, uint8_t frame_type)
{
if (flash_manage->manage_sector_num == 0 || flash_manage->sector_size == 0 || flash_manage->read_flash == 0 ||
flash_manage->write_flash == 0 || flash_manage->erase_sector == 0) {
return -1;
}
/* 可读表存在数据 */
if (data_form[frame_type].state != 0) {
flash_manage->read_flash(pbuf, data_form[frame_type].addr + 4, data_form[frame_type].size - 5);
if (flash_manage->flash_read_mode == FLASH_CLEAR_MODE) {
/* 将flash内部数据帧头尾置为无效数据 */
uint8_t frame_head[flash_manage->align_num];
memset(frame_head, FLASH_NULL, flash_manage->align_num);
flash_manage->write_flash(frame_head, data_form[frame_type].addr, flash_manage->align_num);
flash_manage->write_flash(frame_head, data_form[frame_type].addr + data_form[frame_type].size - 32, flash_manage->align_num);
/* 将对应类型的可读表置0 */
data_form[frame_type].state = 0;
if (flash_manage->flash_write_mode == FLASH_NO_OVERWRITING_MODE) {
/* flash处于覆写模式下, 可读帧是唯一的,故无需更新可读表, 而非覆写模式, 需要更新可读表 */
update_readable_frame(flash_manage, ALIGN_UP(data_form[frame_type].addr + data_form[frame_type].size, flash_manage->align_num), frame_type);
}
}
return 1;
}
return 0;
}
/**
* @brief flash_manage_write写入flash函数
* @note none
* @param flash_manage 指向flash管理结构体的指针
* @param pbuf 指向要写入数据的指针
* @param size 要写入数据的大小
* @param frame_type 要写入数据的类型
* @retval none
*/
int8_t flash_manage_write(flash_manage_t *flash_manage, uint8_t *pbuf, uint16_t size, uint8_t frame_type)
{
uint8_t buff[size + 5];
uint16_t len = 0;
memset(buff, 0, size + 5);
len = size + 5;
if (flash_manage->manage_sector_num == 0 || flash_manage->sector_size == 0 || flash_manage->read_flash == 0 ||
flash_manage->write_flash == 0 || flash_manage->erase_sector == 0) {
return -1;
}
if (writeable_addr > flash_manage->flash_start_address + flash_manage->manage_sector_num * flash_manage->sector_size - len || erase_flag == 1) {
erase_flag = 0;
flash_manage->erase_sector(flash_manage->flash_start_address);
writeable_addr = ALIGN_UP(flash_manage->flash_start_address, flash_manage->align_num);
/* 重置可读表 */
for (uint8_t i = 0; i < 255; i++) {
data_form[i].state = 0;
}
}
buff[0] = FLASH_READABLE_HEAD;
buff[1] = len & 0xff;
buff[2] = len >> 8 & 0xff;
buff[3] = frame_type;
buff[len - 1] = FLASH_READABLE_TAIL;
memcpy(buff + 4, pbuf, size);
flash_manage->write_flash(buff, writeable_addr, len);
if (data_form[frame_type].state == 0) {
/* 可读表为空时更新 */
data_form[frame_type].addr = writeable_addr;
data_form[frame_type].size = len;
data_form[frame_type].state = 1;
} else if (flash_manage->flash_write_mode == FLASH_OVERWRITING_MODE && data_form[frame_type].state == 1) {
/* 将flash内部上一个相同类型的数据帧头置为无效数据 */
uint8_t frame_head[flash_manage->align_num];
memset(frame_head, FLASH_NULL, flash_manage->align_num);
flash_manage->write_flash(frame_head, data_form[frame_type].addr, flash_manage->align_num);
data_form[frame_type].addr = writeable_addr;
data_form[frame_type].size = len;
}
writeable_addr = ALIGN_UP(writeable_addr + len, flash_manage->align_num);
return 1;
}