更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
shell_lk.c
浏览该文件的文档.
1/*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "shell_lk.h"
33#include "securec.h"
34#include "stdio.h"
35#include "stdlib.h"
36#include "unistd.h"
37#include "shcmd.h"
38#ifdef LOSCFG_SHELL_DMESG
39#include "dmesg_pri.h"
40#endif
41#include "los_init.h"
42#include "los_printf_pri.h"
43#include "los_process_pri.h"
44
45//LK 注者的理解是 log kernel(内核日志)
46#ifdef LOSCFG_SHELL_LK
47
48typedef enum {//模块等级
55/**
56 * @brief
57 */
58typedef struct {
59 INT32 module_level; ///< 模块等级
60 INT32 trace_level; ///< 跟踪等级
61 FILE *fp; ///< 文件描述结构体
62} Logger;
63
64STATIC INT32 g_tracelevel; ///< 日志等级
65STATIC INT32 g_modulelevel; ///< 模块等级
66
67STATIC Logger g_logger = { 0 };
68
69VOID OsLkDefaultFunc(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, va_list ap);
70
72//获取日志等级
73STATIC INLINE INT32 OsLkTraceLvGet(VOID)
74{
75 return g_tracelevel;
76}
77
79{
81}
82
84{
85 g_tracelevel = level;
86 g_logger.trace_level = level;
87 return;
88}
89
91{
92 g_modulelevel = level;
93 g_logger.module_level = level;
94 return;
95}
96
98{
99 return g_modulelevel;
100}
101
102VOID OsLkLogFileSet(const CHAR *str)
103{
104 FILE *fp = NULL;
105 FILE *oldfp = g_logger.fp;
106
107 if (str == NULL) {
108 return;
109 }
110 fp = fopen(str, "w+");
111 if (fp == NULL) {
112 printf("Error can't open the %s file\n",str);
113 return;
114 }
115
116 g_logger.fp = fp;
117 if (oldfp != NULL) {
118 fclose(oldfp);
119 }
120}
121
122FILE *OsLogFpGet(VOID)
123{
124 return g_logger.fp;
125}
126/**
127 * @brief log命令用于修改&查询日志配置,即选择打印哪种日志?
128 该命令依赖于LOSCFG_SHELL_LK,使用时通过menuconfig在配置项中开启"Enable Shell lk":
129 Debug ---> Enable a Debug Version ---> Enable Shell ---> Enable Shell lK。
130 log level命令用于配置日志的打印等级,包括6个等级
131 TRACE_EMG = 0,
132 TRACE_COMMON = 1,
133 TRACE_ERROR = 2,
134 TRACE_WARN = 3,
135 TRACE_INFO = 4,
136 TRACE_DEBUG = 5
137 若level不在有效范围内,会打印提示信息。
138 若log level命令不加[levelNum]参数,则默认查看当前打印等级,并且提示使用方法。
139 输入log level 4
140 */
141INT32 CmdLog(INT32 argc, const CHAR **argv)
142{
143 size_t level;
144 size_t module;
145 CHAR *p = NULL;
146
147 if ((argc != 2) || (argv == NULL)) { /* 2:count of parameter */
148 PRINTK("Usage: log level <num>\n");
149 PRINTK("Usage: log module <num>\n");
150 PRINTK("Usage: log path <PATH>\n");
151 return -1;
152 }
153
154 if (!strncmp(argv[0], "level", strlen(argv[0]) + 1)) {
155 level = strtoul(argv[1], &p, 0);
156 if ((*p != 0) || (level > LOS_TRACE_LEVEL) || (level < LOS_EMG_LEVEL)) {
157 PRINTK("current log level %s\n", OsLkCurLogLvGet());
158 PRINTK("log %s [num] can access as 0:EMG 1:COMMON 2:ERROR 3:WARN 4:INFO 5:DEBUG\n", argv[0]);
159 } else {
160 OsLkTraceLvSet(level);
161 PRINTK("Set current log level %s\n", OsLkCurLogLvGet());
162 }
163 } else if (!strncmp(argv[0], "module", strlen(argv[0]) + 1)) {
164 module = strtoul(argv[1], &p, 0);
165 if ((*p != 0) || (module > MODULE4) || (module < MODULE0)) {
166 PRINTK("log %s can't access %s\n", argv[0], argv[1]);
167 PRINTK("not support yet\n");
168 return -1;
169 } else {
170 OsLkModuleLvSet(module);
171 PRINTK("not support yet\n");
172 }
173 } else if (!strncmp(argv[0], "path", strlen(argv[0]) + 1)) {
174 OsLkLogFileSet(argv[1]);
175 PRINTK("not support yet\n");
176 } else {
177 PRINTK("Usage: log level <num>\n");
178 PRINTK("Usage: log module <num>\n");
179 PRINTK("Usage: log path <PATH>\n");
180 return -1;
181 }
182
183 return 0;
184}
185
186#ifdef LOSCFG_SHELL_DMESG
187/// 日志循环记录
188STATIC INLINE VOID OsLogCycleRecord(INT32 level)
189{
190 UINT32 tmpLen;
191 if (level != LOS_COMMON_LEVEL && (level > LOS_EMG_LEVEL && level <= LOS_TRACE_LEVEL)) {
192 tmpLen = strlen(OsLogLvGet(level));
193 const CHAR* tmpPtr = OsLogLvGet(level);
194 (VOID)OsLogRecordStr(tmpPtr, tmpLen);
195 }
196}
197#endif
198/// 内核打印函数,在LOS_LkPrint中回调
199VOID OsLkDefaultFunc(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, va_list ap)
200{
201 if (level > OsLkTraceLvGet()) {
202#ifdef LOSCFG_SHELL_DMESG
203 if ((UINT32)level <= OsDmesgLvGet()) {
204 OsLogCycleRecord(level);
205 DmesgPrintf(fmt, ap);
206 }
207#endif
208 return;
209 }
210 if ((level != LOS_COMMON_LEVEL) && ((level > LOS_EMG_LEVEL) && (level <= LOS_TRACE_LEVEL))) {
211 dprintf("[%s][%s:%s]", OsLogLvGet(level),
212 ((OsCurrProcessGet() == NULL) ? "NULL" : OsCurrProcessGet()->processName),
213 ((OsCurrTaskGet() == NULL) ? "NULL" : OsCurrTaskGet()->taskName));
214 }
215 LkDprintf(fmt, ap);
216}
217/// 打印
218VOID LOS_LkPrint(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, ...)
219{
220 va_list ap;
221 if (g_osLkHook != NULL) {
222 va_start(ap, fmt);
223 g_osLkHook(level, func, line, fmt, ap);
224 va_end(ap);
225 }
226}
227/// 设置回调函数
229{
230 g_osLkHook = hook;
231}
232/// 内核日志初始化
234{
235 (VOID)memset_s(&g_logger, sizeof(Logger), 0, sizeof(Logger));
236 OsLkTraceLvSet(TRACE_DEFAULT);
237 LOS_LkRegHook(OsLkDefaultFunc);//注册钩子函数,将在 LOS_LkPrint中回调钩子
238#ifdef LOSCFG_SHELL_DMESG
239 (VOID)LOS_DmesgLvSet(TRACE_DEFAULT);
240#endif
241 return LOS_OK;
242}
243
244#ifdef LOSCFG_SHELL_CMD_DEBUG
246#endif
247/// 日志模块初始化
248LOS_MODULE_INIT(OsLkLoggerInit, LOS_INIT_LEVEL_EARLIEST);
249
250#endif
@ CMD_TYPE_EX
不支持标准命令参数输入,会把用户填写的命令关键字屏蔽掉,例如:输入ls /ramfs,传入给注册函数的参数只有/ramfs,而ls命令关键字并不会被传入。
Definition: shell.h:91
UINT32 LOS_DmesgLvSet(UINT32 level)
Set the dmesg level
Definition: dmesg.c:611
UINT32 OsLogRecordStr(const CHAR *str, UINT32 len)
记录一个字符串
Definition: dmesg.c:368
UINT32 OsDmesgLvGet(VOID)
Definition: dmesg.c:606
void dprintf(const char *fmt,...)
Format and print data.
VOID LOS_LkPrint(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt,...)
打印
Definition: shell_lk.c:218
VOID(* LK_FUNC)(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, va_list ap)
Define an printf handling function hook.
Definition: shell_lk.h:74
VOID LOS_LkRegHook(LK_FUNC hook)
设置回调函数
Definition: shell_lk.c:228
VOID LkDprintf(const CHAR *fmt, va_list ap)
LK 注者的理解是 log kernel(内核日志)
Definition: los_printf.c:217
const CHAR * OsLogLvGet(INT32 level)
Definition: los_printf.c:64
VOID DmesgPrintf(const CHAR *fmt, va_list ap)
Definition: los_printf.c:228
STATIC INLINE LosProcessCB * OsCurrProcessGet(VOID)
STATIC INLINE LosTaskCB * OsCurrTaskGet(VOID)
signed int INT32
Definition: los_typedef.h:60
unsigned int UINT32
Definition: los_typedef.h:57
char CHAR
Definition: los_typedef.h:63
STATIC INLINE VOID OsLogCycleRecord(INT32 level)
日志循环记录
Definition: shell_lk.c:188
VOID OsLkTraceLvSet(INT32 level)
Definition: shell_lk.c:83
VOID OsLkModuleLvSet(INT32 level)
Definition: shell_lk.c:90
STATIC INT32 g_modulelevel
模块等级
Definition: shell_lk.c:65
STATIC INLINE INT32 OsLkTraceLvGet(VOID)
Definition: shell_lk.c:73
VOID OsLkDefaultFunc(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, va_list ap)
内核打印函数,在LOS_LkPrint中回调
Definition: shell_lk.c:199
INT32 CmdLog(INT32 argc, const CHAR **argv)
log命令用于修改&查询日志配置,即选择打印哪种日志? 该命令依赖于LOSCFG_SHELL_LK,使用时通过menuconfig在配置项中开启"Enable Shell lk": Debug —> E...
Definition: shell_lk.c:141
VOID OsLkLogFileSet(const CHAR *str)
Definition: shell_lk.c:102
LK_FUNC g_osLkHook
Definition: shell_lk.c:71
STATIC INT32 g_tracelevel
日志等级
Definition: shell_lk.c:64
STATIC Logger g_logger
Definition: shell_lk.c:67
LOS_MODULE_INIT(OsLkLoggerInit, LOS_INIT_LEVEL_EARLIEST)
日志模块初始化
MODULE_FLAG
Definition: shell_lk.c:48
@ MODULE0
Definition: shell_lk.c:49
@ MODULE3
Definition: shell_lk.c:52
@ MODULE2
Definition: shell_lk.c:51
@ MODULE4
Definition: shell_lk.c:53
@ MODULE1
Definition: shell_lk.c:50
INT32 OsLkModuleLvGet(VOID)
Definition: shell_lk.c:97
FILE * OsLogFpGet(VOID)
Definition: shell_lk.c:122
SHELLCMD_ENTRY(log_shellcmd, CMD_TYPE_EX, "log", 1,(CmdCallBackFunc) CmdLog)
const CHAR * OsLkCurLogLvGet(VOID)
Definition: shell_lk.c:78
UINT32 OsLkLoggerInit(VOID)
内核日志初始化
Definition: shell_lk.c:233
INT32 module_level
模块等级
Definition: shell_lk.c:59
FILE * fp
文件描述结构体
Definition: shell_lk.c:61
INT32 trace_level
跟踪等级
Definition: shell_lk.c:60
u32_t(* CmdCallBackFunc)(u32_t argc, const char **argv)
Definition: types_adapt.h:86