如何记录嵌入式设备的系统日志_消息
本文将讲述一种简易的系统日志记录方法,用于保存设备的系统日志,视具体嵌入式设备情况而定,可存储在 MCU 内部Flash、外部 Flash、EEPROM等,本文采用外部 Flash 作为示例展开介绍。
(相关资料图)
对于系统日志可以当成文件系统,可以划分为三个重要部分:目录区、参数区、日志区。
目录区:根据日期进行归类,记录当天的日志的存储地址、日志索引、日志大小,通过目录可以获取整个日志文件的概况;
参数区:存储记录日志写位置、目录项个数、写状态等参数;
日志区:这是我们主要的存储区,记录系统的日志,支持环写。
这三个区域都需要占用部分内存,可以自行分配大小。
查询系统日志目录:AT+CATALOG?
LOG_ID: 存储日志按日期分类,该ID用于查询对应日期日志,从1开始计数;
LOG_DATE: 系统日志存储日期;
LOG_ADDR: 系统日志存储外部FLASH地址;
查询指定日期系统日志:AT+CATALOG=
LOG_ID:在查询系统日志目录时获取,当LOG_ID为 0 时,为查询整个系统日志。
另外提供移除系统日志(清除日志目录)指令:AT+RMLOG,后面将讲述具体实现。
FLASH内存需要看具体设备进行合理划分,目录区、参数区与日志区实现环形存储,延长擦写寿命。
#defineFLASH_SECTOR_SIZE((uint32_t)0x001000)#defineFLASH_BLOCK_32K_SIZE((uint32_t)0x008000)#defineFLASH_BLOCK_64K_SIZE((uint32_t)0x010000)#defineSECTOR_MASK(FLASH_SECTOR_SIZE-1)/*扇区掩码------*/#defineSECTOR_BASE(addr)(addr&(~SECTOR_MASK))/*扇区的基地址--*/#defineSECTOR_OFFSET(addr)(addr&SECTOR_MASK)/*扇区内的偏移--*/#defineBLOCK_32K_BASE(addr)(addr&(~(FLASH_BLOCK_32K_SIZE)))#defineBLOCK_64K_BASE(addr)(addr&(~(FLASH_BLOCK_64K_SIZE)))typedefenum{FLASH_BLOCK_4K=0,/**Flash底层实现擦除、读写操作接口,由读者自行实现。
flash_table_t*get_flash_table(flash_zone_ezone){inti=0;for(i=0;istart_address||address>flash_table_tmp->end_address)return-1;returnbsp_spi_flash_erase(address,block_type);}intflash_write(flash_zone_ezone,uint32_taddress,constuint8_t*data,uint32_tlength){flash_table_t*flash_table_tmp=get_flash_table(zone);if(flash_table_tmp==NULL)return-1;if((addressstart_address)||((address+length)>flash_table_tmp->end_address))return-1;returnbsp_spi_flash_buffer_write(address,(uint8_t*)data,length);}intflash_read(flash_zone_ezone,uint32_taddress,uint8_t*buffer,uint32_tlength){flash_table_t*flash_table_tmp=get_flash_table(zone);if(flash_table_tmp==NULL)return-1;if((addressstart_address)||((address+length)>flash_table_tmp->end_address))return-1;bsp_spi_flash_buffer_read(buffer,address,length);return0;} typedefstruct{uint16_tYear;/*年份:YYYY*/uint8_tMonth;/*月份:MM*/uint8_tDay;/*日:DD*/uint8_tHour;/*小时:HH*/uint8_tMinute;/*分钟:MM*/uint8_tSecond;/*秒:SS*/}time_t;intbsp_rtc_get_time(time_t*date);#defineSYSTEM_LOG_MAGIC_PARAM0x87654321/*日志参数标识符*/typedefstruct{uint32_tmagic;/*参数标识符*/uint16_tcrc; /*校验值*/uint16_tlen; /*参数长度*/}single_sav_t;参数区需记录当前日志记录的写位置,以及目录项个数,还有日志区和目录区环写状态,并且存储最新时间等等。
/*日志区参数*/typedefstruct{uint32_twrite_pos;/*写位置*/uint32_tcatalog_num;/*目录项个数*/uint8_tlog_cyclic_status;/*系统日志环形写状态*/uint8_tcatalog_cyclic_status;/*日志目录环形写状态*/time_tlog_latest_time;/*存储最新时间*/}system_log_t;/*目录区参数*/typedefstruct{uint32_tlog_id;/*日志索引*/uint32_tlog_addr;/*日志地址*/uint32_tlog_offset;/*日志偏移大小,单位:字节*/time_tlog_time;/*日志存储时间*/}system_catalog_t;/*系统日志参数*/typedefstruct{single_sav_tcrc_val;system_log_tsystem_log;system_catalog_tsystem_catalog;}sys_log_param_t;typedefstruct{uint8_tsystem_log_print_enable;/*系统日志打印使能*/uint16_tsystem_log_print_id;/*打印指定id系统日志*/uint32_tsystem_log_param_addr;/*当前日志写地址*/}sys_ram_t;sys_ram_tSysRam;sys_log_param_tSysLogParam;sys_ram_t*gp_sys_ram=&SysRam;sys_log_param_t*gp_sys_log=&SysLogParam;/*16位CRC校验高位表*/staticconstuint8_tauchCRCHi[]={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校验低位表*/staticconstuint8_tauchCRCLo[]={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功能函数*/
staticuint16_tCRC16(uint8_t*puchMsg,uint16_tusDataLen)
{uint8_tuchCRCHi=0xff;uint8_tuchCRCLo=0xff;uint16_tuIndex;while(usDataLen--){uIndex=uchCRCHi^*(puchMsg++);uchCRCHi=uchCRCLo^auchCRCHi[uIndex];uchCRCLo=auchCRCLo[uIndex];}returnuchCRCHi<<8|uchCRCLo;}
保存系统日志参数,每实现写日志操作后都需要保存当前的参数值,防止意外丢失。
voidsave_system_log_param(void){uint32_ti=0;uint32_taddr=0;uint32_tremainbyte=0;uint32_tstart_addr;intlen=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;iend_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;}elseif((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;}elseif((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(addrend_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;}}} 导入系统日志默认参数接口,初始化默认参数或者移除日志。
voidload_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();}/*参数初始化,在终端启动时调用*/intload_system_log_param(void){uint32_ti=0;single_sav_tpsav;uint32_tend_addr;uint32_tinteral=sizeof(sys_log_param_t);intdata_len=sizeof(sys_log_param_t)-sizeof(single_sav_t);uint8_t*pram=(uint8_t*)&SysLogParam;flash_table_t*flash_tmp=get_flash_table(FLASH_SYSLOG_PARA_ZONE);end_addr=flash_tmp->end_address-(flash_tmp->end_address-flash_tmp->start_address)%interal;for(i=end_addr-interal;i>flash_tmp->start_address;i-=interal){flash_read(FLASH_SYSLOG_PARA_ZONE,i,(uint8_t*)&psav,sizeof(single_sav_t));if((psav.magic==SYSTEM_LOG_MAGIC_PARAM)&&(psav.len==data_len)){flash_read(FLASH_SYSLOG_PARA_ZONE,i+sizeof(single_sav_t),&pram[sizeof(single_sav_t)],data_len);if(psav.crc!=CRC16(&pram[sizeof(single_sav_t)],data_len))continue;gp_sys_ram->system_log_param_addr=i;log_info("LoadSystemLogParamAddr[0x%08x]!",gp_sys_ram->system_log_param_addr);return0;}}/*扫描不到合法的参数,导入默认系统日志参数*/load_system_log_default_param();/*获取日志写地址*/gp_sys_ram->system_log_param_addr=flash_tmp->start_address;log_info("LoadSystemLogParamAddr(Default)[0x%08x]!",gp_sys_ram->system_log_param_addr);return1;}/*读取日志目录区指定日志索引目录信息*/intsystem_catalog_read(system_catalog_t*catalog,uint32_tid){uint32_taddr;intrlen=sizeof(system_catalog_t);uint8_t*pbuf=(uint8_t*)catalog;flash_table_t*flash_tmp=get_flash_table(FLASH_CATALOG_ZONE);if(0==id)return-1;addr=flash_tmp->start_address+(rlen*(id-1));if(addr>flash_tmp->end_address)return-1;returnflash_read(FLASH_CATALOG_ZONE,addr,pbuf,rlen);}/*写日志目录区目录信息*/intsystem_catalog_write(system_catalog_t*catalog,uint32_tid){uint32_tstart_offset;uint32_tstart_addr;uint32_tstart_base;uint32_tremainbyte;intwlen=sizeof(system_catalog_t);uint8_t*pdata=(uint8_t*)catalog;flash_table_t*flash_tmp=get_flash_table(FLASH_CATALOG_ZONE);if(0==id)return-1;start_addr=flash_tmp->start_address+wlen*(id-1);if((start_addr+wlen)>flash_tmp->end_address){start_addr=flash_tmp->start_address;}/*本扇区剩余空间大小*/remainbyte=FLASH_SECTOR_SIZE-(start_addr%FLASH_SECTOR_SIZE);/*写入数据长度小于本扇区剩余长度,直接写入*/if(remainbyte>wlen){remainbyte=wlen;}/*写目录次数不会太频繁,视具体情况改写操作实现*/while(1){start_base=SECTOR_BASE(start_addr);start_offset=SECTOR_OFFSET(start_addr);flash_read(FLASH_CATALOG_ZONE,start_base,sector_buf,FLASH_SECTOR_SIZE);flash_erase(FLASH_CATALOG_ZONE,start_base,FLASH_BLOCK_4K);memcpy((char*)§or_buf[start_offset],pdata,remainbyte);flash_write(FLASH_CATALOG_ZONE,start_base,sector_buf,FLASH_SECTOR_SIZE);if(remainbyte==wlen){break;}else{pdata+=remainbyte;start_addr+=remainbyte;wlen-=remainbyte;remainbyte=(wlen>FLASH_SECTOR_SIZE)?FLASH_SECTOR_SIZE:wlen;}}return0;}intsystem_catalog_all_print(void){inti=0;system_catalog_tcatalog;printf("SystemLogCommandInformation:\r\n");printf("QuerySpecifiesLog:AT+CATALOG=\r\n" );printf("QueryAllLog:AT+CATALOG=<0>\r\n\r\n" );printf("QueryAllSystemCatalog:\r\n");printf("LOG_IDLOG_DATELOG_ADDRLOG_OFFSET\r\n");for(i=0;isystem_log.catalog_num;i++){/*当前最新目录信息*/if(i==(gp_sys_log->system_catalog.log_id-1)){catalog=gp_sys_log->system_catalog;/*获取当前最新目录信息*/}else{system_catalog_read(&catalog,i+1);}printf("%d%04d-%02d-%02d0x%08X%d\r\n",catalog.log_id,catalog.log_time.Year,catalog.log_time.Month,catalog.log_time.Day,catalog.log_addr,catalog.log_offset);memset((char*)&catalog,0,sizeof(system_catalog_t));}return0;} intsystem_log_task(intargc){intrlen=0;uint32_toffset,start_addr,end_addr;system_catalog_tcatalog;flash_table_t*flash_tmp=get_flash_table(FLASH_SYSLOG_ZONE);if(0==gp_sys_ram->system_log_print_enable)return1;gp_sys_ram->system_log_print_enable=0x00;if(gp_sys_ram->system_log_print_id==ALL_LOG_PRINT){/*log回环写标志,打印整个LOG存储区*/if(0x01==gp_sys_log->system_log.log_cyclic_status){start_addr=flash_tmp->start_address;end_addr=flash_tmp->end_address;offset=end_addr-start_addr;}else{start_addr=flash_tmp->start_address;end_addr=start_addr+gp_sys_log->system_log.write_pos;offset=gp_sys_log->system_log.write_pos;}}else{/*读取指定ID日志*/if(gp_sys_ram->system_log_print_id==gp_sys_log->system_catalog.log_id){catalog=gp_sys_log->system_catalog;}else{system_catalog_read(&catalog,gp_sys_ram->system_log_print_id);}start_addr=catalog.log_addr;offset=catalog.log_offset;}if(0==offset)return1;while(1){rlen=(offset>512)?512:offset;system_log_read(sector_buf,start_addr,rlen);HAL_Delay(80);/*目录信息通过调式串口打印*/bsp_debug_send(sector_buf,rlen);start_addr+=rlen;offset-=rlen;if(0==offset)break;}return0;}intsystem_log_write(uint8_t*wbuf,intwlen){uint32_tstart_addr;uint8_t*pdata=wbuf;uint32_tremainbyte;intsystem_catalog_max_id;flash_table_t*flash_tmp=get_flash_table(FLASH_SYSLOG_ZONE);/*计算目录区的最大存储目录项个数*/system_catalog_max_id=((flash_tmp->end_address-flash_tmp->start_address)/sizeof(system_catalog_t));start_addr=flash_tmp->start_address+gp_sys_log->system_log.write_pos;/*存储数据地址大于规划内存地址范围处理*/if((start_addr+wlen)>flash_tmp->end_address){start_addr=flash_tmp->start_address;/*写位置偏移量重置*/gp_sys_log->system_log.write_pos=0;/*LOG回环存储标志置位*/gp_sys_log->system_log.log_cyclic_status=0x01;}/*写位置偏移*/gp_sys_log->system_log.write_pos+=wlen;if((gp_sys_log->system_log.log_latest_time.Year!=gp_sys_log->system_catalog.log_time.Year)||(gp_sys_log->system_log.log_latest_time.Month!=gp_sys_log->system_catalog.log_time.Month)||(gp_sys_log->system_log.log_latest_time.Day!=gp_sys_log->system_catalog.log_time.Day)){/*日期改变,记录目录信息,当log_id为0,则不写入*/system_catalog_write(&gp_sys_log->system_catalog,gp_sys_log->system_catalog.log_id);/*记录存储日期*/gp_sys_log->system_catalog.log_time=gp_sys_log->system_log.log_latest_time;if((gp_sys_log->system_catalog.log_id+1)>=system_catalog_max_id){gp_sys_log->system_log.catalog_num=system_catalog_max_id;/*目录循环写,目录数应为最大*/gp_sys_log->system_log.catalog_cyclic_status=1;/*目录回环写标志*/}else{if(0==gp_sys_log->system_log.catalog_cyclic_status){/*获取目录数*/gp_sys_log->system_log.catalog_num=gp_sys_log->system_catalog.log_id+1;}}/*存储最新目录项信息*/gp_sys_log->system_catalog.log_id=(gp_sys_log->system_catalog.log_id+1)%system_catalog_max_id;gp_sys_log->system_catalog.log_addr=start_addr;gp_sys_log->system_catalog.log_offset=wlen;}else{gp_sys_log->system_catalog.log_offset+=wlen;}/*写位置为存储起始地址并且不为扇区首地址*/if((flash_tmp->start_address==start_addr)&&(SECTOR_OFFSET(flash_tmp->start_address))){flash_read(FLASH_SYSLOG_ZONE,SECTOR_BASE(start_addr),sector_buf,FLASH_SECTOR_SIZE);flash_erase(FLASH_SYSLOG_ZONE,SECTOR_BASE(start_addr),FLASH_BLOCK_4K);/*将扇区头部至起始地址区间的数据回写*/flash_write(FLASH_SYSLOG_ZONE,SECTOR_BASE(start_addr),§or_buf[0],SECTOR_OFFSET(start_addr));}/*写位置为扇区首地址,则擦除一个扇区的存储区*/if(0==SECTOR_OFFSET(start_addr)){flash_erase(FLASH_SYSLOG_ZONE,SECTOR_BASE(start_addr),FLASH_BLOCK_4K);}/*本扇区剩余空间大小*/remainbyte=FLASH_SECTOR_SIZE-(start_addr%FLASH_SECTOR_SIZE);/*写入数据长度小于本扇区剩余长度,直接写入*/if(remainbyte>wlen){remainbyte=wlen;}while(1){flash_write(FLASH_SYSLOG_ZONE,start_addr,pdata,remainbyte);if(remainbyte==wlen){break;}else{pdata+=remainbyte;start_addr+=remainbyte;wlen-=remainbyte;remainbyte=(wlen>FLASH_SECTOR_SIZE)?FLASH_SECTOR_SIZE:wlen;/*扇区首地址则擦除整个扇区,该扇区数据不保存*/if(0==SECTOR_OFFSET(start_addr)){flash_erase(FLASH_SYSLOG_ZONE,SECTOR_BASE(start_addr),FLASH_BLOCK_4K);}}}/*环形存储参数*/save_system_log_param();return0;}#defineLOG_CLOSE_LEVEL0x00/*关闭调试信息*/#defineLOG_ERROR_LEVEL0x01/*错误调试信息*/#defineLOG_WARN_LEVEL0x02/*警告调试信息*/#defineLOG_INFO_LEVEL0x03/*关键调试信息*/#defineLOG_DEBUG_LEVEL0x04/*debug调试信息*/#defineLOG_RECORD_LEVEL0x10/*保存日志并输出信息*/#defineLOG_PRINT_LEVEL0xff#defineSET_LOG_LEVEL(LEVEL)(gp_sys_param->system_print_level=LEVEL)#defineGET_LOG_LEVEL()(gp_sys_param->system_print_level)#definelog_debug(fmt,args...)log_format(LOG_DEBUG_LEVEL,fmt,##args)#definelog_info(fmt,args...)log_format(LOG_INFO_LEVEL,fmt,##args)#definelog_warn(fmt,args...)log_format(LOG_WARN_LEVEL,fmt,##args)#definelog_error(fmt,args...)log_format(LOG_ERROR_LEVEL,fmt,##args)#definelog_record(fmt,args...)log_format(LOG_RECORD_LEVEL,fmt,##args)#defineprintf(fmt,args...)log_format(LOG_PRINT_LEVEL,fmt,##args)typedefstruct{intlevel;char*fmt_str;}system_print_fmt_t;system_print_fmt_tsystem_print_fmt_list[]={{.level=LOG_ERROR_LEVEL,.fmt_str=":" },{.level=LOG_WARN_LEVEL,.fmt_str=":" },{.level=LOG_INFO_LEVEL,.fmt_str=":" },{.level=LOG_DEBUG_LEVEL,.fmt_str=":" },{.level=LOG_RECORD_LEVEL,.fmt_str=":" },};intlog_format(uint8_tlevel,constchar*fmt,...){#defineTIME_PREFIX_SIZE(21)#definePRINT_MAX_SIZE(1024+TIME_PREFIX_SIZE)va_listargs;intnum=0,i=0,fmt_index=0;intfmt_str_len=0,ret=-1;intfile_str_len=0,line_str_len=0;charline_buf[20]={0};staticcharbuf[PRINT_MAX_SIZE];staticQueueHandle_tsem=NULL;time_ttime={0};/*针对os系统*/if(NULL==sem){sem=xSemaphoreCreateCounting(1,1);/*alwaysthinkofsuccess*/}xSemaphoreTake(sem,portMAX_DELAY);ret=-1;fmt_str_len=0;if(level!=LOG_PRINT_LEVEL){if((GET_LOG_LEVEL()SYSTEM_PRINT_FMT_LIST_MAX){gotoexit_end;}fmt_str_len=strlen(system_print_fmt_list[fmt_index].fmt_str);strncpy((char*)&buf[TIME_PREFIX_SIZE],system_print_fmt_list[fmt_index].fmt_str,fmt_str_len);}va_start(args,fmt);num=vsnprintf((char*)&buf[fmt_str_len+TIME_PREFIX_SIZE],PRINT_MAX_SIZE-fmt_str_len-TIME_PREFIX_SIZE-2,fmt,args);va_end(args);if(num<=0){gotoexit_end;}if(level!=LOG_PRINT_LEVEL){num+=fmt_str_len;buf[num+TIME_PREFIX_SIZE]="\r";buf[num+TIME_PREFIX_SIZE+1]="\n";num+=2;}if((GET_LOG_LEVEL()system_log.log_latest_time=time;system_log_write((uint8_t*)buf,num+TIME_PREFIX_SIZE);}exit_end:xSemaphoreGive(sem);returnret;} 觉得文章不错,点击“分享”、“赞”、“在看” 呗!
标签:
-
2022-02-07 14:57:45
奇迹!绝杀!女足亚洲杯逆转夺冠!<
刚刚,中国女足上演逆转绝杀奇迹!她们在亚洲杯决赛中3:2力克韩国队,时隔16年再夺亚洲杯冠军!
-
2022-02-07 14:57:45
中国政府与阿根廷共和国政府签署共建“一带一路”谅解备忘录<
新华社北京2月6日电(记者安蓓)国家发展改革委6日称,国家发展改革委主任何立峰与阿根廷外交、国际贸易和宗教事
-
2022-02-07 14:57:43
中华人民共和国和阿根廷共和国关于深化中阿全面战略伙伴关系的联合声明(全文)<
新华社北京2月6日电中华人民共和国和阿根廷共和国关于深化中阿全面战略伙伴关系的联合声明一、应中方邀请,阿根廷
-
2022-02-07 14:57:40
春节假期国内旅游出游2.51亿人次<
春节遇冬奥,旅游年味浓。根据文化和旅游部数据中心测算,2022年春节假期7天,全国国内旅游出游2 51亿人次,同比
-
2022-02-07 14:57:40
中吉签署关于经典著作互译出版的备忘录 开启两国人文交流互鉴新阶段<
新华社北京2月6日电(记者史竞男)国家主席习近平6日会见来华出席北京2022年冬奥会开幕式的吉尔吉斯斯坦总统扎帕
-
2023-05-29 08:31:57
如何记录嵌入式设备的系统日志_消息
1扫描关注一起学嵌入式,一起学习,一起成长在嵌入式设备应用场景中,系统日志时常可以监控设备软件的运
-
2023-05-29 08:07:18
当前热点-【机构调研记录】泓德基金调研迪普科技
个股亮点:公司推出“IPv6安全演进解决方案”,针对IPv6升级中所有关键问题,提供一站式解决方案,实现业务
-
2023-05-29 07:12:00
世界热推荐:神奥宝可梦全入手方法(宝可梦晶灿钻石明亮珍珠全宝可梦图鉴)
本作中收集宝可梦依旧是最大卖点,相信不少玩家都需要宝可梦晶灿钻石明亮珍珠全宝可梦图鉴吧,下面小编就为
-
2023-05-29 06:54:49
今日聚焦!上市公司理财降温 投资总额同比降四成
上市公司理财降温投资总额同比降四成
-
2023-05-29 06:22:15
天天最新:人民时评:融合创新 激发文旅消费潜能
下大气力推动文化和旅游更广范围、更高水平深度融合,积极培育人们喜闻乐见的新产品文博看展、文化演艺、国
-
2023-05-29 05:46:24
美媒披露美两党债务上限问题“初步协议”细节,包括6项主要内容 环球速讯
虽然双方都未公布协议的细节,但美国有线电视新闻网(CNN)、美国“政治新闻网”等多家美媒根据众议院共和
-
2023-05-29 04:58:22
库尔图瓦现场观战F1大奖赛,并与冠军维斯塔潘合影留念-今热点
F1摩纳哥大奖赛正赛战罢,维斯塔潘全程领跑赢得个人赛季第4个分站赛冠军。皇马门将库尔图瓦也来到现场观战
-
2023-05-29 04:38:01
焦点热讯:lol攻略阵容选择推荐_lol攻略
1、刚开始玩,别管你成不承认,你都是菜鸟,菜鸟就要有菜鸟的觉悟,别人说什么,你就听,他让你做什么,你
-
2023-05-29 03:25:00
莫斯科机场客机相撞事故(关于莫斯科机场客机相撞事故的简介)|快讯
导读莫斯科机场客机相撞事故,斯科机场客机相撞事故的简介很多人还不知道,现在让我们一起来看看吧!1、201
-
2023-05-29 02:15:49
滨海县发布大雾黄色预警|热头条
【来源:滨海县气象台】滨海县气象台2023年05月27日23时10分发布大雾黄色预警信号:目前我县能见度持续下降
-
2023-05-29 01:29:09
夫妻当街掌掴殴打母子!万宁警方通报
5月25日,万宁市公安局发布警情通报。通报称,5月23日20时左右,万宁市日月湾星辰牧歌小区门口处发生了一起
-
2023-05-29 00:44:09
世界聚焦:方式怎么做_房事怎么做
1、呵呵,当然先要有情调喽,然后做,可以疯狂刺激点。2、我和老婆晚上一起吃饭,吃饭的时候兴趣来了,就在
-
2023-05-28 23:33:19
新资讯:麻辣烫的做法和配方_正宗麻辣烫的底料的做法与配方
欢迎观看本篇文章,小柴来为大家解答以上问题。麻辣烫的做法和配方,正宗麻辣烫的底料的做法与配方很多人还
-
2023-05-28 22:32:07
全球观焦点:jj斗地主怎么赠送好友金币(JJ斗地主好友之间能否赠送金币)
本文教大家jj斗地主中,赠送好友金币的方法1、打开jj斗地主app。登录上账号点击右下角向上箭头点击小海豚,
-
2023-05-28 22:16:24
男子坠桥抓线缆挂在半空!网友:吓得不敢喘大气
近日,河南鹤壁消防接到报警称有人从一“网红桥”上坠落悬挂在半空急需救援消防员到场发现一名男子双手紧抓
-
2023-05-28 22:07:26
天天快看点丨打印机的url在哪里看(打印机url地址怎么获取)
1、最简单的方法你通过那台计算机的IP地址或者计算机名访问一下那台电脑然后双击共享的打印机就解决了。本
-
2023-05-28 21:10:15
安徽:公务用车原则上全部购置新能源汽车
【安徽:公务用车原则上全部购置新能源汽车】5月28日,在“投资安徽行”系列活动启动大会上,安徽省发展改
-
2023-05-28 20:42:34
今晚,中车株机VS北京汽车!
株洲“厂BA”篮球锦标赛今晚将迎来第三场季前赛19:30田心九方体育中心中车株机VS北京汽车欢迎大家现场观战
-
2023-05-28 19:55:12
【报资讯】企业年终礼品要缴纳个税吗_企业年终礼品
1、建议送些时尚有个性点的东西,不但员工喜欢用,而且还可以在上面定制公司LOGO。2、可以增加员工的归属感
-
2023-05-28 19:36:29
青龙管业: 关于实际控制人减持达到1%暨减持计划实施完毕的公告
青龙管业:关于实际控制人减持达到1%暨减持计划实施完毕的公告
-
2023-05-28 19:02:11
新盖中盖高钙片广告2006_新盖中盖高钙片广告
1、吃了鈣中鈣,腰不疼了,腿不痛了,腰桿也值了,吃了鈣中鈣,還真對得起咱這張臉。本文到此分享完毕,希望对你
-
2023-05-28 18:16:29
【速看料】ck内衣品牌介绍图片高清_ck内衣
1、CalvinKlein是美国第一大设计师品牌,曾经连续四度获得知名的服装奖项;旗下的相关产品更是层出不穷,声
-
2023-05-28 17:44:06
环球报道:胆结石能吃鸡蛋吗_结石能吃鸡蛋吗
1、肾结石与蛋白质的摄入有关,蛋白质容易引起尿液中的尿酸、钙、磷,导致结石的形成。2、如果有过钙结石,
-
2023-05-28 17:09:46
世界消息!即将结束隔离回到北京 为迎接丫丫北京动物园熊猫馆加装安检门
5月28日早上8点,长江日报记者探访北京动物园,看到熊猫馆前加装了安检门。工作人员说,因为游客较多,丫丫
-
2023-05-28 17:07:39
江西新闻客户端丨新闻早餐5月28日 星期日
>5月27日,江西省公安厅对部督涉电信网络诈骗犯罪“11·25”专案发起全国集群战役,集中2000余名警力开展
-
2023-05-28 16:41:23
造梦西游2地藏戒怎么(造梦西游2地煞灵戒怎么得) 焦点快播
1、地煞灵戒在鬼门关。2、不过要先打死傀儡。3、再打死秦广王才有几率给。本文到此分享完毕,希望对大家有
-
2023-05-28 16:05:38
部分RTX 3060Ti G6X烤机数据汇总_环球看热讯
本文整理了B站上部分品牌和型号的RTX3060TiG6X的烤机数据,主要是为了做个笔记,也为其他正在选购RTX3060Ti
-
2023-05-28 15:07:15
小燕子迎着风在空中飞行(小燕子之风儿阵阵吹) 热消息
导读1、第一部:子进宫 第二部:紫薇身份确认 第三部:浪浪迹天涯之类 《还珠格格之燕儿翩翩飞》
-
2023-05-28 14:53:36
邮政物流电话多少_邮政物流电话
1、邮政业务客服电话是11185。2、邮储银行客服电话是95580。本文到此分享完毕,希望对大家有所帮助。
-
2023-05-28 14:07:11
天天观热点:电脑动态桌面壁纸怎么弄(电脑动态桌面怎么弄)
1、动态桌面是一个新名词,顾名思义就是能够动的桌面,它将美丽可爱的动态影片或图片替换了原来静态古板的