更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
dmesg.c
浏览该文件的文档.
1/*!
2 * @file dmesg.c
3 * @brief dmesg命令用于控制内核dmesg缓存区。
4 * @link dmesg http://weharmonyos.com/openharmony/zh-cn/device-dev/kernel/kernel-small-debug-shell-cmd-dmesg.html
5 https://man7.org/linux/man-pages/man1/dmesg.1.html
6 * @endlink
7 @verbatim
8 +-------------------------------------------------------+
9 | Info | log_space |
10 +-------------------------------------------------------+
11 |
12 |__buffer_space
13
14 Case A:
15 +-------------------------------------------------------+
16 | |#############################| |
17 +-------------------------------------------------------+
18 | |
19 Head Tail
20 Case B:
21 +-------------------------------------------------------+
22 |##########| |#######|
23 +-------------------------------------------------------+
24 | |
25 Tail Head
26
27 @endverbatim
28 * @version
29 * @author weharmonyos.com | 鸿蒙研究站 | 每天死磕一点点
30 * @date 2021-11-25
31 */
32/*
33 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
34 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without modification,
37 * are permitted provided that the following conditions are met:
38 *
39 * 1. Redistributions of source code must retain the above copyright notice, this list of
40 * conditions and the following disclaimer.
41 *
42 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
43 * of conditions and the following disclaimer in the documentation and/or other materials
44 * provided with the distribution.
45 *
46 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
47 * to endorse or promote products derived from this software without specific prior written
48 * permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
52 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
54 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
55 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
56 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
57 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
58 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
59 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
60 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 */
62
63#ifdef LOSCFG_SHELL_DMESG
64#include "dmesg_pri.h"
65#include "show.h"
66#include "shcmd.h"
67#include "securec.h"
68#include "stdlib.h"
69#include "unistd.h"
70#include "los_init.h"
71#include "los_task.h"
72
73
74#define BUF_MAX_INDEX (g_logBufSize - 1) ///< 缓存区最大索引,可按单个字符保存
75
76LITE_OS_SEC_BSS STATIC SPIN_LOCK_INIT(g_dmesgSpin);
77
78STATIC DmesgInfo *g_dmesgInfo = NULL;///< 保存在 g_mallocAddr 的开始位置,即头信息
79STATIC UINT32 g_logBufSize = 0; ///< 缓冲区内容体大小
80STATIC VOID *g_mallocAddr = NULL;///< 缓存区开始位置,即头位置
81STATIC UINT32 g_dmesgLogLevel = 3; ///< 日志等级
82STATIC UINT32 g_consoleLock = 0; ///< 用于关闭和打开控制台
83STATIC UINT32 g_uartLock = 0; ///< 用于关闭和打开串口
84STATIC const CHAR *g_levelString[] = {///< 日志等级
85 "EMG",
86 "COMMON",
87 "ERR",
88 "WARN",
89 "INFO",
90 "DEBUG"
91};
92/// 关闭控制台
93STATIC VOID OsLockConsole(VOID)
94{
95 g_consoleLock = 1;
96}
97/// 打开控制台
98STATIC VOID OsUnlockConsole(VOID)
99{
100 g_consoleLock = 0;
101}
102/// 关闭串口
103STATIC VOID OsLockUart(VOID)
104{
105 g_uartLock = 1;
106}
107/// 打开串口
108STATIC VOID OsUnlockUart(VOID)
109{
110 g_uartLock = 0;
111}
112
114{
115 if (g_dmesgInfo == NULL) {
116 return LOS_NOK;
117 }
118
120 return LOS_NOK;
121 }
122
123 if (((g_dmesgInfo->logSize == g_logBufSize) || (g_dmesgInfo->logSize == 0)) &&
125 return LOS_NOK;
126 }
127
128 return LOS_OK;
129}
130///< 读取dmesg日志
131STATIC INT32 OsDmesgRead(CHAR *buf, UINT32 len)
132{
133 UINT32 readLen;
134 UINT32 logSize = g_dmesgInfo->logSize;
135 UINT32 head = g_dmesgInfo->logHead;
136 UINT32 tail = g_dmesgInfo->logTail;
137 CHAR *logBuf = g_dmesgInfo->logBuf;
138 errno_t ret;
139
140 if (OsCheckError()) {
141 return -1;
142 }
143 if (logSize == 0) {
144 return 0;
145 }
146
147 readLen = len < logSize ? len : logSize;
148
149 if (head < tail) { /* Case A */
150 ret = memcpy_s(buf, len, logBuf + head, readLen);
151 if (ret != EOK) {
152 return -1;
153 }
154 g_dmesgInfo->logHead += readLen;
155 g_dmesgInfo->logSize -= readLen;
156 } else { /* Case B */
157 if (readLen <= (g_logBufSize - head)) {
158 ret = memcpy_s(buf, len, logBuf + head, readLen);
159 if (ret != EOK) {
160 return -1;
161 }
162 g_dmesgInfo->logHead += readLen;
163 g_dmesgInfo->logSize -= readLen;
164 } else {
165 ret = memcpy_s(buf, len, logBuf + head, g_logBufSize - head);
166 if (ret != EOK) {
167 return -1;
168 }
169
170 ret = memcpy_s(buf + g_logBufSize - head, len - (g_logBufSize - head),
171 logBuf, readLen - (g_logBufSize - head));
172 if (ret != EOK) {
173 return -1;
174 }
175 g_dmesgInfo->logHead = readLen - (g_logBufSize - head);
176 g_dmesgInfo->logSize -= readLen;
177 }
178 }
179 return (INT32)readLen;
180}
181/// 把旧人账目移交给新人
182STATIC INT32 OsCopyToNew(const VOID *addr, UINT32 size)
183{
184 UINT32 copyStart = 0;
185 UINT32 copyLen;
186 CHAR *temp = NULL;
187 CHAR *newBuf = (CHAR *)addr + sizeof(DmesgInfo);
188 UINT32 bufSize = size - sizeof(DmesgInfo);
189 INT32 ret;
190 UINT32 intSave;
191
192 LOS_SpinLockSave(&g_dmesgSpin, &intSave);
193 if (g_dmesgInfo->logSize == 0) {
194 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
195 return 0;
196 }
197
198 temp = (CHAR *)malloc(g_dmesgInfo->logSize);
199 if (temp == NULL) {
200 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
201 return -1;
202 }
203
204 (VOID)memset_s(temp, g_dmesgInfo->logSize, 0, g_dmesgInfo->logSize);
205 copyLen = ((bufSize < g_dmesgInfo->logSize) ? bufSize : g_dmesgInfo->logSize);
206 if (bufSize < g_dmesgInfo->logSize) {
207 copyStart = g_dmesgInfo->logSize - bufSize;
208 }
209
210 ret = OsDmesgRead(temp, g_dmesgInfo->logSize);
211 if (ret <= 0) {
212 goto FREE_OUT;
213 }
214
215 /* if new buf size smaller than logSize */
216 ret = memcpy_s(newBuf, bufSize, temp + copyStart, copyLen);
217 if (ret != EOK) {
218 goto FREE_OUT;
219 }
220 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
221 free(temp);
222
223 return (INT32)copyLen;
224
225FREE_OUT:
226 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
227 PRINT_ERR("%s,%d failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
228 free(temp);
229 return -1;
230}
231/// 重置内存
232STATIC UINT32 OsDmesgResetMem(const VOID *addr, UINT32 size)
233{
234 VOID *temp = NULL;
235 INT32 copyLen;
236 UINT32 intSave;
237
238 if (size <= sizeof(DmesgInfo)) {
239 return LOS_NOK;
240 }
241
242 LOS_SpinLockSave(&g_dmesgSpin, &intSave);
243 temp = g_dmesgInfo;
244 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
245 copyLen = OsCopyToNew(addr, size);
246 if (copyLen < 0) {
247 return LOS_NOK;
248 }
249
250 LOS_SpinLockSave(&g_dmesgSpin, &intSave);
251 g_logBufSize = size - sizeof(DmesgInfo);
252 g_dmesgInfo = (DmesgInfo *)addr;
253 g_dmesgInfo->logBuf = (CHAR *)addr + sizeof(DmesgInfo);
254 g_dmesgInfo->logSize = copyLen;
255 g_dmesgInfo->logTail = ((copyLen == g_logBufSize) ? 0 : copyLen);
256 g_dmesgInfo->logHead = 0;
257
258 /* if old mem came from malloc */
259 if (temp == g_mallocAddr) {
260 goto FREE_OUT;
261 }
262 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
263
264 return LOS_OK;
265
266FREE_OUT:
267 g_mallocAddr = NULL;
268 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
269 free(temp);
270 return LOS_OK;
271}
272///调整缓冲区大小,如下五个步骤
274{
275 VOID *temp = NULL;
276 INT32 copyLen;
277 CHAR *newString = NULL;
278 UINT32 intSave;
279
280 if (size == 0) {
281 return LOS_NOK;
282 }
283 //1. 重新整一块新地方
284 newString = (CHAR *)malloc(size + sizeof(DmesgInfo));
285 if (newString == NULL) {//新人未找到,旧人得接着用
286 return LOS_NOK;
287 }
288
289 LOS_SpinLockSave(&g_dmesgSpin, &intSave);
290 temp = g_dmesgInfo;
291 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
292 //2.把旧人账目移交给新人
293 copyLen = OsCopyToNew(newString, size + sizeof(DmesgInfo));
294 if (copyLen < 0) {
295 goto ERR_OUT;
296 }
297 //3.以新换旧
298 LOS_SpinLockSave(&g_dmesgSpin, &intSave);
299 g_logBufSize = size;
300 g_dmesgInfo = (DmesgInfo *)newString;
301 g_dmesgInfo->logBuf = (CHAR *)newString + sizeof(DmesgInfo);
302 g_dmesgInfo->logSize = copyLen;
303 g_dmesgInfo->logTail = ((copyLen == g_logBufSize) ? 0 : copyLen);
304 g_dmesgInfo->logHead = 0;
305 //4. 有新欢了,释放旧人去找寻真爱
306 if (temp == g_mallocAddr) {
307 goto FREE_OUT;
308 }
309 g_mallocAddr = newString;//5. 正式和新人媾和
310 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
311
312 return LOS_OK;
313ERR_OUT:
314 free(newString);
315 return LOS_NOK;
316FREE_OUT:
317 g_mallocAddr = newString;
318 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
319 free(temp);
320 return LOS_OK;
321}
322
324{
325 return g_consoleLock;
326}
327
329{
330 return g_uartLock;
331}
332/// 初始化 dmesg
334{
335 CHAR* buffer = NULL;
336
337 buffer = (CHAR *)malloc(KERNEL_LOG_BUF_SIZE + sizeof(DmesgInfo));//总内存分 头 + 体两部分
338 if (buffer == NULL) {
339 return LOS_NOK;
340 }
341 g_mallocAddr = buffer;
342 g_dmesgInfo = (DmesgInfo *)buffer;//全局变量
343 g_dmesgInfo->logHead = 0;//读取开始位置 记录在头部
344 g_dmesgInfo->logTail = 0;//写入开始位置 记录在头部
345 g_dmesgInfo->logSize = 0;//日志已占用数量 记录在头部
346 g_dmesgInfo->logBuf = buffer + sizeof(DmesgInfo);//身体部分开始位置
347 g_logBufSize = KERNEL_LOG_BUF_SIZE;//身体部分总大小位置
348
349 return LOS_OK;
350}
351/// 只记录一个字符
353{
355
356 if (g_dmesgInfo->logTail > BUF_MAX_INDEX) {
357 g_dmesgInfo->logTail = 0;
358 }
359
361 (g_dmesgInfo->logSize)++;
362 } else {
364 }
365 return c;
366}
367/// 记录一个字符串
369{
370 UINT32 i = 0;
371 UINTPTR intSave;
372
373 LOS_SpinLockSave(&g_dmesgSpin, &intSave);
374 while (len--) {
375 (VOID)OsLogRecordChar(str[i]);
376 i++;
377 }
378 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
379 return i;
380}
381
382STATIC VOID OsBufFullWrite(const CHAR *dst, UINT32 logLen)
383{
384 UINT32 bufSize = g_logBufSize;
385 UINT32 tail = g_dmesgInfo->logTail;
386 CHAR *buf = g_dmesgInfo->logBuf;
387 errno_t ret;
388
389 if (!logLen || (dst == NULL)) {
390 return;
391 }
392 if (logLen > bufSize) { /* full re-write */
393 ret = memcpy_s(buf + tail, bufSize - tail, dst, bufSize - tail);
394 if (ret != EOK) {
395 PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
396 return;
397 }
398 ret = memcpy_s(buf, bufSize, dst + bufSize - tail, tail);
399 if (ret != EOK) {
400 PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
401 return;
402 }
403
404 OsBufFullWrite(dst + bufSize, logLen - bufSize);
405 } else {
406 if (logLen > (bufSize - tail)) { /* need cycle back to start */
407 ret = memcpy_s(buf + tail, bufSize - tail, dst, bufSize - tail);
408 if (ret != EOK) {
409 PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
410 return;
411 }
412 ret = memcpy_s(buf, bufSize, dst + bufSize - tail, logLen - (bufSize - tail));
413 if (ret != EOK) {
414 PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
415 return;
416 }
417
418 g_dmesgInfo->logTail = logLen - (bufSize - tail);
420 } else { /* no need cycle back to start */
421 ret = memcpy_s(buf + tail, bufSize - tail, dst, logLen);
422 if (ret != EOK) {
423 PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
424 return;
425 }
426 g_dmesgInfo->logTail += logLen;
427 if (g_dmesgInfo->logTail > BUF_MAX_INDEX) {
428 g_dmesgInfo->logTail = 0;
429 }
431 }
432 }
433}
434/// 从头写入
435STATIC VOID OsWriteTailToHead(const CHAR *dst, UINT32 logLen)
436{
437 UINT32 writeLen = 0;
438 UINT32 bufSize = g_logBufSize;
439 UINT32 logSize = g_dmesgInfo->logSize;
440 UINT32 tail = g_dmesgInfo->logTail;
441 CHAR *buf = g_dmesgInfo->logBuf;
442 errno_t ret;
443
444 if ((!logLen) || (dst == NULL)) {
445 return;
446 }
447 if (logLen > (bufSize - logSize)) { /* space-need > space-remain */
448 writeLen = bufSize - logSize;
449 ret = memcpy_s(buf + tail, bufSize - tail, dst, writeLen);
450 if (ret != EOK) {
451 PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
452 return;
453 }
454
457 OsBufFullWrite(dst + writeLen, logLen - writeLen);
458 } else {
459 ret = memcpy_s(buf + tail, bufSize - tail, dst, logLen);
460 if (ret != EOK) {
461 PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
462 return;
463 }
464
465 g_dmesgInfo->logTail += logLen;
466 g_dmesgInfo->logSize += logLen;
467 }
468}
469/// 从尾写入
470STATIC VOID OsWriteTailToEnd(const CHAR *dst, UINT32 logLen)
471{
472 UINT32 writeLen;
473 UINT32 bufSize = g_logBufSize;
474 UINT32 tail = g_dmesgInfo->logTail;
475 CHAR *buf = g_dmesgInfo->logBuf;
476 errno_t ret;
477
478 if ((!logLen) || (dst == NULL)) {
479 return;
480 }
481 if (logLen >= (bufSize - tail)) { /* need cycle to start ,then became B */
482 writeLen = bufSize - tail;
483 ret = memcpy_s(buf + tail, writeLen, dst, writeLen);
484 if (ret != EOK) {
485 PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
486 return;
487 }
488
489 g_dmesgInfo->logSize += writeLen;
490 g_dmesgInfo->logTail = 0;
491 if (g_dmesgInfo->logSize == g_logBufSize) { /* Tail = Head is 0 */
492 OsBufFullWrite(dst + writeLen, logLen - writeLen);
493 } else {
494 OsWriteTailToHead(dst + writeLen, logLen - writeLen);
495 }
496 } else { /* just do serial copy */
497 ret = memcpy_s(buf + tail, bufSize - tail, dst, logLen);
498 if (ret != EOK) {
499 PRINT_ERR("%s,%d memcpy_s failed, err:%d!\n", __FUNCTION__, __LINE__, ret);
500 return;
501 }
502
503 g_dmesgInfo->logTail += logLen;
504 g_dmesgInfo->logSize += logLen;
505 }
506}
507/// 内存拷贝日志
509{
510 UINT32 intSave;
511
512 LOS_SpinLockSave(&g_dmesgSpin, &intSave);
513 if (OsCheckError()) {
514 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
515 return -1;
516 }
519 OsWriteTailToEnd(buf, logLen);
520 } else {
521 OsWriteTailToHead(buf, logLen);
522 }
523 } else {
524 OsBufFullWrite(buf, logLen);
525 }
526 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
527
528 return LOS_OK;
529}
530/// 使用串口打印日志
531VOID OsLogShow(VOID)
532{
533 UINT32 intSave;
534 UINT32 index;
535 UINT32 i = 0;
536 CHAR *p = NULL;
537
538 LOS_SpinLockSave(&g_dmesgSpin, &intSave);
539 index = g_dmesgInfo->logHead;
540
541 p = (CHAR *)malloc(g_dmesgInfo->logSize + 1);
542 if (p == NULL) {
543 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
544 return;
545 }
546 (VOID)memset_s(p, g_dmesgInfo->logSize + 1, 0, g_dmesgInfo->logSize + 1);
547
548 while (i < g_dmesgInfo->logSize) {//一个一个字符拷贝
549 *(p + i) = *(g_dmesgInfo->logBuf + index++);
550 if (index > BUF_MAX_INDEX) {//循环buf,读到尾了得从头开始读
551 index = 0;
552 }
553 i++;
554 if (index == g_dmesgInfo->logTail) {//一直读到写入位置,才退出
555 break;
556 }
557 }
558 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
559 UartPuts(p, i, UART_WITH_LOCK);//串口输出
560 free(p);//释放内存
561}
562/// 设置日志层级
563STATIC INT32 OsDmesgLvSet(const CHAR *level)
564{
565 UINT32 levelNum, ret;
566 CHAR *p = NULL;
567
568 levelNum = strtoul(level, &p, 0);
569 if (*p != 0) {
570 PRINTK("dmesg: invalid option or parameter.\n");
571 return -1;
572 }
573
574 ret = LOS_DmesgLvSet(levelNum);
575 if (ret == LOS_OK) {
576 PRINTK("Set current dmesg log level %s\n", g_levelString[g_dmesgLogLevel]);
577 return LOS_OK;
578 } else {
579 PRINTK("current dmesg log level %s\n", g_levelString[g_dmesgLogLevel]);
580 PRINTK("dmesg -l [num] can access as 0:EMG 1:COMMON 2:ERROR 3:WARN 4:INFO 5:DEBUG\n");
581 return -1;
582 }
583}
584
585STATIC INT32 OsDmesgMemSizeSet(const CHAR *size)
586{
587 UINT32 sizeVal;
588 CHAR *p = NULL;
589
590 sizeVal = strtoul(size, &p, 0);
591 if (sizeVal > MAX_KERNEL_LOG_BUF_SIZE) {
592 goto ERR_OUT;
593 }
594
595 if (!(LOS_DmesgMemSet(NULL, sizeVal))) {
596 PRINTK("Set dmesg buf size %u success\n", sizeVal);
597 return LOS_OK;
598 } else {
599 goto ERR_OUT;
600 }
601
602ERR_OUT:
603 PRINTK("Set dmesg buf size %u fail\n", sizeVal);
604 return LOS_NOK;
605}
607{
608 return g_dmesgLogLevel;
609}
610
612{
613 if (level > 5) { /* 5: count of level */
614 return LOS_NOK;
615 }
616
617 g_dmesgLogLevel = level;
618 return LOS_OK;
619}
620
622{
623 UINT32 intSave;
624
625 LOS_SpinLockSave(&g_dmesgSpin, &intSave);
626 (VOID)memset_s(g_dmesgInfo->logBuf, g_logBufSize, 0, g_logBufSize);
627 g_dmesgInfo->logHead = 0;
628 g_dmesgInfo->logTail = 0;
629 g_dmesgInfo->logSize = 0;
630 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
631}
632/// 设置dmesg缓存大小
633UINT32 LOS_DmesgMemSet(const VOID *addr, UINT32 size)
634{
635 UINT32 ret = 0;
636
637 if (addr == NULL) {
638 ret = OsDmesgChangeSize(size);
639 } else {
640 ret = OsDmesgResetMem(addr, size);
641 }
642 return ret;
643}
644/// 读取 dmesg 消息
646{
647 INT32 ret;
648 UINT32 intSave;
649
650 if (buf == NULL) {
651 return -1;
652 }
653 if (len == 0) {
654 return 0;
655 }
656
657 LOS_SpinLockSave(&g_dmesgSpin, &intSave);
658 ret = OsDmesgRead(buf, len);
659 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
660 return ret;
661}
662
663INT32 OsDmesgWrite2File(const CHAR *fullpath, const CHAR *buf, UINT32 logSize)
664{
665 INT32 ret;
666
667 INT32 fd = open(fullpath, O_CREAT | O_RDWR | O_APPEND, 0644); /* 0644:file right */
668 if (fd < 0) {
669 return -1;
670 }
671 ret = write(fd, buf, logSize);
672 (VOID)close(fd);
673 return ret;
674}
675
676#ifdef LOSCFG_FS_VFS
677/// 将dmesg 保存到文件中
678INT32 LOS_DmesgToFile(const CHAR *filename)
679{
680 CHAR *fullpath = NULL;
681 CHAR *buf = NULL;
682 INT32 ret;
683 CHAR *shellWorkingDirectory = OsShellGetWorkingDirectory();//获取工作路径
684 UINT32 logSize, bufSize, head, tail, intSave;
685 CHAR *logBuf = NULL;
686
687 LOS_SpinLockSave(&g_dmesgSpin, &intSave);
688 if (OsCheckError()) {
689 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
690 return -1;
691 }
692 logSize = g_dmesgInfo->logSize;
693 bufSize = g_logBufSize;
694 head = g_dmesgInfo->logHead;
695 tail = g_dmesgInfo->logTail;
696 logBuf = g_dmesgInfo->logBuf;
697 LOS_SpinUnlockRestore(&g_dmesgSpin, intSave);
698
699 ret = vfs_normalize_path(shellWorkingDirectory, filename, &fullpath);//获取绝对路径
700 if (ret != 0) {
701 return -1;
702 }
703
704 buf = (CHAR *)malloc(logSize);
705 if (buf == NULL) {
706 goto ERR_OUT2;
707 }
708
709 if (head < tail) {
710 ret = memcpy_s(buf, logSize, logBuf + head, logSize);
711 if (ret != EOK) {
712 goto ERR_OUT3;
713 }
714 } else {
715 ret = memcpy_s(buf, logSize, logBuf + head, bufSize - head);
716 if (ret != EOK) {
717 goto ERR_OUT3;
718 }
719 ret = memcpy_s(buf + bufSize - head, logSize - (bufSize - head), logBuf, tail);
720 if (ret != EOK) {
721 goto ERR_OUT3;
722 }
723 }
724
725 ret = OsDmesgWrite2File(fullpath, buf, logSize);//写文件
726ERR_OUT3:
727 free(buf);
728ERR_OUT2:
729 free(fullpath);
730 return ret;
731}
732#else
734{
735 (VOID)filename;
736 PRINTK("File operation need VFS\n");
737 return -1;
738}
739#endif
740
741/**
742 * @brief
743dmesg全称是display message (or display driver),即显示信息。
744
745dmesg命令用于控制内核dmesg缓存区
746dmesg命令用于显示开机信息
747该命令依赖于LOSCFG_SHELL_DMESG,使用时通过menuconfig在配置项中开启"Enable Shell dmesg":
748
749Debug ---> Enable a Debug Version ---> Enable Shell ---> Enable Shell dmesg
750
751dmesg参数缺省时,默认打印缓存区内容。
752
753各“ - ”选项不能混合使用。
754
755写入文件需确保已挂载文件系统。
756关闭串口打印会影响shell使用,建议先连接telnet再尝试关闭串口。
757
758dmesg > /usr/dmesg.log。
759 * @param argc
760 * @param argv
761 * @return INT32
762 */
763INT32 OsShellCmdDmesg(INT32 argc, const CHAR **argv)
764{
765 if (argc == 1) {
766 PRINTK("\n");
767 OsLogShow();
768 return LOS_OK;
769 } else if (argc == 2) { /* 2: count of parameters */
770 if (argv == NULL) {
771 goto ERR_OUT;
772 }
773
774 if (!strcmp(argv[1], "-c")) {//打印缓存区内容并清空缓存区
775 PRINTK("\n");
776 OsLogShow();//打印缓存区内容
778 return LOS_OK;
779 } else if (!strcmp(argv[1], "-C")) {//清空缓存区。
781 return LOS_OK;
782 } else if (!strcmp(argv[1], "-D")) {//关闭控制台打印。
784 return LOS_OK;
785 } else if (!strcmp(argv[1], "-E")) {///开启控制台打印。
787 return LOS_OK;
788 } else if (!strcmp(argv[1], "-L")) {//关闭串口打印
789 OsLockUart();
790 return LOS_OK;
791 } else if (!strcmp(argv[1], "-U")) {//开启串口打印
792 OsUnlockUart();
793 return LOS_OK;
794 }
795 } else if (argc == 3) { /* 3: count of parameters */
796 if (argv == NULL) {
797 goto ERR_OUT;
798 }
799
800 if (!strcmp(argv[1], ">")) {//将缓存区内容写入文件
801 if (LOS_DmesgToFile((CHAR *)argv[2]) < 0) { /* 2:index of parameters */
802 PRINTK("Dmesg write log to %s fail \n", argv[2]); /* 2:index of parameters */
803 return -1;
804 } else {
805 PRINTK("Dmesg write log to %s success \n", argv[2]); /* 2:index of parameters */
806 return LOS_OK;
807 }
808 } else if (!strcmp(argv[1], "-l")) {//设置缓存等级
809 return OsDmesgLvSet(argv[2]); /* 2:index of parameters */
810 } else if (!strcmp(argv[1], "-s")) {//设置缓存区大小 size是要设置的大小
811 return OsDmesgMemSizeSet(argv[2]); /* 2:index of parameters */
812 }
813 }
814
815ERR_OUT:
816 PRINTK("dmesg: invalid option or parameter.\n");
817 return -1;
818}
819
821/*
822将扩展如下:
823CmdItem dmesg_shellcmd __attribute__((section(".liteos.table.shellcmd.data")))
824__attribute__((used)) = {CMD_TYPE_STD,"dmesg",XARGS,OsShellCmdDmesg}
825*/
826LOS_MODULE_INIT(OsDmesgInit, LOS_INIT_LEVEL_EARLIEST);//在非常早期调用
827
828#endif
@ CMD_TYPE_STD
支持的标准命令参数输入,所有输入的字符都会通过命令解析后被传入。
Definition: shell.h:90
char * OsShellGetWorkingDirectory(void)
Definition: shcmd.c:94
UINT32 OsCheckUartLock(VOID)
Definition: dmesg.c:328
STATIC VOID OsWriteTailToHead(const CHAR *dst, UINT32 logLen)
从头写入
Definition: dmesg.c:435
STATIC UINT32 OsCheckError(VOID)
读取dmesg日志
Definition: dmesg.c:113
STATIC CHAR OsLogRecordChar(CHAR c)
只记录一个字符
Definition: dmesg.c:352
STATIC UINT32 g_uartLock
用于关闭和打开串口
Definition: dmesg.c:83
LOS_MODULE_INIT(OsDmesgInit, LOS_INIT_LEVEL_EARLIEST)
STATIC VOID OsLockUart(VOID)
关闭串口
Definition: dmesg.c:103
INT32 OsDmesgWrite2File(const CHAR *fullpath, const CHAR *buf, UINT32 logSize)
Definition: dmesg.c:663
UINT32 OsLogRecordStr(const CHAR *str, UINT32 len)
记录一个字符串
Definition: dmesg.c:368
INT32 OsLogMemcpyRecord(const CHAR *buf, UINT32 logLen)
内存拷贝日志
Definition: dmesg.c:508
INT32 LOS_DmesgToFile(const CHAR *filename)
将dmesg 保存到文件中
Definition: dmesg.c:678
STATIC UINT32 g_consoleLock
用于关闭和打开控制台
Definition: dmesg.c:82
STATIC VOID OsUnlockConsole(VOID)
打开控制台
Definition: dmesg.c:98
STATIC INT32 OsDmesgRead(CHAR *buf, UINT32 len)
Definition: dmesg.c:131
STATIC UINT32 g_logBufSize
缓冲区内容体大小
Definition: dmesg.c:79
UINT32 LOS_DmesgLvSet(UINT32 level)
Set the dmesg level
Definition: dmesg.c:611
STATIC VOID OsWriteTailToEnd(const CHAR *dst, UINT32 logLen)
从尾写入
Definition: dmesg.c:470
STATIC VOID * g_mallocAddr
缓存区开始位置,即头位置
Definition: dmesg.c:80
STATIC UINT32 OsDmesgResetMem(const VOID *addr, UINT32 size)
重置内存
Definition: dmesg.c:232
VOID OsLogShow(VOID)
使用串口打印日志
Definition: dmesg.c:531
UINT32 LOS_DmesgMemSet(const VOID *addr, UINT32 size)
设置dmesg缓存大小
Definition: dmesg.c:633
SHELLCMD_ENTRY(dmesg_shellcmd, CMD_TYPE_STD, "dmesg", XARGS,(CmdCallBackFunc) OsShellCmdDmesg)
STATIC INT32 OsDmesgMemSizeSet(const CHAR *size)
Definition: dmesg.c:585
LITE_OS_SEC_BSS STATIC SPIN_LOCK_INIT(g_dmesgSpin)
STATIC const CHAR * g_levelString[]
Definition: dmesg.c:84
STATIC INT32 OsCopyToNew(const VOID *addr, UINT32 size)
把旧人账目移交给新人
Definition: dmesg.c:182
STATIC VOID OsLockConsole(VOID)
关闭控制台
Definition: dmesg.c:93
STATIC VOID OsUnlockUart(VOID)
打开串口
Definition: dmesg.c:108
STATIC VOID OsBufFullWrite(const CHAR *dst, UINT32 logLen)
Definition: dmesg.c:382
INT32 LOS_DmesgRead(CHAR *buf, UINT32 len)
读取 dmesg 消息
Definition: dmesg.c:645
STATIC INT32 OsDmesgLvSet(const CHAR *level)
设置日志层级
Definition: dmesg.c:563
VOID LOS_DmesgClear(VOID)
Clear dmesg log.
Definition: dmesg.c:621
UINT32 OsCheckConsoleLock(VOID)
Definition: dmesg.c:323
STATIC DmesgInfo * g_dmesgInfo
保存在 g_mallocAddr 的开始位置,即头信息
Definition: dmesg.c:78
STATIC UINT32 OsDmesgChangeSize(UINT32 size)
调整缓冲区大小,如下五个步骤
Definition: dmesg.c:273
UINT32 OsDmesgInit(VOID)
初始化 dmesg
Definition: dmesg.c:333
UINT32 OsDmesgLvGet(VOID)
Definition: dmesg.c:606
STATIC UINT32 g_dmesgLogLevel
日志等级
Definition: dmesg.c:81
INT32 OsShellCmdDmesg(INT32 argc, const CHAR **argv)
dmesg全称是display message (or display driver),即显示信息。
Definition: dmesg.c:763
int vfs_normalize_path(const char *directory, const char *filename, char **pathname)
Definition: fullpath.c:245
VOID LOS_SpinUnlockRestore(SPIN_LOCK_S *lock, UINT32 intSave)
Definition: los_spinlock.c:108
VOID LOS_SpinLockSave(SPIN_LOCK_S *lock, UINT32 *intSave)
Definition: los_spinlock.c:98
signed int INT32
Definition: los_typedef.h:60
unsigned long UINTPTR
Definition: los_typedef.h:68
unsigned int UINT32
Definition: los_typedef.h:57
char CHAR
Definition: los_typedef.h:63
void * malloc(size_t size)
动态分配内存块大小
Definition: malloc.c:81
void free(void *ptr)
释放ptr所指向的内存空间
Definition: malloc.c:66
UINT32 logTail
Definition: dmesg_pri.h:51
UINT32 logSize
Definition: dmesg_pri.h:49
UINT32 logHead
Definition: dmesg_pri.h:50
CHAR * logBuf
Definition: dmesg_pri.h:52
VOID UartPuts(const CHAR *s, UINT32 len, BOOL isLock)
u32_t(* CmdCallBackFunc)(u32_t argc, const char **argv)
Definition: types_adapt.h:86