You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

543 lines
18 KiB

#include "zeeprom_fs.h"
#include "one_conduction_board.h"
static zeeprom_header_t m_eeprom_header;
static bool m_is_init = false;
static filehandler_t m_filehandler[2];
static int m_fd_off;
/*******************************************************************************
* 函数声明 *
*******************************************************************************/
static filehandler_t* filehandler_find(int fd);
static filehandler_t* filehandler_alloc();
static void filehandler_rlease(int fd);
static int32_t sector_mgr_find_earliest_file_created_index();
static int32_t sector_mgr_free_sector(int32_t fileuuid);
static zeeprom_sector_info_t* sector_mgr_find_idle_sector();
static bool sector_mgr_sector_is_open(int32_t fileuuid);
static zeeprom_sector_info_t* sector_mgr_force_find_idle_sector();
static void sector_mgr_open_sector(int32_t fileuuid);
static void sector_mgr_close_sector(int32_t fileuuid);
// static zeeprom_sector_info_t* sector_mgr_find_fileheader(int32_t fileuuid);
static zeeprom_sector_info_t* sector_mgr_find_end_sector(int32_t fileuuid);
static zeeprom_sector_info_t* sector_mgr_find_sector(int32_t fileuuid, int32_t sector_index_in_file);
static int32_t sector_mgr_file_get_size(int32_t fileuuid);
static zeeprom_sector_info_t* sector_mgr_find_fileheader_by_filename(uint8_t* fileid);
static int32_t sector_mgr_get_sector_offset(zeeprom_sector_info_t* sector);
static int32_t sector_mgr_get_sector_rom_add(zeeprom_sector_info_t* sector);
static void zeeprom_read(int32_t add, uint8_t* data, uint16_t len);
static void zeeprom_write(int32_t add, const uint8_t* data, uint16_t len);
static int32_t compute_checksum(uint8_t* data, uint16_t len);
/*******************************************************************************
* CODE *
*******************************************************************************/
static bool m_eeprom_header_inited = false;
int zeeprom_fs_init() { //
SingleLeadECG_eeprom_init();
if (!m_eeprom_header_inited) {
zeeprom_read(0, (uint8_t*)&m_eeprom_header, sizeof(m_eeprom_header));
int32_t checksum_val = compute_checksum((uint8_t*)&m_eeprom_header, sizeof(m_eeprom_header) - sizeof(m_eeprom_header.checksum));
if (checksum_val != m_eeprom_header.checksum) {
memset(&m_eeprom_header, 0, sizeof(m_eeprom_header));
}
}
m_is_init = true;
m_eeprom_header_inited = true;
return 0;
}
int zeeprom_fs_uinit() { //
// zeeprom_write(0, (uint8_t*)&m_eeprom_header, sizeof(m_eeprom_header));
SingleLeadECG_eeprom_uninit();
m_is_init = false;
return 0;
}
zeeprom_header_t* zeeprom_fs_get_header() { return &m_eeprom_header; }
int zeeprom_fs_open(uint8_t* filename, wrflag_t wrflag) {
ZASSERT(m_is_init);
/**
* @brief
* 1. 如果文件已经存在,则打开文件
* 2. 如果文件不存在, 则创建文件
*
* 创建文件:
* 1. 找到一个空闲扇区
* 2. 初始化文件头
*/
filehandler_t* fileHander = filehandler_alloc();
if (!fileHander) {
ZLOGI("fileHander_alloc fail");
return -1;
}
if (wrflag == kwrflag_write_only) {
/*******************************************************************************
* 写文件 *
*******************************************************************************/
zeeprom_sector_info_t* sectorHeaderInfo = NULL;
zeeprom_fs_delete_by_name(filename);
sectorHeaderInfo = sector_mgr_force_find_idle_sector();
if (!sectorHeaderInfo) {
ZLOGE("sector_mgr_force_find_idle_sector fail");
filehandler_rlease(fileHander->fd);
return -1;
}
memset(sectorHeaderInfo, 0, sizeof(zeeprom_sector_info_t));
sectorHeaderInfo->usage = 1;
sectorHeaderInfo->opened = 1;
memcpy(sectorHeaderInfo->filename, filename, 8);
sectorHeaderInfo->sector_index_in_file = 0;
sectorHeaderInfo->datalen = 0;
sectorHeaderInfo->fileuuid = m_eeprom_header.fileuuid++;
fileHander->fileuuid = sectorHeaderInfo->fileuuid;
fileHander->sector_header = sectorHeaderInfo;
fileHander->file_offset = 0;
fileHander->file_size = 0;
return fileHander->fd;
} else {
/*******************************************************************************
* 读文件 *
*******************************************************************************/
zeeprom_sector_info_t* sectorHeaderInfo = sector_mgr_find_fileheader_by_filename(filename);
if (sectorHeaderInfo) {
fileHander->fileuuid = sectorHeaderInfo->fileuuid;
fileHander->file_offset = 0;
fileHander->fd = fileHander->fd;
fileHander->sector_header = sectorHeaderInfo;
fileHander->file_size = sector_mgr_file_get_size(fileHander->fileuuid);
memcpy(fileHander->filename, filename, 8);
memcpy(fileHander->usrdata, sectorHeaderInfo->usrdata, sizeof(sectorHeaderInfo->usrdata));
sector_mgr_open_sector(fileHander->fileuuid);
return fileHander->fd;
} else {
filehandler_rlease(fileHander->fd);
return -1;
}
}
}
int zeeprom_fs_write(int fileid, const uint8_t* data, int32_t size) {
ZASSERT(m_is_init);
filehandler_t* fileHander = NULL;
zeeprom_sector_info_t* header_sinfo = NULL;
zeeprom_sector_info_t* endsector = NULL;
int32_t wadd = 0;
ZASSERT(size == 256);
fileHander = filehandler_find(fileid);
if (!fileHander) {
ZLOGE("fileHander_find fail");
return -1;
}
header_sinfo = fileHander->sector_header;
if (!header_sinfo) {
ZLOGE("header_sinfo fail");
return -1;
}
endsector = sector_mgr_find_end_sector(fileHander->fileuuid);
if (!endsector) {
ZLOGE("sector_mgr_find_end_sector fail");
return -1;
}
if (endsector->datalen + size > EEPROM_SECTOR_SIZE) {
ZLOGE("endsector->datalen + size > EEPROM_SECTOR_SIZE");
return -1;
}
wadd = sector_mgr_get_sector_rom_add(endsector);
if (wadd < 0) {
ZLOGE("sector_mgr_get_sector_rom_add fail");
return -1;
}
ZASSERT(wadd % 256 == 0);
ZASSERT(wadd >= EEPROM_SECTOR_SIZE);
zeeprom_write(wadd + endsector->datalen, data, size);
endsector->datalen = endsector->datalen + size;
fileHander->file_offset += size;
fileHander->file_size += size;
if (endsector->datalen == EEPROM_SECTOR_SIZE) {
zeeprom_sector_info_t* newsector = sector_mgr_force_find_idle_sector();
if (!newsector) {
ZLOGE("sector_mgr_force_find_idle_sector fail");
return -1;
}
memset(newsector, 0, sizeof(zeeprom_sector_info_t));
newsector->usage = 1;
newsector->opened = 1;
memcpy(newsector->filename, header_sinfo->filename, 8);
newsector->sector_index_in_file = endsector->sector_index_in_file + 1;
newsector->datalen = 0;
newsector->fileuuid = header_sinfo->fileuuid;
}
return size;
}
int zeeprom_fs_close(int fileid) {
ZASSERT(m_is_init);
filehandler_t* fileHander = filehandler_find(fileid);
if (!fileHander) {
ZLOGE("zeeprom_fs_close fileHander_find fail");
return -1;
}
sector_mgr_close_sector(fileHander->fileuuid);
int32_t checksum_val = compute_checksum((uint8_t*)&m_eeprom_header, sizeof(m_eeprom_header) - sizeof(m_eeprom_header.checksum));
m_eeprom_header.checksum = checksum_val;
// zeeprom_write(0, (uint8_t*)&m_eeprom_header, sizeof(m_eeprom_header));
filehandler_rlease(fileid);
return 0;
}
int zeeprom_fs_get_filesize_by_fd(int fd) {
ZASSERT(m_is_init);
filehandler_t* fileHander = filehandler_find(fd);
if (!fileHander) return 0;
return fileHander->file_size;
}
int zeeprom_fs_read(int fileid, uint8_t* data, int32_t size) {
ZASSERT(m_is_init);
/**
* @brief
* 找到当前扇区
*/
ZASSERT(size == 256);
filehandler_t* fileHander = filehandler_find(fileid);
if (!fileHander) return -1;
zeeprom_sector_info_t* header_sinfo = fileHander->sector_header;
if (!header_sinfo) {
return -1;
}
int32_t sector_idx = fileHander->file_offset / EEPROM_SECTOR_SIZE;
int32_t sector_off = fileHander->file_offset % EEPROM_SECTOR_SIZE;
zeeprom_sector_info_t* sector = sector_mgr_find_sector(fileHander->fileuuid, sector_idx);
if (!sector) {
return -1;
}
int32_t radd = sector_mgr_get_sector_rom_add(sector);
ZASSERT(radd % 256 == 0);
radd += sector_off;
zeeprom_read(radd, data, size);
fileHander->file_offset += size;
return size;
}
int zeeprom_fs_delete(int32_t fileuuid) {
ZASSERT(m_is_init);
sector_mgr_free_sector(fileuuid);
return 0;
}
int zeeprom_fs_delete_by_name(uint8_t* filename) {
ZASSERT(m_is_init);
zeeprom_sector_info_t* sectorHeaderInfo = sector_mgr_find_fileheader_by_filename(filename);
if (sectorHeaderInfo) {
sector_mgr_free_sector(sectorHeaderInfo->fileuuid);
}
return 0;
}
int zeeprom_fs_get_file_num() {
ZASSERT(m_is_init);
int count = 0;
for (int i = 0; i < MAX_SECTOR_NUM; i++) {
zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
if (sinfo->usage == 1 && sinfo->sector_index_in_file == 0) {
count++;
}
}
return count;
}
int zeeprom_fs_delete_the_oldest_file() {
ZASSERT(m_is_init);
int32_t earliest_file_created_index = sector_mgr_find_earliest_file_created_index();
sector_mgr_free_sector(earliest_file_created_index);
return 0;
}
int zeeprom_fs_get_filesize_by_fileuuid(int32_t fileuuid) {
ZASSERT(m_is_init);
return sector_mgr_file_get_size(fileuuid);
}
static void zeeprom_read(int32_t add, uint8_t* data, uint16_t len) { //
int wrsize = EEPROM_SECTOR_MIN_WR_SIZE;
int readTimes = len / wrsize;
int readRemain = len % wrsize;
for (int i = 0; i < readTimes; i++) {
SingleLeadECG_eeprom_read(add + i * wrsize, data + i * wrsize, wrsize);
}
if (readRemain > 0) {
SingleLeadECG_eeprom_read(add + readTimes * wrsize, data + readTimes * wrsize, readRemain);
}
}
static void zeeprom_write(int32_t add, const uint8_t* data, uint16_t len) {
int wrsize = EEPROM_SECTOR_MIN_WR_SIZE;
int writeTimes = len / wrsize;
int writeRemain = len % wrsize;
for (int i = 0; i < writeTimes; i++) {
// int pageoff = add / wrsize + i;
int32_t writeadd = add + i * wrsize;
SingleLeadECG_eeprom_write(writeadd, data + i * wrsize, wrsize);
}
if (writeRemain > 0) {
int32_t writeadd = add + writeTimes * wrsize;
SingleLeadECG_eeprom_write(writeadd, data + writeTimes * wrsize, writeRemain);
}
}
static int32_t compute_checksum(uint8_t* data, uint16_t len) {
int32_t sum = 0;
for (int i = 0; i < len; i++) {
sum += data[i];
}
return sum;
}
/*******************************************************************************
* filehandler *
*******************************************************************************/
static filehandler_t* filehandler_find(int fd) {
for (int i = 0; i < ZARRAY_SIZE(m_filehandler); i++) {
if (m_filehandler[i].fd == fd) {
return &m_filehandler[i];
}
}
return NULL;
}
static filehandler_t* filehandler_alloc() {
for (int i = 0; i < ZARRAY_SIZE(m_filehandler); i++) {
if (m_filehandler[i].fd == 0) {
m_filehandler[i].fd = ++m_fd_off;
return &m_filehandler[i];
}
}
return NULL;
}
static void filehandler_rlease(int fd) {
for (int i = 0; i < ZARRAY_SIZE(m_filehandler); i++) {
if (m_filehandler[i].fd == fd) {
m_filehandler[i].fd = 0;
return;
}
}
}
/*******************************************************************************
* sector_mgr *
*******************************************************************************/
// 查找最早创建的文件的file_created_index
static int32_t sector_mgr_find_earliest_file_created_index() {
int32_t earliest_file_created_index = INT32_MAX;
for (int i = 0; i < MAX_SECTOR_NUM; i++) {
zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
if (sinfo->usage == 1) {
if (sinfo->fileuuid < earliest_file_created_index) {
earliest_file_created_index = sinfo->fileuuid;
}
}
}
return earliest_file_created_index;
}
// 删除文件
static int32_t sector_mgr_free_sector(int32_t fileuuid) {
for (int i = 0; i < MAX_SECTOR_NUM; i++) {
zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
if (sinfo->usage == 1 && sinfo->fileuuid == fileuuid) {
sinfo->usage = 0;
}
}
return 0;
}
//
static zeeprom_sector_info_t* sector_mgr_find_idle_sector() {
for (int i = 0; i < MAX_SECTOR_NUM; i++) {
zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
if (sinfo->usage == 0) {
return sinfo;
}
}
return NULL;
}
static bool sector_mgr_sector_is_open(int32_t fileuuid) {
for (int i = 0; i < MAX_SECTOR_NUM; i++) {
zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
if (sinfo->usage == 1 && sinfo->fileuuid == fileuuid) {
return sinfo->opened;
}
}
return false;
}
static zeeprom_sector_info_t* sector_mgr_force_find_idle_sector() {
/**
* @brief 查找空闲扇区
*/
zeeprom_sector_info_t* ret_sinfo = sector_mgr_find_idle_sector();
if (ret_sinfo) return ret_sinfo;
/**
* @brief 查找最早创建的文件
*/
int32_t earliest_file_created_index = sector_mgr_find_earliest_file_created_index();
if (sector_mgr_sector_is_open(earliest_file_created_index)) {
return NULL;
}
/**
* @brief 删除最早创建的文件
*/
sector_mgr_free_sector(earliest_file_created_index);
/**
* @brief 重新查找空闲扇区
*/
ret_sinfo = sector_mgr_find_idle_sector();
if (ret_sinfo) return ret_sinfo;
return NULL;
}
static void sector_mgr_open_sector(int32_t fileuuid) {
for (int i = 0; i < MAX_SECTOR_NUM; i++) {
zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
if (sinfo->usage == 1 && sinfo->fileuuid == fileuuid) {
sinfo->opened = true;
}
}
}
static void sector_mgr_close_sector(int32_t fileuuid) {
for (int i = 0; i < MAX_SECTOR_NUM; i++) {
zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
if (sinfo->usage == 1 && sinfo->fileuuid == fileuuid) {
sinfo->opened = false;
}
}
}
// static zeeprom_sector_info_t* sector_mgr_find_fileheader(int32_t fileuuid) {
// for (int i = 0; i < MAX_SECTOR_NUM; i++) {
// zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
// if (sinfo->usage == 1 && sinfo->sector_index_in_file == 0 && sinfo->fileuuid == fileuuid) {
// return sinfo;
// }
// }
// return NULL;
// }
static zeeprom_sector_info_t* sector_mgr_find_sector(int32_t fileuuid, int32_t sector_index_in_file) {
for (int i = 0; i < MAX_SECTOR_NUM; i++) {
zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
if (sinfo->usage == 1 && sinfo->sector_index_in_file == sector_index_in_file && sinfo->fileuuid == fileuuid) {
return sinfo;
}
}
return NULL;
}
static zeeprom_sector_info_t* sector_mgr_find_end_sector(int32_t fileuuid) {
int32_t maxsectorindex = 0;
for (int i = 0; i < MAX_SECTOR_NUM; i++) {
zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
if (sinfo->usage == 1 && sinfo->fileuuid == fileuuid) {
if (sinfo->sector_index_in_file >= maxsectorindex) {
maxsectorindex = sinfo->sector_index_in_file;
}
}
}
return sector_mgr_find_sector(fileuuid, maxsectorindex);
}
static zeeprom_sector_info_t* sector_mgr_find_fileheader_by_filename(uint8_t* fileid) {
for (int i = 0; i < MAX_SECTOR_NUM; i++) {
zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
if (sinfo->usage == 1 && sinfo->sector_index_in_file == 0 && memcmp(sinfo->filename, fileid, 8) == 0) {
return sinfo;
}
}
return NULL;
}
static int32_t sector_mgr_get_sector_offset(zeeprom_sector_info_t* sector) {
for (int i = 0; i < MAX_SECTOR_NUM; i++) {
zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
if (sinfo == sector) {
return i;
}
}
return -1;
}
static int32_t sector_mgr_get_sector_rom_add(zeeprom_sector_info_t* sector) {
int32_t offset = sector_mgr_get_sector_offset(sector);
if (offset < 0) return -1;
return (offset + 1) * EEPROM_SECTOR_SIZE;
}
static int32_t sector_mgr_file_get_size(int32_t fileuuid) {
int32_t filesize = 0;
for (int i = 0; i < MAX_SECTOR_NUM; i++) {
zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
if (sinfo->usage == 1 && sinfo->fileuuid == fileuuid) {
filesize += sinfo->datalen;
}
}
return filesize;
}
static const char* filename2str(uint8_t* filename) {
static char filename_str[32];
sprintf(filename_str, "%02x%02x%02x%02x%02x%02x%02x%02x", filename[0], filename[1], filename[2], filename[3], filename[4], filename[5], filename[6], filename[7]);
return filename_str;
}
int zeeprom_fs_dump_sector_state() {
ZLOGI_BLOCK("zeeprom_fs_dump_sector_state\n");
for (int i = 0; i < MAX_SECTOR_NUM; i++) {
zeeprom_sector_info_t* sinfo = &m_eeprom_header.sectorinfos[i];
if (sinfo->usage == 1) {
ZLOGI_BLOCK("[%d]: usage=%d opened=%d", i, sinfo->usage, sinfo->opened);
ZLOGI_BLOCK(" fname=%s, index_in_file=%d, datalen=%d, fileuuid=%d", filename2str(sinfo->filename), sinfo->sector_index_in_file, sinfo->datalen, sinfo->fileuuid);
} else {
ZLOGI_BLOCK("[%d]: usage=%d", i, sinfo->usage);
}
}
return 0;
}