【研发日记】白话解读UDS协议(一)——19 04读取快照服务

2024-04-04 12:28

本文主要是介绍【研发日记】白话解读UDS协议(一)——19 04读取快照服务,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

前言

19服务

04子服务

19 04协议

快照存储设计

快照发送设计

功能验证

分析和应用

总结


前言

        近期在一个嵌入式软件开发项目中,要按照UDS标准开发相关功能,期间在翻阅UDS标准时,周围同事都说很多地方晦涩难懂。所以利用晚上和周末时间,把这些内容标注了一下,用大白话把他们解释出来。后面会用若干篇文章把它总结分享出来,一方面备着将来翻看,另一方面也希望能够帮到这一领域的粉丝朋友们。

19服务

        在UDS中,诊断仪被认为是客户端,ECU被认为是服务端,所以ECU中的一项UDS功能就被叫做一项服务,19服务是UDS中读取DTC故障相关信息的一类子服务的总称。官方文档中的描述示例如下:

        19服务中包含了很多子服务,最常用的其实就只有两个,19 02子服务是读取故障码的,19 04子服务是读取故障码的快照的。本文主要解析19 04这个子服务。

04子服务

        快照(Snapshot),从字面上理解意思就是,快门触发的瞬间,记录下来这一时刻的各种信息。放在UDS中来讲就是,发生某一故障(DTC)时,记录并存储这一时刻的ECU信息,比如铅酸供电电压、工作温度、车辆档位、车速、里程、日历时间等等。19 04服务的作用就是支持诊断仪把这一快照信息,按照协议从ECU中读取出来。官方文档中的描述示例如下:

        对于我们开发19 04服务而言,就是在ECU中开发这一功能,实现存快照和发送快照的功能。

19 04协议

        首先,诊断仪向ECU发送19 04请求指令,格式如下:

        其中DTCMaskRecord[]是某个故障的故障码。DTCSnapshotGroupNumber是快照内容的分组号,就像快门中照片九宫格一样,每个部分都有一个编号。01代表第一个分组,02代表第二个分组,依次类推。如果想读取全部的快照内容,把DTCSnapshotGroupNumber设置为FF即可。

        然后,ECU向诊断仪发送快照内容,格式如下:

        DTCSnapshotRecordNumber这个字节表示快照记录的组号;

        DTCSnapshotRecordNumberOfldentifiers这个字节表示后面紧跟的DID的个数,这里如果出现了0x00表示一个未定义的未知个数或者异常个数,比如大于255溢出的数字;

        dataldentifier这两个字节表示后面数据的DID;

        snapshotData表示快照DID对应的具体数据。

快照存储设计

        直接上一段代码,在代码中注释,更加一目了然,示例如下:

main(void)
{//省略若干行代码if(Timer100ms == 1){for(i=0;i++;i<16)//遍历16个故障的状态{if((FaultArrayNow[i] == 1)&&(FaultArrayBefore[i] == 0))//如果有新发生的故障{FaultMask = setBit(i,1);}}if(FaultMask > 0){//按顺序存数据,每个Signal都要存在对应的Address上,因为还涉及到分组以及后面的读取解析SnapData[0] = getByte(FaultMask,0);SnapData[1] = getByte(FaultMask,1);SnapData[2] = Signal_01;SnapData[3] = Signal_02;SnapData[4] = Signal_03;//...SnapAddress += 1024;//与前一个快照的存储作地址偏移FlashErase(SnapAddress);FlashWreit(SnapAddress, SnapLength, &SnapData[0]);}}//省略若干行代码}

        注:上述代码是精简后的示意代码,非正式代码。

快照发送设计

        直接上一段代码,在代码中注释,更加一目了然,示例如下:

main(void)
{//省略若干行代码if(Timer100ms == 1){if(SnapReadRequest == 1){switch DTC_Requestcase DTC0DTC_Order = 0;break;case DTC1DTC_Order = 1;break;case DTC2DTC_Order = 2;break;case DTC3DTC_Order = 3;break;case DTC4DTC_Order = 4;break;case DTC5DTC_Order = 5;break;case DTC6DTC_Order = 6;break;case DTC7DTC_Order = 7;break;case DTC8DTC_Order = 8;break;case DTC9DTC_Order = 9;break;case DTC10DTC_Order = 10;break;case DTC11DTC_Order = 11;break;case DTC12DTC_Order = 12;break;case DTC13DTC_Order = 13;break;case DTC14DTC_Order = 14;break;case DTC15DTC_Order = 15;break;for(i=128;i--;i>0)//遍历全部的快照存储模块{FlashRead(SnapAddress, SnapLength, &SnapData[0]);if((SnapData[DTC_Order] == 1) || SnapData[getByte-7] == 1))//匹配故障掩码{//匹配快照的数据分组if(Group_Request == 1){OutputResponse(59,4,DTC_Request,DTC_Staus,1,SignalNum,SignalID1,SnapData[3],SignalID2,SnapData[4],...SignalID497,SnapData[499]);}else if(Group_Request == 2){OutputResponse(59,4,DTC_Request,DTC_Staus,2,SignalNum,SignalID1,SnapData[500],SignalID2,SnapData[501],...SignalID998,SnapData[1000]);}else {OutputResponse(59,4,DTC_Request,DTC_Staus,0xFF,SignalNum,SignalID1,SnapData[3],SignalID2,SnapData[4],...SignalID998,SnapData[1000]);}break;}SnapAddress--;}  }}//省略若干行代码}

        注:上述代码是精简后的示意代码,非正式代码。

功能验证

        如下是诊断仪向车身控制器请求快照的通信数据,示例如下:

分析和应用

        UDS诊断在嵌入式软件中的作用非常强大,特别是汽车领域的ECU软件,大部分都要求必须支持UDS功能,只是对整个UDS中的那么多服务有所裁剪。例如本文提到的0x19服务,官方本来是有24种子服务的,但是大部分车厂只要求ECU开发0x01、0x02、0x4、0x06、0x0A这五个即可,有的ECU甚至只要求开发0x02、0x4这两个。本文着重讲解的0x19 04服务,能够在ECU出现故障时,使工程师使用通用的诊断仪就能获取到更多的故障现场信息,这对分析问题是有很大帮助的。可以更方便地追溯分析问题原因,大大提高工程师的工作效率。

        在嵌入式软件中开发0x19 04服务,主要适用于成熟的或者量产化的软件项目,因为它的前提是需要先搭建UDS的网络传输层、会话层、服务层和应用层这一整套的基础框架,需要投入相当大的工作量,这显然不适用于小批量或者功能性的嵌入式软件项目。

总结

        以上就是本人在开发UDS 0x19 04服务时,一些个人理解和分析的总结,首先介绍了它的基本概念,然后展示它的设计示例和验证过程,最后分析了该服务的特点和适用场景。

        后续还会分享另外几个最近总结的UDS知识点,欢迎评论区留言、点赞、收藏和关注,这些鼓励和支持都将成文本人持续分享的动力。

        另外,上述例程使用的Demo工程,可以到笔者的主页查找和下载。


        版权声明,原创文章,转载和引用请注明出处和链接,侵权必究!

这篇关于【研发日记】白话解读UDS协议(一)——19 04读取快照服务的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/875771

相关文章

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

MySQL之搜索引擎使用解读

《MySQL之搜索引擎使用解读》MySQL存储引擎是数据存储和管理的核心组件,不同引擎(如InnoDB、MyISAM)采用不同机制,InnoDB支持事务与行锁,适合高并发场景;MyISAM不支持事务,... 目录mysql的存储引擎是什么MySQL存储引擎的功能MySQL的存储引擎的分类查看存储引擎1.命令

Java服务实现开启Debug远程调试

《Java服务实现开启Debug远程调试》文章介绍如何通过JVM参数开启Java服务远程调试,便于在线上排查问题,在IDEA中配置客户端连接,实现无需频繁部署的调试,提升效率... 目录一、背景二、相关图示说明三、具体操作步骤1、服务端配置2、客户端配置总结一、背景日常项目中,通常我们的代码都是部署到远程

Spring的基础事务注解@Transactional作用解读

《Spring的基础事务注解@Transactional作用解读》文章介绍了Spring框架中的事务管理,核心注解@Transactional用于声明事务,支持传播机制、隔离级别等配置,结合@Tran... 目录一、事务管理基础1.1 Spring事务的核心注解1.2 注解属性详解1.3 实现原理二、事务事

C#实现SHP文件读取与地图显示的完整教程

《C#实现SHP文件读取与地图显示的完整教程》在地理信息系统(GIS)开发中,SHP文件是一种常见的矢量数据格式,本文将详细介绍如何使用C#读取SHP文件并实现地图显示功能,包括坐标转换、图形渲染、平... 目录概述功能特点核心代码解析1. 文件读取与初始化2. 坐标转换3. 图形绘制4. 地图交互功能缩放

java读取excel文件为base64实现方式

《java读取excel文件为base64实现方式》文章介绍使用ApachePOI和EasyExcel处理Excel文件并转换为Base64的方法,强调EasyExcel适合大文件且内存占用低,需注意... 目录使用 Apache POI 读取 Excel 并转换为 Base64使用 EasyExcel 处

Linux五种IO模型的使用解读

《Linux五种IO模型的使用解读》文章系统解析了Linux的五种IO模型(阻塞、非阻塞、IO复用、信号驱动、异步),重点区分同步与异步IO的本质差异,强调同步由用户发起,异步由内核触发,通过对比各模... 目录1.IO模型简介2.五种IO模型2.1 IO模型分析方法2.2 阻塞IO2.3 非阻塞IO2.4

MySQL8.0临时表空间的使用及解读

《MySQL8.0临时表空间的使用及解读》MySQL8.0+引入会话级(temp_N.ibt)和全局(ibtmp1)InnoDB临时表空间,用于存储临时数据及事务日志,自动创建与回收,重启释放,管理高... 目录一、核心概念:为什么需要“临时表空间”?二、InnoDB 临时表空间的两种类型1. 会话级临时表