BCU/library/bsp/bsp_fdb.c

160 lines
5.1 KiB
C
Raw Normal View History

2025-02-06 15:08:48 +08:00
#include "bsp_fdb.h"
#include "bsp_head.h"
#include "kit_data.h"
#include "kit_debug.h"
#define FDB_HEAD_FREE_MARK (0xFFFFFFFF)
#define FDB_HEAD_VALID_MARK (0xEEEEEEEE)
#define FDB_DATA_MARK (0x5A5A5A5A)
//数据结构 FDB_DATA_MARK(4Byte) + 数据索引(2Byte) + 数据长度(2Byte) + 数据(N Byte)
void bsp_fdb_init(FdbItem *item)
{
uint32_t i, idx, tmp;
if(ARM_READ_INT32U(item->main_area) != FDB_HEAD_VALID_MARK)
{
//可能为旧modbus模型
tmp = ARM_READ_INT16U(item->main_area);
if((tmp < 10 * 1024) && kit_check_crc16((uint8_t *)item->main_area, tmp) == 0)
{
if(ARM_READ_INT32U(item->sub_area) != FDB_HEAD_FREE_MARK)
{
drv_flash_series_erase_page(item->sub_area, 1);
}
drv_drv_flash_write_u32(item->sub_area, FDB_HEAD_VALID_MARK);
drv_drv_flash_write_u32(item->sub_area + 4, FDB_DATA_MARK);
if(tmp % 4 != 0)
{
tmp += 4 - (tmp % 4);
}
drv_drv_flash_write_u32(item->sub_area + 8, ((tmp + 8) << 16) | 0x0A);
drv_bsp_flash_write_data_u32(item->sub_area + 12, (uint8_t *)item->main_area, tmp);
drv_flash_series_erase_page(item->main_area, 1);
drv_bsp_flash_write_data_u32(item->main_area, (uint8_t *)item->sub_area, tmp + 12);
item->write_addr = item->main_area + tmp + 12;
item->data_addr[9] = item->main_area + 12;
}
//第一次存储
else
{
drv_flash_series_erase_page(item->main_area, 1);
drv_flash_series_erase_page(item->sub_area, 1);
drv_drv_flash_write_u32(item->main_area, FDB_HEAD_VALID_MARK);
item->write_addr = item->main_area + 4;
}
}
else
{
tmp = item->main_area + item->area_size;
for(i = item->main_area + 4; i < tmp; )
{
if(ARM_READ_INT32U(i) == FDB_DATA_MARK)
{
idx = ARM_READ_INT16U(i + 4);
if(idx < item->data_cnt)
{
item->data_addr[idx] = i + 8;
i += ARM_READ_INT16U(i + 6);
continue;
}
}
else if(ARM_READ_INT32U(i) == FDB_HEAD_FREE_MARK)
{
break;
}
i += 4;
}
item->write_addr = i;
}
}
bool bsp_fdb_write_data(FdbItem *item, uint8_t data_idx, uint8_t *buf, uint16_t len)
{
kit_ret_e res = kKit_Ret_Ok;
uint32_t i, tmp, addr;
if((item != NULL) && (data_idx < item->data_cnt) && (item->write_addr != NULL))
{
if(len % 4 != 0)
{
len += 4 - (len % 4);
}
if(item->write_addr + len + 4 + 4 >= item->main_area + item->area_size)
{
if(ARM_READ_INT32U(item->sub_area) != FDB_HEAD_FREE_MARK)
{
res |= drv_flash_series_erase_page(item->sub_area, 1);
}
addr = item->sub_area;
res |= drv_drv_flash_write_u32(addr, FDB_HEAD_VALID_MARK);
addr += 4;
//将数据零时搬到副页
for(i = 0; i < item->data_cnt; i++)
{
if((i != data_idx) && (item->data_addr[i] != NULL))
{
tmp = ARM_READ_INT16U(item->data_addr[i] - 2);
drv_bsp_flash_write_data_u32(addr, (uint8_t *)(item->data_addr[i] - 8), tmp);
item->data_addr[i] = item->main_area + (addr - item->sub_area + 8);
addr += tmp;
}
}
//换完页后擦除主页
res |= drv_flash_series_erase_page(item->main_area, 1);
//将数据搬回主页
tmp = 0;
if((addr > item->sub_area) && ((addr - item->sub_area) < item->area_size))
{
tmp = addr - item->sub_area;
}
drv_bsp_flash_write_data_u32(item->main_area, (uint8_t *)item->sub_area, tmp);
item->write_addr = item->main_area + tmp;
}
res |= drv_drv_flash_write_u32(item->write_addr, FDB_DATA_MARK);
item->write_addr += 4;
tmp = data_idx | ((len + 8) << 16);
res |= drv_drv_flash_write_u32(item->write_addr, tmp);
item->write_addr += 4;
item->data_addr[data_idx] = item->write_addr;
res |= drv_bsp_flash_write_data_u32(item->write_addr, buf, len);
item->write_addr += len;
}
return (res == kKit_Ret_Ok);
}
uint16_t bsp_fdb_read_data(FdbItem *item, uint8_t data_idx, uint8_t *buf)
{
uint16_t len = 0;
if((item != NULL) && (data_idx < item->data_cnt) && (item->data_addr[data_idx] != NULL))
{
len = ARM_READ_INT16U(item->data_addr[data_idx] + 6) - 8;
kit_copy_buf(buf, (void *)(item->data_addr[data_idx] + 8), len);
}
return len;
}
uint32_t bsp_fdb_get_data_addr(FdbItem *item, uint8_t data_idx)
{
uint32_t addr = NULL;
if((item != NULL) && (data_idx < item->data_cnt))
{
addr = item->data_addr[data_idx];
}
return addr;
}