皮皮网

【fastchat源码解析】【域名注册系统源码】【java直销系统源码】汽车总线 源码_汽车总线 源码是什么

来源:boss问答系统源码 时间:2024-12-23 21:52:12

1.浅度剖析 SeaBIOS 基础组件之 PCI 枚举
2.vevor是汽车汽车哪个公司的
3.AUTOSAR Ethernet Driver(以太网驱动程序)
4.linux设备驱动程序——i2c总线的添加与实现
5.基于Embedded Coder 的AUTOSAR代码生成及MIL SIL PIL验证
6.autosar E2E 源码解析

汽车总线 源码_汽车总线 源码是什么

浅度剖析 SeaBIOS 基础组件之 PCI 枚举

       欢迎关注我的公众号:窗有老梅

       本文是一篇关于《QEMU/KVM 源码解析与应用》系列读书笔记的番外篇,深入浅出地分析了 SeaBIOS 中 PCI 枚举的总线总线实现,并探讨了 PCI 体系下的源码源码几个有趣细节。以下内容将引导您了解 PCIe 总线基本架构、汽车汽车SeaBIOS PCI 枚举的总线总线实现、以及探讨设备如何得知自己的源码源码fastchat源码解析 bus、device 和 function 号,汽车汽车最后讨论一条总线上最多能挂载的总线总线设备数量。

       在 PCIe 总线的源码源码基本架构中,图1展示了一个直观的汽车汽车总线结构图。理解 PCIe 总线中的总线总线 bridge 概念对于深入学习 PCI 架构至关重要,尽管关于 bridge 在 PCI 和 PCIe 下的源码源码不同含义,文中并未详细区分。汽车汽车

       SeaBIOS 枚举 PCI 的总线总线基本流程如下:遍历一条 bus 上的所有 device,以实现系统对硬件设备的源码源码全面识别与管理。这一过程对于理解 BIOS 如何与硬件交互具有重要意义。

       接下来,本文将深入探讨 PCI 枚举代码背后的一些有趣细节。首先,设备是如何知道自己的 bus 号的。设备的标识 BDF(bus device function)需要通过主机桥在 PCI 总线扫描时分配给设备,此过程基于 DFS(深度优先搜索)策略。当访问到一个 bridge 时,主机桥会为其分配 primary 和 secondary bus number,subordinate bus number 则在 DFS 回溯到当前层时得知。设备在收到的配置报文中包含 bus 和 device 号,此时设备将其记录到寄存器中,类似于当有人敲门告诉你所在的门牌号,你便能知道自己所处的位置。

       其次,设备如何得知自己的 device 号。设备的 device 号在与主机桥的交互过程中被确定,实际上,这是基于地址译码电路将 AD[:] 转换成片选信号,实现设备选择。PCI 总线推荐使用 AD[:] 进行地址译码,通过固化的映射关系,每种设备对应唯一的片选信号,从而确定设备号。

       设备如何知道自己的 function 号?对于单 function 设备,function 号默认为 0。而对于多 function 设备或支持虚拟 function 的设备,function 号由设备内部管理,无需通过总线枚举确定。

       一条总线上能挂载的设备数量受到多种因素限制。理论上,设备的 BDF 寄存器宽度允许最多 个设备。然而,实际限制还包括物理地址译码电路、负载能力,以及内存管理单元(MMU)对地址空间的支持。例如,AD[:] 的输入限制最多只能输出 路片选信号,实际的译码电路输入通常减少到 AD[:],进一步限制到 路。PCI 总线负载能力也限制了最多能挂接 个负载。

       通过本文的深入探讨,您可以对 PCI 架构及其在 SeaBIOS 中的域名注册系统源码应用有更全面的理解,同时对设备识别和硬件交互过程有更深的洞察。

vevor是哪个公司的

       vevor实际上指的是维克多汽车技术有限公司。Vector公司作为先驱,在全球范围内率先推出了首款总线分析工具,并持续扩展其产品系列。如今,Vector已成为业界领先的总线开发工具、网络节点测试验证工具和嵌入式软件组件供应商。其提供的工具和源代码在汽车总线网络设计、建模、仿真、分析、测试以及ECU开发、测试、标定、诊断等关键环节,提供了强有力的支持。Vector的产品和解决方案广泛应用于乘用车、商用车、工程机械、轨道交通以及控制工程领域,为行业提供先进的技术支撑。

AUTOSAR Ethernet Driver(以太网驱动程序)

       AUTOSAR Ethernet Driver(以太网驱动程序)在汽车电子系统中扮演着关键角色,它作为Microcontroller Abstraction Layer(微控制器抽象层)的通信驱动,提供硬件独立的接口,使得上层网络接口能统一访问底层总线系统。其主要功能包括初始化、配置和数据传输,配置需考虑特定通信控制器特性,支持多控制器且可能需要与交换机驱动协作。驱动程序遵循one-fits-all原则,通过目标代码交付,允许无需修改源代码的配置。

       以太网驱动程序的开发基于AUTOSAR提供的通用规范,如SWS BSW General,确保了其在汽车行业的适用性。它存在一些约束,如单线程执行,不能处理大数据量,以及可能需要根据硬件异步/同步特性调整API。以太网驱动模块与多个模块交互,如交换机驱动程序,共同构建复杂的网络堆栈结构。

       功能规范方面,驱动程序提供了丰富的API,如初始化、设置控制器模式、获取物理地址,以及处理数据传输、时间同步和错误处理等功能。API设计注重性能和灵活性,如支持协议校验和计算和丢弃,以及接收数据和发送确认的处理机制。

       总的来说,AUTOSAR Ethernet Driver是一个高度标准化和可配置的以太网驱动解决方案,为汽车电子系统的高效通信提供了坚实的基础。

linux设备驱动程序——i2c总线的java直销系统源码添加与实现

       一文看懂linux内核详解

       深入了解使用linux查看磁盘io使用情况

       在实际驱动开发过程中,i2c总线也是集成在系统中的,驱动开发者不需要关心i2c总线的初始化,只需要将相应的i2c_client和i2c_driver挂载在总线上进行匹配即可。

       那么,i2c总线在系统中是如何初始化得来的呢?

       答案就在文件i2c-core-base.c中,它的过程是这样的:

       在i2c_init函数中,使用bus_register()将i2c总线注册到系统中,那么这个i2c_init()函数是在哪里被调用的呢?

       在内核启动的过程中,进入C语言环境的第一个入口函数是start_kernel(),但是i2c_init()并非由start_kernel()间接调用,而是借助于linux内核中的initcall机制被调用,简而言之,就是将这个函数地址在编译阶段放入特定的段中,在内核初始化时由某个启动函数将这些段中的函数一一取出并执行。

       i2c总线通过postcore_initcall()将init函数注册到系统中。

       当模块被加载进系统时,就会执行i2c_init函数来进行初始化。

       在i2c_bus_type结构体中,定义了match(),probe(),remove()和shutdown()函数,match()函数就是当有新的i2c_client或者i2c_driver添加进来时,试图寻找与新设备匹配的项,返回匹配的结果。

       remove()和shutdown(),顾名思义,这两个函数是管理的驱动移除行为的。

       对于probe函数,在之前的章节中提到:当相应的device和driver经由总线匹配上时,会调用driver部分提供的probe函数。

       那么:

       带着这两个疑问,我们接着往下看。

       在这里我们不免要回顾一下前面章节所说的,作为一个驱动开发者,如果我们要开发某些基于i2c的设备驱动,需要实现的框架流程是怎样的:

       但是问题是,为什么device和driver都注册进去之后,就会调用driver部分提供的probe函数呢?

       为了解决这些问题,最好的办法就是看源代码,假设我们是以设备树的方式进行匹配,device(即i2c_client)部分已经被注册到系统中,此时我们向系统中注册(insmod由driver部分程序编译的模块)相应的driver部分,接下来我们跟踪driver部分注册到i2c总线的流程,看看它是怎么实现的:

       跟踪i2c_add_driver:

       经过一系列的代码跟踪,找到了bus_add_driver(),根据名称可以知道,这个函数就是将当前i2c_driver添加到i2c_bus_type(即i2c总线)中。

       接着往下看:

       从第一部分可以看到,将当前drv链入到bus->p->klist_drivers链表中,那么可以猜到,在注册device部分的时候,就会将device链入到bus->p->klist_devices中。

       然后,再看driver_attach(drv):

       driver_attach调用bus_for_each_dev,传入当前驱动bus(即i2c_bus_type),当前驱动drv,以及一个函数__driver_attach。

       bus_for_each_dev对每个device部分调用__driver_attach。

       在__driver_attach中,对每个drv和dev调用driver_match_device(),android 文件下载源码并根据函数返回值决定是否继续执行调用driver_probe_device()。

       从函数名来看,这两个函数大概就是我们在前文中提到的match和probe函数了,我们不妨再跟踪看看,先看看driver_match_device()函数:

       果然不出所料,这个函数十分简单,如果当前驱动的所属的bus有相应的match函数,就调用match函数,否则返回1.

       当前driver所属的总线为i2c_bus_type,根据上文i2c总线的初始化部分可以知道,i2c总线在初始化时提供了相应的match函数,所以,总线的match函数被调用,并返回匹配的结果。

       接下来我们再看看driver_probe_device()函数:

       在driver_probe_device中又调用了really_probe,在really_probe()中,先判断当前bus总线中是否注册probe()函数如果有注册,就调用总线probe函数,否则,就调用当前drv注册的probe()函数。

       到这里,我们解决了上一节中的一个疑问:总线和driver部分都有probe函数时,程序是怎么处理的?

       答案已经显而易见了:优先调用总线probe函数。

       而且我们理清了总线的match()函数和probe()函数是如何被调用的。

       那么,上一节中还有一个疑问没有解决:总线的match和probe函数执行了一些什么行为?

       对于总线probe函数,获取匹配成功的device,再由device获取driver,优先调用driver->probe_new,因为driver中没有设置,直接调用driver的probe函数。

       总线probe和driver的probe函数的关系就是:当match返回成功时,优先调用总线probe,总线probe完成一系列的初始化,再调用driver的probe函数,如果总线probe函数不存在,就直接调用driver的probe函数,所以当我们在系统中添加了相应的device和driver部分之后,driver的probe函数就会被调用。

       对于总线match函数,我们直接查看在i2c总线初始化时的函数定义:

       i2c_device_match就是i2c_driver与i2c_device匹配的部分,在i2c_device_match函数中,可以看到,match函数并不只是提供一种匹配方式:

       接下来再深入函数内部,查看匹配的细节部分:

       在i2c_of_match_device中,调用了of_match_device()和i2c_of_match_device_sysfs()两个函数,这两个函数代表了两种匹配方式,先来看看of_match_device:

       of_match_device调用of_match_node。

       of_match_node调用__of_match_node函数。

       如果你对设备树有一定的了解,就知道系统在初始化时会将所有设备树子节点转换成由struct device_node描述的节点。

       在被调用的__of_match_node函数中,对device_node中的compatible属性和driver部分的of_match_table中的compatible属性进行匹配,由于compatible属性可以设置多个,所以程序中会对其进行逐一匹配。

       我们再回头来看设备树匹配方式中的i2c_of_match_device_sysfs()匹配方式:

       由i2c_of_match_device_sysfs()的实现可以看出:当设备树中不存在设备节点时,driver部分的of_match_table中的compatible属性试图去匹配i2c_client(device部分)的.driver.name属性.

       因为设备树的默认规则,compatible属性一般形式为"vender_id,jsp源码怎么用product_id",当compatible全字符串匹配不成功时,取product_id部分再进行匹配,这一部分主要是兼容之前的不支持设备树的版本。

       acpi匹配方式较为少用且较为复杂,这里暂且不做详细讨论

       id_table匹配方式中,这种匹配方式一目了然,就是对id_table(driver部分)中的.name属性和i2c_client(device部分)的.name属性进行匹配。那么i2c_client的.name是怎么来的呢?

       在非设备树的匹配方式中,i2c_client的.name属性由驱动开发者指定,而在设备树中,i2c_client由系统对设备树进行解析而来,i2c_client的name属性为设备树compatible属性"vender_id,product_id"中的"product_id",所以,在进行匹配时,默认情况下并不会严格地要求 of_match_table中的compatible属性和设备树中compatible属性完全匹配,driver中.drv.name属性和.id.name属性也可以与设备树中的"product_id"进行匹配。

       关于linux i2c总线的初始化以及运行机制的讨论就到此为止啦

基于Embedded Coder 的AUTOSAR代码生成及MIL SIL PIL验证

       生成符合 AUTOSAR 标准的 C 代码和 ARXML 描述,通过使用 Simulink 编码器和 Embedded Coder 软件,可以构建 AUTOSAR 组件模型。此模型将生成算法 C 代码,并导出符合 AUTOSAR 经典平台规范的 ARXML 描述。在 Simulink 中进行测试或集成到 AUTOSAR 运行时环境中。

       首先打开要从中生成 AUTOSAR C 代码和 ARXML 说明的组件模型。使用 open_system(“autosar_swc”) 来打开一个示例模型。若要优化代码生成的模型配置设置,推荐使用 Embedded Coder 快速入门。通过从“应用”选项卡中打开该应用,并在 “AUTOSAR” 选项卡上单击“快速启动”来完成快速启动过程。选择“输出”窗口中的符合 AUTOSAR 的输出选项 C 代码。快速入门软件将指导您完成配置步骤。

       在生成代码之前,请检查 AUTOSAR 字典中的 XML 选项设置。在“AUTOSAR”选项卡上,选择“代码接口”> AUTOSAR 字典”。在 AUTOSAR 字典中,选择“XML 选项”。配置参数包括将“导出的 XML 文件”打包设置为“模块化”,以便将 ARXML 导出到模块化文件中。这样将生成 modelname_component.arxml、modelname_datatype.arxml 和 modelname_interface.arxml 等文件。

       完成模型的配置后,生成符合经典平台规范的 AUTOSAR C 代码和 XML 组件说明。在模型窗口中按 Ctrl+B 生成模型。生成过程将 C 代码和 ARXML 说明生成到模型生成文件夹中。生成完成后,将打开代码生成报告。通过执行这些步骤,可以确保模型的正确配置和生成。

       要从已配置为 AUTOSAR 经典平台的模型生成符合 AUTOSAR 标准的 C 代码和 ARXML 组件说明,需确保模型的架构版本与 AUTOSAR 标准相匹配。首次导入或为模型选择 AUTOSAR 系统目标文件会将架构版本参数设置为默认值 4.3。导入 ARXML 文件时,导入程序将检测模式版本并在模型中设置模式版本参数。例如,基于架构 4.3 修订版 4.3.0 或 4.3.1 的导入将设置架构版本参数为 4.3。

       生成 AUTOSAR 模型时,代码生成器会导出 ARXML 说明并生成符合当前架构版本的 C 代码。例如,架构版本为 4.3 时,导出将使用架构 4.3(修订版 4.3.1)的导出架构修订版。在导出 AUTOSAR 软件组件前,检查所选架构版本。如有需要更改,可使用模型配置参数为架构版本生成 XML 文件。

       最大短名称长度的指定范围为 到 个字符(包括 和 )。默认值为 个字符。使用模型配置参数“最大短名称长度”来设置此值。启用 AUTOSAR 编译器抽象宏可以独立于平台生成编译器指令,这有助于在 位平台上优化代码效率,而无需为每个编译器单独移植源代码。

       根级矩阵 I/O 配置允许在生成的 C 代码中保留多维数组的维度,增强代码集成。如果应用设计需要列主数组布局,则可以配置 ARXML 导出以支持根级矩阵 I/O。默认情况下,对于列主阵列布局,软件不允许根级矩阵 I/O。启用此功能,可以指定支持使用一维数组的根级矩阵 I/O。

       配置完成 AUTOSAR 代码生成和 XML 选项后,生成代码。通过生成组件模型,将生成符合 AUTOSAR 的 C 代码和 AUTOSAR XML 描述到模型生成文件夹中。生成过程会生成一个或多个型号名称 *.arxml 文件,具体取决于“导出的 XML 文件打包”设置为“单个文件”还是“模块化”。这些文件将包含模型名称、组件描述和其他相关组件信息。

       将 AUTOSAR XML 组件描述合并回 AUTOSAR 创作工具中,以便利用已分区的文件结构进行合并。在 AUTOSAR 创作工具和基于 Simulink 模型的设计环境中,代码生成器保留 AUTOSAR 元素及其通用唯一标识符(UUID),以支持模型的往返传输。

       使用 AUTOSAR 4.0 代码替换库,可以生成与 AUTOSAR 标准紧密一致的函数。此代码替换库允许自定义代码生成器以生成兼容 AUTOSAR 标准的 C 代码。在 MATLAB 和 Simulink 查找表索引与 AUTOSAR MAP 索引之间存在差异时,代码替换软件会转置 AUTOSAR MAP 例程的输入参数。浏览支持的 AUTOSAR 库例程并配置代码生成器使用 AUTOSAR 4.0 代码替换库。

       为了支持 AUTOSAR 模型的 MATLAB 主机代码验证,AUTOSAR Blockset 提供了 IFX、IFL、MFX 和 MFL 例程的主机实现。使用这些实现作为模型启用软件在环(SIL)验证,而处理器在环(PIL)验证则适用于在生产目标硬件上验证目标代码。

       配置并运行模型的 SIL 仿真,以验证生成的 AUTOSAR C 代码。使用测试工具执行相关操作以检查组件模型与生成代码之间的等效性。对于多实例软件组件,可构建配置为多个实例化的 AUTOSAR 软件组件模型,并导入先前版本中的 AUTOSAR 代码进行观察。

       在进行 AUTOSAR 代码生成时,需注意以下限制:未选中“仅生成代码”复选框时,生成模型时会提示只有在使用 AUTOSAR 系统目标文件构建可执行文件的情况下才能使用 AUTOSAR 系统目标文件。此外,总线元素尺寸保留在导出的 ARXML 中,并在模型配置为“以行为主”时生成代码。C++ 为 AUTOSAR 自适应应用生成的样式范围枚举类在头文件中生成,以方便集成。

       了解这些关键步骤和注意事项后,即可高效地利用 Embedded Coder 和 Simulink 进行基于 AUTOSAR 的代码生成、验证和部署过程。

autosar E2E 源码解析

       在多年的实践应用中,我们曾利用E2E技术来确保车速和转速信息的准确性,通过在报文里加入Check和RollingCounter信号,监测信号的完整性和一致性。虽然起初可能觉得这种额外的使用是资源浪费,但其实是对总线负载的有效管理。E2E的核心其实并不复杂,本质上是CRC校验和滚动计数器的结合,不同厂商可能在位序和配置上有所差异,但原理相通。

       具体到源码操作,发送E2E报文的过程如下:首先从SWC获取E2E信号值,然后通过vector库进行处理,校验AppData的指针,配置报文,组织msg,更新E2E buffer,并进行CRC和滚动计数器的更新。最后,通过RTE接口发送信号。

       接收E2E报文则与发送过程相反,包括准备接收缓冲区,调用库函数读取数据,验证数据和计数器,将接收到的数据结构赋值,检查接收和本地滚动计数器的匹配,以及校验CRC结果。整个过程旨在确保数据的完整性和正确性。

Vert.x 源码解析(4.x)——Local EvnentBus入门使用和源码解析

       Vert.x 源码解析(4.x)——Local EvnentBus入门使用和源码解析

       本文将介绍使用和解析Vert.x的本地事件总线(Local EvnentBus)的基本概念、入门使用方法以及源码解析。

       1. 简介

       Vert.x EventBus是一个用于异步通信的分布式事件总线,支持在同个Vert.x应用程序内部或跨多个Vert.x应用程序之间的消息交互,实现组件、模块或服务之间的松耦合与高度可扩展性。

       2. 基本概念

       EventBus分为Local模式和Clustered模式,Local模式适用于项目内部通信,而Clustered模式用于集群间传输。

       3. 入门使用

       3.1 获取EventBus

       每个Vertx实例仅有一个EventBus实例,可使用注册处理器、调用consumer()方法获取MessageConsumer对象。

       在集群模式下注册处理器时,注册信息传播至集群中所有节点可能需要时间。

       3.2 注销处理器

       通过unregister方法注销处理器,在集群模式下,此动作传播至节点可能需要额外时间,可使用回调完成通知。

       3.3 发布消息

       使用publish方法指定地址发布消息,消息将传递给所有在该地址注册的处理器。

       3.4 发送消息

       使用send方法发送消息至指定地址的单个处理器。

       3.5 设置消息头

       在发送或publish消息时可提供DeliveryOptions来设置头信息。

       3.6 消息顺序

       消息按发送顺序传递给处理器。

       3.7 消息对象

       消息处理器接收到的对象类型为Message,包含消息体和头信息。

       3.8 应答消息/发送回复

       通过reply方法在处理器接收到消息后发送回复至消息来源,确认处理。

       3.9 带超时的发送

       使用DeliveryOptions指定超时时间,若超时未收到回复,则调用应答处理器。

       3. 发送失败

       消息发送失败时,应答处理器将接收到异常失败结果。

       3. 消息编解码器

       注册消息编解码器支持发送任何对象,通过DeliveryOptions指定对象类型。

       3. 集群模式的Event Bus

       将多个Vert.x实例组合为集群,实现分布式Event Bus。

       4. 关键类简介

       4.1 主要类的作用

       EventBus、EventBusInternal、EventBusImpl: EventBus接口定义方法,EventBusImpl实现管理消息、监听器注册、消息派发等功能,异步操作。

       HandlerRegistration、MessageConsumerImpl: 消费者实现类,管理订阅关系与消息派发。

       DeliveryContextBase、InboundDeliveryContext、OutboundDeliveryContext: 消息传递管理类,处理发送和接收过程。

       4.2 EventBus系列

       EventBus、EventBusInternal: EventBus接口,EventBusImpl实现。

       4.3 MessageConsumer系列

       MessageConsumerImpl实现消息消费与订阅管理。

       4.4 DeliveryContext系列

       DeliveryContextBase管理消息传递过程,InboundDeliveryContext处理接收消息,OutboundDeliveryContext处理发送消息。

       4.5 Message系列

       Message实现消息对象,MessageImpl具体实现。

       4.5.3 MessageCodec系列

       CodecManager获取解码器,lookupCodec方法实现消息解码。

       5. Local模式EventBus源码解析

       5.1 consumer方法分析

       绑定时调用consumer方法,创建MessageConsumerImpl实例。

       5.2 handler

       注册处理器,涉及HandlerRegistration、EventBusImpl等类。

       5.3 send

       发送消息,EventBusImpl类实现,包括创建消息、发送上下文等。

       5.4 reply

       回复消息,与send方法类似。

       5.5 总结

       本地事件总线操作简单,消息发布与发送遵循明确的步骤。回复消息与发送类似,关键在于消息处理与应答机制。

linux设备驱动程序——i2c设备驱动源码实现

       深入了解Linux内核中的i2c设备驱动程序详解

       在Linux内核中,i2c设备驱动程序的实现是一个关键部分。本文将逐步剖析其形成、匹配及源码实现,以帮助理解i2c总线的工作原理。

       首先,熟悉I2C的基本知识是必不可少的。作为主从结构,设备通过从机地址寻址,其工作流程涉及主器件对从机的通信。了解了基础后,我们接着来看Linux内核中的驱动程序框架。

       Linux的i2c设备驱动程序框架由driver和device两部分构成。当driver和device加载到内存时,会自动调用match函数进行匹配,成功后执行probe()函数。driver中,probe()负责创建设备节点并实现特定功能;device则设置设备的I2C地址和选择适配器,如硬件I2C控制器。

       示例代码中,i2c_bus_driver.c展示了driver部分的实现,而i2c_bus_device.ko和i2c_bus_device.ko的编译加载则验证了这一过程。加载device后,probe函数会被调用,确认设备注册成功。用户程序可测试驱动,通过读写传感器寄存器进行操作。

       在设备创建方面,i2c_new_device接口允许在设备存在时加载驱动,但有时需要检测设备插入状态。这时,i2c_new_probed_device提供了检测功能,确保只有实际存在的设备才会被加载,有效管理资源。

       深入源码分析,i2c_new_probed_device主要通过检测来实现设备存在性,最终调用i2c_new_device,但地址分配机制确保了board info中的地址与实际设备地址相符。

       至此,关于Linux内核i2c驱动的讨论结束。希望这个深入解析对您理解i2c设备驱动有帮助。如果你对此话题有兴趣,可以加入作者牧野星辰的Linux内核技术交流群,获取更多学习资源。

       学习资源

       Linux内核技术交流群:获取内核学习资料包,包括视频教程、电子书和实战项目代码

       内核资料直通车:Linux内核源码技术学习路线+视频教程代码资料

       学习直达:Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈

无人驾驶技术入门(十一)| 无人驾驶中的CAN消息解析

       前言

       本文聚焦于无人驾驶技术中至关重要的CAN总线机制。在无人驾驶系统中,CAN总线扮演着不可或缺的角色,不仅用于传输VCU信号,还涉及雷达、Mobileye等传感器的数据交换。

       实现一个完整的无人驾驶系统需涉及感知、融合、规划与控制等多个层级。在这篇分享中,重点探讨了“驱动层”相关的CAN总线内容。

       正文

       作为高效可靠的通信机制,CAN总线在汽车电子领域广泛应用。本文着重于解释在无人驾驶系统接收到CAN消息后,如何利用CAN协议解析出所需数据,解析传感器信息是自动驾驶工程师的核心技能。

       认识CAN消息

       以Apollo开源代码为例,剖析CAN消息结构,包括ID号、长度、数据和时间戳。ID号用于确认节点间通信,扩展帧和普通帧的区分依据于此。长度表示数据量,最多8个无符号整数或8*8个bool类型数据。数据部分是消息的核心,通过8*8方格可视化,解析变得直观。时间戳记录接收时刻,用于判断通信状态。

       认识CAN协议

       业界使用后缀为dbc的文件存储CAN协议,Vector公司的CANdb++ Editor软件专门用于解析dbc文件。Mobileye的车道线信息通过dbc文件格式传递,以ID号0x的LKA_Left_Lane_A为例,解析信号包括类型、质量、曲率等物理量。通过软件界面直接关联彩色图与data,解析过程变得清晰。

       解析CAN信号

       解析过程基于彩色图与data的一一对应关系,通过叠加图表,揭示数据结构。对于Factor为1的物理量,解析直接。Factor为小数的物理量则需运用位移运算。以Apollo源码为例,通过移位和位运算解析出完整物理量。

       与CAN类似的通信协议

       虽然传感器采用不同通信方式,如雷达、激光雷达、GPS和惯导,但解析方法保持一致。解析的关键在于理解信号的类型、值和单位。

       结语

       本篇分享全面解析了CAN总线消息的解析过程,涵盖了无人驾驶系统驱动层的基本理论。解析ID不同的CAN消息结构要求高度细致,避免后续处理中的意外错误。如有疑问,欢迎在评论区互动。赞赏与关注是对文章价值的直接体现。

       获取相关软件和文件的方法,请关注公众号:自动驾驶干货铺,后台回复“CAN”获取。更多Mobileye资料和技术支持,值乎平台提问。