DLT:dlt-daemon示例解析
回顾一下上期第一个示例打印DLT日志的流程。
这次来分析第二个示例。
目录dlt-daemon/examples/example2/下有以下文件
CMakeLists.txt dlt_id.h example2.c example2.xml
其中example2.xml编译用不到,里面描述了一些程序的信息,我们先不管它。
// CMakeLists.txt
#######
# SPDX license identifier: MPL-2.0
#
# Copyright (C) 2011-2015, BMW AG
#
# This file is part of GENIVI Project DLT - Diagnostic Log and Trace.
#
# This Source Code Form is subject to the terms of the
# Mozilla Public License (MPL), v. 2.0.
# If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
#
# For further information see http://www.genivi.org/.
########
# DLT example implementation
#cmake_minimum_required( VERSION 2.6 )
project( automotive-dlt-example2 )#
# find dependency packages
#find_package(PkgConfig)
pkg_check_modules(DLT REQUIRED automotive-dlt)#
# include directories
#include_directories(${DLT_INCLUDE_DIRS}
)#
# build project
#set(dlt_example2_SRCS example2.c)
add_executable(dlt-example2 ${dlt_example2_SRCS})
target_link_libraries(dlt-example2 ${DLT_LIBRARIES})
set_target_properties(dlt-example2 PROPERTIES LINKER_LANGUAGE C)install(TARGETS dlt-example2RUNTIME DESTINATION binCOMPONENT base)
//dlt_id.h
/** SPDX license identifier: MPL-2.0** Copyright (C) 2011-2015, BMW AG** This file is part of GENIVI Project DLT - Diagnostic Log and Trace.** This Source Code Form is subject to the terms of the* Mozilla Public License (MPL), v. 2.0.* If a copy of the MPL was not distributed with this file,* You can obtain one at http://mozilla.org/MPL/2.0/.** For further information see http://www.genivi.org/.*//* generated file, do not edit */#ifndef DLT_ID_H
#define DLT_ID_H#define DLT_EXA2_CON_EXA2_ID1 1000
#define DLT_EXA2_CON_EXA2_ID2 1001
#define DLT_EXA2_CON_EXA2_ID3 1002#endif /* DLT_ID_H */
文件中用宏定义了3个ID,打印log时使用,没有什么特殊意义。
//example2.c
/** SPDX license identifier: MPL-2.0** Copyright (C) 2011-2015, BMW AG** This file is part of GENIVI Project DLT - Diagnostic Log and Trace.** This Source Code Form is subject to the terms of the* Mozilla Public License (MPL), v. 2.0.* If a copy of the MPL was not distributed with this file,* You can obtain one at http://mozilla.org/MPL/2.0/.** For further information see http://www.genivi.org/.*//*!* \author Alexander Wenzel <alexander.aw.wenzel@bmw.de>** \copyright Copyright © 2011-2015 BMW AG. \n* License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.** \file example2.c*//*******************************************************************************
** **
** SRC-MODULE: example2.c **
** **
** TARGET : linux **
** **
** PROJECT : DLT **
** **
** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
** **
** PURPOSE : **
** **
** REMARKS : **
** **
** PLATFORM DEPENDANT [yes/no]: yes **
** **
** TO BE CHANGED BY USER [yes/no]: no **
** **
*******************************************************************************/#include <stdio.h> /* for printf() and fprintf() */
#include <stdlib.h> /* for atoi() and exit() */#include <dlt.h>#include "dlt_id.h"DLT_DECLARE_CONTEXT(con_exa2);int main()
{int num;struct timespec ts;DLT_REGISTER_APP("EXA2", "Third Example");DLT_REGISTER_CONTEXT(con_exa2, "CON", "First context");DLT_NONVERBOSE_MODE();for (num = 0; num < 10; num++) {DLT_LOG_ID(con_exa2, DLT_LOG_INFO, DLT_EXA2_CON_EXA2_ID1, DLT_INT32(12345678), DLT_STRING("Hello world 1!"));DLT_LOG_ID(con_exa2, DLT_LOG_ERROR, DLT_EXA2_CON_EXA2_ID2, DLT_INT32(87654321), DLT_STRING("Hello world 2!"));DLT_LOG_ID(con_exa2, DLT_LOG_WARN, DLT_EXA2_CON_EXA2_ID3, DLT_INT32(11223344), DLT_STRING("Hello world 3!"));ts.tv_sec = 0;ts.tv_nsec = 1000000;nanosleep(&ts, NULL);}DLT_UNREGISTER_CONTEXT(con_exa2);DLT_UNREGISTER_APP();
}
Application ID是“EXA2”, Context ID是“CON”。
这里的流程与示例1相比有变化:
1. 增加了DLT_NONVERBOSE_MODE设置。
2. 打印log的位置换成了 DLT_LOG_ID.
3. 打印的内容变成多条,更贴近实际。
4. 每条消息中的等级不同,包括INFO,ERROR,WARN等。消息中增加了ID,消息包括int和String多种类型。
三条消息每条打印10次。
DLT_NONVERBOSE_MODE
/*** Switch to non-verbose mode**/
#define DLT_NONVERBOSE_MODE() do { \(void)dlt_nonverbose_mode(); } while(false)
这个宏调用了dlt_nonverbose_mode()函数,含义为切换到非冗余模式。默认是冗余模式。
简单说明下非冗余模式和冗余模式:
NonVerbose Mode
To be able to transmit parameter values only - without the need of any meta information about them -, additional properties like parameter names or types -, the Non-Verbose Mode can be used.
To allow the correct disassembly of the contained parameter values within a received Dlt message, a dedicated Message ID is added to the payload.
A separate, external file contains the description of the payload layout according to the corresponding Message ID.
概况的说就是传递消息比较简洁。
数据格式如下,消息头后面就是消息ID和数据
Verbose Mode
Dlt messages which are sent in Verbose Mode contain a complete description of the parameters next to the parameter values itself.
This means that on the one hand no external file is needed for disassembly; On the other hand, a higher amount of data is sent on the bus.
The Verbose Mode can be used on ECUs where enough memory and high network bandwidth are available. Because of the self-description, the stored data on the external client is interpretable at any time and without any further external information.
通俗的含义就是什么详细信息都发,发的数据多所以用在内存充足而且网络带宽高的地方。
数据格式比上面详细很多。
DLT_LOG_ID
/*** Send log message with variable list of messages (intended for non-verbose mode)* @param CONTEXT object containing information about one special logging context* @param LOGLEVEL the log level of the log message* @param MSGID the message id of log message* @param ... variable list of arguments* calls to DLT_STRING(), DLT_BOOL(), DLT_FLOAT32(), DLT_FLOAT64(),* DLT_INT(), DLT_UINT(), DLT_RAW()* @note To avoid the MISRA warning "The comma operator has been used outside a for statement"* use a semicolon instead of a comma to separate the __VA_ARGS__.* Example: DLT_LOG_ID(hContext, DLT_LOG_INFO, 0x1234, DLT_STRING("Hello world"); DLT_INT(123));*/
#ifdef _MSC_VER
/* DLT_LOG_ID is not supported by MS Visual C++ */
/* use function interface instead */
#else
# define DLT_LOG_ID(CONTEXT, LOGLEVEL, MSGID, ...) \do { \DltContextData log_local; \int dlt_local; \dlt_local = dlt_user_log_write_start_id(&CONTEXT, &log_local, LOGLEVEL, MSGID); \if (dlt_local == DLT_RETURN_TRUE) \{ \__VA_ARGS__; \(void)dlt_user_log_write_finish(&log_local); \} \} while(false)
#endif
发送带有消息变量列表的日志消息(用于NonVerbose Mode)。日志带ID。
带有ID的日志更有实用性,可以区分不同来源的日志。运行的结果在dlt-viewer中显示如下:
只关注log日志(而且是打印消息的),其他消息由DLT处理不关注。解析第1条打印log日志:
[1000] Na----Hello world 1!-|4e 61 bc 00 0f 00 48 65 6c 6c 6f 20 77 6f 72 6c 64 20 31 21 00
1000:表示MSGID,就是程序里面的DLT_EXA2_CON_EXA2_ID1
Na----Hello world 1!-:表示LOG数据DLT_INT32(12345678)和DLT_STRING("Hello world 1!")
其中12345678写成16进制为0x00bc614e,在小端模式存储时,写成4e 61 bc 00。其余字符按照ASCII码显示。
4e 61 bc 00 0f 00 48 65 6c 6c 6f 20 77 6f 72 6c 64 20 31 21 00这串数字表示DLT_INT32(12345678)和DLT_STRING("Hello world 1!")的ASCII码值。
其他条目的日志类似。