1 单片机从上电开始的启动过程
我们在<<单片机启动分析(上)单核单片机的启动>>和<<单片机启动分析(下)多核单片机的启动>>分别分析了单核单片机和多核单片机的启动流程。BootROM中的抛开不谈。运行到用户可见的流程为:关闭中断、初始化寄存器、初始化全局变量(初始化.data段(有初始化值的数据段)、初始化.code段以及初始化.bss段(未初始化和初始化值为0的段))。对于多核单片机而言,此时Core0开始运行,当主核初始化完外设(通过EcuM_AL_DriverInitZero和EcuM_AL_DriverInitOne函数,详见<<EcuM功能分析及实现(上)之STARTUP>>),然后调用EcuM_Prv_StartSlaveCores启动其他核。
2 CanTp多包传输过程
我们在<<万字讲解Can协议栈配置之CanTp>>讲解了CanTp模块。CanTp不提供缓存功能,因此CanTp调用PduR_CanTpCopyTxData() or PduR_CanTpCopyRxData()函数来获取上层模块的缓存。上层模块需要锁住(lock)这块内存不被污染直到PduR_CanTpTxConfirmation() or PduR_CanTpRxIndication()被调用。
2.1 发送多包
这个调用时序忽略接收和处理流控帧,只为了说明CanTp和上层的接口调用。
1:PduR调用CanTp_Transmit函数请求发送50个字节的数据;
2:CanTp调用PduR_CanTpCopyTxData函数请求PduR的数据,然后发送首帧;
3:CanTp通过连续帧发送剩余的数据;
4:CanTp调用PduR_CanTpTxConfirmation函数通知PduR发送完成。
2.2 接收多包
这个调用时序忽略发送流控帧,只为了说明CanTp和上层的接口调用。在这个调用时序中需要接收的数据是49个字节,而上层的缓存只有25个字节,具体调用如下。
1:CanIf调用CanTp_RxIndication函数告诉CanTp有新的数据来了, 然后CanTp通过PduR_CanTpStartOfReception函数告知PduR并且锁定一块缓存;
2:PduR通过PduR_CanTpStartOfReception函数告知CanTp可用的缓存大小为25个字节,CanTp开始发送继续发送的流控帧;
3 :CanTp将接收的数据传给PduR并且监控缓存的剩余空间,当接收完第二个连续帧后,缓存空间不够接收下一块数据了;
4:CanTp通过调用PduR_CanTpCopyRxData得知剩余为0,然后再次发送一个等待流控帧;
5:当缓存足够容纳下一个块时,CanTp将会发送继续发送的流控帧;
6:在接收完两帧连续帧后,缓存再次不够了,此时CanTp将需要再次发送一个等待流控帧;
7:当缓存可用时,CanTp继续接收;
8:接收完成后调用PduR_CanTpRxIndication通知PduR。
3 CanNm有几个状态,每个状态的报文发送和接收状态是什么样的。
我们在<<网络管理(上)之CanNM模块>>已详细描述。
AUTOSAR 网络管理包含3个运行模式:
1 网络模式(Network Mode);
2 网络准备休眠模式(Prepare Bus-Sleep Mode);
3 网络休眠模式(Bus-Sleep Mode)。
其中,网络模式包含3个运行状态:1 报文快发状态(Repeat Message State)2 正常网络状态(Normal Network State)3 准备休眠状态(Ready Sleep State)。
报文收发状态之前应用报文在prepare Bus-Sleep模式下描述有点问题,应该是不允许收发(已缓存在can底层寄存器中的报文允许继续发送)。
节点模式 | 报文类型 | Bus-Sleep Mode | Network Mode | Prepare Bus-Sleep mode | ||
Repeat message | Normal Operation | Ready Sleep | | |||
主动节点 | 应用报文 | 不允许收发 | 允许收发 | 允许收发 | 允许收发 | 不允许收发 |
网络管理报文 | 允许收,不允许发 | 允许收发,且快发模式 | 允许收发, 正常模式 | 允许收,不允许发 | 允许收,不允许发 | |
被动节点 | 应用报文 | 不允许收发 | 允许收发 | 允许收发 | 允许收发 | 不允许收发 |
网络管理报文 | 允许收,不允许发 | 允许收 | 允许收 | 允许收 | 允许收 |
4 网络唤醒的流程
EcuM调用EcuM_StartWakeupSources函数启动校验唤醒源的计时,超时则认为唤醒源无效。随后开始循环调用EcuM_CheckValidation->CanIf_CheckValidation来检测CAN总线上的唤醒源,当CAN总线完整的接收了一帧报文(通常配置为网络管理报文)后,向EcuM报告唤醒源有效,至此完成唤醒源的校验。假如EcuM模块中的EcuMComMChannelRef配置了ComM的通道,那么当唤醒源有效时,就会通过调用ComM_EcuM_WakeUpIndication函数触发ComM的状态(假如配置了PNC也包括PNC)转移。
5 Spinlock和Resource的区别
详见<<AUTOSAR OS之Resource和Spinlock>>.Resource主要用于核内的任务通信,Spinlock主要用于核间的任务通信。当用户调用GetResource时会通过GetCoreID函数确保使用resource的这些任务在同一个核上。调用时会使用天花板优先级来短暂改变当前任务的优先级,防止优先级反转(原理有点类似开源操作系统中的互斥量)。Spinlock(自旋锁)可以用在多核的任务通信。它的原理是一个忙等待(while中判断一个lock变量是否可用(基于原子操作的test and set))。
6 Autosar看门狗有几种监控机制及喂狗方法,目前项目上看门狗设置考虑了什么因素。
WdgM提供了三种监控机制:1 针对周期运行软件的的Alive监控;2 针对非周期运行软件的DeadLine监控;3 针对执行顺序的逻辑(Logical)监控。Alive监控通过配置一段时间内的软件期望执行次数来监测Entity是否执行的过快或者过慢。DeadLine监控通过设置两个监控点(Checkpoint)间允许运行的时间来监测Entity的执行时间是否符合要求。Logical监测聚焦于流程的运行,主要用来监测Entity是否按照给定的流程运行。
我们可以在WdgM_MainFunction中喂狗,也可以在在中断中喂狗。中断中喂狗一般适用于窗口狗(<<Autosar看门狗系列(中)之搞懂看门狗的分类和使用>>).
我们通常对比较重要的任务进行看门狗监测。在汽车电子中,如CAN报文的发送和接收任务,如果接收报文任务超时,则获取不到正确的行车状态,如发送任务超时,则无法控车,这都很是很严重的问题!
7 谈一谈CAN BusOff。
我们在<<深入解析BusOff及CanSM模块>>和<<CAN BusOff及快慢恢复的测试原理及方法分析>>等文中详细描述了CAN BusOff的机制。
BusOff产生的可能原因有如下几种:
1 CAN线路问题,如CAN_H开路、CAN_L开路、CAN_H对CAN_L短路/开路、CAN_L对VBAT短路、CAN_H对GND短路、CAN_L对GND短路、终端电阻开路等;
2 CAN控制器或收发器等元器件故障导致;
3 CAN总线信号干扰。
当发送错误计数器大于255时,进入总线关闭状态,在总线关闭状态在检测到128次11个连续的隐性位后即可恢复通信。以500K的波特率为例,128*11*(1/500000)=0.002816s。这意味着如果节点所在的CAN总线的帧间隔时间大于0.002816s,节点在总线空闲时间内便可轻易恢复通信。但是当进入总线关闭状态时,节点已经发生了严重的错误,处于不可信状态,如果迅速恢复参与总线通信,具有较高的风险。因此,在实际的应用中,往往会通过MCU对CAN控制器总线关闭状态的恢复过程进行软件处理,以控制节点从总线关闭状态恢复到错误主动状态的等待时间,达到既提高灵活性又保证节点在功能上的快速响应性的目的。具体包括“快恢复”和“慢恢复”策略,两种策略一般同时应用。所谓快恢复,就是产生Bus Off后,ECU尝试恢复发送报文,此时的发送周期通常为50ms左右,一般快恢复5次,如果发送成功,则Bus Off解除,否则进入慢恢复机制,通常慢恢复的时间为200ms。