160 lines
5.1 KiB
C
160 lines
5.1 KiB
C
#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;
|
|
}
|
|
|
|
|