当前位置: 首页 > news >正文

展锐7870 Camera HAL层日志调试

HAL层日志的调用接口定义

#define HAL_LOGE(format, args...) LOG(LOG_PRI_E, LOG_HAL, LOG_ALL, format, ##args)
#define HAL_LOGW(format, args...) LOG(LOG_PRI_W, LOG_HAL, LOG_ALL, format, ##args)
#define HAL_LOGI(format, args...) LOG(LOG_PRI_I, LOG_HAL, LOG_ALL, format, ##args)
#define HAL_LOGD(format, args...) LOG(LOG_PRI_D, LOG_HAL, LOG_ALL, format, ##args)
#define HAL_LOGV(format, args...) LOG(LOG_PRI_V, LOG_HAL, LOG_ALL, format, ##args)

参数

LOG(LOG_PRI_V, LOG_HAL, LOG_ALL, format, ##args)

优先级定义

const int LOG_PRI_E = '1';
const int LOG_PRI_W = '2';
const int LOG_PRI_I = '3';
const int LOG_PRI_D = '4';
const int LOG_PRI_V = '5';

模块

typedef enum{LOG_HAL = 0,LOG_OEM,LOG_ISP_MW,LOG_SENSOR,LOG_ISPALG,LOG_ARITH,LOG_MODULE_MAX,
}LOG_MODULE_E;
typedef enum{LOG_ALL = 0,LOG_AE,LOG_AF,LOG_AWBC,LOG_FUNC_MAX
}LOG_FUNC_E;
#ifndef LOG
#define LOG(prio, module, func,format,...) \((void)PRI_LOG(prio, module, func,LOG_TAG, \"%d, %s: " format,__LINE__, __FUNCTION__,##__VA_ARGS__))
#endif

LOG_TAG 在调用打印log的文件定义。不同文件会有不同的标签定义,用于查看和筛选日志用。

#ifndef PRI_LOG
#define PRI_LOG(prio, module, func,tag, format...) \__print_log(prio,module,func,tag,format)
#endif

最终会调用到__print_log()函数

int __print_log(int pri, int module, int func,const char* tag, const char* format, ...){int prio=0;if((g_log_level[module] > LOG_PRI_V) ||(g_log_level[module] < LOG_PRI_E)) {g_log_level[module] = LOG_PRI_D;}if((int)g_log_module_setting[module] == LOG_STATUS_EN) {if((int)g_log_func_setting[func] == LOG_STATUS_EN) {//update g_log_level according to module priorityif((int)g_log_level[module] >= pri){va_list ap;char buf[1024];va_start(ap, format);vsnprintf(buf, 1024, format, ap);va_end(ap);switch(pri) {case LOG_PRI_E: prio=ANDROID_LOG_ERROR; break;case LOG_PRI_W: prio=ANDROID_LOG_WARN; break;case LOG_PRI_I: prio=ANDROID_LOG_INFO; break;case LOG_PRI_D: prio=ANDROID_LOG_DEBUG; break;case LOG_PRI_V: prio=ANDROID_LOG_VERBOSE; break;default:prio=ANDROID_LOG_DEBUG;}return __android_log_write(prio, tag, buf);}}}return 0;
}

g_log_level是一个数组(全局变量)。

这个函数会将参数与数组的一个成员变量比较,判断是否需要打印。与数组的哪个成员变量比较就看调用LOG()传递的是哪个LOG_MODULE_E

如何修改日志打印等级

静态修改

修改数组成员变量

数组下标是LOG_MODULE_E

char g_log_level[LOG_MODULE_MAX] = {'4', '4', '4', '4', '4', '4'};

动态修改

在创建SprdCamera3OEMIf对象时会调用log_monitor_thread_init()

void *SprdCamera3OEMIf::log_monitor_thread_proc(void *p_data) {char prop[PROPERTY_VALUE_MAX];char version[PROPERTY_VALUE_MAX];char loglevel_stat[LOG_MODULE_MAX+1];int num = 0;struct timespec ts;SprdCamera3OEMIf *obj = (SprdCamera3OEMIf *)p_data;s_mLogState = 1;HAL_LOGI("E, %d",s_mLogMonitor.load());while(s_mLogMonitor.load() > 1) {/**prop[0]:hal,HAL_LOGX/F_HAL_LOGX*prop[1]:oem,CMR_LOGX/F_CMR_LOGX*prop[2]:MW&PM,ISP_LOGX/F_ISP_LOGX*prop[3]:sensor,SENSOR_LOGX/F_SENSOR_LOGX*prop[4]:3A ctrl&alg, undefined*prop[5]:arithmetic,ARITH_LOGX/F_ARITH_LOGX*/property_get("persist.vendor.cam.mlog.on_off", prop, "000000");for (num = 0 ;num < LOG_MODULE_MAX; num++) {if ((prop[num] != g_log_module_setting[num]) &&((prop[num] == LOG_STATUS_EN) || (prop[num] == LOG_STATUS_DIS))) {g_log_module_setting[num] = prop[num];}}/**prop[0]:ALL*prop[1]:AE*prop[2]:AF*prop[3]:AWBC*/property_get("persist.vendor.cam.flog.on_off", prop, "0000");for (num = 0; num < LOG_FUNC_MAX; num++) {if ((prop[num] != g_log_func_setting[num]) &&((prop[num] == LOG_STATUS_EN) || (prop[num] == LOG_STATUS_DIS))) {g_log_func_setting[num] = prop[num];}}/**prop[0]:hal,HAL_LOGX/F_HAL_LOGX,*prop[1]:oem,CMR_LOGX/F_CMR_LOGX*prop[2]:MW&PM,ISP_LOGX/F_ISP_LOGX*prop[3]:sensor,SENSOR_LOGX/F_SENSOR_LOGX*prop[4]:3A ctrl&alg,undefined*prop[5]:arithmetic,ARITH_LOGX/F_ARITH_LOGX*/property_get("ro.debuggable", version, "1");strcmp(version, "0") ? strncpy(loglevel_stat, "444444", LOG_MODULE_MAX+1): strncpy(loglevel_stat, "333333", LOG_MODULE_MAX+1);property_get("persist.vendor.cam.mlog.loglevel", prop, loglevel_stat);for (num = 0; num < LOG_MODULE_MAX; num++) {if ((prop[num] != g_log_level[num]) &&(prop[num] >= LOG_PRI_E) && (prop[num] <= LOG_PRI_V)) {g_log_level[num] = prop[num];}}obj->log_monitor_test();if (clock_gettime(CLOCK_REALTIME, &ts))continue;ts.tv_nsec += ms2ns(1000);if (ts.tv_nsec > 1000000000) {ts.tv_sec += 1;ts.tv_nsec -= 1000000000;}sem_timedwait(&s_mLogMonitorSem, &ts);}s_mLogState = 0;HAL_LOGV("X");return NULL;
}

通过属性配置

    property_get("persist.vendor.cam.mlog.loglevel", prop, loglevel_stat);for (num = 0; num < LOG_MODULE_MAX; num++) {if ((prop[num] != g_log_level[num]) &&(prop[num] >= LOG_PRI_E) && (prop[num] <= LOG_PRI_V)) {g_log_level[num] = prop[num];}}

例如所有日志等级配置为V

setprop persist.vendor.cam.mlog.loglevel 555555

http://www.mrgr.cn/news/17778.html

相关文章:

  • 钢铁百科:A633D交货状态、A633D对应牌号、A633D力学性能解析
  • 软件项目实施方案(Word原件-项目案例)
  • 007.Python爬虫系列_初识爬虫
  • pyro ExponentialLR 如何设置优化器 optimizer的学习率 pytorch 深度神经网络 bnn,
  • C++身份证实名认证-实名制-身份证三要素认证-身份认证-身份验真-接口
  • 欧科云链OKLink受邀参与WebX ,旗下EaaS助力项目方“弯道超车”
  • Qt定时器详解
  • nodejs程序如何确定哪个是主进程文件?
  • Nuxt3入门:路由系统(第4节)
  • 【GeoScenePro】Generic Server Error
  • 【Java】SpringBoot 单体项目创建 与 整合 Mybatis-Plus
  • 深度学习模型量化方法
  • sed awk 第二版学习(二)—— 正则表达式语法
  • DSADC、量化噪声、噪声整形
  • NFS 各个版本之间的比较
  • PHP跨越城市界限一站式招聘求职平台系统小程序源码
  • 偶然发现破局之路
  • 每天一个数据分析题(五百一十四)- 决策树算法
  • 【C++设计模式】(三)创建型模式:单例模式
  • [C++] C、C++类型转换