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

发布于:2024-04-05 ⋅ 阅读:(249) ⋅ 点赞:(0)

文章目录

前言

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_Request
        case DTC0
          DTC_Order = 0;
          break;
        case DTC1
          DTC_Order = 1;
          break;
        case DTC2
          DTC_Order = 2;
          break;
        case DTC3
          DTC_Order = 3;
          break;
        case DTC4
          DTC_Order = 4;
          break;
        case DTC5
          DTC_Order = 5;
          break;
        case DTC6
          DTC_Order = 6;
          break;
        case DTC7
          DTC_Order = 7;
          break;
        case DTC8
          DTC_Order = 8;
          break;
        case DTC9
          DTC_Order = 9;
          break;
        case DTC10
          DTC_Order = 10;
          break;
        case DTC11
          DTC_Order = 11;
          break;
        case DTC12
          DTC_Order = 12;
          break;
        case DTC13
          DTC_Order = 13;
          break;
        case DTC14
          DTC_Order = 14;
          break;
        case DTC15
          DTC_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工程,可以到笔者的主页查找和下载。


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