Can驱动模块规范规定了AUTOSAR基本软件模块CAN驱动程序的功能、API和配置(本文称为“CAN模块”)。Can模块是CAN栈中最低层的一部分代码实现,它用来执行具体的硬件访问,并为上层提供一个与硬件无关的API。唯一可以访问Can模块的上层是Canlf模块。CAN模块提供发送/接收CAN帧的服务,并调用CanIf模块的回调函数来通知事件,这独立于硬件。此外,它还提供分别控制同一CAN硬件单元中CAN控制器的行为和状态的服务(多个CAN控制器可以由单个CAN模块控制,只要它们属于同一个CAN硬件单元,由一个Can驱动进行管理)。

缩略语与概念
CAN controller:CAN控制器完全服务于一个物理通道。
CAN Hardware Unit:CAN硬件单元可以由一个或多个相同类型的CAN控制器和一个或多个CAN RAM区域组成。CAN硬件单元可以是片上设备或外部设备。CAN硬件单元由一个CAN驱动程序表示。
CAN L-PDU:数据链路层协议数据单元。由标识符、数据长度和数据组成(SDU)。
CAN L-SDU:数据链路层服务数据单元。表示在L-PDU内传输的数据。
DLC:数据长度(L-PDU中描述SDU的长度)。
Hardware Object:CAN硬件对象被定义为CAN硬件单元/CAN控制器的CAN RAM中的PDU缓冲区硬件对象,用作缓存L-PDU。
Hardware Receive Handle (HRH):硬件接收句柄(HRH)由CAN驱动程序定义和提供。每个HRH通常只代表一个硬件对象,也可以表示硬件对象的集合(接收FIFO)。HRH可用于优化软件过滤。
Hardware Transmit Handle (HTH):硬件发送句柄(HTH)由CAN驱动程序定义和提供。每个HTH可以代表一个或多个硬件对象(多路传输),这些对象被配置为硬件传输缓冲池。
Inner Priority Inversion:内部优先级反转,指的是由于在同一发送硬件对象中存在待发的低优先级L-PDU,高优先级L-PDU的传输被阻止的情况。
ISR:Interrupt Service Routine,中断服务例程。
L-PDU Handle:L-PDU句柄被定义并放置在Canlf模块层内。通常每个句柄代表一个L-PDU,这是一个包含用于Tx/Rx处理的信息的结构体常量。
MCAL:Microcontroller Abstraction Layer。
Outer Priority Inversion:外部优先级反转,指的是由于在两个连续发送的L-PDU之间会出现时间间隔,当此时另一个节点优先级较低的L-PDU尝试发送报文,并赢得了仲裁之后,则可以阻止本节点发送自己优先级较高的L-PDU。
Physical Channel:物理信道表示从CAN控制器到CAN网络的接口。不同的CAN硬件单元的物理信道可以访问不同的网络。
Priority:CAN的L-PDU的优先级由CAN标识符表示。标识符的数字值越低,优先级越高。
SFR:Special Function Register,特殊功能寄存器,控制控制器行为的硬件寄存器。
SPAL:Standard Peripheral Abstraction Layer。
ICOM:Intelligent Communication Controller。
优先级反转


在某些CAN实现中可能会发生外部优先级反转的问题。假设一个CAN节点希望传输一系列具有较高优先级的CAN帧,这些消息存储在不同的消息缓冲区中,如果在CAN网络上这些消息之间的帧间空间大于CAN标准定义的最低空间,则第二个节点在趁着这个帧间空隙可以开始传输优先级较低的消息。最小间空间由CAN帧中ITM(3bit,Intermission)确定,由3个隐性位组成。当一个消息在传输另一个消息时处于等待状态,它将在总线空闲期间启动,最早在间隙字段之后的位上开始传输(有的节点可能会在第三个位不传输SOF,直接传帧ID进行仲裁)。为了避免在间隙中总线被别的节点报文抢走,这就要求CAN模块的内部处理时间必须足够短,以在最小帧间间隔内连续发送消息,以避免所有提到的场景下的外部优先级反转。
CAN硬件单元
CAN硬件单元将一个或多个CAN控制器与公共或独立的硬件对象结合在一起,这些控制器可以位于芯片上或作为同类型的外部独立设备。下图显示了一个CAN硬件单元,该单元由分别连接到两个物理通道的两个CAN控制器组成。

模块依赖
首先,Can驱动作为MCAL的一个模块,我们可以采用手动配置的方式,但是工作量较大,一般采用的直接导入ISOLAR生成的arxml文件,首先打开对应的MCAL工程,选择im-and Exporters选项,如下图。

然后我们选择AUTOSAR Options页签,将生成的ISOLAR生成的CAN模块的ARXML导入,即可。注意:导入过程会将我们手配的一些参数覆盖,如果不一致需要我们手动复原。

然后,CAN驱动还会依赖一些驱动服务。函数Can_Init应初始化CAN控制器使用的所有片上硬件资源。唯一的例外是数字I/O引脚配置(用于CAN的引脚),这由端口驱动程序完成。在初始化Can模块之前,应先初始化Mcu模块,MCU驱动模块提供一些例如时钟等通用的功能配置给到CAN驱动。如果使用外部CAN控制器,则CAN模块应使用其他MCAL驱动程序(例如SPI)的服务。CAN驱动的实现还依赖ISR模块,我们应该正确的分配CAN控制器对应节点的中断优先级情况。一个CAN控制器对应了四个中断(分别对应接收,发送,BusOff,接收FIFO中断),如下图。

最后,CAN驱动还依赖一些系统服务,包括需要周期调度一些轮询的函数(Can_MainFunction_Write、Can_MainFunction_Read、Can_MainFunction_BusOff等),以及当硬件未在预期时间内响应(硬件故障)时,Can模块应使用系统服务提供的OsCounter进行超时检测,以防止无限循环(等待超时时间应小于对应主函数的调度周期)。
功能规范说明
在L-PDU传输中,CAN模块将L-PDU写入CAN控制器硬件内的适当缓冲区。在L-PDU接收中,Can模块调用以ID、数据长度和L-SDU的指针为参数的RX指示回调函数。
CAN模块提供了一个接口,作为定期处理功能,并且必须由基础软件定期调用。此外,CAN模块提供控制CAN控制器状态的API,并通过回调函数通知总线断开和唤醒事件。Can模块应为所有需要的CAN硬件单元中断实现中断服务例程。CAN模块应禁用CAN控制器中所有未使用的中断。CAN模块应在ISR结束时重置中断标志(如果硬件没有自动完成),CAN模块不应设置向量表项的配置(即优先级)。
驱动适用范围
一个CAN模块提供对一个CAN硬件单元的访问,该硬件单元可能由多个CAN控制器组成。对于不同类型的CAN硬件单元,应实施不同的Can模块。如果在一个ECU中实现多个CAN硬件单元(相同或不同供应商),则CAN模块的功能名称和全局变量应独立实现,以便不会产生两个具有相同名称的功能。命名惯例如下:<Can module name>_<vendorID>_<Vendor specific API name><driver abbreviation>()。如果只使用一个控制器类型,则没有任何<driver abbreviation>扩展的原始命名约定就足够了。
驱动状态机
Can模块有一个非常简单的状态机,有CAN_UNINIT和CAN_READY两种状态。下图显示了状态
机。在power-up/reset后,Can模块应处于CAN _UNINIT状态。函数Can_Init应在初始化硬件单元内的所有控制器后将模块状态更改为CAN_READY。

Can_Init函数应根据其配置初始化所有CAN控制器。每个CAN控制器必须通过调用函数Can_SetControllerMode(CAN_CS_STARTED)单独启动。对硬件单元中的所有CAN控制器有影响的硬件寄存器设置只能在Can_Init函数中设置。ECU状态管理器模块在运行时最多应调用Can_Init一次。Can_Delnit应在去初始化硬件单元内的所有控制器之前将模块状态更改为CAN_UNINIT。
Can控制器状态机
每个CAN控制器都有在硬件IP核中实现的复杂状态机。为了简化,本描述中将状态数减少到以下四个基本状态:UNINIT、STOPPED、STARTED和SLEEP。任何CAN硬件访问都由Can模块的功能API封装,但Can模块不会存储状态更改。CAN模块提供Can_Init、Can_SetBaudrate和Can_SetControllerMode等服务。这些服务执行配置必要的寄存器,从而引起硬件CAN控制器状态完成所需的更改。外部事件触发状态变化的可能性有两种:
Bus-off event
HW wakeup event
这些事件可以通过中断或在Can_MainFunction_BusOff或Can_MainFunction_Wakeup中轮询的状态位来指示。Can模块会在中断处理中进行必要的寄存器设置,以实现所需的行为(例如在BusOff终端中取消挂起的发送请求),它还会用相应的回调函数通知Canlf模块,然后Canlf模块会在这个回调函数中改变对应软件状态。如果启用了开发错误,并且上层要求进行不允许的转换,Can模块将回复开发错误CAN_E_TRANSITION。Can模块在执行Can_Write或引发回调之前不会检查Can控制器实际状态。下面我们分别介绍一下这四种状态。
UNINIT:CAN控制器未初始化。所有属于CAN模块的寄存器处于重置状态,CAN中断被禁用。CAN控制器未参与CAN总线。
STOPPED:在这种状态下,CAN控制器被初始化,但不参与总线。此外,逻辑链路层上的错误帧不会发送,ACK也不会响应。(对于许多控制器来说,初始化之后控制器为停止状态。)
STARTED:控制器处于正常操作模式并具有完整功能,这意味着它参与网络。
SLEEP:对于支持睡眠模式(CAN硬件直接支持在CAN总线上唤醒)的CAN硬件,才有这个模式,否则与STOPPED状态表现一致。当CAN硬件支持睡眠模式并被触发进入SLEEP状态时,CAN模块应将控制器设置为SLEEP状态,硬件可以从该状态通过CAN总线唤醒。当CAN硬件不支持睡眠模式并被触发进入睡眠状态时,CAN模块应模拟一个逻辑睡眠状态,只有当软件触发它进入停止状态时它才会返回。
下面我们介绍一下CAN控制器状态机的转换逻辑。状态转换Can_SetControllerMode()函数触发,转换的状态由参数传入。软件触发的成功状态转换由回调函数CanIf_ControllerModeIndication通知。管理请求的状态是否实现是上层模块的一部分,不是CAN模块的一部分。一些状态转换是由总线(硬件)上的事件触发的。这些转换通过回调函数(CanIf_ControllerBusOff,EcuM_CheckWakeup)通知。下图描述了各个状态可能的转化关系。下面我们介绍不同触发条件引起的状态转换:
Can_Init():它应该引起初始化的CAN硬件单元内所有控制器UNINIT到STOPPED的状态转换。所有控制寄存器的配置都是根据MCAL生成的动态配置来配置的。如果调用的控制器没有在UNINIT状态,则上报CAN_E_TRANSITION错误。
Can_SetBaudrate():他应该引起控制器维持在STOPPED、SLEEP以及STARTED状态。它会改变当前的通信速率。如果Can_SetBaudrate()的调用会导致CAN控制器的重新初始化,并且CAN控制器没有处于STOPPED状态,它将返回E_NOT_OK。
Can_SetControllerMode():Can_SetControllerMode函数触发CAN控制器的状态转换。根据CAN硬件的不同,将寄存器设置更改以切换到新的CAN控制器状态可能需要延迟。在成功状态转换后,Can模块会通过CanIf_ControllerModeIndication()通知上层。请求的状态是否实现是上层模块要关心的,不是Can模块的一部分。Can_Mainfunction_Mode函数应轮询CAN状态寄存器的标志,直到标志表示更改生效,并通过上层函数CanIf_ControllerModeIndication()通知成功的状态转换,参数为Canlf相应的CAN控制器抽象Controllerld。 函数Can_SetControllerMode()应使用系统服务GetCounterValue()进行超时监视,以避免阻塞函数。如果转换标志位表示更改无效且已到达最大时间CanTimeoutDuration,则应退出Can_SetControllerMode()函数,而CanMainfunction_Mode函数应继续轮询转换标志位。
Can_SetControllerMode (CAN_CS_STARTED):由软件触发从STOPPED状态转化为STARTED状态。在CAN控制器开始工作之前发出的请求会丢失。。发送可能会遇到确认超时,上层需要能够处理这种情况。
Can_SetControllerMode (CAN_CS_STOPPED):由软件触发从STARTED/SLEEP状态到STOPPED状态。Can_SetControllerMode(CAN_CS STOPPED)应设置CAN硬件内的位,以便CAN控制器停止参与网络,并取消待处理消息。
Can_SetControllerMode(CAN_CS_SLEEP):从STOPPED状态到SLEEP状态。如果CAN硬件支持睡眠模式,则函数Can_SetControllerMode(CAN_CS_SLEEP)应等待有限的时间,直到CAN控制器处于睡眠状态,并确保CAN硬件是可唤醒的。如果CAN硬件不支持休眠模式,函数Can_SetControllerMode(CAN_CS_SLEEP)将CAN控制器设置为逻辑休眠模式。当调用Can_SetControllerMode(CAN_CS_SLEEP)函数且CAN控制器既非处于STOPPED状态也非处于SLEEP状态时,应检测到无效状态转换
Hardware Events:下面介绍一下硬件触发的CAN控制器状态变化:
Hardware Wakeup:状态从SLEEP到STOPPED切换,通过CAN总线上接收到的L-PDUs,然后通过EcuM_CheckWakeup()通知EcuM唤醒事件(CAN模块应在中断上下文中或在Can_MainFunction_Wakeup的上下文中调用EcuM_CheckWakeup函数)。Can模块不得进一步处理导致唤醒的L-PDU。
Bus-Off:触发状态从STARTED到STOPPED切换,如果CAN控制器达到总线关闭状态,则由硬件触发。在达到停止状态后,通过Canlf_ControllerBusOff函数通知CanIf模块,并传递与相应的CAN控制器关联的抽象Controllerld。在检测到总线关闭后,Can模块应取消仍待处理的消息。Can模块应禁用或抑制控制器IP核自带的自动总线Bus-Off恢复。
Can_DeInit():触发状态从STOPPED/SLEEP到UNINIT状态切换。当调用函数Can_Delnit()且Can模块中任何 CAN 控制器不在状态STARTED时,应引发错误CAN_E_TRANSITION。
Can模块/控制器初始化
EcuM模块应首先在启动阶段通过调用Can_Init函数来初始化Can模块,然后再使用Can模块的任何其他功能。Can_Init应初始化:静态变量、包含标志、对于硬件单元的通用配置以及对每个Can控制器的独立配置。Can_Init不得更改CAN控制器的寄存器未使用的硬件资源。Can模块应在控制器寄存器的初始化方面应用以下规则:
如果硬件只允许使用寄存器一次,则实现该功能的Can模块负责初始化寄存器。
如果寄存器可以影响多个硬件模块,如果是I/O寄存器,则应由PORT模块初始化。
如果寄存器可以影响多个硬件模块,如果它不是I/O寄存器,则应由MCU模块初始化。
重置后需要直接初始化的一次性可写寄存器应由启动代码初始化。
所有其他寄存器都应由启动代码初始化。
如果Can_SetBaudrate()引起的目标配置更改需要重新初始化且CAN控制器处于停止状态,则Can_SetBaudrate应重新初始化CAN控制器和控制器特定设置。如果需要重新初始化,在应用新的波特率配置之前必须将CAN控制器切换到停止状态。
配置是一个指向存储在ROM中的特定于实现的数据结构数组的指针。不同的控制器配置设置作为数据结构位于ROM中。Can模块配置定义了全局CAN硬件单元设置和对默认CAN控制器配置集的引用。
L-PDU 发送
在L-PDU传输中,Can模块将L-PDU的数据内容、ID和数据长度转换为硬件特定格式(如有必要),并触发传输。CAN到内存的数据映射定义如下:首先发送的是CAN数据字节的数组元素0,最后发送的CAN数据字节是数组元素DLC-1。如果CAN硬件缓冲区内的格式表示与AUTOSAR定义不同Can模块必须为上层提供一个适应的SDU-Buffer。常用的是一个HTH对应一个TX hardware objects,如下图展示。
CAN模块应调用Canlf_TxConfirmation()以指示成功传输。它要么由相应硬件资源的TX中断服务例程调用,要么在轮询模式下在Can_MainFunction_Write中调用。
CAN模块的函数Can_Write()应存储在CanIf提供的参数Pdulnfo中给出的swPduHandle,直到Can模块为该请求调用Canlf_TxConfirmation(),其中将swPduHandle作为参数回给CanIf模块,这么做的目的是在Canlf模块实现中减少搜索时间。
多传输通道是必要的,以防止优先级倒置。Can模块应允许功能“Multiplexed Transmission”在编译前是静态可配置的。

多个传输硬件对象(定义为“CanHwObjectcount”)应分配到一个HTH,以代表一个传输实体到上层。Can模块应支持按L-PDU优先级顺序发送L-PDU的设备的多路传输。应避免对优先级进行软件处理,因为开销会使多路传输的优势化为乌有。

Can模块应直接从上层缓冲区复制数据。在函数调用返回之前,上层负责保持缓冲区的一致性(Can Write)
L-PDU 接收
在L-PDU接收时,CAN模块应调用CanIf_RxIndication(const Can_HwType *Mailbox, const PduInfoType *PduInfoPtr)回调函数,Mailbox指针指向结构体包含CanId(Standard/Extended CAN ID of CAN L-PDU)、Hoh(ID of the corresponding Hardware Object)以及ControllerId(ControllerId provided by CanIf);PduInfoPtr指针指向结构体包含swPduHandle(SW Handle that will identify the request in the confirmation callback function.)、length(DLC)、id(Identifier of L-PDU)以及sdu(Pointer to L-SDU)。
在扩展CAN帧的情况下,接收到的CAN帧ID通过或上0x80000000,以将接收到的CAN帧标记为扩展。首先接收到的CAN数据字节是数组元素0,最后接收到的CAN数据字节是7,在CAN FD的情况下最后接收到的CAN数据字节是数组元素是63。Can模块同样应指示接收到的消息是常规CAN帧还是CAN FD帧,通过CANID或上0x40000000表示。CANID的这种表示方式对发送也同样适用。
为了防止接收到的消息丢失,一些控制器支持从一组硬件对象来构建接收FIFO,而在其他控制器上,可以配置具有相同属性的另一个硬件对象,该对象作为影子缓冲区工作,并在主对象忙碌时介入。CAN驱动程序应支持实现控制器硬件接收FIFO,FIFO的大小通过CanHwObjectCount配置。不支持硬件FIFO的控制器通常提供实现影子缓冲区机制的能力,当主硬件对象繁忙时,额外的硬件对象接管。硬件对象的数量通过CanHwObjectCount进行配置。下图展示了三个硬件对象来构建一个HRH的例子。

CAN模块在接收后,如果RX缓冲区不能被CAN硬件保护(锁定)以防止被新接收的消息覆盖,则应在阴影缓冲区中复制L-SDU。 如果CAN硬件无法被全局访问,Can模块应复制L-SDU的影子缓冲区供全局访问,完整的接收处理(包括复制到目标模块,例如COM)是在接收中断或CanMainFunction_Read上下文中完成的。CAN模块应保证ISR和函数CanMainFunction_Read不会被其自身中断。CAN硬件(或影子)缓冲区始终保持一致,因为它在一个从未被其自身中断的函数中按顺序写入和读取。如果CAN硬件无法在接收后配置锁定RX硬件对象(硬件功能),则可能发生硬件缓冲区被新到达的消息覆盖的情况。在这种情况下,如果硬件支持,CAN控制器会检测到“overwrite”事件。如果CAN硬件在接收后可以配置为锁定RX硬件对象,则可能发生新到达的消息无法存储到硬件缓冲区的情况。在这种情况下,如果硬件支持,CAN控制器会检测到“overrun”事件。Can模块应该检测到“overwrite”或者“overrun”事件之后上报运行时错误CAN_E_DATALOST。系统设计人员应确保消息接收(中断或轮询处理)的运行时间应尽可能的快。
唤醒概念
Can模块处理可由Can控制器本身检测而非Can收发器的唤醒。这有两种可能的情况:通过中断唤醒和通过轮询唤醒。对于中断唤醒,当硬件检测到唤醒时,会调用Can模块的ISR。如果唤醒事件的ISR被调用,它应调用EcuM_CheckWakeup,传递给EcuM_CheckWakeup的参数应是CanWakeupSourceRef配置参数引用的唤醒源ID。当通过轮询检测到唤醒事件时,ECU状态管理器将像以前一样通过CAN接口周期性调用Can_CheckWakeup。在这两种情况下,Can_CheckWakeup将检查CAN控制器是否检测到唤醒事件,并返回结果。然后,CAN驱动程序将通过EcuM_SetWakeupEvent将唤醒事件通知ECU状态管理器。唤醒验证的目的是以防止错误的唤醒事件,它将由ECU状态管理器和CanIf模块完成,不需要Can模块的任何帮助。
通知概念
Can模块仅向Canlf模块提供一个事件触发通知接口。每个通知都由一个回调函数来表示。硬件事件可以通过中断或轮询硬件对象的标志来检验。关于轮询的配置可能性取决于硬件(即哪些事件可以轮询,哪些事件需要轮询),不受本标准的限制。应该可以配置驱动程序,使其完全不使用中断(完全轮询)。CAN模块配置什么会被轮询,什么不会被轮询是驱动器的内部信息,在块外部是不可见的。轮询是在CAN主函数(Can MainFunction xxx)内部完成的。轮询事件也由适当的回调函数通知。因此,轮询的通知调用上下文不是ISR,而是CAN主函数,但是所有回调函数的实现应像调用上下文是ISR一样完成。有关进一步的详细信息,请参阅CAN主要功能API的描述,包括Can_MainFunction_Read,Can_Mainfunction_Write,Can_Mainfunction_BusOff和Can_Mainfunction_Wakeup。
重入问题
函数必须满足下列条件才能具有重入性:
它以原子的方式使用所有共享变量,除非每个变量被分配到函数的特定实例。
它不调用非重入函数。
它不以非原子的方式使用硬件。
传输请求只需由Canlf模块中的Canlf_Transmit函数转发。Canlf_Transmit函数是可重入的。因此Can_Write函数需要以线程安全的方式实现(例如使用互斥)。当无法再次执行写入时,将返回前一步调用,并返回CAN_BUSY。在CAN_BUSY的情况下,Canlf模块会排队等待请求。(行为与所有硬件对象都忙碌相同)。Can_EnableCanInterrupts和Can_DisableCanInterrupt可以在重入函数内调用,因此这些函数也需要重入。CAN主功能(即Can_MainFunction_Read)不得被自身中断,因此这些CAN主功能是不可重入的。
虚拟网络
在汽车领域,优化能源效率变得越来越重要,因为能源消耗直接影响燃油消耗、二氧化碳排放量和混合动力或全电动汽车的续航里程。虚拟网络的概念在ECU级别上具有很高的节能潜力。
Intelligent Communication Controllers(智能通信控制器,ICOM)的实施支持这些功能(没有强制性的特定硬件实现)。基于车辆状态,如果ECU的某些或全部功能暂时不需要,ECU可以进入“虚拟联网”模式。在此模式下,MCU和/或外围设备被切换到低功耗模式。只有ICOM和连接的收发器保持活动状态。当ICOM判断ECU需要恢复操作时,会生成唤醒事件,例如由总线上接收到消息引起。根据ICOM的实现方式,接收到消息的报文ID和有效载荷可能在硬件中完全进行评估和过滤,或者在软件中需要回调机制。如下图所示,ECU的实现可以分为三种可能的变体:第一种软件方法a,没有特定的硬件来利用实现虚拟网络。方法b描述了基于通信控制器的功能硬件扩展实现,方法c显示了具有第二个扩展通信控制器的硬件变体实现,用于唤醒处理。
根据硬件实现,ICOM也能够发送消息(状态消息)。此外,虚拟网络旨在减少唤醒响应时间,即唤醒事件和ECU有效行为之间的时间。通过在激活期间使用ICOM保存相关消息,应用程序在恢复操作后可以直接访问最后有效的信号值。因此,ECU可以在唤醒后立即响应用户请求,而不必等待再次收到相应消息。

CAN驱动应该在初始化CAN控制器之后退出虚拟网络,虚拟网络应该通过调用Can_SetIcomConfiguration()实现,CAN驱动负责正确配置CAN控制器。切换完成调用CanIf_CurrentIcomConfiguration(),回调函数中包含对应控制器ID和切换状态,如果切换成功,则为ICOM_SWITCH_E_OK,失败则为ICOM_SWITCH_E_FAILED。在虚拟网络模式下,只有接收的报文符合CanIcomConfig的唤醒条件才会调用CanIf_RxIndication();发送报文则直接拒绝,返回CAN_BUSY。CAN控制器在通过SetControllerMode(CAN_CS_STARTED)启动前,应退出虚拟网络。
如果Can_SetIcomConfiguration()中传入的configuration ID等于0,则退出虚拟网络。退出之后,CAN驱动应该正常处理报文。CAN控制器在通过SetControllerMode(CAN_CS_STOPPED)配置控制器状态为STOPPED时,应退出虚拟网络。如果ICOM在软件中实现,控制器不得在虚拟网络发送消息。CAN驱动应该转发在虚拟网络中接收到的报文到CanIf。CanIcomVariant参数定义是否有额外的硬件支持ICOM自动发送报文。
CAN FD支持
出于性能原因,一些CAN控制器允许使用称为CAN FD的灵活数据速率功能。通过在仲裁阶段的特定帧位域指示,在有效载荷和CRC期间可以切换到更高的波特率。第二个波特率必须通过扩展的CanControllerBaudrateConfig子容器CanControllerFdBaudrateConfig进行配置。驱动判断如果存在CanControllerFdBaudrateConfig配置,则将为该控制器启用CAN FD功能。需要使用指定的第二波特率完成具有位率切换(BRS)的CAN FD帧的接收。是否使用第二波特率进行传输取决于配置参数CanControllerTxBitRateSwitch。
然而,在某些情况下,可能需要在网络中传输支持CAN-FD消息的常规CAN 2.0消息,例如为了完成CAN选择性唤醒。在这些情况下,有必要支持将交错的常规CAN消息与CAN FD消息一起传输。这可以通过在帧级别上使用在CanWrite()传递的Canld来或上0x40000000来表示使用CAN FD帧。
CAN FD还支持扩展载荷,最多允许传输64字节。因此,如果CAN控制器处于CAN FD模式(有效的CanControllerFdBaudrateConfig)且在Can Write()中传递的Canld设置了CANFD标志,则CAN驱动支持传输长度可达64字节的PDU。如果请求传输CAN FD帧但是CAN控制器未处于CAN FD模式(没有配置CanControllerFdBaudrateConfig),但是只要PDU长度小于或等于8字节,则该帧将以常规CAN帧的形式发送。
ISOLAR-AB配置
CAN
该模块在生成BSW Code,BSWMDs, and SWCDs后并不生成静态/动态代码,它只向ISOLAR-AB内部提供必要的底层驱动配置项(其他模块需要引用),并如前文所示提供给EB tresos工具对应底层驱动配置项的arxml用作配置导入,省去重复的人工配置(诸如MailBox等),并能保证底层驱动与ISOLAR-B的配置统一。
CAN模块的配置由Automatically Configure BSW from System Description自动生成。
CanGeneral
本容器主要包含CAN模块的一些通用配置,如下图所示:

下面介绍一些该容器常见配置:
CanDevErrorDetection:切换默认错误跟踪器(Det)检测和通知的开启或关闭。
Canlndex:指定此模块实例的Instanceld。如果只有一个实例存在,则其ID为0。
CanMainFunctionModePeriod:此参数描述循环调用Can_MainFunction_Mode的周期。单位为秒。
CanMultiplexedTransmission:指定是否支持多路传输。打开或关闭。
CanPubliclcomsupport:在Can驱动程序中选择对虚拟网络功能的支持。
CanTimeoutDuration:指定阻塞函数的最大时间,直到报超时错误。单位为秒(这个参数默认生成1秒,且生成的调度周期小于1秒是相互矛盾的,它会导致OS重复调度同一Task从而关闭OS,用户应根据实际的情况正确配置MCAL里的这个参数)。
CanSupportTTCANRef:该参数指CAN接口模块配置中的CanlfSupportTTCAN参数。
CanController
本子容器包含CAN模块包含的控制器配置。

下面我们介绍一下常见的配置:
CanBusoffProcessing:启用/禁用Can_MainFunction_BusOff()来处理在轮询模式下的BusOff事件。
CanControllerActivation:定义配置中是否使用CAN控制器。
CanControllerBaseAddress:CAN控制器的基地址。
CanRxProcessing:启用/禁用Can_MainFunction_Read(),进行轮询模式下处理
PDU接收事件。
CanTxProcessing:启用/禁用Can_MainFunction_Write()来处理在轮询模式下的PDU传
输事件。
CanWakeupFunctionalityAPl:从代码中添加/删除Can_CheckWakeup()函数。
CanWakeupProcessing:启用/禁用Can_MainFunction_Wakeup(),用于在轮询模式下处理唤醒事件。
CanWakeupsupport:CAN驱动程序是否支持通过CAN总线进行唤醒。
CanControllerDefaultBaudrate:参考为Can控制器配置的波特率配置容器。
这个容器还有一个子容器,名为CanControllerBaudrateConfig,是控制器的波特率配置,如下图所示。

可以看出,默认的是500波特率的配置,下图是在CAN控制器频率为40Mhz的一个500k波特率的配置,其采样点计算为((1+62+1)/(1+62+1+15+1))=80%。

因为我们工程没有使用CAN FD,所以没有CanControllerFdBaudrateConfig子容器相关配置。
CanHwObjectCount
该容器存储根据DBC生成的MailBox配置信息。

可以根据上图看到,一共生成了6个MailBox,3收3发,我们针对常见的配置项加以说明。
CanHandleType:说明这个MailBox是Full-Can的还是Basic-Can的。默认为Full-Can。
CanHwObjectCount:用于实现一个HOH的硬件对象数量。在HRH的情况下,该参数定义硬件FIFO中的元素数量或影子缓冲区的数量;在HTH的情况下,它定义用于多路传输或用于FuIICAN HTH的硬件FIFO的硬件对象数量。
CanldType:Can帧ID的类型,是标准帧还是扩展帧。
CanObjectld:此参数的值是唯一的,应该以0开头,并无间隙地继续,来表示MailBox。
CanObjectType:指定硬件对象是用作发送对象还是接收对象。
CanControllerRef:当前MailBox所对应的控制器。
当这个硬件对象是接收类型的时候,这个容器里还有个子容器,CanHwFilter,会根据默认的Full-Can类型,生成对应的过滤Mask和匹配ID。

例如上图,它是标准真,Mask是0x7FF,则需要帧ID的所有位匹配0x5DE才会接收这个报文到这个MailBox中。
诚邀您参加 MPS 机器人模块设计大赛
不要求整机开发,用MPS产品实现适合机器人应用的以下其中之一即可:
电源子系统
电池子系统
运动控制子系统
【大赛奖项】
一等奖1名,华为笔记本电脑
二等奖1名,大疆无人机
三等奖1名,哈趣投影仪
优秀奖4名,正点原子数控电源DP100
成功完赛奖,完成作品即可获得¥200
【报名时间】即日起—4月30日
扫描下方二维码,了解报名详情


· END ·
欢迎关注EEWorld旗下订阅号:“汽车开发圈”

扫码添加小助手回复“进群”
和电子工程师们面对面交流经验
夜雨聆风