#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; 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; } 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; } } } 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; } 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; }