文章目录
前言
本文介绍CP AUTOSAR 架构下的CanTrcv组件,基于S32K312芯片、Vector提供的CBD包,使用DaVinci Configurator工具进行配置的经验。
CanTrcv组件位于Communication Hardware Abstraction层,通常被CanIf所调用。
CanTrcv组件负责管理ECU上的CAN收发器芯片。
上图为CP AUTOSAR CAN网络架构。
一、CAN收发器功能
CAN收发器可以将CAN总线上的电平转换为MCU可识别的数字信号电平,MCU的CAN控制器收发的数字信号经过CAN收发器传到CAN总线上。
CAN收发器还能检测电气故障,如BUSOFF、接地偏移等。
通常CAN收发器有Sleep、Standby、Normal、Listen-only等模式,在Sleep模式下收到CAN总线的wakeup pattern(ISO 11898-2)后CAN收发器可被唤醒然后切换到Standby模式并且给MCU输出唤醒信号(INH引脚拉高或者RXD引脚拉高),有些CAN收发器支持特定的消息帧进行唤醒,但价格也就贵了。
CAN总线标准有高速CAN ISO11898、低速CAN ISO11519、单线CAN SAEJ2411,选择CAN收发器时需要清楚要通信的CAN总线是什么物理标准。
有些收发器不能通过CANFD唤醒。
有些CAN收发器还集成了电源控制和看门狗功能,称为SBC芯片通过SPI控制。
通常ECU在正常工作时将收发器设置为Normal,休眠时将收发器设置为Standby或者Sleep,通过引脚或者SPI控制。
收发器进入休眠后除了能被CAN总线上的报文唤醒(远程唤醒),通常本身也有WAKE引脚支持被MCU拉高然后主动唤醒(本地唤醒)。
通常ECU会用到收发器的INH引脚(唤醒指示脚)用来控制ECU的电源,休眠时INH引脚拉低MCU电源关闭,唤醒后INH引脚拉高MCU电源开启,或者MCU进入低功耗模式收到INH引脚从低变高后,触发中断然后切回高速运行模式。
通常收发器支持PN功能。即收发器休眠后可选择特定帧来唤醒或者收到任意帧都唤醒,ECU可根据休眠唤醒策略来选择哪种模式,一般ECU带有网络管理功能,如果收到任意帧都唤醒,那么MCU在唤醒后要在软件里判断当前有没有NM帧,如果没有继续休眠。而带有网络管理的ECU,休眠时如果选择不带PN功能的收发器,要两帧NM报文才能唤醒,第一帧用来唤醒收发器然后MCU上电,在第二帧来时MCU才能确认是NM帧然后正常工作,如果选择带PN功能的收发器,那么设置收发器只有NM帧才能唤醒,这样只要MCU程序运行了就认为是NM帧给MCU唤醒的,就实现了一帧NM报文唤醒ECU的策略,具体策略视需求来定。
CanTrcv不支持符合SAE J2411标准的单线CAN。
上图是TJA1043收发器的状态迁移图。
二、CAN收发器运行模式
根据AUTOSAR文档里的描述,CanTrcv状态机有如下状态:
POWER_ON:
ECU开始上电。
NOT_ACTIVE:
CAN收发器还未经过端口或SPI进行初始化。
ACTIVE:
CanTrcv_Init()调用后,CAN收发器进行该状态,该状态下有以下三个子状态。
CANTRCV_TRCVMODE_NORMAL:
此模式下能与CAN总线进行通信,不检测远程唤醒帧,收发器的INH引脚始终处于激活状态。调用Icu_DisableNotification()关闭对应的ICU唤醒捕捉通道。
CANTRCV_TRCVMODE_STANDBY:
此模式下CAN收发器是不能与CAN总线通信和进行收发,CAN收发器进入低功耗状态,能被唤醒,收发器的INH引脚始终处于激活状态,ECU处于通电状态。调用Icu_EnableNotification()开启对应的ICU唤醒捕捉通道。
CANTRCV_TRCVMODE_SLEEP:
此模式下CAN收发器是不能与CAN总线通信和进行收发,CAN收发器进入低功耗状态,收发器的INH引脚始终处于不激活状态,能被唤醒,唤醒后INH引脚处于激活状态,ECU处于断电状态。调用Icu_EnableNotification()开启对应的ICU唤醒捕捉通道。
可调用CanTrcv_SetOpMode()使CanTrcv在CANTRCV_TRCVMODE_NORMAL、CANTRCV_TRCVMODE_STANDBY、CANTRCV_TRCVMODE_SLEEP之间切换,切换成功后CanTrcv调用CanIf_TrcvModeIndication()通知CanIf。
CAN收发器硬件实际的状态是比AUTOSAR文档里描述的多的,比如有Go-To-Sleep模式,收发器在进入SLEEP模式前的一个步骤或者ListenOnly模式,收发器只接收数据但不发数据并且ACK也不发等。
三、CAN收发器唤醒类型
AUTOSAR文档里描述有三种唤醒的情况:
(一)、MCU未上电
ECU里只有CAN收发器或其他小部分硬件有上电,主控芯片和其他耗电器件已断电,CAN收发器处于SLEEP模式,当CAN收发器检测到CAN总线上的唤醒帧后,拉高INH引脚(唤醒指示脚)使MCU和其他硬件上电,这对AUTOSAR而言,称为冷启动而不是唤醒。
(二)、MCU处于低功耗模式
MCU没有全速运行处于低功耗状态,CAN收发器或其他小部分硬件有上电,CAN收发器处于STANDBY模式,当CAN收发器检测到CAN总线上的唤醒帧后,CAN收发器触发MCU软件中断进行唤醒,这对AUTOSAR而言,这是来自MCU和CAN通道的唤醒(TJA1043在STANDBY下INH脚是拉高的,MCU可通过判断ERR_N引脚,TJA1043有唤醒标志后,ERR_N引脚会拉高,RXD引脚也会从高到低,着两个都可以作为唤醒信号)。
(三)、MCU处于运行模式
MCU处于运行模式,ECU里的器件都有上电,CAN收发器处于STANDBY模式,当CAN收发器检测到CAN总线上的唤醒帧后拉高引脚通知MCU唤醒了或者MCU周期性的轮询收发器有没有唤醒,这对AUTOSAR而言,这是CAN通道的唤醒(TJA1043在STANDBY下INH脚是拉高的,MCU可通过判断ERR_N引脚,TJA1043有唤醒标志后,ERR_N引脚会拉高)。
根据AUTOSAR里描述收发器的唤醒源类型CanTrcv_TrcvWakeupReasonType有以下几种类型:
四、唤醒支持和PN功能
CanTrcv通过CanTrcvWakeUpSupport宏定义来选择CANTRCV_WAKEUP_BY_POLLING还是CANTRCV_WAKEUP_NOT_SUPPORTED。
CANTRCV_WAKEUP_NOT_SUPPORTED模式下唤醒相关功能失效。
CANTRCV_WAKEUP_BY_POLLING模式下CanTrcv_MainFunction()轮询函数里查找收发器有没有唤醒事件,有的话调用EcuM_CheckWakeup()。
每个收发器通道可以通过CanTrcvWakeupByBusUsed配置是否单独打开唤醒相关功能。
有些收发器携带PN功能,即可以配置成收到特定帧唤醒,ECU每次唤醒后CanTrcv如果开启了PN功能则会调用CanIf_ConfirmPnAvailability()通知CanIf,CanIf再调用CanSM_ConfirmPnAvailability()通知CanSM。
通过将CanTrcv_PNActivationType配置为PN_ENABLED使能CanTrcv的PN功能。
一般收发器都是通过传统CAN帧唤醒的,如果想要CANFD唤醒,当收发器没开启PN功能下,在MCU里对收到的CAN帧进行判断是不是CANFD,如果收发器开启了PN功能,收发器在识别到CANFD时会认为是错误帧,里面的错误计时器会累加,累加到最大值会同样会唤醒,此动作可认为是收到CANFD帧。
如下图是某个收发器对CAN和CANFD的唤醒支持策略:
五、休眠唤醒时序图
如上图,EcuM在进入睡眠前通过CanIf调用CanTrcv的CanTrcv_SetWakeupMode()让CanTrcv的唤醒模式ENABLE,同时CanSM组件也会调用CanIf_SetControllerMode和CanIf_SetTransceiverMode让CAN控制器和CAN收发器进入睡眠模式,接着EcuM再调用Icu_EnableWakeup()让唤醒引脚Icu通道继续保持输入捕获唤醒功能,接着MCU进入休眠状态,如果CAN总线上有唤醒报文出现,收发器激活硬线信号输入到ICU通道,MCU唤醒进入输入捕获中断,Icu组件调用EcuM_CheckWakeup()检查唤醒源,EcuM通过CanIf调用CanTrcv的CanTrcv_CheckWakeup(),CanTrcv从收发器那里知道有总线唤醒,便调用EcuM_SetWakeupEvent()通知EcuM有CanTrcv的唤醒事件,,接着MCU唤醒正常运行。
六、主要代码描述
(一)、void CanTrcv_Init( const CanTrcv_ConfigType* ConfigPtr )
初始化CanTrcv组件,初始化时将查询收发器是否有唤醒标志,有的话调用EcuM_SetWakeupEvent()告诉EcuM有唤醒源。
如果CanTrcvHwPnSupport等于TRUE并且收发器支持的话,有检测到收发器有POR和SYSERR标志的话,则调用EcuM_SetWakeupEvent()告诉EcuM有这些唤醒源。
调用后进入ACTIVE状态。
(二)、Std_ReturnType CanTrcv_SetOpMode( uint8 Transceiver, CanTrcv_TrcvModeType OpMode )
用来设置收发器的模式,是NORMAL、STANDBY、SLEEP之一,如果设置了NORMAL模式,则调用Icu_DisableNotification()关闭对应的输入捕获引脚通知。如果设置了STANDBY或SLEEP,则调用Icu_EnableNotification()开启对应的输入捕获引脚通知。
如果CanTrcvHwPnSupport等于TRUE并且收发器支持而且使能了的话,那么有检测到POR标志,收发器应该重新初始化,而没有设置SYSERR标志且请求的模式为NORMAL,则收发器应该调用CanIf_ConfirmPnAvailability()通知CanNm(通过CanIf和CanSm)已经启用了选择性唤醒(PN功能)。
收发器模式控制被CanSM调用
(三)、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 )
设置收发器的唤醒模式。
如果设置为ENABLE,则收发器有唤醒事件后通知上层,并且设置为ENABLE时有唤醒事件马上通知上层。
如果设置为DISABLE,则收发器屏蔽唤醒事件,有唤醒事件先暂存起来下次为ENABLE则立马通知上层。
如果设置为CLEAR,则清除软件里存储的收发器的唤醒事件。上层组件使用时要在唤醒通知禁止下使用。
(六)、Std_ReturnType CanTrcv_GetTrcvSystemData( uint8 Transceiver, uint32* TrcvSysData )
用来输出收发器的状态,CanTrcvHwPnSupport等于TRUE下才可使用。
(七)、Std_ReturnType CanTrcv_ClearTrcvWufFlag( uint8 Transceiver )
用来清除收发器中的唤醒标志,CanTrcvHwPnSupport等于TRUE下才可使用。
在进入低功耗模式前需要先调用这个确保不会丢失唤醒事件。
在清除完后应该进入STANDBY模式。
如果清除成功CanTrcv应该调用CanIf_30_ClearTrcvWufFlagIndication()通知CanIf。
(八)、Std_ReturnType CanTrcv_ReadTrcvTimeoutFlag( uint8 Transceiver, CanTrcv_TrcvFlagStateType* FlagState )
从收发器里读取超时标志,如果收发器支持的话。CanTrcvHwPnSupport等于TRUE下才可使用。
(九)、Std_ReturnType CanTrcv_ClearTrcvTimeoutFlag( uint8 Transceiver )
清除收发器的超时标志,如果收发器支持的话。CanTrcvHwPnSupport等于TRUE下才可使用。
(十)、Std_ReturnType CanTrcv_ReadTrcvSilenceFlag( uint8 Transceiver, CanTrcv_TrcvFlagStateType* FlagState )
从收发器读取静默标志,如果收发器支持的话。CanTrcvHwPnSupport等于TRUE下才可使用。
(十一)、Std_ReturnType CanTrcv_CheckWakeup( uint8 Transceiver )
CanTrcv处于WUMODE_ENABLE模式下检查收发器是否有唤醒事件,有的话调用EcuM_SetWakeupEvent()通知EcuM有唤醒事件。
(十二)、Std_ReturnType CanTrcv_SetPNActivationState( CanTrcv_PNActivationType ActivationState )
设置收发器是否开启PN功能。
(十三)、Std_ReturnType CanTrcv_CheckWakeFlag( uint8 Transceiver )
请求向收发器检查唤醒标志,如果允许返回OK并且调用CanIf_CheckTrcvWakeFlagIndication()通知CanIf。
(十四)、Std_ReturnType CanTrcv_DeInit( uint8 Transceiver )
CanTrcv模块反初始化,调用后进入NOT_ACTIVE状态。
在NOT_ACTIVE状态下收发器硬件允许重新配置。
(十五)、void CanTrcv_MainFunction( void )
周期调用函数,如果CanTrcvWakeUpSupport等于CANTRCV_WAKEUP_BY_POLLING下并且模式为STANDBY、SLEEP时检测到有唤醒事件调用EcuM_CheckWakeup()通知EcuM。通常MCU是之前处于断电模式然后被唤醒软件运行期间调用该函数时检测到收发器的唤醒源,如果MCU之前处于休眠模式,那么在MCU被唤醒中断后,在中断里直接调用EcuM_CheckWakeup()检查收发器是否有唤醒标志了。
七、DaVinci Configurator主要配置
CanTrcv需要和Sbc一起配置。
(一)、CanTrcv配置
这里设置轮询函数的周期、CanTrcvWakeUpSupport是POLLING还是NOT_SUPPORTED等。
这里配置收发器的通道。通道是否使用、PN功能是否使用、如果有唤醒功能ICU通道是什么、如果检测到POR或SYSERR标志报告的唤醒源是什么、唤醒功能是否使用等。
这里选择SBC通道。
(二)、Sbc配置
CanTrcv模块需要和Sbc模块搭配使用,每个ECU的SBC可能都不一样,相应的配置也不一样,大概就是配置SBC的波特率、SPI通道、WDG超时时间、PN功能属性等。
八、使用范例
无,CanTrcv主要被CanIf所调用,然后再被CanSm或BswM调用控制收发器是进行正常收发还是进入睡眠模式,如果SBC里有看门狗或电源控制,那CanTrcv里没有相关的操作,CanTrcv主要是控制CAN收发器用的。
九、参考资料
AUTOSAR_CP_SWS_CANInterface
AUTOSAR_CP_SWS_CANTransceiverDriver
AUTOSAR_EXP_LayeredSoftwareArchitecture
AUTOSAR_CP_SWS_ECUStateManager
AUTOSAR_CP_SWS_ICUDriver
TechnicalReference_CanTrcv_30_Sbc
TechnicalReference_Sbc_Tcan114x
ISO7498
ISO11898
ISO11519
ISO15765
ISO14229
can2.0
can_fd_spec
总结
本文文字描述多点,更像是本人的使用笔记,仅供参考,如有不对地方欢迎指教。