一、日志子系统简介
为了能够实时记录系统中发生的各种事件,SylixOS加入了日志管理功能。通过分析日志文件可以及时发现和处理系统运行过程中的问题。SylixOS日志子系统的主要功能是记录系统发生的各个事件,根据不同使用场景可以选择不同的日志等级,来决定是否打印信息,还可以设置日志系统输出的文件集。
二、SylixOS中日志系统初始化
系统内核启动时候会调用到_logInit函数,创建消息队列;调用函数API_PartitionCreate创建内存分区,建立printk缓冲;同时建立日志处理线程t_log,并初始化t_log线程。
t_log线程处理日志系统中消息的接收和发送,执行流程如下:
-
调用函数API_MsgQueueReceive从消息队列接收消息;
-
判断是任务中发送,还是中断中发送,根据是否打印头部的参数,选择是否打印头部信息;
-
调用函数__logPrintk或者__logPrintf函数打印数据;
-
更新_G_iLogMsgsLost值,即丢失的日志消息数量。
三、SylixOS中日志打印函数printk
SylixOS中会调用函数printk来实现日志打印,函数执行过程如下:
-
解析输入字符串中的打印等级,如果有则设置解析值为打印级别,若没有则设置为默认级别,即default_message_loglevel;
-
判断打印级别,若大于console_loglevel则不打印信息;
-
调用C库函数vsnprintf向字符串中打印自定义数据格式;
-
填充消息结构体中其余成员参数;
-
判断log系统是否初始化,如果没有初始化则调用函数__logBspMsg打印信息;若初始化完成,则调用API_MsgQueueSend函数向消息队列发送消息,发送失败则增加丢失消息队列计数值,即_G_iLogMsgsLost值。
由函数执行过程可以看出,printk函数本质上是将需要打印的数据保存到消息中,以消息队列的方式发送出去,由t_log线程接收消息队列中的消息,执行打印数据的操作。
四、相关Shell命令
SylixOS提供了相关Shell命令供用户使用。包括:logfiles命令用于显示内核日志打印文件列表;logfileclear命令从内核日志打印文件表中清除指定的内核文件描述符;logfileadd命令向内核日志打印函数加入指定的内核文件描述符;loglevel命令显示或设置当前内核日志(printk)打印等级。
根据以上Shell命令,构建测试程序,演示printk函数向文件描述符中输出日志信息的使用方法。
4.1 测试程序代码
构建简单的测试程序,在应用层调用printk函数打印字符串"Hello SylixOS!"。
#include <stdio.h>
#include "system/loglib/loglib.h"
int main (int argc, char **argv)
{
printk("Hello SylixOS!\n");
return (0);
}
编译测试程序并部署到mini2440虚拟机上。
4.2 使用Shell命令测试
测试过程如图 4.1所示。
图 4.1 日志系统使用演示
由测试用例可以看出,printk函数完成了向文件中输出打印信息的操作。
采用同样的方法也可以向telnet终端,串口终端等输出打印信息。