实现接口说明CRC校验接口,可以自定义实现。
/* 16位CRC校验高位表 */
static const uint8_t auchCRCHi[]={
0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,
0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40,0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,
0x00,0xc1,0x81,0x40,0x01,0xc0,0x80,0x41,0x01,0xc0,0x80,0x41,0x00,0xc1,0x81,0x40
};
/* 16位CRC校验低位表 */
static const uint8_t auchCRCLo[]={
0x00,0xc0,0xc1,0x01,0xc3,0x03,0x02,0xc2,0xc6,0x06,0x07,0xc7,0x05,0xc5,0xc4,0x04,
0xcc,0x0c,0x0d,0xcd,0x0f,0xcf,0xce,0x0e,0x0a,0xca,0xcb,0x0b,0xc9,0x09,0x08,0xc8,
0xd8,0x18,0x19,0xd9,0x1b,0xdb,0xda,0x1a,0x1e,0xde,0xdf,0x1f,0xdd,0x1d,0x1c,0xdc,
0x14,0xd4,0xd5,0x15,0xd7,0x17,0x16,0xd6,0xd2,0x12,0x13,0xd3,0x11,0xd1,0xd0,0x10,
0xf0,0x30,0x31,0xf1,0x33,0xf3,0xf2,0x32,0x36,0xf6,0xf7,0x37,0xf5,0x35,0x34,0xf4,
0x3c,0xfc,0xfd,0x3d,0xff,0x3f,0x3e,0xfe,0xfa,0x3a,0x3b,0xfb,0x39,0xf9,0xf8,0x38,
0x28,0xe8,0xe9,0x29,0xeb,0x2b,0x2a,0xea,0xee,0x2e,0x2f,0xef,0x2d,0xed,0xec,0x2c,
0xe4,0x24,0x25,0xe5,0x27,0xe7,0xe6,0x26,0x22,0xe2,0xe3,0x23,0xe1,0x21,0x20,0xe0,
0xa0,0x60,0x61,0xa1,0x63,0xa3,0xa2,0x62,0x66,0xa6,0xa7,0x67,0xa5,0x65,0x64,0xa4,
0x6c,0xac,0xad,0x6d,0xaf,0x6f,0x6e,0xae,0xaa,0x6a,0x6b,0xab,0x69,0xa9,0xa8,0x68,
0x78,0xb8,0xb9,0x79,0xbb,0x7b,0x7a,0xba,0xbe,0x7e,0x7f,0xbf,0x7d,0xbd,0xbc,0x7c,
0xb4,0x74,0x75,0xb5,0x77,0xb7,0xb6,0x76,0x72,0xb2,0xb3,0x73,0xb1,0x71,0x70,0xb0,
0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92,0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,
0x9c,0x5c,0x5d,0x9d,0x5f,0x9f,0x9e,0x5e,0x5a,0x9a,0x9b,0x5b,0x99,0x59,0x58,0x98,
0x88,0x48,0x49,0x89,0x4b,0x8b,0x8a,0x4a,0x4e,0x8e,0x8f,0x4f,0x8d,0x4d,0x4c,0x8c,
0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,0x43,0x83,0x41,0x81,0x80,0x40
};
/* 实现crc功能函数 */
static uint16_t CRC16(uint8_t* puchMsg, uint16_t usDataLen)
{
uint8_t uchCRCHi=0xff;
uint8_t uchCRCLo=0xff;
uint16_t uIndex;
while(usDataLen--) {
uIndex=uchCRCHi^*(puchMsg++);
uchCRCHi=uchCRCLo^auchCRCHi[uIndex];
uchCRCLo=auchCRCLo[uIndex];
}
return uchCRCHi<<8|uchCRCLo;
}
保存系统日志参数,每实现写日志操作后都需要保存当前的参数值,防止意外丢失。void save_system_log_param(void)
{
uint32_t i = 0;
uint32_t addr = 0;
uint32_t remainbyte = 0;
uint32_t start_addr;
int len = sizeof(sys_log_param_t);
uint8_t *pdata = (uint8_t *)&SysLogParam;
flash_table_t *flash_tmp = get_flash_table(FLASH_SYSLOG_PARA_ZONE);
/* 校验参数 */
gp_sys_log->crc_val.magic = SYSTEM_LOG_MAGIC_PARAM;
gp_sys_log->crc_val.len = sizeof(sys_log_param_t) - sizeof(single_sav_t);
gp_sys_log->crc_val.crc = CRC16(&pdata[sizeof(single_sav_t)], gp_sys_log->crc_val.len);
start_addr = gp_sys_ram->system_log_param_addr;
/* 剩余内存不够写,则重新从起始地址开始写,实现环形存储功能 */
if ((start_addr + len) > flash_tmp->end_address) {
start_addr = flash_tmp->start_address;
}
gp_sys_ram->system_log_param_addr = start_addr + len;
/* 首地址存储,擦除整个系统日志参数存储区,如果划分的内存较大,可能出现第一次擦写等待时间较长,
但实际应用嵌入式设备应该不会占用太多的内存存储系统日志,只当为辅助使用,有额外应用可自行实现 */
if (flash_tmp->start_address == start_addr) {
/*for (i = flash_tmp->start_address; i < flash_tmp->end_address; i+= FLASH_SECTOR_SIZE)
flash_erase(FLASH_SYSLOG_PARA_ZONE, SECTOR_BASE(i), FLASH_BLOCK_4K);
*/
addr = flash_tmp->start_address;
do {
if ((addr + FLASH_BLOCK_64K_SIZE) <= flash_tmp->end_address) {
flash_erase(FLASH_SYSLOG_PARA_ZONE, BLOCK_64K_BASE(i), FLASH_BLOCK_64K);
addr += FLASH_BLOCK_64K_SIZE;
} else if ((addr + FLASH_BLOCK_32K_SIZE) <= flash_tmp->end_address) {
flash_erase(FLASH_SYSLOG_PARA_ZONE, BLOCK_32K_BASE(i), FLASH_BLOCK_32K);
addr += FLASH_BLOCK_32K_SIZE;
} else if ((addr + FLASH_SECTOR_SIZE) <= flash_tmp->end_address) {
flash_erase(FLASH_SYSLOG_PARA_ZONE, SECTOR_BASE(i), FLASH_BLOCK_4K);
addr += FLASH_SECTOR_SIZE;
} else {
break;
}
} while (addr < flash_tmp->end_address);
}
remainbyte = FLASH_SECTOR_SIZE - (start_addr % FLASH_SECTOR_SIZE);
if (remainbyte > len) {
remainbyte = len;
}
while (1) {
flash_write(FLASH_SYSLOG_PARA_ZONE, start_addr, pdata, remainbyte);
if (remainbyte == len) {
break;
} else {
pdata += remainbyte;
start_addr += remainbyte;
len -= remainbyte;
remainbyte = (len > FLASH_SECTOR_SIZE) ? FLASH_SECTOR_SIZE : len;
}
}
}
导入系统日志默认参数接口,初始化默认参数或者移除日志。
void load_system_log_default_param(void)
{
/* 系统日志默认参数 */
/* 目录环写状态标志 */
gp_sys_log->system_log.catalog_cyclic_status = 0x00;
/* 目录项个数 */
gp_sys_log->system_log.catalog_num = 0;
/* 日志环写标志 , 1:环写状态 */
gp_sys_log->system_log.log_cyclic_status = 0;
/* 设置默认值,实际会重新从RTC获取最新时间 */
gp_sys_log->system_log.log_latest_time.Year = 2019;
gp_sys_log->system_log.log_latest_time.Month = 5;
gp_sys_log->system_log.log_latest_time.Day = 8;
gp_sys_log->system_log.log_latest_time.Hour = 13;
gp_sys_log->system_log.log_latest_time.Minute = 14;
gp_sys_log->system_log.log_latest_time.Second = 10;
/* 日志写位置从0开始 */
gp_sys_log->system_log.write_pos = 0;
gp_sys_log->system_catalog.log_addr = 0;
gp_sys_log->system_catalog.log_id = 0;
gp_sys_log->system_catalog.log_offset = 0;
gp_sys_log->system_catalog.log_time.Year = 2019;
gp_sys_log->system_catalog.log_time.Month = 5;
gp_sys_log->system_catalog.log_time.Day = 8;
gp_sys_log->system_catalog.log_time.Hour = 12;
gp_sys_log->system_catalog.log_time.Minute = 12;
gp_sys_log->system_catalog.log_time.Second = 14;
gp_sys_log->crc_val.magic = SYSTEM_LOG_MAGIC_PARAM;
/* 导入默认参数后进行保存 */
save_system_log_param();
}
|