【AUTOSAR 基础软件】CanIf模块详解(Can栈之接口模块)

文章包含了AUTOSAR基础软件(BSW)中CanIf模块相关的内容详解。本文从AUTOSAR规范解析,ISOLAR-AB配置以及模块相关代码分析三个维度来帮读者清晰的认识和了解CanIf这一基础软件模块。文中涉及的ISOLAR-AB配置以及模块相关代码都是依托于ETAS提供的工具链来配置与生成的,与AUTOSAR规范之间可能会有些许的出入,但总体的功能要点与处理流程都应该是一致的。

CanIf模块作为AUTOSOR的CAN栈最下层模块,向CAN栈的上层提供了不同CAN控制器与收发器的统一抽象接口。CanIf模块主要的作用是将上层需要发送的数据转化为对应CAN帧格式之后通过CAN驱动对应的MailBox发送出去,并将底层驱动接收的数据转发到对应的上层接收模块,CanIf还提供控制器与收发器模式控制的接口给其余基础软件模块。这部分配置由RTA-BSW自动生成,但是由于可能底层的HW Object数目不足以满足通信矩阵中所有的Message用FullCan收发,我们就需要在CanIf这里将多个PDU映射到一个MailBox。CanIf还提供了动态L-PDU的功能来支持运行时根据特定条件动态创建的L-PDU,利用同一个MailBox传输可变CANID与数据长度的CAN帧。

目录

AUTOSAR规范解析

概述

缩略语与概念

模块依赖

CanIf上层模块

CanIf下层模块

配置概述

文件结构

功能说明

一般功能

硬件对象句柄

静动态L-PDUs

物理通道 

CAN硬件单元 

BasicCAN和FulICAN接收 

CanIf初始化 

CanIf发送

CanIf接收

PDU通道模式控制

时序图

Transmit request (single CAN Driver)

Transmit confirmation (interrupt mode) 

Transmit confirmation (with buffering)

Trigger Transmit Request 

Receive indication (interrupt mode)

Read received data

Start CAN network

BusOff notification 

BusOff recovery 

ISOLAR-AB配置  

CanIf

CanIfPublicCfg

CanIfCtrlDrvCfg

CanIfDispatchCfg 

CanIfPrivateCfg 

CanIfPrivateCfg 

代码解析 

动态配置代码

集成代码 

静态代码 


AUTOSAR规范解析

概述

如下图所示,CAN接口模块位于下层CAN设备驱动(控制器与收发器驱动)和上面的通信服务层(即CAN状态管理器、CAN网络管理、CAN传输协议,PDU路由器)。它是上层通信层与CAN驱动程序之间的抽象接口。
CAN 接口模块提供了一个独特的接口,用于管理不同的CAN硬件设备,类型包含CAN控制器与CAN收发器。因此多个芯片的内部或者外部CAN控制器或者CAN收发器可以根据与物理CAN通道完成映射后由CAN状态管理模块控制。

CAN接口模块由所有独立的CAN硬件功能组成,这些功能属于相应的ECU的CAN通信设备驱动程序。这些功能在CAN接口模块中实现一次,因此底层的CAN设备驱动程序只专注于访问和控制相应的特定CAN硬件设备。 

Canlf模块满足PduR和COM堆栈等上层通信模块的主控制流和数据流要求,它包括:发送请求处理、发送确认/接收指示/错误通知和CAN控制器的启动/停止,并参与到休眠唤醒与网络管理等功能中。它的数据处理和通知APIs是基于CAN的L-SDU,而控制和模式处理APIs源自CAN控制器提供的机制。

在传输请求的情况下,Canlf用相应的参数完成L-PDU传输,并通过适当的CanDr将CANL-PDU中继到对应CAN控制器。在接收端,Canlf将接收到的L-PDU作为L-SDU分发给上层。接收的L-SDU和上层之间的对应关系是静态配置的。在发送确认时,Canlf负责向上层通知成功传输。

Canlf模块提供了对CAN驱动程序和CAN收发器驱动程序服务的抽象访问,用于控制和监视CAN网络。Canlf模块向下将CAN状态管理器发出的状态更改请求转发给下层CAN设备驱动程序,向上将CAN驱动程序/CAN收发器驱动程序事件转发给相应的NM模块。


缩略语与概念

  • CAN L-PDU:CAN协议数据单元。由标识符、数据长度和数据(SDU)组成,CAN驱动程序可见。
  • CAN L-SDU:CAN服务数据单元。在CAN L-PDU内传输的数据。对CAN接口的上层(例如PDU Router)可见。
  • CanDrv:CAN驱动模块。
  • CAN FD:具有可变数据速率的CAN。
  • CanId:CAN标识符。
  • CanIf:CAN接口模块。
  • CanNm:CAN网络管理模块。
  • CanSm:CAN状态管理模块。
  • CanTp:CAN传输层模块。
  • CanTrcv:CAN收发器驱动模块。
  • CanTSyn:CAN上的全局时间同步。
  • ComM:通信管理模块。
  • DCM:诊断通信管理模块。
  • EcuM:ECU状态管理模块。
  • HOH:CAN硬件对象句柄。
  • HRH:CAN硬件接收句柄。
  • HTH:CAN硬件发送句柄。
  • J1939Nm:J1939网络管理模块。
  • J1939Tp:J1939传输层模块。
  • PduR:PDU路由模块。
  • PN:部分特定网络。
  • SchM:调度模块。
  • Buffer:固定大小的单个数据单元(如CANID、数据长度、SDU等)存储在RAM中的专用存储地址。
  • CAN communication matrix:描述整个CAN网络,包括:
    • 网络中的CAN节点。
    • 所有CAN PDU的定义(标识符,数据长度等)。
    • 所有所有CAN PDU的发送以及接收方。
  • CAN Controller:CAN控制器是一个CPU片上或外部独立的硬件设备。一个CAN控制器对应到一个物理通道。
  • CAN Device Driver:CAN驱动程序和CAN收发器驱动程序的通用术语。
  • CAN Hardware Unit:CAN硬件单元可以由一个或多个相同类型的CAN控制器和一个两个或多个CAN RAM区域组成。CAN硬件单元位于芯片上或作为外部设备。CAN硬件单元由一个CAN驱动器表示。
  • CanIf Controller mode state machine:这实际上不是一个受传输请求影响的状态机。这是一个适当的CAN控制器当前的状态抽象。状态转换只能通过CanSM之类的上层模块或BusOff之类的外部事件来实现。
  • CanIf Receive L-PDU / CanIf Rx L-PDU:被设置为“从下到上层”的L-PDU。
  • CanIf Receive L-PDU buffer / CanIfRxBuffer:位于Canlf中的单个RAM缓冲区,用于存储整个接收的L-PDU。
  • CanIf Transmit L-PDU / CanIf Tx L-PDU:被设置为“从上到下层”的L-PDU。
  • CanIf Transmit L-PDU buffer / CanIfTxBuffer:位于Canlf中的单个CanlfTxBuffer元素,用于存储一个或多个Canlf Tx L-PDU。如果将单个CanlffTxBuffer元素的缓冲区大小设置为0,则CanlfTxBuffer元素仅用于引用 HTH。
  • Hardware object / HW object:CAN硬件对象被定义为CAN硬件单元或者CAN控制器的CAN RAM中的PDU缓冲区。
  • Hardware Receive Handle(HRH):硬件接收句柄(HRH)由CAN驱动程序定义和提供。每个HRH通常仅表示一个硬件对象。HRH用作Canlf的功能参数(例如软件过滤)。
  • Hardware Transmit Handle(HTH):硬件发送句柄(HTH)由CAN驱动程序定义并提供。每个HTH通常代表一个或多个配置为CAN硬件发送缓冲池的CAN硬件对象。
  • Inner priority inversion:由于同一传输硬件对象中存在待处理的低优先级L-PDU所以高优先级L-PDU的传输被阻止。
  • Integration Code:集成商需要管理的代码,以适应非标准化的功能。例如,ECU状态管理的调用和各种其他BSW模块的回调。I/O硬件抽象也称为集成代码。
  • Lowest In - First Out / LOFO:这是一个数据存储过程,它总是会提取值最低的元素。
  • Outer priority inversion:两个连续传输L-PDU之间存在的时间间隔。在这种情况下,来自另一个节点的较低优先级的L-PDU可以阻止发送自己的较高优先级的L-PDU。在这种情况下,较高优先级的L-PDU无法在网络访问期间参与仲裁,因为较低优先级的L-PDU已经赢得了仲裁。
  • Physical channel:物理信道表示从CAN控制器到CAN网络的接口。CAN硬件单元的不同物理信道可以访问不同的网络。
  • Tx request:从Canlf的上层模块向CAN接口模块申请发送。

模块依赖

本节描述了与AUTOSAR基本软件体系结构中的其他模块的关系。它包含了对CAN接口层从其他模块中所需配置信息和服务(见下图)的简要描述。


CanIf上层模块

在AUTOSAR的基础软件架构中,CAN接口模块的上层由PDU路由器模块(缩写PduR)、CAN网络管理模块(缩写:CanNm)、CAN传输层模块(缩写CanTp)、CAN状态管理器模块(缩写:CanSm)ECU状态管理器模块(缩写:EcuM)、复杂驱动程序模块(缩写:CDD)通用校准协议模块(缩写XCP)、CAN全局时间同步模块(缩写CanTSyn)、J1939传输层模块(缩写J1939Tp)和J1939网络管理模块(缩写J1939Nm)组成。
AUTOSAR的基础软件架构表明,应用程序数据缓冲区位于上层,它们属于上层。禁止直接访问这些缓冲区。缓冲区位置在传输和接收期间通过Canlf传递给CAN驱动程序模块(缩写:CanDrv)。在执行这些发送/接收指示服务期间传递缓冲区位置(指针)。每次访问缓冲区时,使用锁定机制确保数据完整性。
Canlf使用的APIs包括通知服务,作为将CAN相关数据(例如数据长度等)传输到目标上层的基本代理。这些服务的调用参数指向CanDrv中缓冲的信息,或者直接指向CAN硬件。

EcuM初始化CanIf模块,CanSm模块负责所有支持的CAN控制器和CAN收发器的模式控制管理。

CanIf下层模块

主要的下层CAN设备驱动程序由CanDrv表示。由于Canlf在AUTOSAR基本软件体系结构中的位置,它与CanDrv密切相关。CanDrv仅提供对CAN控制器的硬件抽象访问,但CAN控制器模式的控制仅在CanSm中完成。CanDrv检测并处理CAN控制器的事件,并将这些事件通知Canlf。Canlf将CanSm的控制模式请求传递给相应的底层CAN控制器。
CanDrv提供了一个标准化的L-PDU,以确保Canlf的硬件独立性。指向这个标准化L-PDU的指针要么指向临时缓冲区,要么指向依赖于CAN硬件的CanDrv。对于Canlf,L-PDU缓冲区的类型是不可见的。
Canlf提供CanDrv在所有通知场景下的通知服务,例如:传输确认、接收指示、传输取消通知和控制器模式更改通知。如果使用多个CanDrv服务于不同的中断向量表,则上述回调服务必须是可重入的。CanDrv调用的回调服务在Canlf中声明并实现,Canlf调用的回调服务在适当的上层通信服务层中声明并放置,例如 PduR、CanNm、CanTp。
配置的CAN控制器的数量不一定等于使用的CAN收发器的数量。如果不同类型的CAN控制器需要在同一CAN网络上运行,则就需要一个CanTrcv和多个CAN控制器即可,而取决于CAN控制器设备的类型,需要一个或多个不同的CanDrv。

第二个可用的下层CAN设备驱动程序由CanTrcv表示,每个CanTrcv本身都执行CAN收发器设备的模式控制。Canlf只需将底层CanTrcv的所有API映射到一个唯一的CanSm,从而使CanSm能够触发相应的CAN收发器模式的转换。在Canlf中不会执行任何属于CanTrcv的控制或处理功能。
Canlf将所有底层CanTrcv的以下服务映射到一个唯一的接口。这些服务在CAN收发器驱动程序中进一步描述:

  • 独特的CanTrcv模式请求和读取服务,以管理每个底层CAN收发器设备的模式。
  • 读取CAN收发器服务,用于支持唤醒原因查询。
  • 模式请求服务,用于启用/禁用/清除每个使用的CAN收发器的唤醒事件状态(Canlf SetTrcvMode())。

配置概述

Canlf设计经过优化,以管理CAN协议特定功能和使用的底层CAN控制器。Canlf能够在不重新构建的情况下更改CAN配置。因此,Canlf Init()函数从配置容器和参数中检索所需的CAN配置信息,例如:

  • CAN控制器的数量。CAN控制器的数量对于传输和接收L-PDU的调度以及控制可用CAN驱动器的状态是必要的。
  • 硬件对象句柄的数量。为了监督传输请求,CAN接口需要知道HTH的数量以及每个HTH和相应的CAN控制器之间的分配。
  • 每个硬件对象的接收CANID的范围。CAN接口使用HRH和L-PDU之间的固定映射关系,以便在相应的硬件对象中接收,以执行搜索过滤算法。

Canlf需要有关所有使用的上层通信服务层和L-SDUs的信息。在AUTOSAR的COM堆栈内集成Canlf时,必须在配置时间设置以下信息:

  • CanIfTxPduId:绑定上层发送模块和每个发送L-SDU传输的I-PDU,参数用于分派发送确认服务。
  • CanIfRxPduId:绑定上层接收模块和每个接收L-SDU上传的I-PDU,参数用于L-SDU接收期间的指示调度。

Canlf需要控制器和自己的ECU的描述,该ECU连接到一个或多个 CAN 网络。因此,从 AUTOSAR系统配置的一部分CAN通信矩阵中检索以下信息:

  • 针对ECU每个物理通道所有接收的L-PDUs,它用于软件过滤和接收L-SDU的分派。
  • 针对ECU每个物理通道所有应该被发送的L-SDUs,用于发送请求和传输L-PDU调度。
  • L-PDUs的属性信息(例如ID,数据长度),它被用于软件过滤,接收指示服务,数据长度检测。
  • 每一个发送L-SDU的发送者(例如PduR,CanNm,CanTp),它被用作发送确认服务。
  • 每一个接收L-SDU的接收者(例如PduR, CanNm, CanTp),它被用作L-PDU的分发。
  • L-PDU/L-SDU的符号名称,用作用于表示Rx/Tx数据缓冲区地址。

文件结构

因为CanIf模块文件结构较为复杂,文件结构示意图如下:

下面我们来简要描述一个各个文件包含的内容信息:

  • Can_<vendorID>_<Vendor specific name>.h:用于CanDrv的服务和类型定义(例如Can_99_Ext1.h, Can_99_Ext2.h)。
  • CanTrcv_<vendorID>_<Vendor specific name>.h:用于CanTrcv的服务和类型定义(例如:CanTrcv_99_Ext1.h)。
  • Can_GeneralTypes.h:对于一般的CAN栈类型声明。
  • ComStack_Types.h:用于COM相关类型定义。
  • PduR_CanIf.h:对于PduR的服务和回调声明。
  • SchM_CanIf.h:用于SchM的服务和回调声明。
  • CanSM_Cbk.h/CanNm_Cbk.h/CanTp_Cbk.h/EcuM_Cbk.h/<CDD>_Cbk.h/Xcp_Cbk.h/CanTSyn_Cbk.h/J1939Tp_Cbk.h/J1939Nm_Cbk.h:对应模块回调函数声明。
  • Can_<vendorID>_<Vendor specific name>.h:用于CanDrv的配置数据(Can_99_Ext1.h)。
  • CanTrcv_<Vendor Id>_<Vendor specific name>.h:用于CanTrcv的配置数据(CanTrcv_99_Ext1.h)。
  • PduR.h/CanNm.h/CanTp.h/Xcp.h/J1939Tp.h/J1939Nm.h:对应模块的配置数据。

功能说明

一般功能

Canlf提供的服务可分为以下主要组别:

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

CanIf的可能服务:

  • Interrupt Mode:CanDrv处理由CAN控制器触发的中断。事件驱动的Canlf在事件发生时得到通知。在这种情况下,相关Canlf服务在CanDrv的相应ISR中调用。
  • Polling Mode:CanDrv由SchM触发并执行后续过程(轮询模式)。在这种情况下,必须在定义的时间间隔内定期调用Can_MainFunction_<Write/Read/BusOff/Wakeup/Transceiver>()函数。Canlf由CanDrv通知事件(接收、传输总线关闭、传输取消、超时),这些事件发生在CAN控制器之一中,但是在轮询中处理。CanDrv负责更新CAN控制器中属于已发生事件的相应信息,例如接收L-PDU。
  • Mixed Mode:中断和轮询驱动CanDrv根据所使用的CAN控制器,功能可分为中断驱动和轮询驱动两种操作式。示例:轮询驱动的FuIICAN接收和中断驱动的BasicCAN接收,轮询驱动的传输和中断驱动接收等。

总结一下,Canlf以相同的方式工作,无论是否在中断、轮询(任务级别)或混合上处理任何事件。唯一的区别是调用上下文和通知的中断方式:抢占式或协作式。所有服务也均按照配置执行。

硬件对象句柄

传输(HTH)和接收(HRH)的硬件对象句柄(HOH)代表对包含CAN帧相关参数(例如Canld、DLC和数据)的CAN邮箱结构的抽象引用。基于CAN硬件缓冲区抽象,每个硬件对象都独立于CAN硬件缓冲区布局被CanIf所引用。HoH在CanDrv接口服务的调用中用作参数,由CanDrv的配置提供,并由CanDrv作为CAN邮箱通信缓冲区的标识符使用。Canlf仅作为硬件对象处理的用户,而不是基于硬件特定信息来解释它。因此,Canlf仍然独立于硬件。下图体现了PDU Ids与硬件对象句柄的映射路径。可以从下图中看出,一个MailBox中可以包含多个硬件对象,当一个HRH配置为接收时,它可以只接收一个CAN帧ID(FullCAN),或者一组CAN帧ID(BasicCAN)。


静动态L-PDUs

Canlf支持激活和停用属于一个CAN控制器的所有L-PDU的传输和接收。每个L-PDU都与上层模块相关联,以确保在接收、传输确认和数据访问期间正确分配。每个上层模块都可以使用L-PDUs来为不同的CAN控制器服务。
根据为整个AUTOSAR通信堆栈定义的PDU结构,L-PDU的使用有两种不同的方式:

  • 对于传输请求和传输/接收轮询API,上层模块使用由Canlf定义的L-SDU ID(CanTxPduld/CanRxPduld)作为参数。
  • 对于Canlf在上层模块调用的所有回调API,Canlf传递每个上层模块目标的PduId作为参数。

原则是调用者必须使用被调用者指定的目标L-PDU/L-SDU。如果在上电的时候没有执行相关的初始化,上层对Canlf执行传输请求时,将不会将L-SDUs传输到下层,且会调用DET。因此,网络中不能传输未初始化的数据。

Canlf应支持使用CanlfRxPdu-CanldMask过滤传入消息的能力。过滤应通过将传入的Canld在与CanIfRxPduCanIdMask相与之后,与CanIfRxPduCanId跟CanIfRxPduCanIdMask相与之后进行比较。这应该在未应用掩码的常规Canlds过滤之后进行,以便区别处理。

此外,应支持动态Tx和Rx的L-SDUs,其中Canld位于L-SDU的MetaData中。在传输动态L-SDUs时,当定义了CanlfTxPduCanldMask时,通过元数据提供的Canld的变量部分必须使用此掩码与Canld合并。如果没有配置CanlfTxPduCanldMask和CanlfTxPdu-Canld,则元数据应直接用作Canld。在接收动态L-SDU时,接收到的Canld应放置在L-SDU的MetaData中。MetaData的内容独立于CanlfRxPduCanld-Mask参数。


物理通道 

一个物理信道与一个CAN控制器和一个CAN收发器连接,而一个或多个物理信道可以连接到单个网络。Canlf提供控制所有CAN设备的服务,如所有支持的ECU的CAN通道的CAN控制器和CAN收发器。这些APls由CanSm用于向ComM提供网络结构,并用于对所有连接到单个网络的物理通道执行唤醒和睡眠请求。Canlf将CanDrv和CanTrcv为每个物理信道分别提供的状态信息传递为CanSm的状态信息(<User ControllerBusOff>())。下面这个例子展示同一个CanDrv驱动两个控制器,每个控制器对应一个收发器并连接到一个CAN网络。

下面这个例子则展示了更复杂的物理通道形式,包括多个控制器对应一个收发器。


CAN硬件单元 

CAN硬件单元将一个或多个相同类型的CAN控制器模块组合在一起,这些模块可以位于芯片上或作为外部独立设备。每个CAN硬件单元都由相应的CanDrv提供服务(一对一)。如果使用不同类型的CAN控制器,则必须使用统一的API与Canlf一起来实现不同类型的CanDrvs。Canlf在配置期间收集有关CAN控制器及其硬件对象的数量和类型的信息。这允许上层模块使用HOHs来透明且独立于硬件地访问CAN控制器。下图显示了一个CAN硬件单元,该单元由两个相同类型的CAN控制器组成,这些控制器连接到两个物理信道:


BasicCAN和FulICAN接收 

Canlf在激活软件接收过滤时区分BasicCAN和FulCAN来进行不同处理。仅用于FulCAN操作的CAN邮箱只能传输或接收单个Canld。对应来说,BasicCAN的一个硬件对象可以发送或接收一系列 Canlds。配置的BasicCAN的接收硬件对象通过其硬件接受过滤器的Canlds范围完成接收。此范围可能超过由HRH接收的预定义Rx L-PDU列表。因此,Canlf随后应执行软件过滤,仅将预定义的Rx L-PDU列表传递给相应的上层块。


CanIf初始化 

EcuM调用Canlf的函数Canlf_Init()对整个Canlf进行初始化。在初始化过程中,包括标志和缓冲区在内的所有全局变量和数据结构都进行了初始化。EcuM通过调用相应的初始化服务,分别执行CanDrvs和CanTrcvs的初始化。
Canlf期望CAN控制器在初始化过程完成后保持STOPPED模式,就像在开机复位后一样。在这种模式下,Canlf和CanDry都无法传输或接收CAN L-PDUS。如果在运行时需要重新初始化整个CAN模块,则EcuM应通过CanSm调用CAN接口模块的API服务Canlf_SetControllerMode()来启动CAN 控制器的所需状态转换。Canlf将来自CanSm的调用映射到相应的CanDrvs的调用。


CanIf发送

CanIf的发送请求函数CanIf_Transmit()是上层模块传输L-PDU的通用接口。上层通信层模块需要通过CanIf的服务启动传输,无法直接访问CanDrv。如果CanDrv能够将L-PDU数据写入CAN硬件传输对象中,则发起的传输请求成功完成。上层模块使用API服务CanIf_Transmit ()来发起一个传输请求。CanIf在调用服务CanIf_Transmit()时对L-PDU传输执行以下操作:

  • 检查,初始化CanIf的状态。
  • 当使用多个CanDrv时,识别CanDrv。
  • 确定访问CAN硬件传输对象的HTH。
  • 调用CanDrv的Can_Write()。

如果传输请求服务CanIf_Transmit()返回E_OK,则传输成功完成。如果一个L-PDU被请求通过一个PDU通道来传输,但是当前通道的模式为CANIF_OFFLINE,那么CanIf应该向DET通过Det_ReportRuntimeError()服务报告运行时的错误代码CANIF_E_STOPPED,而CanIf_Transmit() 将返回E_NOT_OK。

发送请求服务CanIf_Transmit ()是基于L-PDU的。对L-SDU特定数据的访问按以下参数组织:

  • 发送的L-PDU =>L-SDU ID
  • 引用包含L-SDU相关数据的数据结构(包括指向L-SDU的指针,指向元数据的指针和L-SDU长度)

对L-SDU数据结构的引用被用作几个CanIf的API服务中的参数,例如CanIf_Transmit()或回调服务<User RxIndication>()。如果L-PDU配置为触发传输,则L-SDU指针为空指针。下图展示了发送的数据流。

CanIf会存储为传输而配置的硬件对象信息。函数CanIf_Transmit()将CanTxPduId映射到对应的HTH,并调用函数Can_Write()。如果总线镜像是全局启用的CanIfBusMirroringSupport(),并且通过调用CAN控制器的CanIf_EnableBusMirroring()来激活,那么CanIf通过Can_Write()在控制器上传输每帧内容之前将其存储。只有在实际发送时,才提供总线镜像模块。因此,为了能够从CanIf_TxConfirmation()将其提供给总线镜像模块,必须考虑存储内容。

对CanIf而言, 传输过程从调用CanIf_Transmit()开始,到调用上层模块的回调服务结束。 在传输过程中,CanIf、CanDrv和CAN Mailbox一起存储L-PDU,只在一个位置传输一次。根据传送方式的不同,分为: 

  • CAN硬件传输对象
  • 如果发送缓冲使能,发送L-PDU缓冲区在CanIf内。

对于触发传输,CanIf只需要存储给定L-PDU的传输请求,而不需要存储它的数据。当HTH空闲时,数据将会通过触发发送函数及时获取。请求传输的单个TxLPDU永远不会被存储两次。这种行为对应于CAN网络上的周期性通信的通常方式。如果CanIf在传输请求时被CanDrv拒绝,CanIf将启用传输缓冲,并将在传输L-PDU缓冲区(CanIfBufferCfg)中存储一个发送L-PDU。

基本上,用于缓冲发送L-PDU的整个CanIf中的缓冲区包含一个或多个CanIfBufferCfg。而每个CanIfBufferCfg被分配给一个或多个专用的CanIfBufferHthRef,可以配置为缓冲一个或多个发送I-PDU。但是,在CanIfBufferCfg的总体数量中,针对每个发送L-PDU只能缓冲一个实例。

根据在相应的发送L-PDU配置中是否启用传输缓冲,CanIf在L-PDU传输期间对应的行为是不同的。 如果发送缓冲被禁用,并且发送到CanDrv的请求失败,那么L-PDU不会被复制到CAN控制器,CanIf_Transmit()将返回值E_NOT_OK 。如果启用了传输缓冲,并且发送到CanDrv的请求失败,根据CanIfTxBuffer配置,L-PDU可以存储在CanIfTxBuffer中。在这种情况下,尽管无法执行传输,CanIf_Transmit()也会返回E_OK值 。在这种情况下,CanIf通过CanIf_TxConfirmation()回调和处理L-PDU未完成的传输,而上层不必重新提出传输请求。CanIf发送L-PDU缓冲区的数量,可以独立于CAN网络描述文件中定义的传输L-PDU的数量来配置。如果不需要缓存,则可以将CanIfBufferCfg的缓冲区大小设置为0。

如果前一个传输请求成功完成,CanDrv会通过调用CanIf_TxConfirmation()将其通知给CanIf。如果对于CAN控制器,启用了全局总线镜像CanIfBusMirroringSupport和激活调用CanIf_EnableBusMirroring(), CanIf将会调用Mirror_ReportCanFrame()对每一帧传输控制器确认过的CanIf_TxConfirmation()帧数据,提供存储内容和实际的ID。

调用回调函数CanIf_TxConfirmation()时,CanIf标识与成功传输L-PDU相连的上层通信层,通过调用CanIf的传输确认服务<User TxConfirmation>(E OK)来通知其传输执行情况。可以配置上层通信层模块,通过对不同的I-PDU或I-PDU组使用单个或多个(一般我们使用的是单个)回调服务来处理发送确认。所有那些服务在发送L-PDU传输请求确认发送之后,会被CanIf调用。传输L-PDU允许分派与目标上层模块关联的不同确认服务,该分配是在静态配置期间完成。一个发送L-PDU只能分配给一个发送确认回调服务。如果启用了CanlfPublicTxConfirmPollingSupport,则当CAN控制器的控制器模式处于CAN_CS_STARTED状态时,Canlf应缓冲有关接收到的TxConfirmation的信息。


CanIf接收

根据AUTOSAR的基础软件架构,接收到的数据将在上层通信模块,即COM、CanNm、CanTp和 DCM中进行评估和处理。这意味着,上层模块既不能使用CanDrv的缓冲区,也不能访问CanIf的缓冲区。只有当CANIF_PUBLIC_READRXPDU_DATA_API设置为TRUE时,CanIf才会在接收路径中提供内部缓冲。如果接收到CanDrv的L-PDU,则调用CanIf的CanIf_RxIndication ()。对L-PDU特定数据的访问由以下参数组织:

  • 硬件接收手柄(HRH)
  • 接收CAN标识符(CanId)
  • 接收数据长度
  • 已收到的L-PDU引用。

接收到的L-PDU依赖于硬件,并分配给通信系统的最低层CanDrv。 HRH是CanDrv和使用L-PDU的上层模块之间的链接 。HRH标识CAN硬件接收句柄,接收新的CAN L-PDU。在CanDrv调用CanIf_RxIndication(),指示接收到的L-PDU后,CanIf将进行处理。CanIf无法识别CanDrv是使用临时缓冲还是直接访问硬件。它期望在调用CanIf_RxIndication()时得到标准化的L-PDU数据。CAN硬件接收句柄会被锁定,直到复制到临时或上层模块缓冲区的过程结束。硬件对象将在CanIf的CanIf_RxIndication()返回后立即释放。CanDrv、CanIf和接收到L-PDU对应的上层模块访问相同的临时缓冲区,该临时缓冲区可以位于CAN控制器的硬件接收对象中,也可以位于CanDrv中的临时缓冲区中。下图为CanIf的接收流图。

底层驱动调用CanIf_RxIndication()引用新接收到的L-PDU的参数,如果调用了函数CanIf_RxIndication(),CanIf将对CAN L-PDU进行评估接收,并准备L-SDU供上层通信层访问。CanIf使用<User_RxIndication>()通知上层模块这个异步事件。

如果总线镜像是全局启用的,并且通过调用CAN控制器的CanIf_EnableBusMirroring()激活,那么CanIf应该为该控制器上用CanIf_RxIndication()来通知的每一帧接收调用Mirror_ReportCanFrame()。

如果调用函数CanIf_RxIndication(),CanIf会按照指定的方式处理接收到的L-PDU。如果软件过滤拒绝接收到的L-PDU,CanIf会结束对CanIf_RxIndication调用的进一步接收通知。

如果CanIf在软件过滤过程中接受通过CanIf_RxIndication()接收到的L-PDU, CanIf随后会进行数据长度检查。如果CanIf在数据长度检查期间底层又使用CanIf_RxIndication()接收L-PDU, CanIf将根据配置的数据长度的字节数暂时将其复制到静态接收缓冲区。

如果为接收的L-SDU配置了元数据,CanIf将PDU有效负载复制到静态接收缓冲区,并将CANID复制到类型为CAN_ID_32的Meta-DataItem。

在数据长度检查期间,如果CanIf接受到了通过CanIf_RxIndication()的L-PDU,CanIf会识别是否配置了目标上层模块(CanIfRxPduUserRxIndicationUL,CanIfRxPduUserRxIndicationName),并为接收到的L-SDU提供接收通知服务。

如果目标上层模块被配置为提供接收通知服务,CanIf应该调用配置的接收通知回调服务,并提供所需的参数至上层通知回调函数。

CanIf在底层调用CanIf_RxIndication()时执行以下步骤:

  • 软件过滤(只有Basic CAN),如果配置了。
  • 数据长度检查。
  • 缓冲接收L-SDU。
  • 调用上层接收通知回调服务。

读取接收到的数据通过CanIf_ReadRxPduData(),其是上层模块读取最近从CAN网络接收到的CANL-SDU的公共接口。上层模块只通过CanIf服务发起接收请求,而不直接访问CanDrv。发起的接收请求成功完成,CanIf将接收到的L-SDU写入上层模块I-PDU缓冲区。

函数CanIf_ReadRxPduData()使得在不依赖接收事件的情况下读取数据成为可能。在配置时启用它,他不会为相同的L-SDU配置接收通知服务。如果需要,可以启用接收通知服务。

在底层调用CanIf_RxIndication()并通过软件过滤和数据长度检查后,CanIf将接收到的L-SDU存储在这个接收到的L-SDU缓冲区中。如果调用CanIf_ReadRxPduData()将数据复制到指定的接收L-SDU缓冲区时,CanIf应避免抢占指定的接收L-SDU缓冲区的访问事件。
CanIf提供用于控制由CanDrv支持的CAN控制器通信模式的服务。这意味着所有CAN控制器都由相应的API服务来控制,以请求和读取当前控制器模式。

可以通过调用CanIf_SetControllerMode()服务,来根据上层的请求更改CAN控制器状态。请求通过CanIf经过CanDrv的API传递到指定的CAN控制器。在CAN网络上对所有CAN控制器的一致性管理是CanSm的任务。通过这种方式, CanSm负责将CAN网络的所有CAN控制器按顺序设置为睡眠模式或唤醒 。CanIf通过调用函数CanIf_SetControllerMode()或CanIf_ControllerBusOff()接受每个状态转换请求。CanIf不决定CAN控制器请求的模式转换是否有效。CanIf仅通过获取当前模式和执行请求的模式转换来与CanDrv交互,仅提供一个桥梁的工作。网络相关状态机在CanSm中实现。CanIf只存储请求的模式并执行请求的转换。

如果ControllerId引用的控制器模式处于CAN_CS_STOPPED状态,并且如果CanIf_Transmit()调用中的PduIdType参数被分配给该CAN控制器,那么CanIf_Transmit()调用不会导致Can_Write()调用,而是返回E_NOT_OK。如果ControllerId引用的控制器模式进入CAN_CS_STOPPED状态,
CanIf会清除分配给CAN控制器相应的CanIf传输缓冲区。

如果ControllerId引用的控制器模式进入CAN_CS_STOPPED状态,那么CanIf通过调用<User TxConfirmation>(id,E NOT OK)为分配给CAN控制器的每个未完成的TxConfirmation,通知相应的上层模块传输失败。如果启用了CanIfPublicTxConfirmPollingSupport,那么CanIf还会清除关于TxConfirmation的信息。这确保了对于每个PDU,都会调用一个<User TxConfirmation>。

当底层调用回调CanIf_ControllerBusOff(ControllerId)时,CanIf会调用CanSm或CDD的CanSM_ControllerBusOff(ControllerId)。


PDU通道模式控制

每个L-PDU都分配到一个专用的物理CAN通道,该通道连接到一个CAN控制器和一个CAN网络。通过这种方式,属于一个物理通道的所有L-PDU都可以通过处理逻辑上的单个L-PDU通道组来控制。这些逻辑组表示连接到底层CAN网络的一个ECU上的所的L-PDU。

下图显示了L-PDU通道群组的一种可能用途及其与上层网络的关系。
L-PDU只能分配给一个通道组。PduR或网络管理器等典型用户负责控制PDU操作模式。

只允许在对应的控制器模式等于CAN_CS_STARTED时,更改PDU通道模式。虽然CANIF_ONLINE和CANIF_OFFLINE在PDU信道模式下影响整个通信,但是可以分别启用和禁用CANIF_TX_OFFLINE和CANIF_TX_OFFLINE_ACTIVE传输路径。CanIf通过服务CanIf_GetPduMode()提供关于当前PDU通道模式的信息。

在初始化期间,CanIf应该将每个通道切换到CANIF_OFFLINE。对于切换到CANIF_OFFLINE模式的物理通道,CanIf应该:

  • 防止将相关L-PDU的传输请求CanIf_Transmit()转发给CanDrv。
  • 清除相应的CanIf传输缓冲区。
  • 防止调用上层模块的接收通知回调服务。
  • 防止调用上层模块的传输确认回调服务。 

如果底层调用CanIf_SetControllerMode()或CanIf_ControllerBusOff(),则CanIf应将相应通道的PDU通道模式设置为CANIF_TX_OFFLINE。对于切换到CANIF_ONLINE模式的物理信道,CanIf应该:

  • 允许将相关L-PDU的传输请求CanIf_Transmit()转发到CanDrv。
  • 支持调用上层模块的接收指示回调服务。
  • 允许调用上层模块的传输确认回调服务。

如果CanIfTxOfflineActiveSupport为TRUE,CanIf提供通过CANIF_TX_OFFLINE_ACTIVE模式来模拟成功传输。对于每个被分配到CANIF_TX_OFFLINE_ACTIVE模式信道的L-PDU, CanIf会立即调用上层模块的传输确认回调服务,而不是在调用CanIf_Transmit()时将L-PDU缓冲或转发到CanDrv。


时序图

这里只介绍部分常用的功能时序图,详细完整的CanIf模块时序图见《AUTOSAR_SWS_CANInterface.pdf》。

Transmit request (single CAN Driver)

可以看到他在Busy的时候将L-PDU存放在在发送buffer中。


Transmit confirmation (interrupt mode) 


Transmit confirmation (with buffering)

针对利用TX Buffer的发送确认动态图。


Trigger Transmit Request 

触发试发送,发送数据不在调用CanIf_Transmit的时候往下层送,而是底层触发发送的时候拷贝数据过去。


Receive indication (interrupt mode)

可以看到,针对Tempoary buffer使用与否,有两种不同的处理方式。


Read received data

可以看到这种处理方式会在接收中断来临的时候把数据放在CanIf的buffer中,用户主动读取。


Start CAN network

下图展示了启动CAN控制器的流程,并针对当前控制器状态体现了不同的动态动作。


BusOff notification 

BusOff的通知动态图如下。


BusOff recovery 

BusOff的恢复动态图,CanIf仅改变内部状态,真正的BusOff的恢复逻辑由CanSm提供,其简单概述为尝试重新配置控制器为Start。


ISOLAR-AB配置  

CanIf

这里的配置在导入DBC之后,经过RTA-BSW工序之后会自动根据DBC中包含的报文进行生成,但是不免会因为要使用BasicCan或者别的其他原因更改这部分的配置。我们下边介绍一下这个CAN栈模块的各个配置项。

CanIfPublicCfg

这个容器中包含CanIf的公共信息,能对各个模块产生影响的部分,如下图所示。

我们下边介绍几个比较重要的配置:

  • CanIfMetaDataSupport:是否使能动态ID处理L-SDU Metadata。
  • CanIfPublicCancelTransmitSupport:该参数允许请求取消I-PDU的发送支持。但是可以由下面的代码截图看出,ETAS的静态代码并没有实现这个部分。

  •  CanIfPublicHandleTypeEnum:Can_HwHandleType表示CAN的硬件单元,当HW object大于255的时候,需要是UINT16的数据类型。
  • CanIfPublicIcomSupport:是否支持虚拟CAN网络功能,ETAS尚未实现此功能。
  • CanIfPublicReadRxPduDataApi:打开Canlf_ReadRxPduData()。此函数用于读取CAN的SDU信息。传入CanIfRxSduId,为PDU ID,函数回填指针,指向CanIf_PduInfoType。

  • CanIfTriggerTransmitSupport:COM层面要是由触发传输,此处会设置为Ture。Canlf_TriggerTransmit()会被使能。

CanIfCtrlDrvCfg

这个容器不仅包含了下边CanIfInitHohCfg容器的引用CanlfCtrlDrvInitHohConfigRef配置,以及驱动程序的类型参考CanlfCtrlDrvNameRef配置项,配置项CanlfRbCtrlDryPrefix方便集成第三方驱动,其中包含供应商前缀和API中缀,方便使用对应的接口和变量。

 子容器CanIfCtrlDrvCfg中包含对CAN模块中定义的控制器引用。


CanIfDispatchCfg 

本容器主要包含Canlf的上层模块相关的回调函数,其对所有配置的CAN驱动程序/CAN收发器驱动程序模块都是通用的。下图主要涉及的配置项有CanlfDispatchUserCtrlBusOffUL、CanlfDispatchUserCtrlModelndicationUl与CanlfDispatchUserTrcvModelndicationName。他们的配置都是CAN_SM,这些参数分别定义了当CAN控制器BusOff,CAN控制器模式变化以及收发器模式变化时,通知的上层模块。


CanIfPrivateCfg 

此容器包含CAN接口模块的初始化参数。它主要包含四个子容器,我们逐一来分析。

首先是CanlfBufferCfgs。默认RTA-BSW生成的Mailbox都是FullCan的,每个Mailbox包含一个HW object,但是这个子容器依然会针对每个发送的Mailbox生成对应的Buffer配置,方便用户修改成BasicCan,如果用户使用的为FullCan,则CanlfBufferSize应配置为0。

然后是CanIfInitHohCfg子容器,其中包含CanlfHrhCfg与CanlfHthCfg两个子容器,分别对应CAN模块接收以及发送的MailBox引用和CanIf定义的CanlfCtrlCfg引用,CanlfHrhCfg如果对应多个PDU,则可以在CanIfHrhListCfg配置PDUs的CANID。

然后我们介绍CanlfRxPduCfg容器,它包含接收PDU的属性配置(接收CanId,DLC,CanId类型,接收上层的模块以及接收通知名称),还包含刚才提到的HRH引用,如果要实现BasicCan则需要多个CanlfRxPduCfg引用同一个HRH,还有EcuC的Pdu路径等引用。

最后的是CanlfTxPduCfg,它其中包含一个PDU属性(CanId,CanId类型,DLC,静态还是动态PDU,以及上层的使用模块),还包含CanIf模块的buffer引用,以及PduR的路径等引用。


CanIfPrivateCfg 

这个容器包含CanIf模块的私有配置,其中CanlfPrivateDlcCheck用作开启/关闭DLC的检查。


代码解析 

动态配置代码

CanIf生成的动态配置代码如下。

我们针对一些常用的文件内容说明:

  • CanIf_Cfg_SymbolicNames.h: 文件包含一些符号化的值,包括 Rx Receive Handles,TxPduIds以及RxPduIds。
    /*
    ***********************************************************************************************************************
    * 
    * Product Info
    * Isolar version: ISOLAR-AB 4.0.2
    * Product release version: RTA-BSW 3.1.0
    * 
    ***********************************************************************************************************************
    */
    
    
    /*<VersionHead>
     * This Configuration File is generated using versions (automatically filled in) as listed below.
     *
     * $Generator__: CanIf / AR42.4.0.1                Module Package Version
     * $Editor_____: 9.0                Tool Version
     * $Model______: 2.0.2.1                ECU Parameter Definition Version
     *
    
     </VersionHead>*/
    
    #ifndef  CANIF_Cfg_SymbolicNames_H
    #define  CANIF_Cfg_SymbolicNames_H
    /**************************************************************************/
    /*                            Include Section                             */
    /**************************************************************************/
    
    
    /*
     **************************************************************************
     * Defines
     **************************************************************************
     */
    
    /* Definition of Rx Receive Handles (HRH) for __KW_COMMON*/
     
    
    #define CanIfConf_CanIfHrhCfg_Can_Network_CANNODE_ECAN_Rx_Std_MailBox_1_Config       0
    #define CanIfConf_CanIfHrhCfg_Can_Network_CANNODE_ECAN_Rx_Std_MailBox_2_Config       1
    #define CanIfConf_CanIfHrhCfg_Can_Network_CANNODE_ECAN_Rx_Std_MailBox_3_Config       2
    
    /* Definition of TxPduIds for Precompile */
    
    #define CanIfConf_CanIfTxPduCfg_DV_Test_Message_1_Can_Network_CANNODE_ECAN        0
    #define CanIfConf_CanIfTxPduCfg_Tx_Test_Message_01_Can_Network_CANNODE_ECAN        1
    #define CanIfConf_CanIfTxPduCfg_Diag_VCU_Resp_Can_Network_CANNODE_ECAN        2
    
    
    /* Definition of RxPduIds for Precompile*/
    
    #define CanIfConf_CanIfRxPduCfg_Rx_Test_Message_01_Can_Network_CANNODE_ECAN        0
    #define CanIfConf_CanIfRxPduCfg_Diag_VCU_ReqPhsy_Can_Network_CANNODE_ECAN        1
    #define CanIfConf_CanIfRxPduCfg_Diag_ECAN_ReqFunc_Can_Network_CANNODE_ECAN        2
    
    
     #endif /* CANIF_Cfg_SymbolicNames_H */
  • CanIf_Cfg.h:CanIf的一些通用配置,包括一些功能与API的开关宏定义。
    /*
    ***********************************************************************************************************************
    * 
    * Product Info
    * Isolar version: ISOLAR-AB 4.0.2
    * Product release version: RTA-BSW 3.1.0
    * 
    ***********************************************************************************************************************
    */
    
    /*<VersionHead>
     * This Configuration File is generated using versions (automatically filled in) as listed below.
     *
     * $Generator__: CanIf / AR42.4.0.1                Module Package Version
     * $Editor_____: 9.0                Tool Version
     * $Model______: 2.0.2.1                ECU Parameter Definition Version
     *
    
     </VersionHead>*/
    
    
    
    #ifndef  CANIF_CFG_H
    #define  CANIF_CFG_H
    /**************************************************************************/
    /*                            Include Section                             */
    /**************************************************************************/
    #include "CanIf_Cfg_SymbolicNames.h"
    /*
     **************************************************************************
     * Defines
     **************************************************************************
     */
    /**************************************************************************/
    /*  Common Published Information                                          */
    /**************************************************************************/
     /**
     * @ingroup CANIF_H
     *
     * Vendor Id
     */
    #define CANIF_VENDOR_ID                          6u
    
    /**
     * @ingroup CANIF_H
     *
     * Module Id
     */
    #define CANIF_MODULE_ID                          60u
    
    /**
     * @ingroup CANIF_H
     *
     * Autosar Release Major Version
     */
    #define CANIF_AR_RELEASE_MAJOR_VERSION           4u
    /**
     * @ingroup CANIF_H
     *
     * Autosar Release Minor Version
     */
    #define CANIF_AR_RELEASE_MINOR_VERSION           2u
    /**
     * @ingroup CANIF_H
     *
     * Autosar Release revised version
     */
    #define CANIF_AR_RELEASE_REVISION_VERSION        2u
    
    /**
     * @ingroup CANIF_H
     *
     * Software Release Major Version
     */
    #define CANIF_SW_MAJOR_VERSION                   4u
    /**
     * @ingroup CANIF_H
     *
     * Software Release Minor Version
     */
    #define CANIF_SW_MINOR_VERSION                   0u
    /**
     * @ingroup CANIF_H
     *
     * Software Release Patch Version
     */
    #define CANIF_SW_PATCH_VERSION                   1u
    
    
    #define CANIF_CONFIGURATION_VARIANT MODULE_VARIANT_PRE_COMPILE
    
    
    /*Number of variants configured in CanIf*/
    #define CANIF_TOTAL_CFG_SETS                1
    
    /**************************************************************************/
    /* Description :  Enables or disables the development error detection &   */
    /*                notification mechanism                                  */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    #define CANIF_DEV_ERROR_DETECT                     STD_OFF
    /**************************************************************************/
    /* Description :  Enables or disables BaudRateChange in the CanDriver     */
    /*                                                                         */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    #define CANIF_PUBLIC_CHANGE_BAUDRATE_SUPPORT             STD_OFF
    
    /**************************************************************************/
    
    /* Description :  Enables or disables CanIf_SetBaudrate API               */
    /*                                                                        */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    #define CANIF_PUBLIC_SET_BAUDRATE_SUPPORT             STD_OFF
    
    /**************************************************************************/
    
    /* Description :  Enables or disables the API CanIf_CancelTransmit()      */
    /*                                                                        */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    #define CANIF_PUBLIC_CANCEL_TRANSMIT_SUPPORT        STD_OFF
    
    /**************************************************************************/
    /* Description :  Enables or disables Rx indication for busoff recovery   */
    /*                                                                        */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    #define CANIF_PUBLIC_BUSOFF_RECOVERY_FROM_RXINDICATION        STD_OFF
    
    /*******************************************************************************************************/
    /* Description :  Enables or disables the API CanIf_DirectHw_Write() &  CanIf_Get_DirectHw_Info()      */
    /*                                                                                                     */
    /* Range       :  STD_ON/STD_OFF                                                                       */
    /*******************************************************************************************************/
    #define CANIF_DIRECT_HW_WRITE               STD_OFF
    
    /***************************************************************************/
    /* Description :  Enables/disables API for reading received L-PDU data     */
    /* Range       : STD_OFFD_ON/STD_OFF                                       */
    /***************************************************************************/
    #define CANIF_READRXPDU_DATA_API                 STD_OFF
    
    /**************************************************************************/
    /* Description :  Enables/disables API for reading the notification status*/
    /*                of transmit and receive L-PDU                           */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    #define CANIF_READRXPDU_NOTIFY_STATUS_API         STD_ON
    
    /**************************************************************************/
    /* Description :  Enables/disables API for reading the notification status*/
    /*                of transmit and receive L-PDU                           */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    #define CANIF_READTXPDU_NOTIFY_STATUS_API         STD_ON
    
    /***************************************************************************/
    /* Description :  Enables / Disables the APIs CanIf_ReadTxmsgId() and      */
    /*                CanIf_ReadRxmsgId() for reading configured CanId for     */
    /*                configured hardware object (HOH).                        */
    /* Range       :  STD_ON/STD_OFF                                           */
    /**************************************************************************/
    #define CANIF_READMSGID_API                STD_OFF
    
    /***************************************************************************/
    /* Description :  Enables / Disables the call back for reading received    */
    /*                CanId for configured hardware object (HOH).              */
    /* Range       :  STD_ON/STD_OFF                                           */
    /**************************************************************************/
    #define CANIF_READBUFFERID                STD_OFF
    
    /**********************************************************************************************/
    /* Description : Enables/disables the user notification when a PDU in the TxBuffer is cleared */
    /*  	due to CAN driver couldn't accept the transmission request                            */
    /* Range       :  STD_ON/STD_OFF										                      */
    /**********************************************************************************************/
    #define CANIF_USER_TXBUFCLEARNOTIFY_API 		STD_OFF
    /**************************************************************************/
    
    /* Description :  Configure Error Passive support                         */
    /* Range STD_OFF   :  STD_ON/STD_OFF                                      */
    /**************************************************************************/
    #define CANIF_ERROR_PASSIVE_SUPPORT             STD_OFF
     
    
    /**************************************************************************/
    /* Description :  Configure Wakeup support                                */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    #define CANIF_WAKEUP_SUPPORT                         STD_OFF
    
    /**************************************************************************/
    /* Description :  Configure Controller Wakeup support                     */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    #define CANIF_CTRL_WAKEUP_SUPPORT                   STD_OFF
    
    /**************************************************************************/
    /* Description :  Configure  Transceiver Wakeup support                   */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    #define CANIF_TRCV_WAKEUP_SUPPORT                     STD_OFF
    
    /**************************************************************************/
    /* Description :  Configure Wakeup support                                */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    #define CANIF_TRCV_DRV_CFG                             STD_OFF
    
    /**************************************************************************/
    /* Description :  Configure Wakeup Validation                             */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    #define CANIF_PUBLIC_WAKEUP_CHECK_VALIDATION_API       STD_OFF
    
    /**************************************************************************/
    /* Description :  Configure Wakeup Validation                             */
    /* Range       :  0....Num of transceivers                                */
    /**************************************************************************/
    #define CANIF_NUM_TRANSCEIVERS                        0
    
    
    /**************************************************************************/
    /* Description :  Enables/disables API for reading the version information*/
    /*           .     about the CAN interface                                */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    #define CANIF_VERSION_INFO_API                     STD_OFF
    
    /**************************************************************************/
    
    /* Description :  Enables/disables usage of dynamic IDs                   */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    #define CANIF_DYNAMIC_ID                         STD_OFF
    
    /**************************************************************************/
    /* Description :  Enables/disables API for reconfiguration of the CAN     */
    /*                Identifier for each transmit L-PDU                      */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    #define CANIF_SETDYNAMICTXID_API                 STD_OFF
    
    /**************************************************************************/
    /* Description :  Enables/disables Metadata Support                       */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    #define CANIF_METADATA_SUPPORT                 STD_OFF
    
    
    /**************************************************************************/
    /* Description :  Enables/disables use of transmit buffers                */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    
    #define CANIF_TRANSMIT_BUFFER                     STD_OFF
    
    
    /**************************************************************************/
    
    /* Description :  Enables/disables use of receive buffers                 */
    /* Range       :  STD_ON/STD_OFF                                          */
    /**************************************************************************/
    #define CANIF_RECEIVE_BUFFER                      STD_OFF
    
    
    
    /**********************************************************************************************************/
    /* Description :  Max Pdu Index for FULL CAN Pdus based on ecuC.ecucPduCollection.pduIdTypeEnum selection */
    /* Range       :  0xFFu/ 0xFFFFu                                                                          */
    /**********************************************************************************************************/
    #define CANIF_MAX_PDU_INDEX  0xFFFFu
    
    
    /**************************************************************************/
    /* Description :  Total Number of Dynamic CanTxPduIds to be handled       */
    /* Range       :  1..Max Number of defined CanTxPduIds                    */
    /**************************************************************************/
    #define CANIF_NUM_DYNAMIC_CANTXPDUIDS             0
    
    
    /**************************************************************************/
    /* Description :  Total Number of CanRxPduIds to be handled               */
    /* Range       :  1..Max Number of defined CanRxPduIds                    */
    /**************************************************************************/
    
    #define CANIF_NUM_CANRXPDUIDS                     3
    
    
    /**************************************************************************/
    /* Description :  Total Number of Static CanTxPduIds to be handled               */
    /* Range       :  1..Max Number of defined CanTxPduIds                    */
    /**************************************************************************/
    
    #define CANIF_NUM_STATIC_CANTXPDUIDS                    3
    
    
    /**************************************************************************/
    /* Description :  Define Number of transmit buffers.                      */
    /*                The L-PDU buffers shall store DLC and max of 8bytes     */
    /*                of data.                                                */
    /* Range       :  0..Max Number of Tx buffers                             */
    /**************************************************************************/
    #define CANIF_NUM_TXBUFFERS                     0
    
    
    /**************************************************************************/
    /* Description :  Gives the Number of BASIC CAN HTHs.                     */
    /* Range       :  0..Max Number of BASIC CAN HTHs                         */
    /**************************************************************************/
    #define CANIF_NUM_BASIC_HTH                     0
    
    
    /******************** Parameters Newly Introduced *************************/
    
    
    /*Total number of Tx-Pdus configured in CanIf*/
    #define CANIF_TOTAL_TXPDUS                  3
    
    
    /*Total number of Rx-Pdus configured in CanIf*/
    #define CANIF_TOTAL_RXPDUS                  3
    
    
    /*Number of entries in CanIf_TxPduId_CustId_LUT[][]*/
    #define CANIF_NUM_CUSTID_ENTRIES            3
    
    
    /**************************************************************************/
    /* Description :  Selects whether the DLC check is supported              */
    /* Range       :  STD_ON/STD_STD_OFF                                                  */
    /**************************************************************************/
    #define CANIF_DLC_CHECK                         STD_OFF
    
    
    /* Total number of Controllers present in one or more drivers */
    
    
    #define CANIF_NUM_CONTROLLERS                   1
    
    
    /* Configuration for the Tx and Rx buffer size */
    
     
    #define CANIF_TXBUFFER_SIZE                     0
    
    
    
    #define CANIF_RXBUFFER_SIZE                     0
    
    
    /* Configuration for retransmission of PDU */
    #define CANIF_MAX_RETRY_TIMES                     1
    
    /* Configure the number of HRH handles */
    #define CANIF_NUM_HRH_HANDLES                   3
    
    
    /* Configure total number of CanIds to be received in the list */
    #define CANIF_NUM_LIST_CANID                 0
    
    
    /**************************************************************************/
    /* Description :  Number of served CAN hardware units                     */
    /* Range       :  1..Max Number of underlying supportted CAN HW units     */
    /**************************************************************************/
    #define CANIF_NUM_CAN_DRIVERS                   1
    
    
    /* Configuration for use of extended CAN identifiers */
    #define CANIF_EXTENDED_ID                         STD_OFF
    
    
    /* Configuration for use of extended CAN identifiers */
    #define CANIF_FD_SUPPORT                       STD_OFF
    
    
    /* Instance ID */
    
    #define CANIF_INSTANCE_ID                         1
    
    
    /* Configure CanIf Lite */
    #define CANIF_LITE_CONFIGURATION                STD_OFF
    
    
    /* Configure transmission of CANTP/USER Pdus when the Tx Pdu mode is OFFLINE */
    #define CANIF_USER_TP_TX_OFFLINE_MODE            STD_OFF
    
    
    /* Configuration for enabling/disabling the API CanIf_GetTxConfirmationState() */
    #define CANIF_PUBLIC_TXCONFIRM_SUPPORT          STD_OFF
    
    
    /*PN support*/
    #define CANIF_PUBLIC_PN_SUPPORT            STD_OFF
    
    
    
    /* CanIf variant info */
    #define CANIF_VARIANT_INFO				1   /* PRE-COMPILE */
       
    
    /* Configure support of filtering of CanNm transmit CanIds during reception */
    #define CANIF_CANNM_TXID_FILTER                 STD_OFF
    
    /* Enable/Disable CanNm Support */
    #define CANIF_CANNM_ENABLED                     STD_OFF
    
    
    
    /* Enable/Disable J1939Nm Support */
    #define CANIF_J1939NM_ENABLED                     STD_OFF
    
    
    /* Enable/Disable CanTp Support */
    #define CANIF_CANTP_ENABLED                     STD_ON
    
    
    
    /* Enable/Disable CAN_TSYN Support */
    #define CANIF_CANTSYN_ENABLED                    STD_OFF
    
    
    /* Enable/Disable PduR Support */
    #define CANIF_PDUR_ENABLED                     STD_ON
    
    
    /* Enable/Disable CDD Support */
    #define CANIF_CDD_RX_ENABLED                    STD_OFF
    
    
    /* Enable/Disable USER Support */
    #define CANIF_USER_RX_ENABLED                    STD_OFF
    
    
    /* Enable/Disable USER or CDD Support */
    #define CANIF_USER_CDD_TX_ENABLED                STD_OFF
    
    
    /* Enable/Disable XCP Support */
    #define CANIF_XCP_ENABLED                       STD_OFF
    
    /* Enable/Disable XCP Support */
    #define CANIF_J1939TP_ENABLED                       STD_OFF
    
    
    /*Wakeup Validation by NM-Pdu*/
    #define CANIF_PUBLIC_WAKEUP_CHECK_VALID_BY_NM         STD_OFF
    
    
    /* Configure support of BASIC CAN Reception */
    
    
    #define CANIF_BASIC_CAN_SUPPORT                   STD_OFF
    
    
    /* Configure support of CanId List for reception */
    #define CANIF_BASIC_CAN_SUPPORT_LIST            STD_OFF
    
    /* Macro generated via scripts when multiple Ranges of CanIds are configured under a HRH */
    #define CANIF_RXPDU_CANID_RANGE                    STD_OFF
    
    
    /* Calibration Enabled/Disabled */
    
    #define CANIF_CALIBRATION                STD_OFF
    
    
    /* Include the Controller name */
    typedef enum
    {
        CANIF_Can_Network_CANNODE_ECAN = 0
    
    }CanIf_ControllerName;
    
    
    #endif /* CANIF_CFG_H */
    
  • CanIf_PBcfg.c:这个文件中包含CanIf_Callback的映射信息,还有CanIf_TxPduConfig,其包含了针对每个TxPdu的Id等配置信息,其中最重要的是Hth_Ref_Id这个值,它会需要我们集成工程师手动定义这个宏定义,映射到MCAL生成的MailBox的ID,诸如在Can_17_MCanP_Cfg.h定义预留的发送MailBox的ID。
    文件还有CanIf_HrhConfig,其包含接收Mailbox中的诸如CanId、HrhRangeMask等属性信息,这个结构体数据会的排序应该与MCAL中的mailbox的排序一致。对于接收还有CanIf_RxPduConfig结构体数据,它包含一个PDU的关系信息,向下为HrhRef,它应该与MCAL中对应接收MailBox的Object ID保持一致,向上为TargetRxPduId与RxPduId两个属性,分别对应向上的接收PDUID和CanIf本模块的接收ID。最后有一个完整的CanIf结构体,名为CanIf_Config。注意不要用ETAS生成的注释来理解结构体中值对应的属性,要实际看到当前的结构体定义来一一对应。
    新的Isolar版本提供了tx和rx的映射关系,我们可以基于此修改pdu和mailbox的映射关系,从而支持启动时采用不同的mcal初始化参数。注意不要用ETAS生成的注释来理解结构体中值对应的属性,要实际看到当前的结构体定义来一一对应。
    ​
    /*
    ***********************************************************************************************************************
    * 
    * Product Info
    * Isolar version: ISOLAR-AB 4.0.2
    * Product release version: RTA-BSW 3.1.0
    * 
    ***********************************************************************************************************************
    */
    
    /*<VersionHead>
     * This Configuration File is generated using versions (automatically filled in) as listed below.
     *
     * $Generator__: CanIf / AR42.4.0.1                Module Package Version
     * $Editor_____: 9.0                Tool Version
     * $Model______: 2.0.2.1                ECU Parameter Definition Version
     *
     </VersionHead>*/
    
    
    /******************************************************************************/
    /*                                  Include Section                                */
    /******************************************************************************/
    
    /* CanIf Private header */
    #include "CanIf_Priv.h"
    /* CanIf post build header */
    #include "CanIf_PBcfg.h"
    /* CanIf post build header */
    #include "CanIf_Cfg_Internal.h"
    
    /* BusOff callback functions to Can State Manager */
    #include "CanSM_Cbk.h"
    #if (!defined(CANSM_AR_RELEASE_MAJOR_VERSION) || (CANSM_AR_RELEASE_MAJOR_VERSION != CANIF_AR_RELEASE_MAJOR_VERSION))
    #error "AUTOSAR major version undefined or mismatched"
    #endif
    #if (!defined(CANSM_AR_RELEASE_MINOR_VERSION) || (CANSM_AR_RELEASE_MINOR_VERSION != CANIF_AR_RELEASE_MINOR_VERSION))
    #error "AUTOSAR minor version undefined or mismatched"
    #endif
    
    /*
     ******************************************************************************
     * Variables
     ******************************************************************************
     */
    
    
    /* CANIF callback configuration */
    
    #if(CANIF_VARIANT_INFO != 2) && (CANIF_VARIANT_INFO != 3)
    #define CANIF_START_SEC_CONST_UNSPECIFIED
    #else
    #define CANIF_START_SEC_CONFIG_DATA_POSTBUILD_UNSPECIFIED
    #endif
    #include "CanIf_MemMap.h"
    CONST(CanIf_CallbackFuncType, CANIF_CONST) CanIf_Callback =
    {
    
        &CanSM_ControllerBusOff,
        NULL_PTR,  
        &CanSM_ControllerModeIndication,
        NULL_PTR,
        NULL_PTR,  
        NULL_PTR
    };
    
    #if(CANIF_VARIANT_INFO != 2) && (CANIF_VARIANT_INFO != 3)
    #define CANIF_STOP_SEC_CONST_UNSPECIFIED
    #else
    #define CANIF_STOP_SEC_CONFIG_DATA_POSTBUILD_UNSPECIFIED
    #endif
    #include "CanIf_MemMap.h"
    
    /* Tx PDUs Configuration */
    #if(CANIF_VARIANT_INFO != 2) && (CANIF_VARIANT_INFO != 3)
    #define CANIF_START_SEC_CONST_UNSPECIFIED
    #else
    #define CANIF_START_SEC_CONFIG_DATA_POSTBUILD_UNSPECIFIED
    #endif
    #include "CanIf_MemMap.h"
    CONST(CanIf_TxPduInfo, CANIF_CONST) CanIf_TxPduConfig[]=
    {
    /*
        CanTxPduId, TargetTxPduId, CanTxPduId, Hth_Ref_Id, Controller, CanIdType,  User,  ReadTxPdu,  CbkIdx ,Tx_Buffer Offset , Start Indx , End Indx, HTHIndex, CanId,  DLC,                                     Type                                                 Notify
                                                                                            Status
    */
    
    
    {   CanIfConf_CanIfTxPduCfg_DV_Test_Message_1_Can_Network_CANNODE_ECAN,    0 ,   CANIF_STATIC,   (uint8)CanConf_CanHardwareObject_Can_Network_CANNODE_ECAN_Tx_Std_MailBox_1,    (uint8)CANIF_Can_Network_CANNODE_ECAN,   0x00,   PDUR,   FALSE    ,    0,   0x5DF,   8 },
    {   CanIfConf_CanIfTxPduCfg_Tx_Test_Message_01_Can_Network_CANNODE_ECAN,    1 ,   CANIF_STATIC,   (uint8)CanConf_CanHardwareObject_Can_Network_CANNODE_ECAN_Tx_Std_MailBox_2,    (uint8)CANIF_Can_Network_CANNODE_ECAN,   0x00,   PDUR,   FALSE    ,    0,   0x5DC,   8 },
    {   CanIfConf_CanIfTxPduCfg_Diag_VCU_Resp_Can_Network_CANNODE_ECAN,    CanTpConf_CanTpTxNPdu_CanTpTxNPdu ,   CANIF_STATIC,   (uint8)CanConf_CanHardwareObject_Can_Network_CANNODE_ECAN_Tx_Std_MailBox_3,    (uint8)CANIF_Can_Network_CANNODE_ECAN,   0x00,   CANTP,   FALSE    ,    0,   0x7EA,   8 }};
    #if(CANIF_VARIANT_INFO != 2) && (CANIF_VARIANT_INFO != 3)
    #define CANIF_STOP_SEC_CONST_UNSPECIFIED
    #else
    #define CANIF_STOP_SEC_CONFIG_DATA_POSTBUILD_UNSPECIFIED
    #endif
    #include "CanIf_MemMap.h"
    
    /* Rx Handle configuration */
    
    #define CANIF_START_SEC_CONFIG_DATA_POSTBUILD_UNSPECIFIED
    #include "CanIf_MemMap.h"
    
    CONST(CanIf_HrhConfigType, CANIF_CONST) CanIf_HrhConfig[] =
    {
    /*   HRHInfo ,    Pdu/ListIdx,   NumCanIds/NumRanges,     Controller,  ReadRxPduInfo,    CanId,  HrhRangeMask */
    
    { CANIF_FULL,       0    ,       1    ,   (uint8)CANIF_Can_Network_CANNODE_ECAN,       CANIF_READ_NOTIFSTATUS,   0x5DE,       0x1FFFFFFFU }/*Can_Network_CANNODE_ECAN_Rx_Std_MailBox_1*/,
    { CANIF_FULL,       1    ,       1    ,   (uint8)CANIF_Can_Network_CANNODE_ECAN,       CANIF_READ_NOTIFSTATUS,   0x7E2,       0x1FFFFFFFU }/*Can_Network_CANNODE_ECAN_Rx_Std_MailBox_2*/,
    { CANIF_FULL,       2    ,       1    ,   (uint8)CANIF_Can_Network_CANNODE_ECAN,       CANIF_READ_NOTIFSTATUS,   0x7DF,       0x1FFFFFFFU }/*Can_Network_CANNODE_ECAN_Rx_Std_MailBox_3*/
    };
    
    #define CANIF_STOP_SEC_CONFIG_DATA_POSTBUILD_UNSPECIFIED
    #include "CanIf_MemMap.h"
    
    
    /* Rx PDUs Configuration */
    
    #define CANIF_START_SEC_CONFIG_DATA_POSTBUILD_UNSPECIFIED
    #include "CanIf_MemMap.h"
    CONST(CanIf_RxPduConfigType, CANIF_CONST) CanIf_RxPduConfig[]=
    {
    /*     RxBufferOffset,  target ID,  RxPduId , HRH , CbkIdx, User, CanIdType, DLC,  RxPduCanId      */
    
    {    PduRConf_PduRSrcPdu_Rx_Test_Message_01_Can_Network_CANNODE_ECAN_CanIf2PduR ,   CanIfConf_CanIfRxPduCfg_Rx_Test_Message_01_Can_Network_CANNODE_ECAN,       0,  0,   PDUR,   0x20u,   8,   0x5DE },
    {    CanTpConf_CanTpRxNPdu_CanTpRxPyNPdu ,   CanIfConf_CanIfRxPduCfg_Diag_VCU_ReqPhsy_Can_Network_CANNODE_ECAN,       1,  0,   CANTP,   0x20u,   1,   0x7E2 },
    {    CanTpConf_CanTpRxNPdu_CanTpRxFyNPdu ,   CanIfConf_CanIfRxPduCfg_Diag_ECAN_ReqFunc_Can_Network_CANNODE_ECAN,       2,  0,   CANTP,   0x20u,   1,   0x7DF }
    };
    
    #define CANIF_STOP_SEC_CONFIG_DATA_POSTBUILD_UNSPECIFIED
    #include "CanIf_MemMap.h"
    
    #if(CANIF_VARIANT_INFO == 3)
    /* Generate an instance of structure Std_VersionInfoType in CanIf_PBcfg_c.xpt*/
    #define CANIF_START_SEC_CONFIG_DATA_POSTBUILD_UNSPECIFIED
    #include "CanIf_MemMap.h"
    static CONST(Std_VersionInfoType, CANIF_CONST)  CanIf_VersionInfo =
    {
        6,    /* Vendor Id */
        60,    /* Module Id */
        4,    /* Sw Major Version */
        0,    /* Sw Minor Version */
        1     /* Sw Patch Version */
    };
    #define CANIF_STOP_SEC_CONFIG_DATA_POSTBUILD_UNSPECIFIED
    #include "CanIf_MemMap.h"
    #endif
    
    
    
    /* Global configuration structure */
    
    
    #define CANIF_START_SEC_CONST_UNSPECIFIED
    #include "CanIf_MemMap.h"
    CONST(CanIf_ConfigType, CANIF_CONST) CanIf_Config =
    {
        CanIf_TxPduConfig,
        /* MR12 RULE 1.1 VIOLATION:This is a known defect in CChecker 2.1.0 tool.No fix required in the component.*/
        CanIf_RxPduConfig,
        CanIf_HrhConfig,
        CANIF_NUM_STATIC_CANTXPDUIDS,
        CANIF_NUM_CANRXPDUIDS,
        CANIF_NUM_DYNAMIC_CANTXPDUIDS,
        CANIF_NUM_CONTROLLERS
    };
    #define CANIF_STOP_SEC_CONST_UNSPECIFIED
    #include "CanIf_MemMap.h"
    
    ​

集成代码 

下图为CanIf模块包含的集成代码,其中SchM、MemMap和APPL文件这里就不赘述了。

CanIf_RxIndication_Integration.c这个文件包含了CanIf_RxIndication()函数的实现,底层代码在接收到报文之后会调用CanIf_RxIndication这个函数,把底层的L-PDU相关信息送上来。一般在调试CAN栈之间会在这里做一些测试代码,确保底层CAN驱动确实将报文传了上来。


静态代码  

主要介绍常见的静态代码涉及API说明,具体详细完整的介绍读者可以参考《AUTOSAR_SWS_CANInterface.pdf》以及《RTA-BSWReferenceGuide.pdf》。注意CanIf本身并没有周期调用的函数,但是如果接收,发送或者busoff选择Polling而非Interrupt,则需要将驱动中对应的Can_MainFunction_Read/Can_MainFunction_Write/Can_MainFunction_BusOff放在对应的周期任务中。

  • CanIf_Init/CanIf_DeInit:CanIf模块的初始化与去初始化API。
  • CanIf_SetControllerMode/CanIf_GetControllerMode:CanIf模块设置和获取。
  • CanIf_Transmit:CanIf模块发送报文。
  • CanIf_SetPduMode/CanIf_GetPduMode:设置/获取当前Pdu状态。
  • CanIf_TxConfirmation:此函数当驱动已成功处理的CANTxPDU传输之后调用。
  • CanIf_RxIndication:此函数当驱动已接收到CAN帧之后调用。
  • CanIf_ControllerBusOff:此函数指示一个控制器BusOff事件,该事件引用了抽象的 CanlfControllerld所对应的CAN Controller。

十六宿舍 原创作品,转载必须标注原文链接。

©2023 Yang Li. All rights reserved.

欢迎关注 『十六宿舍』,大家喜欢的话,给个👍,更多关于嵌入式相关技术的内容持续更新中。

内容概要:本文档详细介绍了AUTOSAR标准中CAN收发器驱动(CanTrcv)模块的架构、状态机、数据类型及交互序列。CanTrcv作为微控制器抽象层(MCAL)的重要组件,起到连接底层硬件与上层软件的桥梁作用,通过Dio、SPI等驱动与CAN收发器硬件通信,并与CanIf、DET和DEM等模块交互。文档解析了CanTrcv模块的架构图解及其在AUTOSAR分层架构中的位置,重点阐述了其支持的多种唤醒模式和选择性唤醒功能。状态机部分描述了从POWER_ON到ACTIVE下的正常、待机和睡眠模式,以及各模式间的转换路径。数据类型部分定义了收发器的操作模式、唤醒通知控制模式、唤醒原因及部分网络激活状态等核心枚举类型,还涵盖了配置结构体和错误类型的定义。 适合人群:熟悉汽车电子架构,尤其是对AUTOSAR标准有一定了解的嵌入式系统工程师和技术人员。 使用场景及目标:①理解CAN收发器驱动在AUTOSAR架构中的作用及其与其他模块的交互方式;②掌握CAN收发器驱动的状态机运作机制,包括不同模式间的转换规则;③熟悉CanTrcv模块定义的数据类型,以便进行正确的配置和错误处理。 其他说明:此文档适用于希望深入了解CAN收发器驱动设计细节的专业人士,对于从事汽车电子开发、测试和维护工作的人员具有重要参考价值。文档提供了详细的图表辅助理解,并附有外部链接供进一步阅读。
### AUTOSAR CANIF 模块中的中断与轮询工作原理 #### 中断驱动机制 在AUTOSAR架构下的CAN接口(CAN Interface, CanIf)模块中,当采用中断驱动的方式处理数据传输时,硬件检测到特定事件(如接收到新消息或完成发送)后立即向CPU发出中断请求。一旦发生这样的情况,操作系统会暂停当前正在执行的任务并转而运行相应的中断服务程序(ISR)[^1]。 这种方式能够快速响应外部设备的变化,在实时性要求较高的应用场景下非常适用;同时因为只有真正有事情要做才会打断正常流程,所以也提高了系统的效率。不过需要注意的是,为了保持良好的性能表现,ISR内部的操作应当尽量简洁高效[^2]。 ```c void CanIf_IrqHandler(void){ // 处理接收缓冲区满的情况 if (Can_HwRxIndication()){ PduIdType rxPduId; Std_ReturnType result; while((result = Can_RxGetNextPdu(&rxPduId)) == E_OK){ CanIf_TrlReceiveNotification(rxPduId); } } // 发送完成后通知上层应用 if (Can_HwTxConfirmation()){ PduIdType txPduId; while ((txPduId = Can_GetTxDone()) != INVALID_PDU_ID){ CanIf_TransmitConfirm(txPduId); } } } ``` #### 轮询机制 相比之下,基于轮询的方法则是由软件周期性地查询外设寄存器的状态位来判断是否有新的活动需要处理。这意味着即使没有任何实际的数据交换也要不断地检查状态,这可能会占用较多的处理器时间片特别是对于那些频繁但每次只传递少量信息的服务而言[^3]。 尽管如此,在某些情况下比如资源受限环境或是希望简化设计的时候,轮询仍然是可行的选择之一。它不需要额外配置复杂的中断优先级关系,并且可以更容易实现多任务间的同步协调。 ```c void CanIf_MainFunction(void){ static uint8_t pollCounter = 0U; /* 增加计数器 */ ++pollCounter %= POLLING_INTERVAL; /* 如果达到了设定的时间间隔则进行一次轮询 */ if(0U == pollCounter){ // 执行类似于IrqHandler的功能但是通过主动询问而非被动等待触发 ... } } ```
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值