AUTOSAR CAN通信介绍

概述

在AUTOSAR的分层和模块化架构中,使用PduR(Protocal Data Unit Router)将总线或者网络数据进行抽象,使得上层应用不用关心信号的来源。本文从PduR下层的CAN Interface、CAN Driver和CAN Transceiver Driver模块介绍CAN总线在AUTOSAR架构中的工作机制以及信号的收发等功能。PduR以及COM等上层模块的介绍可以参考公众号内发布的历史文章。

CAN通信网络架构

在车辆中,CAN通信是一种基于信号的通信。如下图参考的车辆E/E架构,多个域总线,比如车身CAN、动力CAN等连接在中央网关上,网关负责路由不用总线的数据,实现不同总线上节点ECU的数据交互。信号的发送一般是基于事件和周期的属性,常见的周期有20ms,50ms,100ms,200ms等,发送方ECU在信号更新或者改变时发送信号,而不关心其他接收方ECU是否需要该信号。CAN信号的发送是采用广播形式,也就是说同一总线上,一个节点发送的报文都会被其他节点接收到,类似于在一个教室里,一个同学发言,其他同学都可以听到。如下图,在车身CAN这条总线上,当车门ECU发送一条车门打开的消息时,灯光、空调、座椅以及网关这些节点都可以收到该消息。同一总线上不允许多个ECU节点发送相同CAN ID的消息,这样会导致总线冲突。当多个节点同时发送数据时,会进行优先级仲裁,CAN ID小的优先级高。

CAN通信是一种安全通信,节点对总线错误的识别是通过CAN控制器来完成。CAN控制器输出给收发器发送引脚TX的逻辑信号位会从收发器接收引脚RX接收,这使得CAN控制器可以在发送一个逻辑位期间同时监测总线的实际电平值。CAN通信过程中的错误类型包括5种,分别是:位错误、填充错误、CRC错误、帧格式错误、应答错误。CAN通讯的标准可以参考ISO11898。

CAN通信硬件架构

CAN通信硬件由CAN控制器和CAN收发器组成,CAN控制器有内置和外挂两种形式,一般的微控制器都有内置CAN控制器。

如下图所示,CAN通信硬件架构,由MCU控制器、CAN控制器以及CAN收发器组成。CAN控制器一般都内置于MCU控制器中。其中CAN控制器用于实现CAN总线的协议底层以及数据链路层,用于生成CAN帧并以二进制码流的方式发送,在此过程中进行位填充、添加CRC校验、应答检测等操作;将接收到的二进制码流进行解析并接收,在此过程中进行收发比对、去位填充、执行CRC校验等操作。此外还需要进行冲突判断、错误处理等诸多任务。

CAN收发器(有时也称为驱动器)是CAN总线的物理层,用于将二进制码流转换为差分信号发送,将差分信号转换为二进制码流接收。

image-20220316141942656

AUTOSAR CAN协议栈层级结构

由于CAN通信需要CAN控制器和CAN收发器两种硬件设备,因此需要两种设备的驱动。如下图CAN控制器的驱动位于MCAL层,CAN收发器的驱动位于通信设备抽象层。在AUTOSAR架构中,使用PduR(Protocal Data Unit Router)将总线或者网络数据进行抽象,使得上层应用不用关心信号的来源,所以在通信服务层下对于每种总线或网络都有一个管理Driver的Interface层,对于CAN总线则是CAN Interface。

image-20220316095734631

CAN Transceiver Driver功能概述

CAN Transceiver Driver(CanTrcv)抽象了CAN收发器硬件设备,为上层提供了独立于硬件的接口去管理下层的硬件设备。CAN收发器将CAN总线上使用的信号电平调整为微控制器所识别的逻辑(数字)信号电平。此外,收发器能够检测电气故障,如布线问题,对地偏移等。CAN收发器的配置方式一般采用DIO或者SPI通信方式。

image-20220316150438209

CAN Driver功能概述

Can Driver(CanDrv)执行CAN控制器硬件访问,并向上层提供与硬件无关的API。唯一能够访问Can Driver模块的上层是CanIf模块。Can Driver模块为发起传输提供服务,并调用CanIf模块的回调函数来通知事件,独立于硬件。此外,它还提供服务来控制属于同一CAN硬件单元的CAN控制器的行为和状态。多个CAN控制器可以由一个CAN Driver模块控制,只要它们属于同一个CAN硬件单元。

CAN Interface功能概述

CAN Interface(CANIf)属于通信硬件抽象层,其作用是抽象下层的CAN控制器和收发器,为上层提供唯一的接口去管理下层的一个或多个CAN控制器和收发器。

CANIf实现了PDU Router和AUTOSAR COM栈上层通信模块的主控制流和数据流要求,分别为:发送请求处理、发送确认/接收指示/错误通知、CAN控制器的启动/停止,从而唤醒/参与网络。

CanTrcv介绍

CanTrcv和其他模块的依赖

模块名 依赖关系描述
CanIf 所有收发器驱动都属于CanIf下层
ComM ComM通过CanIf引导CAN收发器驱动程序的通信模式。每个CAN收发器驱动器都是独立操作。
DET DET从收发器驱动模块获取开发错误信息
DIO DIO模块通过Port口访问收发器驱动
EcuM EcuM通过CanIf从收发器驱动获取唤醒事件
SPI 有些收发器驱动是用过SPI通信,所以SPI模块通过SPI总线访问收发器

功能规范

CanTrcv状态图

如下图CanTrcv的状态迁移,并且给出了状态迁移的条件或方法,其中包含四个状态

  • NOT_ACTIVE
  • CANTRCV_TRCVMODE_NORMAL
  • CANTRCV_TRCVMODE_STANDBY
  • CANTRCV_TRCVMODE_SLEEP

image-20220317084640104

CanTrcv唤醒的三种方案
  1. 方案1(冷启动,非唤醒)

    • MCU未供电

    • CAN收发器硬件有供电

    • 假设收发器处于SLEEP模式

    • 由CAN收发器检测到CAN BUS一个唤醒事件

    • CAN收发器从硬件上引起MCU供电

  2. 方案2(CAN唤醒)

    • MCU处于低功耗模式
    • CAN收发器有供电
    • 假设收发器处于STANDBY模式
    • 由CAN收发器检测到CAN BUS一个唤醒事件
    • CAN收发器引起一个软件中断从而引起MCU唤醒
  3. 方案3(CAN唤醒)

    • MCU全供电
    • CAN收发器有供电
    • 假设CAN收发器处于STANDBY模式
    • 由CAN收发器检测到CAN BUS一个唤醒事件
    • CAN收发器引起一个软件中断或者MCU周期查询唤醒事件

对比以上方案可知:使用CAN通信的硬件,一般可以借助CAN收发器对于CAN唤醒事件的检测能力作为一种唤醒源,要有检测能力必须为CAN收发器供电,方案1中一般是借助某种CAN收发器可以检测到唤醒事件后引起硬线上电平跳变的机制在检测到唤醒事件后为MCU上电,可以视为一种冷启动方式。通常,方案2使用的较多。

几个重要的API
//设置CAN收发器的模式
Std_ReturnType CanTrcv_SetOpMode(uint8 Transceiver, CanTrcv_TrcvModeType OpMode)
// 获取CAN收发器的模式
Std_ReturnType CanTrcv_GetOpMode(uint8 Transceiver, CanTrcv_TrcvModeType* OpMode)
// 获取总线唤醒原因
Std_ReturnType CanTrcv_GetBusWuReason(uint8 Transceiver, CanTrcv_TrcvWakeupReasonType* reason) 
// 使能、禁止或清除某种唤醒类型
Std_ReturnType CanTrcv_SetWakeupMode(uint8 Transceiver, CanTrcv_TrcvWakeupModeType TrcvWakeupMode)
// 如果唤醒中断检测到由CanIf调用
Std_ReturnType CanTrcv_CheckWakeup(uint8 Transceiver)
时序图
DIO模块与CanTrcv模块交互

image-20220317095121141

CAN唤醒时序图

CAN收发器中断唤醒

image-20220317095534246

CAN控制器中断唤醒

image-20220317095557215

CAN收发器或控制器查询唤醒

image-20220317095613166

CAN唤醒验证

image-20220317095632836

CanDrv介绍

CAN硬件单元介绍

一般的CAN硬件单元如下图所示,CAN硬件单元通常由一个或多个CAN控制器和消息邮箱组成,CAN硬件单元可以是内置于MCU或外挂形式。

image-20220317103715025

CanDrv状态机

CanDrv通常由两个简单的状态组成的状态机,如下图所示

image-20220317104046221

CAN控制器状态机

根据硬件实现CAN控制器可以由很复杂的状态机,为了简化,可以由如下四个基本的状态

  • UNINIT

    CAN控制器还未初始化。所有寄存器都处于reset状态,中断被禁止。CAN控制器还未参与总线通信。

  • STOPPED

    在此状态,CAN控制器被初始化但还未参与总线通信。另外,此状态不能发生错误帧和ACK信息。

  • STARTED

    此状态是正常操作状态,全功能可操作,参与总线通信。

  • SLEEP

    此状态只是与STOPPED状态的硬件设置不一样。

状态迁移图如下,状态的迁移有些由软件触发比如使用Can_SetControllerMode,有些由硬件事件触发,比如总线唤醒事件。

image-20220317104354282

L-PDU发送接收

对于L-PDU(Link Layer-Protocal Data Unit)的发送,CAN模块转换L-PDU的内容ID以及数据长度为硬件规定的格式,然后触发发送。CAN模块采用多路复用发送避免优先级翻转,并且直接从上层buffer拷贝数据保持发送数据一致性。

对于L–PDU的接收,CAN模块调用接收指示callback函数 CanIf_RxIndication获取ID等信息。为了防止接收报文的丢帧,一些CAN控制器支持FIFO机制。如果接收到的RX缓冲区不能被Can硬件保护(锁定),以避免被新接收到的消息覆盖,那么Can模块应该在一个shadow buffer中复制L-SDU。

CAN模块提供了一些时间驱动的notifictaion接口,通常是以callback函数形式提供。比如接收的indication通知以及发送的confirmation通知等。

几个重要的API

// 设置CAN控制器通信的波特率
Std_ReturnType Can_SetBaudrate(uint8 Controller, uint16 BaudRateConfigID)
// 设置CAN控制器的模式
Std_ReturnType Can_SetControllerMode(uint8 Controller, Can_ControllerStateType Transition)
// 检查给定控制器上的唤醒事件
Std_ReturnType Can_CheckWakeup(uint8 Controller)
// 使能控制器中断
void Can_EnableControllerInterrupts(uint8 Controller)
// 当CAN发送处理设置为Polling模式时执行发送功能
void Can_MainFunction_Write(void)
// 当CAN发送处理设置为Polling模式时执行读取功能
void Can_MainFunction_read(void)
// 当bus-off处理设置为Polling模式时执行查询bus-off事件的功能
void Can_MainFunction_BusOff(void)

时序图

发送请求

image-20220317112045400

发送确认中断形式

image-20220317112210300

发送确认查询模式

image-20220317112252085

接收指示中断模式

image-20220317112410990

接收指示查询模式

image-20220317112501158

读取接收数据

image-20220317112550371

启动CAN网络

image-20220317112624196

BusOff通知

image-20220317112658184

BusOff恢复

image-20220317112722247

CAN唤醒

参考CAN Trcv章节时序图

CanIf介绍

CanIf和上下层模块的关系图如下,CanIf为上层通信服务层的模块提供访问CAN模块的接口。基于CAN实现的上层协议比如UDSonCAN,XCPonCAN都使用CanIf访问CAN硬件资源;CanSM通过CanIf控制或访问CAN硬件状态,Com通过PduR访问CanIf收发信号。

image-20220317133155426

基本功能

由于CanIf主要用来封装抽象底层的硬件设备CAN控制器和收发器,因此其作用主要为上层提供统一的访问下层硬件的接口,其主要功能分为如下几大类,可以参考CanDrv章节的时序图简要了解。

  • 初始化
  • 发送请求服务
  • 发送确认服务
  • 接收指示服务
  • 控制器模式控制服务
  • PDU模式控制服务
CanIf的应用模式

CanIf的应用模式有三种:

  1. interrupt模式

    CanDrv处理CAN控制器触发的中断。CanIf是基于事件的,在事件发生时得到通知。在这种情况下,相关的CanIf服务在CanDrv中相应的ISR中被调用。

  2. Polling模式

    CanDrv由SchM触发并执行后续处理(Polling Mode)。在这种情况下,Can_MainFunction_<Write/Read/BusOff/Wakeup/Transceiver>()必须在定义的时间间隔内周期性地被调用。CanIf是由CanDrv通知事件(接收,传输,总线关闭,超时),发生在一个CAN控制器,同样的中断驱动操作。CanDrv负责更新CAN控制器中发生事件的相应信息,例如接收L-PDU。

  3. Mixed模式

    该功能可以分为中断驱动和轮询驱动的操作模式,这取决于所使用的CAN控制器。例如:轮询驱动的FullCAN接收和中断驱动的BasicCAN接收,轮询驱动的发送和中断驱动的接收等。

硬件对象句柄

CAN控制器将接收的报文数据存储的本地的邮箱(Mailbox)。本小节介绍存储的机制,首先介绍三种硬件对象句柄:

  • Hardware Object Handles(HOH)

    HOH可以表示如下的HTH或者HRH,其抽象了CAN mailbox的结构,包括CAN相关的参数,比如CanId,DLC,data。CanIf使用如下的HTH和HRH访问CanDrv。

  • Hardware Transmit Handle(HTH)

    硬件发送句柄,抽象了接收的CAN mailbox的结构。HTH应使CanIf能够使用参考发送单元的BasicCAN或FullCAN发送方法,并将发送确认的L-SDU(Link Layer-Service Data Unit)通知给目标上层模块。

  • Hardware Receive Handle(HRH)

    硬件接收句柄,抽象了发送的CAN mailbox的结构。HRH应使CanIf能够使用参考接收单元的BasicCAN或FullCAN接收方法,并将接收到的L-SDU指示给目标上层模块。

    HRH可以配置如下的接收方式:

    • 一个单独的CanId(FullCAN)
    • 一组单独的CanId(BasicCAN)
    • 一个范围的CanId(BaicCAN)
    • 所有CanId

PDU Id与硬件对象句柄的映射图如下:

image-20220316102301404

BasicCAN和FullCAN的接收

CanIf能够识别BasicCAN和FullCAN处理然后激活软件过滤。

BasicCAN和FullCAN的在mailbox上的区别是:FullCAN只能发送或接收单个CanId,BasicCAN可以收发一个范围的CanId

对于配置为BasicCAN的硬件接收对象其可以接收一个范围的CanId,可以配置硬件过滤器。

软件接收过滤器

通过配置硬件接收过滤器,使得不是所有接收的L-PDU都能通过硬件接收过滤器。CanIf能够过滤掉一些不需要的L-PDU,禁止软件的进一步处理。通过配置的软件过滤器算法能够优化软件过滤运行时间。软件滤波机制的方法是从当前正在处理的HRH和CanId中找出相应的L-PDU。找到L-PDU后,CanIf接受接收,允许上层直接访问L-SDU信息。

在AUTOSAR工具链中,当我们导入CAN数据库文件后,可以配置相应的过滤器。

数据长度检查

接收的L-PDU的数据长度会与配置的数据长度进行比较。数据长度的检查必须要有全局使能,不能为某个PDU独立关闭。CanIf会接收所有接收到的L-DPU的数据长度等于或大于配置的数据长度

时序图

参考CanDrv章节时序图

为了帮助大家更好的理解AUTOSAR中CAN通信,大家可以参考如下历史文章

通过配置的软件过滤器算法能够优化软件过滤运行时间。软件滤波机制的方法是从当前正在处理的HRH和CanId中找出相应的L-PDU。找到L-PDU后,CanIf接受接收,允许上层直接访问L-SDU信息。

在AUTOSAR工具链中,当我们导入CAN数据库文件后,可以配置响应的过滤器。

数据长度检查

接收的L-PDU的数据长度会与配置的数据长度进行比较。数据长度的检查必须要有全局使能,不能为某个PDU独立关闭。CanIf会接收所有接收到的L-DPU的数据长度等于或大于配置的数据长度

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注