INT16U SSC_logdriver_read(SSC_log_def * plogcb, INT8U * pdlog, INT16U item_pos)
//读1个item, return:0 -- all FF,1 -- item_pos error,2 -- chksum error, 3 -- read ok
// item_pos <= 2*total_items - 1 and item_pos >= 0 - (total_items-1)
{
INT16U total_items = plogcb->total_items;
INT16U item_size = plogcb->item_size;
INT16U actual_size = plogcb->item_actual;
INT32U flash_off;
if(item_pos > 0x8000U)//序号为负数?
item_pos += total_items;
else if(item_pos >= total_items)
item_pos -= total_items;
if(item_pos >= total_items)
return LOG_READ_RETCODE_POS_ERR;
flash_off = plogcb->flash_start_addr + LOG_SECTOR_SIZE * (item_pos/plogcb->items_per_sector) + LOG_SECTOR_RSV_BYTES;
flash_off += ((item_pos%plogcb->items_per_sector) * item_size);
SSC_logdiver_readflash(flash_off, actual_size, pdlog);
if(isFF(pdlog, actual_size))
return LOG_READ_RETCODE_ALL_FF;
if(plogcb->chkmode == SSC_LOGDRIVER_CRC16)
{
// if(SSC_logdiver_crc16(pdlog, item_size-2) != (pdlog[item_size-2]*256U+pdlog[item_size-1]))
if(SSC_logdiver_crc16(pdlog, actual_size-2) != (pdlog[actual_size-2]*256U+pdlog[actual_size-1]))
return LOG_READ_RETCODE_CHKSUM_ERR;
}
else
{
if(SSC_logdiver_chksum(pdlog, actual_size-1) != pdlog[actual_size-1])
return LOG_READ_RETCODE_CHKSUM_ERR;
}
return LOG_READ_RETCODE_OK;
}
//保存1个item, return:next free item_pos
//item_pos >= 0 and item_pos < total_items
//compute chksum in this proc
INT16U SSC_logdriver_save(SSC_log_def * plogcb, INT8U * pslog, INT16U item_pos,u32 *seq_no)
{
INT16U total_items = plogcb->total_items,crc;
INT16U item_size = plogcb->item_size;
INT16U actual_size = plogcb->item_actual;
INT32U flash_off;
INT32U wbuf[2];
if(plogcb->chkmode == SSC_LOGDRIVER_CRC16)
{
// crc = SSC_logdiver_crc16(pslog, item_size-2);
// pslog[item_size-2] = (crc>>8);
// pslog[item_size-1] = crc;
crc = SSC_logdiver_crc16(pslog, actual_size-2);
pslog[actual_size-2] = (crc>>8);
pslog[actual_size-1] = crc;
}
else
// pslog[item_size-1] = SSC_logdiver_chksum(pslog, item_size-1);
pslog[actual_size-1] = SSC_logdiver_chksum(pslog, actual_size-1);
if(item_pos >= total_items)
item_pos = 0;
flash_off = plogcb->flash_start_addr + LOG_SECTOR_SIZE * (item_pos/plogcb->items_per_sector);
if((item_pos%plogcb->items_per_sector) == 0) //new sector 新扇区,该日志一共32个扇区
{
SSC_logdiver_eraseflash(flash_off, LOG_SECTOR_SIZE);
wbuf[0] = *seq_no;
wbuf[1] = *seq_no;//保留的8字节中存放相同的序号,用来校验。
FlashWrite(&QspiInstance,flash_off,8,(INT8U *)wbuf,WRITE_CMD);
// SSC_logdiver_writeflash(flash_off, 8, (INT8U *)wbuf);
*seq_no =*seq_no+1;
}
else
flash_off += ((item_pos%plogcb->items_per_sector) * item_size);
flash_off += LOG_SECTOR_RSV_BYTES;
FlashWrite(&QspiInstance,flash_off,actual_size,pslog,WRITE_CMD);
// SSC_logdiver_writeflash(flash_off, actual_size, pslog);
item_pos ++;
if(item_pos >= total_items)
item_pos = 0;
return item_pos;
}
//初始化,return:next free item_pos,
//若无有效item,则将pdlog内容置0,否则置为最新item
INT16U SSC_logdriver_init(SSC_log_def * plogcb, INT8U * pdlog,INT8U * USER_STRUCT,u32 *seq_no)
{
INT32U i, flash_off;
INT32U big_sector=0xffffUL, big_seq = 0;
INT32U rbuf[2];
INT16U item_size;
INT16U actual_size ;
actual_size= plogcb->item_actual;
INT16U item_start, item_end;
item_size = plogcb->item_size;//256
flash_off = plogcb->flash_start_addr;//0xA00000
for(i=0; i<plogcb->sectors; i++) //寻找最新sector plogcb->sectors 32扇区
{
SSC_logdiver_readflash(flash_off, 8, (INT8U *)rbuf);
if(rbuf[0]==rbuf[1] && rbuf[0]!=0xffffffffUL)
{
if(rbuf[0] >= big_seq)
{
big_seq = rbuf[0];
big_sector = i;
}
}
flash_off += LOG_SECTOR_SIZE;
}
if(big_sector == 0xffffUL) //没找到有效sector
{
setmem_0(pdlog,item_size);
return 0;
}
if(*seq_no <= big_seq)
*seq_no = big_seq + 1;
//二分法寻找最新item
flash_off = plogcb->flash_start_addr + big_sector*LOG_SECTOR_SIZE + LOG_SECTOR_RSV_BYTES;
item_start = 0;
item_end = plogcb->items_per_sector;
while(item_start < item_end)
{
if(item_start ==(item_end-1))
i = item_end;
else
i = (item_start + item_end)/2;
SSC_logdiver_readflash(flash_off + i*item_size, actual_size, pdlog);
if(isFF(pdlog, actual_size))
item_end = i-1;
else
item_start = i;
}
big_seq = big_sector * plogcb->items_per_sector + item_start; //item_pos --> free item
SSC_logdiver_readflash(flash_off + item_start*item_size, actual_size, pdlog);
if(!isFF(pdlog, actual_size))
big_seq++;
for(i=0; i<8; i++)
{
if(SSC_logdriver_read(plogcb, pdlog, big_seq-i-1)==LOG_READ_RETCODE_OK)
{
sdn_memcpy(pdlog+2,USER_STRUCT, plogcb->item_actual);
return big_seq;
}
}
setmem_0(pdlog,actual_size);
return 0;//big_seq;
}
zynq-flash滚动存储日志信息——bug修改
最新推荐文章于 2024-09-14 08:21:25 发布