DLT 示例应用

要在应用程序中使用 DLT,它必须链接到 DLT 库。在系统上安装 DLT 守护程序后,将有一个名为 libdlt.so 的共享库,它为应用程序提供接口以获取与 DLT 守护程序的连接。在使用共享 dlt 库构建程序之前,必须在构建环境中设置库路径和包含路径。默认情况下,头文件“dlt.h”位于标准包含目录中名为“dlt/”的目录中。

此示例通过使用最少的代码示例概述了应用程序内部的 DLT 使用情况。

#include <dlt/dlt.h>DLT_DECLARE_CONTEXT(ctx); /* declare context */int main()
{DLT_REGISTER_APP("TAPP", "Test Application for Logging");DLT_REGISTER_CONTEXT(ctx, "TES1", "Test Context for Logging");/* … */DLT_LOG(ctx, DLT_LOG_ERROR, DLT_CSTRING("This is an error"));/* … */DLT_UNREGISTER_CONTEXT(ctx);DLT_UNREGISTER_APP();return 0;
}

DLT 非常易于使用。开发人员必须做的第一件事是包含 dlt 头文件。可以使用下一行中显示的宏静态声明 DLT 上下文。首先,必须在主函数内注册一个 DLT 应用程序。为此,必须指定应用程序标识符 APID 和应用程序描述。之后,可以指定一个或多个 DLT 上下文。要以详细模式记录消息,可以使用 DLT_LOG 宏。作为参数,必须指定日志上下文、日志级别和参数变量列表。 DLT 要求使用 DLT 类型宏对每个参数进行强类型化。在本例中,DLT_CSTRING 用于指定一个常量字符串。在应用程序清理时,所有 DLT 上下文以及 DLT 应用程序都必须注销。

cmake 中如何加入 DLT

要将 DLT 加入 CMake,推荐的方法是使用作为安装一部分生成的 CMake 配置文件。

你可以这样:

find_package(automotive-dlt REQUIRED)
...
target_link_libraries(myapp PRIVATE Genivi::DLT)

这让您的项目自动获得 libdlt 所需的所有必要编译和链接标志,包括包含目录。

生成的 CMake 配置文件遵循“Modern CMake”约定,并且只导出一个 IMPORTED CMake 目标;它不设置任何变量,除了可用于将 DLT 视为可选依赖项的automotive-dlt_FOUND 变量。

生成的 CMake 配置文件(在调用 find_package(automotive-dlt) 时隐式使用)默认仅将顶级目录添加到编译器的头文件搜索路径中;这要求用户的 #include 指令以常规形式编写,例如<dlt/dlt.h>。如果您还希望能够使用旧形式 <dlt.h>(出于向后兼容性原因,pkg-config 模块始终允许使用),您可以使用 CMake 选项 -DWITH_LEGACY_INCLUDE_PATH=On 配置 DLT,以便达到目的。

DLT使用 pkg​​-config

除了上面详述的 CMake 集成之外,还可以通过 pkg-config 使用 DLT。这也可以通过 CMake 的 PkgConfig 模块来完成。

PkgConfig 与“Modern CMake”的使用

在这里,您也让 PkgConfig 模块创建目标;然而,目标的名称由 PkgConfig 模块确定:

find_package(PkgConfig)
pkg_check_modules(DLT REQUIRED IMPORTED_TARGET automotive-dlt)

根据“Modern CMake”,不需要再添加的变量,而只有要添加到链接库的 CMake 目标:

target_link_libraries(myapp PRIVATE PkgConfig::DLT)

PkgConfig 与“Legacy CMake”(<3.0)的使用

在这里,您让 PkgConfig 模块只创建变量,而不创建目标:

find_package(PkgConfig)
pkg_check_modules(DLT REQUIRED automotive-dlt)

到 INCLUDE_DIRECTORIES(或者,从 CMake 2.8.11 开始,TARGET_INCLUDE_DIRECTORIES),添加

${DLT_INCLUDE_DIRS}

TARGET_LINK_LIBRARIES:

${DLT_LINK_LIBRARIES}  (preferred, for CMake >= 3.12)
${DLT_LIBRARIES}       (otherwise)

${DLT_LIBRARIES} 的内容不包括库的路径(例如 -L/path/to/lib),因此如果库驻留在不在链接器默认搜索路径上的位置,您要么必须添加LINK_DIRECTORIES 的路径:

link_directories(${DLT_LIBRARY_DIRS})

或者,不使用 ${DLT_LIBRARIES},而是使用 ${DLT_LDFLAGS},它结合了 ${DLT_LIBRARIES} 和 ${DLT_LIBRARY_DIRS}:

target_link_libraries(myapp ${DLT_LDFLAGS})

局限性

在 Android 上,应避免在 DLT 应用程序中定义 SIGUSR1,因为 DLT 库会阻止 SIGUSR1 在退出时终止管家线程。

测试工程源码

下面是我的工程:

dlt_test/
├── CMakeLists.txt
├── dlt_test.c
└── LICENSE

dlt_test.c

#include <dlt/dlt.h>DLT_DECLARE_CONTEXT(ctx); /* declare context */int main()
{DLT_REGISTER_APP("TAPP", "Test Application for Logging");// DLT_REGISTER_CONTEXT(ctx, "TES1", "Test Context for Logging");// 向守护进程注册新的上下文,初始日志级别为DLT_LOG_VERBOSEDLT_REGISTER_CONTEXT_LL_TS(ctx, "TES1", " First context ", DLT_LOG_VERBOSE, DLT_TRACE_STATUS_OFF);// dlt_register_context_ll_ts(&ctx, "TES1", " First context ", DLT_LOG_VERBOSE, DLT_TRACE_STATUS_OFF);/* … */sleep(3);DLT_LOG(ctx, DLT_LOG_VERBOSE , DLT_CSTRING("This is an error"));/* … */sleep(3);DLT_UNREGISTER_CONTEXT(ctx);DLT_UNREGISTER_APP();return 0;
}

CMakeLists.txt

# for dlt_testcmake_minimum_required (VERSION 3.0)
# The version number.
set (rtser_VERSION_MAJOR 0)
set (rtser_VERSION_MINOR 1)
set (rtser_VERSION_PATCH 0)
######################### Project settings #####################################
project(dlt_test)
#打印make详细信息
set(CMAKE_VERBOSE_MAKEFILE on)
#设置编译级别
add_definitions (-Wall -g)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0")
#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0 -pthread")
#include( FindPkgConfig )######## config inc&src&linklib settings and build #############################
find_package(PkgConfig)
pkg_check_modules(DLT REQUIRED IMPORTED_TARGET automotive-dlt)
include_directories(
)link_directories(
)file(GLOB SOURCES"*.c"
)add_executable(dlt_test${SOURCES}
)target_link_libraries(dlt_test PRIVATE PkgConfig::DLT)#安装位置
set(CMAKE_INSTALL_PREFIX ${PROJECT_BINARY_DIR})
# build a CPack driven installer package
include (InstallRequiredSystemLibraries)
set (CPACK_RESOURCE_FILE_LICENSE  "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set (CPACK_PACKAGE_VERSION_MAJOR "${rtser_VERSION_MAJOR}")
set (CPACK_PACKAGE_VERSION_MINOR "${rtser_VERSION_MINOR}")
set (CPACK_PACKAGE_VERSION_PATCH "${rtser_VERSION_PATCH}")
include (CPack)######## Install targets ########
install(TARGETS dlt_testRUNTIME DESTINATION  /usr/bin/
)

记录的一般规则

需要在关键位置打印log,例如错误处理,不要乱用log,因为打印log需要消耗资源;

避免高频输出;

合并多条消息,请始终考虑每条日志消息都会产生一定的开销。所有必要的信息总是被组合在一起。此类log通常使用正则表达式 - 让工作更轻松!

不要使用 ASCII art;

不要使用 ASCII 创建图表;

避免在循环中跟踪;

日志级别的使用

DLT 中提供以下日志级别:

DLT_LOG_FATAL 致命的系统错误,应该很少见

DLT_LOG_ERROR 影响正确功能的错误

DLT_LOG_WARN 无法确保正确行为时发出警告

DLT_LOG_INFO 信息,提供高层次的理解

DLT_LOG_DEBUG 程序员详细调试信息

DLT_LOG_VERBOSE 程序员的详细调试信息

请注意默认日志级别设置为 INFO;这意味着记录在 INFO、WARN、ERROR 和 FATAL 中的消息将被记录。提示:可以通过设置环境变量来更改默认日志级别(请参阅 DLT 库 - 运行时配置)。

DLT API 使用

注册申请

重要的提示:因为 DLT是非异步线程安全函数,所以在子线程中不能使用。

DLT_REGISTER_APP 是异步的。建立 IPC 通道可能需要几毫秒的时间。因此,如果您在注册后立即登录,可能会丢失消息。在应用程序初始化期间,必须通过调用 DLT_REGISTER_APP() 尽早注册 DLT 应用程序。每个应用程序只允许调用一次 DLT_REGISTER_APP()。必须指定应用程序 ID(最多四个字符)并且在 ECU 中必须是唯一的。在这个例子中使用了“MAPP”。并且还可以指定应用程序的描述,这里是“用于日志记录的测试应用程序”。

int main(int argc, const char* argv[])
{DLT_REGISTER_APP("MAPP","Test Application for Logging");
}

获取应用程序 ID

要获取应用程序 ID 值,请求分配一个至少 4 字节长度的字符数组并输入到函数调用中。

应用程序 ID 将存储在此输入字符数组中。

MACRO

DLT_GET_APPID(appid);

Function

dlt_get_appid(appid);

定义和注册所有日志上下文

可以根据需要定义尽可能多的上下文。这些上下文可以在不同的 C 或 CPP 文件中声明为上下文。但是每个上下文只允许声明一次。因此,必须为每个上下文使用唯一的变量名称。

DLT_DECLARE_CONTEXT(myContext1);
DLT_DECLARE_CONTEXT(myContext2);
DLT_DECLARE_CONTEXT(myContext3);

如果应使用来自另一个 C 或 CPP 文件的上下文,则可以通过调用来导入这些上下文:

DLT_IMPORT_CONTEXT(myContext1);
DLT_IMPORT_CONTEXT(myContext2);
DLT_IMPORT_CONTEXT(myContext3);

在注册应用程序并声明上下文后,需要在应用程序初始化期间尽早注册上下文。 DLT_REGISTER_CONTEXT() 不应在 DLT_REGISTER_APP() 之前调用。

在注册每个上下文期间,必须提供一个上下文 ID(最多四个字符)。在这个例子中使用了“TESX”。还可以提供上下文的描述;这里是“用于日志记录的测试上下文 X”。还可以使用宏 DLT_REGISTER_CONTEXT_LL_TS 使用预定义的日志级别和跟踪状态注册上下文。使用此方法注册第三个上下文。

int main(int argc, const char* argv[])
{DLT_REGISTER_APP("MAPP","Test Application for Logging");DLT_REGISTER_CONTEXT(myContext1,"TES1","Test Context 1 for Logging");DLT_REGISTER_CONTEXT(myContext2,"TES2","Test Context 2 for Logging");DLT_REGISTER_CONTEXT_LL_TS(myContext3, "TES3","Test Context 3 for Logging",DLT_LOG_DEBUG, DLT_TRACE_STATUS_OFF);
}

注意:请注意,在 DLT 守护程序和应用程序之间的日志级别同步完成之前,可能需要一秒钟的时间。

注销上下文和应用程序

在终止应用程序注册的上下文之前,最后需要取消注册应用程序。

int main(int argc, const char* argv[])
{
/* business logic */DLT_UNREGISTER_CONTEXT(myContext1);DLT_UNREGISTER_CONTEXT(myContext2);DLT_UNREGISTER_CONTEXT(myContext3);DLT_UNREGISTER_APP();return 0;
}

log命令

DLT 提供的函数允许使用任意数量的参数灵活构建消息。支持 Verbose 和 Non-Verbose 消息,具有不同的 API。使用这些函数发送消息需要多个函数调用,以启动消息构造、添加参数和发送消息。

下表显示了使用常量字符串和整数进行日志记录的所有 4 种类型的示例。

Verbose与非Verbose API

以下部分显示了所有 4 种日志类型的示例,例如一个字符串和一个整数。

MACRO

Verbose

DLT_LOG(ctx, DLT_LOG_INFO, DLT_STRING("ID: "), DLT_UINT32(123));

Non-Verbose

DLT_LOG_ID(ctx, DLT_LOG_INFO, 42 /* unique message ID */, DLT_STRING("ID: "),DLT_UINT32(123));

Function

Verbose

if (dlt_user_log_write_start(&ctx, &ctxdata, DLT_LOG_INFO) > 0) {dlt_user_log_write_string(&myctxdata, "ID: ");dlt_user_log_write_uint32(&myctxdata, 123);dlt_user_log_write_finish(&myctxdata);
}

Non-Verbose

if (dlt_user_log_write_start_id(&ctx, &ctxdata, DLT_LOG_INFO, 42) > 0) {dlt_user_log_write_string(&myctxdata, "ID: ");dlt_user_log_write_uint32(&myctxdata, 123);dlt_user_log_write_finish(&myctxdata);
}

记录参数

可以使用以下参数类型。可以将多个参数添加到单个日志消息中。所有日志参数的大小加在一起不应超过 1390 字节,包括 DLT 消息头。

类型 说明

DLT_STRING(TEXT) 字符串

DLT_STRING_ATTR(TEXT,NAME) 字符串(带属性)

DLT_SIZED_STRING(TEXT,LENGTH) 已知长度的字符串

DLT_SIZED_STRING_ATTR(TEXT,LENGTH,NAME) 已知长度的字符串(带属性)

DLT_CSTRING(TEXT) 常量字符串(不以非详细模式发送)

DLT_CSTRING_ATTR(TEXT,NAME) 常量字符串(带属性;不以非详细模式发送)

DLT_SIZED_CSTRING(TEXT,LENGTH) 已知长度的常量字符串(不以非详细模式发送)

DLT_SIZED_CSTRING_ATTR(TEXT,LENGTH,NAME) 已知长度的常量字符串(带属性;不以非详细模式发送)

DLT_UTF8(TEXT) utf8 编码的字符串

DLT_UTF8_ATTR(TEXT,NAME) Utf8 编码字符串(带属性)

DLT_SIZED_UTF8(TEXT,LENGTH) 已知长度的 Utf8 编码字符串

DLT_SIZED_UTF8_ATTR(TEXT,LENGTH,NAME) 已知长度的 utf8 编码字符串(带属性)

DLT_RAW(BUF,LENGTH) 原始缓冲区

DLT_RAW_ATTR(BUF,LENGTH,NAME) 原始缓冲区(带属性)

DLT_INT(VAR) 整数变量,取决于平台

DLT_INT_ATTR(VAR,NAME,UNIT) 整数变量,取决于平台(带属性)

DLT_INT8(VAR) 整数 8 位变量

DLT_INT8_ATTR(VAR,NAME,UNIT) 整数 8 位变量(带属性)

DLT_INT16(VAR) 整数 16 位变量

DLT_INT16_ATTR(VAR,NAME,UNIT) 整数 16 位变量(带属性)

DLT_INT32(VAR) 整数 32 位变量

DLT_INT32_ATTR(VAR,NAME,UNIT) 整数 32 位变量(带属性)

DLT_INT64(VAR) 整数 64 位变量

DLT_INT64_ATTR(VAR,NAME,UNIT) 整数 64 位变量(带属性)

DLT_UINT(VAR) 无符号整数变量

DLT_UINT_ATTR(VAR,NAME,UNIT) 无符号整数变量(带属性)

DLT_UINT8(VAR) 无符号 8 位整数变量

DLT_UINT8_ATTR(VAR,NAME,UNIT) 无符号 8 位整数变量(带属性)

DLT_UINT16(VAR) 无符号 16 位整数变量

DLT_UINT16_ATTR(VAR,NAME,UNIT) 无符号 16 位整数变量(带属性)

DLT_UINT32(VAR) 无符号 32 位整数变量

DLT_UINT32_ATTR(VAR,NAME,UNIT) 无符号 32 位整数变量(带属性)

DLT_UINT64(VAR) 无符号 64 位整数变量

DLT_UINT64_ATTR(VAR,NAME,UNIT) 无符号 64 位整数变量(带属性)

DLT_BOOL(VAR) 布尔变量

DLT_BOOL_ATTR(VAR,NAME) 布尔变量(带属性)

DLT_FLOAT32(VAR) 浮点型 32 位变量

DLT_FLOAT32_ATTR(VAR,NAME,UNIT) 浮点型 32 位变量(带属性)

DLT_FLOAT64(VAR) Float 64 位变量

DLT_FLOAT64_ATTR(VAR,NAME,UNIT) Float 64 位变量(带属性)

DLT_HEX8(UINT_VAR) 8 位十六进制值

DLT_HEX16(UINT_VAR) 16 位十六进制值

DLT_HEX32(UINT_VAR) 32 位十六进制值

DLT_HEX64(UINT_VAR) 64 位十六进制值

DLT_BIN8(UINT_VAR) 8 位二进制值

DLT_BIN16(UINT_VAR 16 位二进制值

DLT_PTR(PTR_VAR) 用于打印指针的架构独立宏

Diagnostic Log and Trace——开发人员如何使用 DLT相关推荐

  1. Diagnostic Log and Trace——dlt的编译和安装

    概述 GENIVI DLT 提供日志和跟踪接口,基于 AUTOSAR 标准 4.0 DLT 中指定的标准化协议.它被其他 GENIVI 组件使用,但可以作为其他应用程序的日志框架,与 GENIVI 无 ...

  2. 【DLT学习笔记2】-- 什么是DLT?(Diagnostic Log and Trace)

    DLTGENIVI项目下的log软件工程 DLT包括:DLT daemon DTL viewer两个子工程. DLT daemon运行在ECU上,DTLviewer运行在调试PC上. github地址 ...

  3. DLT(Diagnostic Log and Trace)嵌入式系统程序运行记录

    http://blog.csdn.net/yanlinembed/article/details/49837975 DLT的使用有属于Application范畴与Context范畴.在使用DLT时,需 ...

  4. Diagnostic Log and Trace——DLT 离线日志存储

    doc/dlt_offline_logstorage.md · RTplay/dlt-daemon - Gitee.com DLT离线日志存储介绍 Logstorage 是一种将 DLT 日志存储在目 ...

  5. 面向JavaScript开发人员的Adobe AIR与Dreamweaver

    入门教程,非常详细,CS4里面应该可以省略前面几步直接开发了. Adobe AIR对于HTML/JavaScript应用程序与桌面的集成有着出色的支持,但除了所有附加功能之外,还需要一些其他工具和技术 ...

  6. 面向.NET开发人员的Dapr——可观察性

    目录: 面向.NET开发人员的Dapr--前言 面向.NET开发人员的Dapr--分布式世界 面向.NET开发人员的Dapr--俯瞰Dapr 面向.NET开发人员的Dapr--入门 面向.NET开发人 ...

  7. 为什么JavaScript仅在IE中打开开发人员工具一次后才能工作?

    IE9错误-JavaScript仅在打开开发人员工具一次后才能工作. 我们的网站为用户提供免费的pdf下载,并且具有简单的"输入密码下载"功能. 但是,它根本无法在Internet ...

  8. 终端软件升级功能开发_5个很棒的终端技巧可帮助您升级为开发人员

    终端软件升级功能开发 There are plenty of beginner tutorials around that help you learn command line basics, su ...

  9. 初级开发人员的缺点_作为一名初级开发人员,我如何努力克服自己的挣扎

    初级开发人员的缺点 by Syeda Aimen Batool 通过Syeda Aimen Batool 作为一名初级开发人员,我如何努力克服自己的挣扎 (How I'm working to ove ...

最新文章

  1. ADPRL - 近似动态规划和强化学习 - Note 8 - 近似策略迭代 (Approximate Policy Iteration)
  2. C++建立动态二维数组
  3. C语言常用字符串操作函数大全详解(strstr,strtok,strrchr,strcat,strcmp,strcpy,strerror,strspn,strchr等)
  4. ViT(Vision Transformer)学习
  5. C++ 什么是伪函数,以及伪函数的使用
  6. Decorator模式设计模式
  7. 数学基础知识总结 —— 12. 求极限的重要工具「洛必达法则」
  8. 各邮箱的邮件接收服务器和发送服务器
  9. php中fastcgi和php-fpm是什么
  10. 选择变色镜片——爱眼护眼
  11. flutter引入高德地图_Flutter接入高德地图后运行报错
  12. 微信小程序----Grid(九宫格)(flex实现九宫格布局)
  13. 如何清除注册表中的Java安装信息
  14. 软考证书可以落户上海吗?很多人不知道
  15. Android studio百度地图SDK开发 2020最新超详细的Android 百度地图开发讲解(6) POI检索, 根据地址输入提示检索 Sug
  16. MATLAB2018
  17. esp8266 mesh 组网
  18. 设置.exe程序图标(ico文件)
  19. RPM包安装或者安装源码包
  20. ORA-00604: error occurred at recursive SQL level 1 ...——oracle服务空间不足

热门文章

  1. AE实例教程-使用AE制作图标动效
  2. 玩转kindle paperwhite: 如何越狱,安装强大外挂软件koreader
  3. 专题:知乎推荐学习APP评测目录及计划
  4. 四种区块链底层技术形态的对比解读
  5. Centos7安装教程图示
  6. win10桌面图标和任务栏图标一直闪烁,就和刷新一样,怎么解决?
  7. java使用poi导出excel太慢
  8. python中的None与False
  9. 苹果虚拟home键_好奇?手机为什么现在都是虚拟键?终于明白了!
  10. Ubuntu使用Foxit Reader + GoldenDict实现PDF划译