dlt-daemon中带有一些示例程序,路径为dlt-daemon/examples/,这里对example1进行解析。
这个示例展示了怎样创建dlt程序,包括注册和取消注册,发送log等。log的值可通过dlt-viewer查看。
dlt对一些函数用宏进行了封装,这样可以减少开发的代码量。
示例1:
//example1.cpp
#include <stdio.h> /* for printf() and fprintf() */
#include <stdlib.h> /* for atoi() and exit() */
#include <dlt.h>
DLT_DECLARE_CONTEXT(con_exa1);
int main()
{
struct timespec ts;
DLT_REGISTER_APP("app1", "First Example");
DLT_REGISTER_CONTEXT(con_exa1, "con1", "First context");
DLT_LOG(con_exa1, DLT_LOG_INFO, DLT_STRING("Hello world! This is first example"));
ts.tv_sec = 1;
ts.tv_nsec = 1000000;
nanosleep(&ts, NULL);
DLT_UNREGISTER_CONTEXT(con_exa1);
//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-example1 )
#
# find dependency packages
#
find_package(PkgConfig)
pkg_check_modules(DLT REQUIRED automotive-dlt)
#
# include directories
#
include_directories(
${DLT_INCLUDE_DIRS}
)
#
# build project
#
set(dlt_example1_SRCS example1.c)
add_executable(dlt-example1 ${dlt_example1_SRCS})
target_link_libraries(dlt-example1 ${DLT_LIBRARIES})
set_target_properties(dlt-example1 PROPERTIES LINKER_LANGUAGE C)
install(TARGETS dlt-example1
RUNTIME DESTINATION bin
COMPONENT base)
运行步骤:
1. 运行dlt-daemon
2. 运行dlt-viewer
3. 运行example1,在dlt-viewer中查看结果
dlt-daemon/include/dlt/dlt_user_macros.h
/**
* Create an object for a new context.
* This macro has to be called first for every.
* @param CONTEXT object containing information about one special logging context
* @note To avoid the MISRA warning "Null statement is located close to other code or comments"
* remove the semicolon when using the macro.
* Example: DLT_DECLARE_CONTEXT(hContext)
*/
声明 DltContext对象,每个dlt程序都需要新建 DltContext对象。
#define DLT_DECLARE_CONTEXT(CONTEXT) \
DltContext CONTEXT;
dlt-daemon/include/dlt/dlt_user_macros.h
/**
* Register application.
* @param APPID application id with maximal four characters
* @param DESCRIPTION ASCII string containing description
*/
#define DLT_REGISTER_APP(APPID, DESCRIPTION) do { \
(void)dlt_check_library_version(_DLT_PACKAGE_MAJOR_VERSION, _DLT_PACKAGE_MINOR_VERSION); \
(void)dlt_register_app(APPID, DESCRIPTION); } while(false)
DLT_REGISTER_APP是一个注册函数的宏,展开后是这样的:
do{
(void)dlt_check_library_version(_DLT_PACKAGE_MAJOR_VERSION, _DLT_PACKAGE_MINOR_VERSION); //(1)
(void)dlt_register_app(APPID, DESCRIPTION);
}while(false)
(1)此句虽然是用来检测版本,但是没有它的处理返回值,相当于没判断。可以用dlt_register_app(APPID, DESCRIPTION)代替此宏。
/**
* Register context (with default log level and default trace status)
* @param CONTEXT object containing information about one special logging context
* @param CONTEXTID context id with maximal four characters
* @param DESCRIPTION ASCII string containing description
*/
#define DLT_REGISTER_CONTEXT(CONTEXT, CONTEXTID, DESCRIPTION) do { \
(void)dlt_register_context(&(CONTEXT), CONTEXTID, DESCRIPTION); } while (false)
调用 dlt_register_context函数注册context
/**
* Send log message with variable list of messages (intended for verbose mode)
* @param CONTEXT object containing information about one special logging context
* @param LOGLEVEL the log level of the log message
* @param ... variable list of arguments
* @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(hContext, DLT_LOG_INFO, DLT_STRING("Hello world"); DLT_INT(123));
*/
#ifdef _MSC_VER
/* DLT_LOG is not supported by MS Visual C++ */
/* use function interface instead */
#else
# define DLT_LOG(CONTEXT, LOGLEVEL, ...) \
do { \
DltContextData log_local; \
int dlt_local; \
dlt_local = dlt_user_log_write_start(&CONTEXT, &log_local, LOGLEVEL); \
if (dlt_local == DLT_RETURN_TRUE) \
{ \
__VA_ARGS__; \
(void)dlt_user_log_write_finish(&log_local); \
} \
} while
发送一个带有可变消息列表的日志
参数CONTEXT:CONTEXT 对象,其中包含有关一个特殊日志记录上下文的信息。
参数LOGLEVEL: 日志消息的等级。
log等级划分:
/**
* Definitions of DLT log level
*/
typedef enum
{
DLT_LOG_DEFAULT = -1, /**< Default log level */
DLT_LOG_OFF = 0x00, /**< Log level off */
DLT_LOG_FATAL = 0x01, /**< fatal system error */
DLT_LOG_ERROR = 0x02, /**< error with impact to correct functionality */
DLT_LOG_WARN = 0x03, /**< warning, correct behaviour could not be ensured */
DLT_LOG_INFO = 0x04, /**< informational */
DLT_LOG_DEBUG = 0x05, /**< debug */
DLT_LOG_VERBOSE = 0x06, /**< highest grade of information */
DLT_LOG_MAX /**< maximum value, used for range check */
} DltLogLevelType;
/**
* Unregister context.
* @param CONTEXT object containing information about one special logging context
*/
#define DLT_UNREGISTER_CONTEXT(CONTEXT) do { \
(void)dlt_unregister_context(&(CONTEXT)); } while(false)
在dlt-daemon中注销context
DLT_UNREGISTER_APP
/**
* Unregister application.
*/
#define DLT_UNREGISTER_APP() do { \
(void)dlt_unregister_app(); } while(false)
在dlt-daemon中注销app
运行结果,可以在dlt-viewer中看到打印的log