背景介绍
ulog
是用来打印日志的,EasyFlash
是用来存储数据的,这两个软件包加在一起,就可以实现日志的掉电保存功能,并且支持日志打印等级的动态设置,这些等级等级可以存储在EasyFlash
中,这样不需要每次上电都设置一次调试等级。
问题介绍
移植成功EasyFlash+ulog
以后,我直接就在main函数中初始化了EasyFlash
,因为EasyFlash
依赖FAL
,因此也需要先初始化FAL
。而ulog
是自动初始化的,我就没有对他进行初始化了。如下所示,
int main(void)
{
fal_init();
easyflash_init();
while (1)
{
rt_thread_mdelay(10);
}
}
然后发现使用ulog_lvl
命令设置的过滤等级在重启以后失效了,如下所示,
排查过程
经过排查发现,当我们添加了软件包ulog_easyflash
以后,查找INIT_APP_EXPORT
这个自动初始化机制,会发现有两个相关的函数会自动初始化,请看下图
ulog_ef_backend_init
函数会将EasyFlash
注册到ulog
中,这样打印的时候,会同时将日志写入EasyFlash
。因此,我们必须在此之前将EasyFlash
初始化。
int ulog_ef_backend_init(void)
{
flash_backend.output = ulog_easyflash_backend_output;//日志的输出函数,会写EasyFlash
ulog_backend_register(&flash_backend, "easyflash", RT_TRUE);
return 0;
}
ulog_ef_filter_cfg_load
函数会将EasyFlash
中的参数读取出来,例如调试全局过滤等级、全局标签等级等等。这里面会读取EasyFlash
的数据,所以我们必须在此之前将EasyFlash
初始化。
int ulog_ef_filter_cfg_load(void)
{
char *value;
/* restore the saving global level */
if ((value = ef_get_env(ENV_FILTER_GLOBAL_LVL_NAME)) != NULL)//读取全局过滤等级,这里会去读取easyflash上的数据
{
ulog_global_filter_lvl_set(atoi(value));
}
/* restore the saving global tag */
if ((value = ef_get_env(ENV_FILTER_GLOBAL_TAG_NAME)) != NULL)//读取全局标签过滤等级,这里会去读取easyflash上的数据
{
ulog_global_filter_tag_set(value);
}
...
return 0;
}
解决办法
基于以上两点,我这里使用INIT_COMPONENT_EXPORT
初始化机制,将EasyFlash
在组件这层进行初始化,这样可以保证它初始化在INIT_APP_EXPORT
之前。如下所示: