目录
1 前言
内核除了提供接口rt_kprintf()用于输出打印信息,还支持一整套完善的日志组件ulog。两者在实现上有重叠部分,都使用到console模块;其余功能都相互独立,只有深究其实现机制,才能更好的去使用或者移植该系统。
2 rt_kprintf()
- 内核提供一个用于输出日志信息的接口
- 默认使用console设备输出打印,其设备名称可在配置选项中修改
- 如果未注册console设备,rt_kprintf最终会调用rt_hw_console_output()输出打印;该函数供用户自己实现功能
3 配置选项
使用该接口,需要在编译前进行如下配置
- 主要决定如下两个参数
//打印缓存长度 #define RT_CONSOLEBUF_SIZE 256 //控制台设备名称 #define RT_CONSOLE_DEVICE_NAME "uart2"
4 console设备
rt_kprintf()系统默认使用console设备输出打印信息,所有需要先了解内核如何创建并使用sonsole设备
4.1 设备声明
内核使用全局变量_console_device来维护console设备
static rt_device_t _console_device = RT_NULL;
4.2 设备创建
- 在启动过程中,内核会调用rt_hw_usart_init()完成uart设备注册;
- 然后调用rt_console_set_device(RT_CONSOLE_DEVICE_NAME),去已注册的设备中查找是否有名称为RT_CONSOLE_DEVICE_NAME的设备,如果有则将该设备作为为_console_device
4.3 获取_console_device
- 外部统一调用rt_console_get_device()来获取_console_device
rt_device_t rt_console_get_device(void)
{
return _console_device;
}
5 分析rt_kprintf()函数
RT_WEAK void rt_kprintf(const char *fmt, ...)
{
//1 缓存区声明,注意是静态局部变量,最大长度为RT_CONSOLEBUF_SIZE
static char rt_log_buf[RT_CONSOLEBUF_SIZE];
va_start(args, fmt);
//2 整理打印日志保存到rt_log_buf,并返回实际输出长度
length = rt_vsnprintf(rt_log_buf, sizeof(rt_log_buf) - 1, fmt, args);
//3 限制长度
if (length > RT_CONSOLEBUF_SIZE - 1)
length = RT_CONSOLEBUF_SIZE - 1;
if (_console_device == RT_NULL)
{
//4 如果内核未注册console设备,则执行rt_hw_console_output()完成输出。
rt_hw_console_output(rt_log_buf);
}
else
{
//5 直接使用console设备输出信息
rt_device_write(_console_device, 0, rt_log_buf, length);
}
va_end(args);
}
6 rt_kprintf重定向
- 可以利用系统预留的rt_hw_console_output()接口。
- 不注册console设备,自己在rt_hw_console_output()中完成重定向
- 或者将console注册为任意设备,比如以太网,CAN,USB等