620 lines
16 KiB
C
620 lines
16 KiB
C
|
|
/*
|
|
@NOT_ACT_USED
|
|
*/
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
版权所有 (C), 2001-2011, 上海全波通信技术有限公司
|
|
|
|
******************************************************************************
|
|
文 件 名 : log_task.c
|
|
版 本 号 : 初稿
|
|
作 者 : 郭金涛
|
|
生成日期 : 2014年1月16日
|
|
最近修改 :
|
|
功能描述 : 系统日志处理文件,系统日志放在第2片E2中. 除了部分备份参数,大部分还未使用
|
|
函数列表 :
|
|
log_task
|
|
修改历史 :
|
|
1.日 期 : 2014年1月16日
|
|
作 者 : 郭金涛
|
|
修改内容 : 创建文件
|
|
|
|
******************************************************************************/
|
|
#include <string.h>
|
|
#include "rtc.h"
|
|
#include "type.h"
|
|
#include "delay.h"
|
|
#include "os_task.h"
|
|
#include "sys_config.h"
|
|
#include "eeprom.h"
|
|
#include "i2c_drv.h"
|
|
#include "log_task.h"
|
|
|
|
|
|
#if USE_LOG_MODULE
|
|
#if (LOG_MAX_RECORD_NUM*LOG_PER_RECORD_SIZE+3)>3900
|
|
#error "sys log max size must < 3900 bytes"
|
|
#endif
|
|
|
|
extern void* rtc_get_log_mem_address(void);
|
|
|
|
|
|
#define LOG_USE_RAM_FLAG 0X4329
|
|
#define LOG_USE_E2PROM_FLAG ((uint8)LOG_USE_RAM_FLAG) //每个平台要区分开,平台切换后,日志需初始化
|
|
|
|
|
|
|
|
static S_OS_LOG *pos_log;
|
|
static uint32 log_use_bk_ram_flag = 0; //是否使用bkram标志, 若使用,则存储时先把日志放入RAM,否则直接存入E2中
|
|
static uint32 log_e2_latest_index = 0; //未使用BKRAM时有效
|
|
static uint32 log_e2_num = 0;
|
|
|
|
static uint8 log_save_bit_map[13]; //LOG_MAX_RECORD_NUM/8+1 13字节 每位表示一条日志是否需要存E2ROM
|
|
|
|
#define LOG_SET_ALL_SAVE_BIT() \
|
|
do{memset(log_save_bit_map,0xff,sizeof(log_save_bit_map));}while(0)
|
|
|
|
#define LOG_SET_SAVE_BIT_INDEX(n) \
|
|
do{ \
|
|
uint32 LOG_T_N = (n)/8; \
|
|
uint32 LOT_T_O = (n)%8; \
|
|
log_save_bit_map[LOG_T_N]|=(1<<LOT_T_O);\
|
|
}while(0)
|
|
#define LOG_CLEAR_SAVE_BIT_INDEX(n) \
|
|
do{ \
|
|
uint32 LOG_T_N = (n)/8; \
|
|
uint32 LOT_T_O = (n)%8; \
|
|
log_save_bit_map[LOG_T_N]&=~(1<<LOT_T_O);\
|
|
}while(0)
|
|
|
|
#define LOG_SAVE_BIT_IS_SET(index) (log_save_bit_map[(index)/8]&(1<<((index)%8)))
|
|
|
|
|
|
|
|
//上电后,若RAM中为无效数据,从E2中更新数据
|
|
static void log_init_ram_by_e2prom(S_OS_LOG *plog)
|
|
{
|
|
uint32 i = 0;
|
|
uint32 address = 0;
|
|
S_LOG_STRUCT log_temp[2]; //64字节,E2的一页
|
|
|
|
//判断E2中的有效标志是否置位
|
|
if(c256_byteread2(E2_SYSTEM_LOG_VALID_ADDRESS)!=LOG_USE_E2PROM_FLAG)
|
|
{
|
|
c256_bytewrite2(E2_SYSTEM_LOG_VALID_ADDRESS,LOG_USE_E2PROM_FLAG);
|
|
|
|
LOG_SET_ALL_SAVE_BIT();
|
|
plog->lastest_index = 0;
|
|
plog->total_num = 0;
|
|
memset(plog->log,0,sizeof(plog->log));
|
|
return;
|
|
}
|
|
|
|
plog->lastest_index = c256_byteread2(E2_SYSTEM_LOG_CURRENT_INDEX_ADDRESS);
|
|
plog->total_num = c256_byteread2(E2_SYSTEM_LOG_CURRENT_NUM_ADDRESS);
|
|
if(plog->lastest_index>LOG_MAX_RECORD_NUM)
|
|
{
|
|
plog->lastest_index = 0;
|
|
}
|
|
if(plog->total_num>LOG_MAX_RECORD_NUM)
|
|
{
|
|
plog->total_num = LOG_MAX_RECORD_NUM;
|
|
}
|
|
|
|
//一次读取两条log
|
|
address = E2_SYSTEM_LOG_START_ADDRESS;
|
|
for(i=0;i<LOG_MAX_RECORD_NUM/2;i++,address+=LOG_PER_RECORD_SIZE*2)
|
|
{
|
|
atmel_read_e2((uint8*)&log_temp,address,LOG_PER_RECORD_SIZE*2);
|
|
memcpy(&plog->log[i*2],log_temp,LOG_PER_RECORD_SIZE*2);
|
|
}
|
|
|
|
//判断读取的log是否有效
|
|
for(i=0;i<LOG_MAX_RECORD_NUM;i++)
|
|
{
|
|
if(plog->log[i].valid!=1)
|
|
{
|
|
LOG_SET_SAVE_BIT_INDEX(i); //同时更新E2PROM
|
|
memset(&plog->log[i],0,sizeof(S_LOG_STRUCT));
|
|
}
|
|
}
|
|
}
|
|
|
|
//上电检查E2PROM中是否和RAM中的一致,以RAM有效,则以RAM为准
|
|
static void log_init_e2prom_by_ram(S_OS_LOG *plog)
|
|
{
|
|
uint32 i = 0;
|
|
uint32 address = 0;
|
|
S_LOG_STRUCT log_temp;
|
|
|
|
//判断E2中的有效标志是否置位,若未置为,则E2需要全部更新
|
|
if(c256_byteread2(E2_SYSTEM_LOG_VALID_ADDRESS)!=LOG_USE_E2PROM_FLAG)
|
|
{
|
|
c256_bytewrite2(E2_SYSTEM_LOG_VALID_ADDRESS,LOG_USE_E2PROM_FLAG);
|
|
c256_bytewrite2(E2_SYSTEM_LOG_CURRENT_INDEX_ADDRESS,plog->lastest_index);
|
|
c256_bytewrite2(E2_SYSTEM_LOG_CURRENT_NUM_ADDRESS,plog->total_num);
|
|
LOG_SET_ALL_SAVE_BIT();
|
|
return;
|
|
}
|
|
|
|
address = E2_SYSTEM_LOG_START_ADDRESS;
|
|
for(i=0;i<LOG_MAX_RECORD_NUM;i++,address+=LOG_PER_RECORD_SIZE)
|
|
{
|
|
atmel_read_e2((uint8*)&log_temp,address,LOG_PER_RECORD_SIZE);
|
|
if(memcmp(&plog->log[i],&log_temp,LOG_PER_RECORD_SIZE))
|
|
{
|
|
LOG_SET_SAVE_BIT_INDEX(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void log_save_new_record(MSG *pmsg)
|
|
{
|
|
S_LOG_STRUCT *plog;
|
|
uint32 address;
|
|
|
|
if(!pmsg)
|
|
{
|
|
return;
|
|
}
|
|
if(pmsg->wPara==LOG_TYPE_INVALID)
|
|
{
|
|
if(pmsg->lPara)
|
|
{
|
|
free_mem((void*)pmsg->lPara);
|
|
}
|
|
return;
|
|
}
|
|
|
|
plog = (S_LOG_STRUCT*)pmsg->lPara;
|
|
if(log_use_bk_ram_flag)
|
|
{
|
|
if(pos_log->total_num+1<LOG_MAX_RECORD_NUM)
|
|
{
|
|
pos_log->total_num++;
|
|
}
|
|
else
|
|
{
|
|
pos_log->total_num = LOG_MAX_RECORD_NUM;
|
|
}
|
|
memcpy(&pos_log->log[pos_log->lastest_index],plog,LOG_PER_RECORD_SIZE);
|
|
LOG_SET_SAVE_BIT_INDEX(pos_log->lastest_index);
|
|
pos_log->log[pos_log->lastest_index].valid = 1;
|
|
|
|
if(pos_log->lastest_index+1<LOG_MAX_RECORD_NUM)
|
|
{
|
|
pos_log->lastest_index++;
|
|
}
|
|
else
|
|
{
|
|
pos_log->lastest_index = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(log_e2_num+1<LOG_MAX_RECORD_NUM)
|
|
{
|
|
log_e2_num++;
|
|
}
|
|
else
|
|
{
|
|
log_e2_num = LOG_MAX_RECORD_NUM;
|
|
}
|
|
|
|
c256_bytewrite2(E2_SYSTEM_LOG_CURRENT_INDEX_ADDRESS, log_e2_latest_index);
|
|
c256_bytewrite2(E2_SYSTEM_LOG_CURRENT_NUM_ADDRESS, log_e2_num);
|
|
address = E2_SYSTEM_LOG_START_ADDRESS+log_e2_latest_index*LOG_PER_RECORD_SIZE;
|
|
|
|
plog->valid = 1;
|
|
atmel_write_e2((uint8*)plog,address,LOG_PER_RECORD_SIZE);
|
|
if(log_e2_latest_index+1<LOG_MAX_RECORD_NUM)
|
|
{
|
|
log_e2_latest_index++;
|
|
}
|
|
else
|
|
{
|
|
log_e2_latest_index = 0;
|
|
}
|
|
}
|
|
if(pmsg->lPara)
|
|
{
|
|
free_mem((void*)pmsg->lPara);
|
|
}
|
|
}
|
|
static void log_init_mem_para(void)
|
|
{
|
|
pos_log =(S_OS_LOG*)rtc_get_log_mem_address();
|
|
if(pos_log)
|
|
{
|
|
log_use_bk_ram_flag = 1;
|
|
if(pos_log->ram_flag!=LOG_USE_RAM_FLAG)
|
|
{
|
|
pos_log->ram_flag=LOG_USE_RAM_FLAG;
|
|
log_init_ram_by_e2prom(pos_log);
|
|
}
|
|
else
|
|
{
|
|
log_init_e2prom_by_ram(pos_log);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
log_use_bk_ram_flag = 0;
|
|
if(c256_byteread2(E2_SYSTEM_LOG_VALID_ADDRESS)!=LOG_USE_E2PROM_FLAG)
|
|
{
|
|
c256_bytewrite2(E2_SYSTEM_LOG_VALID_ADDRESS,LOG_USE_E2PROM_FLAG);
|
|
c256_bytewrite2(E2_SYSTEM_LOG_CURRENT_INDEX_ADDRESS,0);
|
|
c256_bytewrite2(E2_SYSTEM_LOG_CURRENT_NUM_ADDRESS,0);
|
|
log_e2_latest_index = 0;
|
|
}
|
|
else
|
|
{
|
|
log_e2_latest_index = c256_byteread2(E2_SYSTEM_LOG_CURRENT_INDEX_ADDRESS);
|
|
log_e2_num = c256_byteread2(E2_SYSTEM_LOG_CURRENT_NUM_ADDRESS);
|
|
if(log_e2_latest_index>LOG_MAX_RECORD_NUM)
|
|
{
|
|
log_e2_latest_index = 0;
|
|
log_e2_num = 0;
|
|
}
|
|
if(log_e2_num>LOG_MAX_RECORD_NUM)
|
|
{
|
|
log_e2_num = LOG_MAX_RECORD_NUM;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//周期性检查是否有LOG需要存E2PROM
|
|
static void log_check_save_to_e2prom(void)
|
|
{
|
|
uint32 i = 0;
|
|
uint32 j = 0;
|
|
S_LOG_STRUCT *ponelog;
|
|
uint32 address;
|
|
|
|
//已经直接存入E2PROM
|
|
if(!log_use_bk_ram_flag)
|
|
{
|
|
return;
|
|
}
|
|
ponelog = &pos_log->log[0];
|
|
for(i=0;i<sizeof(log_save_bit_map);i++)
|
|
{
|
|
if(log_save_bit_map[i]==0)
|
|
{
|
|
ponelog+=8;
|
|
continue;
|
|
}
|
|
for(j=0;j<8;j++,ponelog++)
|
|
{
|
|
if(LOG_SAVE_BIT_IS_SET(i*8+j))
|
|
{
|
|
address = E2_SYSTEM_LOG_START_ADDRESS+(i*8+j)*LOG_PER_RECORD_SIZE;
|
|
|
|
atmel_write_e2((uint8*)ponelog,address,LOG_PER_RECORD_SIZE);
|
|
LOG_CLEAR_SAVE_BIT_INDEX(i*8+j);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void log_task(void * pvParameters)
|
|
{
|
|
MSG *pmsg = NULL;
|
|
S_SYS_TIME close_time;
|
|
|
|
(void)pvParameters;
|
|
|
|
delay_ms(1000);
|
|
|
|
log_init_mem_para();
|
|
|
|
config_time_msg(MSG_SEC);
|
|
config_time_msg(MSG_MINUTE);
|
|
|
|
//发送一个上次断电的告警日志? 这个还有问题,若直接通过复位键复位,系统断电时间是不更新的!!
|
|
rtc_get_last_close_time(&close_time);
|
|
log_system_event_generate(&close_time,LOG_TYPE_POWER_OFF,NULL,0);
|
|
|
|
//上电先自己发送一个电源上电告警日志
|
|
log_system_event_generate(NULL,LOG_TYPE_POWER_ON,NULL,0);
|
|
|
|
while((pmsg = get_msg(OS_WAIT_FOREVER))!=NULL)
|
|
{
|
|
switch(pmsg->type)
|
|
{
|
|
case MSG_SEC:
|
|
task_is_ok();
|
|
|
|
break;
|
|
case MSG_LOG: //有新的系统日志产生,暂存到4K掉电不丢失RAM中,然后有MIN消息去保存
|
|
if(update_flag)
|
|
{
|
|
;
|
|
}
|
|
else
|
|
{
|
|
log_save_new_record(pmsg);
|
|
}
|
|
break;
|
|
case MSG_MINUTE:
|
|
log_check_save_to_e2prom();
|
|
break;
|
|
case MSG_LOG_RECORD_RESET:
|
|
log_record_reset();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if(MSG_NEED_TO_FREE(pmsg))
|
|
free_msg(pmsg);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
/*****************************************************************************
|
|
函 数 名 : log_read_record_by_index
|
|
功能描述 : 根据序号,读取log日志内容
|
|
输入参数 : uint32 index 读取起始序号,为0,则表示最新的,越大则表示越旧的日志
|
|
void *pdata 读取到的日志内容,存到改指针中,
|
|
输出参数 : 无
|
|
返 回 值 :实际读取的log条数
|
|
调用函数 :
|
|
被调函数 :
|
|
|
|
修改历史 :
|
|
1.日 期 : 2014年1月16日
|
|
作 者 : 郭金涛
|
|
修改内容 : 新生成函数
|
|
|
|
*****************************************************************************/
|
|
uint32 log_read_record_by_index(uint32 index,void *pdata)
|
|
{
|
|
#if USE_LOG_MODULE
|
|
S_LOG_STRUCT *pdest;
|
|
uint32 current_index = 0;
|
|
|
|
if(index>LOG_MAX_RECORD_NUM)
|
|
{
|
|
return 0;
|
|
}
|
|
if(!pdata)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
pdest = (S_LOG_STRUCT*)pdata;
|
|
|
|
if(log_use_bk_ram_flag)
|
|
{
|
|
if(index>pos_log->total_num)
|
|
{
|
|
return 0;
|
|
}
|
|
if(pos_log->lastest_index>index)
|
|
{
|
|
current_index = pos_log->lastest_index-1-index;
|
|
}
|
|
else
|
|
{
|
|
current_index = pos_log->lastest_index+LOG_MAX_RECORD_NUM-1-index;
|
|
}
|
|
|
|
if(pos_log->log[current_index].valid==1)
|
|
{
|
|
*pdest = pos_log->log[current_index];
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
memset(pdest,0,sizeof(S_LOG_STRUCT));
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
S_LOG_STRUCT log_temp;
|
|
uint32 address;
|
|
|
|
if(index>log_e2_num)
|
|
{
|
|
return 0;
|
|
}
|
|
if(log_e2_latest_index)
|
|
{
|
|
current_index = log_e2_latest_index-1;
|
|
}
|
|
else
|
|
{
|
|
current_index = LOG_MAX_RECORD_NUM-1;
|
|
}
|
|
|
|
address = E2_SYSTEM_LOG_START_ADDRESS+current_index*LOG_PER_RECORD_SIZE;
|
|
|
|
atmel_read_e2((uint8*)&log_temp,address,LOG_PER_RECORD_SIZE);
|
|
|
|
if(log_temp.valid==1)
|
|
{
|
|
*pdest = log_temp;
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
memset(pdest,0,sizeof(S_LOG_STRUCT));
|
|
return 0;
|
|
}
|
|
}
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
//清除log信息
|
|
void log_record_reset(void)
|
|
{
|
|
#if USE_LOG_MODULE
|
|
if(log_use_bk_ram_flag)
|
|
{
|
|
pos_log->lastest_index = 0;
|
|
pos_log->total_num = 0;
|
|
|
|
memset(pos_log->log,0,LOG_MAX_RECORD_NUM*LOG_PER_RECORD_SIZE);
|
|
LOG_SET_ALL_SAVE_BIT();
|
|
}
|
|
else
|
|
{
|
|
uint32 i = 0;
|
|
uint32 address = 0;
|
|
S_LOG_STRUCT log_temp;
|
|
|
|
log_e2_latest_index = 0;
|
|
log_e2_num = 0;
|
|
c256_bytewrite2(E2_SYSTEM_LOG_CURRENT_INDEX_ADDRESS, log_e2_latest_index);
|
|
c256_bytewrite2(E2_SYSTEM_LOG_CURRENT_NUM_ADDRESS, log_e2_num);
|
|
|
|
memset(&log_temp,0,LOG_PER_RECORD_SIZE);
|
|
address = E2_SYSTEM_LOG_START_ADDRESS;
|
|
|
|
for(i=0;i<LOG_MAX_RECORD_NUM;i++,address+=LOG_PER_RECORD_SIZE)
|
|
{
|
|
atmel_write_e2((uint8*)&log_temp,address,LOG_PER_RECORD_SIZE);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
/*****************************************************************************
|
|
函 数 名 : log_system_event_generate
|
|
功能描述 : 系统事件发生时,调用的函数
|
|
输入参数 : S_SYS_TIME* ptime 事件发生时间,若为NULL,则有该函数自动填充为当前事件,若有特殊需要,自己手动填写
|
|
uint32 type 事件发生类型
|
|
uint8 *pcontent 事件的具体内容 根据需要填写,如"RF_OFF"等
|
|
uint32 ctlen 时间具体内容的长度
|
|
输出参数 :
|
|
返 回 值 : 0: 正常,其他参数,错误
|
|
调用函数 :
|
|
被调函数 :
|
|
|
|
修改历史 :
|
|
1.日 期 : 2014年1月16日
|
|
作 者 : 郭金涛
|
|
修改内容 : 新生成函数
|
|
|
|
*****************************************************************************/
|
|
uint32 log_system_event_generate(S_SYS_TIME* ptime,uint32 type,uint8 *pcontent,uint32 ctlen)
|
|
{
|
|
#if USE_LOG_MODULE
|
|
MSG *pmsg;
|
|
S_LOG_STRUCT *plog;
|
|
S_SYS_TIME *pttemp;
|
|
|
|
if((type>=LOG_TYPE_END)||(type==LOG_TYPE_INVALID))
|
|
{
|
|
return LOG_ERR_PARA_INVALID;
|
|
}
|
|
|
|
pmsg = alloc_msg();
|
|
if(!pmsg)
|
|
{
|
|
return LOG_ERR_ALLOC_MSG_FAILED;
|
|
}
|
|
|
|
plog = alloc_mem(sizeof(S_LOG_STRUCT));
|
|
if(!plog)
|
|
{
|
|
free_msg(pmsg);
|
|
return LOG_ERR_ALLOC_MEM_FAILED;
|
|
}
|
|
|
|
plog->type = type;
|
|
if((ctlen)&&(pcontent))
|
|
{
|
|
ctlen = ctlen>sizeof(plog->content)?sizeof(plog->content):ctlen;
|
|
memcpy(plog->content,pcontent,ctlen);
|
|
}
|
|
else
|
|
{
|
|
memset(plog->content,0,sizeof(plog->content)); //进行清空,防止原先旧数据干扰
|
|
}
|
|
if(ptime)
|
|
{
|
|
plog->year = ptime->year-2000;
|
|
plog->month= ptime->month;
|
|
plog->date = ptime->date;
|
|
plog->hour = ptime->hour;
|
|
plog->min = ptime->min;
|
|
plog->sec = ptime->sec;
|
|
}
|
|
else
|
|
{
|
|
pttemp = os_get_sys_time_ptr();
|
|
|
|
plog->year = pttemp->year-2000;
|
|
plog->month= pttemp->month;
|
|
plog->date = pttemp->date;
|
|
plog->hour = pttemp->hour;
|
|
plog->min = pttemp->min;
|
|
plog->sec = pttemp->sec;
|
|
}
|
|
|
|
pmsg->type = MSG_LOG;
|
|
pmsg->wPara = type;
|
|
pmsg->lPara = (uint32)plog;
|
|
|
|
send_msg(LOG_TASK_ID,pmsg);
|
|
return LOG_ERR_NO_ERR;
|
|
#else
|
|
return LOG_ERR_NO_ERR;
|
|
#endif
|
|
}
|
|
|
|
//获取当前日志总条数
|
|
uint32 log_get_total_record_num(void)
|
|
{
|
|
#if USE_LOG_MODULE
|
|
if(log_use_bk_ram_flag)
|
|
{
|
|
return pos_log->total_num;
|
|
}
|
|
else
|
|
{
|
|
return log_e2_num;
|
|
}
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
#if USE_DEBUG_UART
|
|
void log_record_printf(void)
|
|
{
|
|
uint32 i = 0;
|
|
uint32 j = 0;
|
|
S_LOG_STRUCT log_temp;
|
|
uint32 ret_num;
|
|
const uint8 log_type[][16] = {"NO ERR","POWER_ON","POWER_OFF","PARA_CHANGE","TIME_CHANGE","GPS_UNLOCK","TS_ERR"};
|
|
|
|
i = log_get_total_record_num();
|
|
printf("log total num:%d.\n",i);
|
|
|
|
for(j=0;j<i;j++)
|
|
{
|
|
ret_num = log_read_record_by_index(j,&log_temp);
|
|
if((ret_num)&&(log_temp.valid==1))
|
|
{
|
|
printf("log num:%d,type:%s,time:20%02d/%02d/%02d %02d:%02d:%02d,",
|
|
j+1,log_type[log_temp.type],log_temp.year,log_temp.month,log_temp.date,log_temp.hour,log_temp.min,log_temp.sec);
|
|
if(strlen((char*)log_temp.content))
|
|
printf("log content:%s\n",log_temp.content);
|
|
else
|
|
printf("\n");
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|