首页 > 其他分享 >基于UDS的DoIp实现(五) -- UDS单帧、多帧处理

基于UDS的DoIp实现(五) -- UDS单帧、多帧处理

时间:2023-04-19 10:01:41浏览次数:37  
标签:UDS 字节 -- FRAME len buffer DoIp 单帧

  通常来讲,上位机一般只会发送8个字节数据,那么对于UDS,只需要处理这个8个字节就可以,这里也不会涉及大数据传输。但是,有些机器,比如毫米波雷达,其设计是64位,那么每次发送的数据,按照单帧的处理,是无法接收完全的,这个时候就需要进行多帧处理。

一、单帧

二、多帧

 以下列举部分帧类型,以及区分方法:

//pci type
typedef enum {
    SINGLE_FRAME = 0x00,
    FIRST_FRAME = 0x10,
    CONSECUTIVE_FRAME = 0x20,
    FLOW_CONTROL_FRAME = 0x30
} UDS_PCI_Type_T;

解释:

  SINGLE_FRAME:单帧,其第一个字节为0x00 | 数据长度(这个长度通常是不需要的);

  FIRST_FRAME:首帧,其第一个字节为0x10 | 数据长度;

  CONSECUTIVE_FRAME:连续帧,其第一个字节为0x20 | 块号(1、2、3.....);

  FLOW_CONTROL_FRAME:流控帧,这个是UDS服务向上位机发送请求数据的帧信息,其第一个字节为0x30 | 块号(也有的实现,将块号放在第二个或第三个字节发出去)。

一、单帧

s_boolean ReceiveMsg(u_uint8_t *buffer, u_uint16_t len) {
    //数据检测实现

    //获取帧类型
    UDS_PCI_Type_T type = buffer[0] & FRAME_TYPE_MASK;
    //按照不同的类型,执行不同的操作
    if (type == SINGLE_FRAME) {
        return receive_sf(buffer, len);
    } else if (type == FIRST_FRAME) {
        return receive_ff(buffer, len);
    } else if (type == CONSECUTIVE_FRAME) {
        return receive_cf(buffer, len);
    } 

    //其它操作

    return SE_LORF;
}
s_boolean receive_sf(u_uint8_t *buffer, u_uint16_t len) {
    //数据处理

    char *ptr = GetValidBuffer(len);
    memcpy(ptr, buffer, len);

    //通知UDS Server,已经获取数据

    return S_OK;
}

  单帧的实现,只是一些数据检测、拷贝数据操作,过程还是比较简单的,但是多帧的实现,就比较复杂了。

二、多帧

  多帧流程图:

    +----------------+                +----------------+
    |  Client        |                |  Server        |
    +----------------+                +----------------+
           |                                   |
           |  Send frame 1                      |
           |---------------------------------->|
           |                                   |
           |  Receive acknowledgement for frame1 |
           |<----------------------------------|
           |                                   |
           |  Send frame 2                      |
           |---------------------------------->|
           |                                   |
           |  Receive acknowledgement for frame2 |
           |<----------------------------------|
           |                                   |
           |           ...                     |
           |                                   |
           |                                   |
           |  Send frame n                      |
           |---------------------------------->|
           |                                   |
           |  Receive acknowledgement for frame n |
           |<----------------------------------|
           |                                   |
           |  Process the entire message and   |
           |  send the processing result.      |
           |---------------------------------->|
           |                                   |
           |  Receive processing result.       |
           |<----------------------------------|
           |                                   |
           |  Done.                            |
           |                                   |
    +----------------+                +----------------+
    |  Client        |                |  Server        |
    +----------------+                +----------------+

解释:(Client -上位机 Server - UDS服务)

  • 上位机先发送第一帧,逻辑判断是FF后,进行FF处理;
  • 服务向上位机发送FC,请求下一帧;
  • 上位机接收到请求后,再发送一帧(CF);
  • 后面便进入FC与CF的循环中,直到数据完全发送结束。

示例:

s_boolean receive_ff(u_uint8_t *buffer, u_uint16_t len) {
    //数据处理,获取数据长度、分块信息

    char *ptr = GetValidBuffer(len);
    memcpy(ptr, &buffer[2], len - 2);
    //发送FC
    send_fc(mFrame.current_block);

    //其它处理
}
s_boolean send_fc(int block_cnt) {
    u_uint8_t tx_buf[MSG_SEND_SIZE] = {0};
    tx_buf[0] = (FLOW_CONTROL_FRAME | block_cnt);
        //发送tx_buf到上位机
}
s_boolean receive_cf(u_uint8_t *buffer, u_uint16_t len) {
    //数据检测、保存
    if (判断数据是否接收完成) {            
        //接收完成处理
    } else {
      //未接收完成,继续请求数据
        send_fc(++mFrame.current_block);
    }        

    //其它处理
}

 

  

 

标签:UDS,字节,--,FRAME,len,buffer,DoIp,单帧
From: https://www.cnblogs.com/liuqiongcn/p/17272678.html

相关文章

  • linux常用命令随笔
    1.linux-centos7的目录结构/:centos7的根目录bin:脚本目录--包含很多linux命令sbin:命令目录--包含linux的命令etc:配置目录--可以配置很多参数--IP地址,环境变量配置root:它是root用户的目录usr:用户安装软件的目录----等价于window中programfilestmp:缓存--临......
  • async function 报eslint 错误:Parsing error: Unexpected token function 解决方法
    asyncfunctiongetData(){这个代码报eslint错误:Parsingerror:Unexpectedtokenfunction。.eslintrc中parserOptions:{ecmaVersion:6},根据ESLint的官方文档,"ecmaVersion"配置项可以配置以下值:3:ECMAScript 3(默认值)5:ECMAScript 56:ECMAScrip......
  • VMware Site Recovery Manager 8.7 (for vSphere 8 U1) - 数据中心灾难恢复 (DR)
    请访问原文链接:https://sysin.org/blog/vmware-srm-8/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgSiteRecoveryManager8.7|18APR2023|Build21590800什么是SiteRecoveryManager(SRM)?SiteRecoveryManager是业界领先的灾难恢复(DR)软件,可自动编......
  • VMware vSphere 8.0 Update 1 正式版发布 - 企业级工作负载平台
    ESXi8.0U1&vCenterServer8.0U1请访问原文链接:https://sysin.org/blog/vmware-vsphere-8-u1/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org2023-04-18,VMwarevSphere8.0Update1正式版发布。企业级工作负载平台vSphere将云计算的优势引入本地部署工作负......
  • springboot项目 宿舍管理系统 (源码+数据库文件+1w字论文+ppt)
    来了就点个赞再走呗,即将毕业的兄弟有福了文章底部获取源码springboot项目宿舍管理系统(源码+数据库文件+1w字论文+ppt)技术框架:java+springboot+vue+mysql后端框架:SpringBoot、SpringMVC、MyBatisPlus前端界面:vue、BootStrap、jQuery、ajxs系统共分为三种用户系统主要功......
  • go语言中如何把数字转换成字节切片并在网络中传输
    客户端:先把数字转换成uint32类型:varpkgLen=uint32(len(data))再定义一个字节切片:varbuf=make([]byte,4)最后通过encoding.binary包中的方法,把无符号数字装载到字节切片中:binary.BigEndian.PutUint32(buf[0:4],pkgLen)这样就可以在网络中发送数字了:conn.Wri......
  • Burley SubSurface Profile
    BurleySubSurfaceProfile的渲染方程可以基于经典的双向反射分布函数(BRDF)公式,通过增加次表面散射项的计算来实现次表面散射的效果。该渲染方程具体为:\(I_{o}({x_{o}},\omega_{o})=I_{e}(x_{o},\omega_{o})+\int_{H^{+}}\!f_{r}(\omega_{i},D){(\omega_{i},{x_{o}})}\time......
  • VO、DTO、Entity的区别
    只能说从实际用法的一般习惯上进行区分:1、entity里的每一个字段,与数据库相对应,注意:entity与对应的实际数据库表的字段没有强制要求但是一般建议保持一致(包括字段数据类型),当然,从实际使用中,entity也可以比对应的实际数据库表的字段少但是一定不能多2、vo里的每一个字段,是和你前......
  • 失败与不甘
    第一次大创比赛就这样难产了,不是倒在评审的过程中,而是在申请书阶段就胎死腹中,回顾一整个过程,真的是很难一口气说尽。起初,是由一个实验室学长牵头搞的项目,但是学长并没有具体的想法和实施过程,直到临近ddl,才得知整个项目连一个大体的思路框架都没有,只有我和另一位大一学生负责招人,......
  • 在Go语言中,如何优化内存使用效率?
    在Go语言中,可以通过以下几种方式来优化内存使用效率:避免使用过多的内存尽可能地避免使用过多的内存是最有效的内存优化方法之一。在编写代码时,应该尽可能地避免使用全局变量和大量的临时变量。同时,可以使用常量、静态变量和缓存等方式来避免频繁地分配和释放内存。及时释放不......