当前位置:   article > 正文

鸿蒙子系统,鸿蒙的DFX子系统

inithiviewstaticcache

做者:liangkz  更新时间:2021.05.05shell

咱们仍然是先对子系统的目录结构作一次整理,作成表格,把模块之间的调用关系理一下:app

2b55d9260798e9c5db82aeec2f3c769f.png

3069abc219dc6d42acc8bd18fea1bd85.png

1. Hi3861 平台如上表,上电后在SystemInit阶段会依次init:HiviewConfigInit、HiLogInit、hiview service:iview

[system_init] HOS_SystemInit begin: %%%%%%%%%%%函数

[system_init] MODULE_INIT(core)============================ui

[hiview_config] CORE_INIT_PRI(HiviewConfigInit, 0);        this

[hiview_log] HiLogInit. CORE_INIT_PRI(HiLogInit, 0) url

[hiview_output_log] InitCoreLogOutput. call HiviewRegisterMsgHandlespa

[system_init] SYS_INIT(service)============================.net

[hiview_service] SYS_SERVICE_INIT(Init).debug

[samgr_lite] RegisterService(name: hiview)

[hiview_service] Init.InitHiviewComponent.

[hiview_file] InitHiviewFile

......

......

[hiview_service] Initialize.

咱们分别来看一下他们都作了些什么事情:

A. HiviewConfigInit

位于:Hi3861/base/hiviewdfx/utils/lite/hiview_config.c

其主要是初始化全局变量g_hiviewConfig的配置,以下

48af93f3c2b320cdc94e889f459e72e3.png

hiviewInited:标记hiview service是否已经完成初始化。hiview service完成初始化以后将其置为TRUE,

“The communication of task can be use after the service is running.”,包括了相关的Message Handle才可用。

outputOption:标记Control log output mode. default to OUTPUT_OPTION_FLOW.

typedef enum{

//不通过buffer,直接在终端上实时打印log,Debug版本建议用这个

OUTPUT_OPTION_DEBUG = 0, /* Output to the UART without buffer. Commercial versions are forbidden. */ //不会实时打印log,先保存到buffer里,知足条件时才会经过SAMGR发消息一次性打印一条或多条log到终端上 OUTPUT_OPTION_FLOW, /* Output to UART via SAMGR */ //不会实时打印log,先保存到buffer里,知足条件时才会经过SAMGR发消息将buffer的log写入TextFile OUTPUT_OPTION_TEXT_FILE, /* Output to Text File: “/user/log/debug.log”, see ‘HIVIEW_FILE_PATH_LOG’ */ //不会实时打印log,先保存到buffer里,知足条件时才会经过SAMGR发消息将buffer的log写入BinFile OUTPUT_OPTION_BIN_FILE, OUTPUT_OPTION_MAX } HiviewOutputOption;

level:标记Control log output level. Default to HILOG_LV_DEBUG.

低于此标记级别的log不会打印出来(?),仍是不会被记录到TEXT_FILE/BIN_FILE里(??)

#defineHILOG_LV_INVALID0 #defineHILOG_LV_DEBUG1 #defineHILOG_LV_INFO2 #defineHILOG_LV_WARN3 #defineHILOG_LV_ERROR4 #defineHILOG_LV_FATAL5 #defineHILOG_LV_MAX6

B. HiLogInit

位于:Hi3861/base/hiviewdfx/frameworks/hilog_lite/mini/hiview_log.c

f02744f7be9aa6d0d98c3398a0387309.png

InitCoreLogOutput();

61892ec50f5d85f46e35a4efa5cba2ba.png

先去初始化全局变量HiviewCache g_logCache

typedef struct{

HiviewMutexId_t mutex;

uint16 wCursor; // 0-65535 uint16 usedSize; // 0-65535,buffer已经使用掉的size uint16 size; // cache size 0-65535,由LOG_STATIC_CACHE_SIZE指定,1024 Byte HiviewCacheType type; uint8 *buffer; // Circular buffer,由g_logCacheBuffer 指定的空间,1024 Byte } HiviewCache;

而全局变量 HiviewFile  g_logFile,这是在上面将outputOption标记设置为 OUTPUT_OPTION_TEXT_FILE/BIN_FILE 时用得上的配置,

如输出TextFile时,文件会生成在“user/log/debug.log”。

接下来是注册三个MsgHandle,用于处理知足条件时,将g_logCache/g_logCacheBuffer 中的log写入文件 或者经过Uart在默认终端上打印出来。这中间还有一个从新格式化log的处理,如:

HILOG_INFO(HILOG_MODULE_SAMGR, "Initialized all system and application services!");

这条log会处理成:

00 00:00:00 0 220 I 1/SAMGR: Initialized all system and application services!

前面新增一串字符分别表明着:开机以来的天数+时:分:秒+0+task+logLevel+module+moduleName.

task这个看起来并非打印这个log的任务的TaskID,貌似是能够自行修改的,待验证。

logLevel 就是:

static char g_logLevelInfo[HILOG_LV_MAX] = { 'N', // "NONE" 'D', // "DEBUG" 'I', // "INFO" 'W', // "WARN" 'E', // "ERROR" 'F' // "FATAL" };

module就是枚举HiLogModuleType定义的数字,这里的1就是 HILOG_MODULE_SAMGR 的值。

moduleName就是module对应的字符名字,见下面经过HiLogRegisterModule()注册的module参数。

HiLogRegisterModule()

注册log的模块,按照官方文档的“Hilog_lite开发指导”中的例子进行配置便可。

HiviewRegisterInitFunc()

注册InitLogOutput()是为了在hiview service init时建立和初始化log输出的TextFile/BinFile等文件的相关信息,outputOption == OUTPUT_OPTION_DEBUG/OUTPUT_OPTION_FLOW 是不须要建立文件的。

注册InitLogLimit()是为了在hiview service init时给log的打印设置一些限制条件:

SetLimitThreshold(HILOG_MODULE_HIVIEW, LOG_LIMIT_LEVEL3);

SetLimitThreshold(HILOG_MODULE_APP, LOG_LIMIT_LEVEL2);

过于频繁地打印log,有可能会致使log的丢失。

C. hiview service

位于:Hi3861/base/hiviewdfx/services/hiview_lite/hiview_service.c

4165b50b19168a86251beb6f006e8883.png

先是向SAMGR注册了g_hiviewService以及FeatureApi,而后经过InitHiviewComponent()去依次执行 g_hiviewInitFuncList[ ] 中的 InitLogOutput()和InitLogLimit()作相关的配置。

注意,这里仅仅是向SAMGR注册服务和注册MsgHandle API而已,还须要等到后面SAMGR把各类资源环境配置好后,才会调用g_hiviewService.Initialize()去初始化和拉起hiview service,提供log方面的相关服务。

2. 在接下来的系统启动过程、系统运行过程、应用运行过程当中,只要有调用上表C的声明中 log.h/hiview_log.h头文件定义的宏,来打印log,就都会跑到下面所分析的流程中去。

hiview_log.h 定义了:一些宏、枚举、辅助函数和

/*

* Interface for printing basic logs. Use the macro definition interface instead of directly using this interface.

* @param module Module ID.

* @param level Log Level.

* @param nums Parameters automatically generated by macro.

* @param fmt Format string.

* @attention Do not use this interface directly, you should use the HILOG_XXX interface.

*/

voidHiLogPrintf(uint8 module, uint8 level,constchar*nums,constchar*fmt,...)__attribute__((format(printf,4,5))); #defineHILOG_DEBUG(mod, fmt,...)HiLogPrintf(mod, HILOG_LV_DEBUG,FUN_ARG_NUM(__VA_ARGS__), fmt,##__VA_ARGS__) #defineHILOG_INFO(mod, fmt,...)HiLogPrintf(mod, HILOG_LV_INFO,FUN_ARG_NUM(__VA_ARGS__), fmt,##__VA_ARGS__) #defineHILOG_WARN(mod, fmt,...)HiLogPrintf(mod, HILOG_LV_WARN,FUN_ARG_NUM(__VA_ARGS__), fmt,##__VA_ARGS__) #defineHILOG_ERROR(mod, fmt,...)HiLogPrintf(mod, HILOG_LV_ERROR,FUN_ARG_NUM(__VA_ARGS__), fmt,##__VA_ARGS__) #defineHILOG_FATAL(mod, fmt,...)HiLogPrintf(mod, HILOG_LV_FATAL,FUN_ARG_NUM(__VA_ARGS__), fmt,##__VA_ARGS__)

系统建议不要直接使用HiLogPrintf()来打印log,而是使用下面的一组宏来分级别/类型来打印log。

501b9bd71d167565fbae83c3f7789cc8.png

HiLogPrintf() 的实如今:Hi3861/base/hiviewdfx/frameworks/hilog_lite/mini/hiview_log.c

通过一些判断后,调用  Hi3861/base/hiviewdfx/frameworks/hilog_lite/mini/hiview_output_log.c

文件内的OutputLog():

3daa16ba55fbc3aed5f1cace79f49cef.png

Hi3861/base/hiviewdfx/services/hiview_lite/hiview_service.c

【这里的MessageHandle()和Output()函数,若是进一步深刻去分析和理解,就会涉及到samgr_lite组件的一些东西了,这里先不进一步细说。文末我把我作的两张图附上,你们能够先自行理解一下。】

d75935f64376d516adcbb2f98545ca4a.png

b9c54fb9d2a6679e6a7bcff2971eef55.png

hiview service经过MessageHandle()调用以前InitCoreLogOutput()注册的MsgHandle API来处理相关消息:

实时打印log、把log写入TextFile或者写入BinFile。

6272fb8fe8be2139daca6040e9b6ab50.png

最上面表格中“D的实现”中关于hiview_cache.c、hiview_file.c、hiview_util.c等辅助函数的实现以及DFX系统外部提供的支持,就请各位本身去研究了。

Hi3516工程上的目录结构,相比Hi3861的多了:

hilog.cpp  C++类对上面几个宏的封装;上层应用开发,有本身的JS/Java的相关类的封装,请自行根据API参考文档进行配置和调用。

hiview_applogcat.c  apphilogcat 服务进程,负责从日志设备(dev/hilog)读取数据,格式化输出到终端,同时也写入磁盘文件。

hiview_logcat.c  编译成可执行程序hilogcat,看起来是能够经过shell执行,传入参数来动态调整log的打印,不过并不会写入磁盘文件。

我没有Hi3516平台,暂没法验证。

附上两张我在整理 HiviewService 时作的展开图片:

a30601a46b83d3601181a48dc78fcc02.png

87d68444f0891c119daa213818df531c.png

做者:liangkz

想了解更多内容,请访问51CTO和华为合做共建的鸿蒙社区:https://harmonyos.51cto.com

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/227785
推荐阅读
相关标签
  

闽ICP备14008679号