简易的AUTOSAR BSW层 CAN通信配置总结

📅 2026/7/10 23:36:50
简易的AUTOSAR BSW层 CAN通信配置总结
前言近期公司为产品新增车控模块功能这要求我们在原有的裸机运行架构基础上引入符合 AUTOSAR 规范的 BSW基础软件层以实现与底层硬件的标准化交互。本文聚焦于 BSW 层与 MCAL微控制器抽象层的配置实践不涉及应用层开发。在完整工程交付前我搭建了一条简易的 BSW 层 CAN 通信链路手动配置了几个信号将其绑定到 IPDU再映射至 CanIf 层最终与 MCAL 层的 CAN 收发器和控制器对接实现了最基础的 CAN 通信功能。MCAL 层采用常见的 EB 工具进行配置过程中也遇到了不少问题后续将另文总结。需要说明的是当前几个 BSW 协议栈能够正常运行的前提是 MCAL 层已实现了一套类裸机的任务调度系统。BSW 的初始化及报文周期发送均依托于 GPT通用定时器中断函数来驱动。未来引入操作系统OS后底层调度机制还需进一步调整这也留待后续探讨。一条报文从 SWC软件组件调用 Rte运行时环境发送接口开始穿越 BSW 层的各个协议栈经历打包、路由、控制器选择直至最终执行 can_write其完整流程如下Com_SendSignal →Com_MainFunctionTx_ComMainFunctionTx0 →Com_PduPeriodicTxProcess →Com_PduCycleSend →Com_OnePduSend →PduR_ComTransmit →PduR_Local_Transmit →CanIf_Transmit → can_write该流程涵盖了 Com、PduR、CanIf 三个核心协议栈。下文将逐一详解各层的具体配置步骤。一、Com配置ComGeneral按模块默认配置就行需要注意的是当前只需要CAN能正常收发就行而且没有配OS所以这里要取消多核勾选。只有CAN一种通信方式的情况下不需要网关转发ComGwMapping无需配置。从Com到PduR是以IPDU的形式传输所以在ComIPdus下面分别添加一条ComIPdu_rx和ComIPdu_tx这里着重讲tx。ComIPdu_tx分为ComTxModeFalse和ComTxModeTrue。ComTxModeFalse指数据变化时触发式发送ComTxModeTrue是周期性发送两个可以同时配上。ComIPduGroup中可按收发各配置一条一般项目中如果收发报文数量较少就按报文单独发送或者只配一个IPduGroup即可这里的ID就是后续Com_IpduGroupStart的入参。ComMainFunctionRxs和ComMainFunctionTxs用于生成收发主函数只需设置收发主函数的周期。最关键的就是具体的信号内容了包括信号的起始位信号的大小大小端排序可以给你的信号取一个高分辨度的名称方便后续在代码中查找当然实际生成代码中一个报文中生成的信号宏都是从0开始排序二、PduR配置在配置PduR之前需要先在EcuC中添加两个PdusEcuC相当于BSW中的全局变量定义和管理模块为其他模块提供索引的锚点。报文发送是从Com出发所以添加一个tx pdu索引Com module。接收都是从CanIf上送所以添加一个rx pdu索引CanIf module。回到PduR的配置首先就是添加两个BswModules这里暂不考虑诊断、存储的情况下PduR的上下层分别只有Com和CanIf各自索引到对应模块。工具会根据你选择的module自行区分该协议栈是PduR的upper还是lower module。在PduRDestPdus和PduRSrcPdus中分别新增一个tx和rx配置项注意PduRDestPdus_tx和PduRSrcPdus_tx要索引EcuC中同一个PduR信号。接着在PduRRoutingPath中对源端和目的端引用的PduR进行组合收发各配置一条routingpath。接着在PduRRoutingPath中对源端和目的端引用的PduR进行组合收发各配置一条routingpath。三、CanIf配置最后是CanIf的配置首先与MCAL层对应的配4个can控制器和4个can收发器当然这里配的can收发器和控制器的参数并不会真正用得到这里只是保证CanIf索引到对应的can控制器ID具体还是用的MCAL层can相关的配置。CanHardwareObjects中先配接收再配发送里面具体的内容还是以MCAL层的配置为准这里也可以简单配下CanHandleType选BASIC即一个硬件对象邮箱能处理一个范围的CAN ID选FULL的话一个邮箱只能处理某一具体ID的can报文CanIdType选MIXED表示既可以收/发can类型也可以收/发canfd类型的报文。注意下面的can控制器索引一定要选对RXTX要选同一个can控制器。波特率啥的可以就不配了只要CanIf索引到对的can控制器的ID号就行剩下交给MCAL层来实现。这里同样取消勾选多核由于裸机GPT中断触发机制的局限性这里取消txbuffer。简单说下原因就是在当前简易工程下开启这个buffer会误读未初始化的数据发送的 CAN 报文ID都为0且内容为空。本次暂不配置网络管理相关的协议栈这里所有相关交互模块暂时就选复杂驱动回调函数设空。接着看CanIfHthCfg和CanIfHrhCfg选择对应的can控制器后通过Hth和Hrh可以连接到具体收/发的硬件对象。这里底层只有can控制器1可用所以将分别索引到can控制器1的收/发object。然后到CanIfBufferCfgCanIfBufferCfg特指发送缓冲区Txbuffer可配置多个不同容量的缓冲区。 这里大小设为 0索引通过本CanIfBufferCfg引用对应的硬件发送通道即CanIfHthCfg。再到CanIfTxPduCfgsCanIfTxPduRef绑定到EcuC中定义的PduCanIf的上层选PduR最后绑定具体的txbuffer。这样就通过EcuC模块将每条PDU绑定到了对应的CAN控制器。BSW侧的三个协议栈的配置就到这边了。实际代码运行时还需要添加初始化和周期运行函数INITvoid Bsw_Init(void){CanIf_Init(NULL_PTR);PduR_Init(PduRPBConfig);Com_Init(NULL_PTR);Com_IpduGroupStart(COM_IPDU_GROUP_COMIPDUGROUP_TX_INDEX, TRUE);CanIf_SetControllerMode(0, CAN_CS_STARTED);CanIf_SetControllerMode(1, CAN_CS_STARTED);CanIf_SetControllerMode(2, CAN_CS_STARTED);CanIf_SetControllerMode(3, CAN_CS_STARTED);CanIf_SetPduMode(0, CAN_CONTROLLER_ONLINE);CanIf_SetPduMode(1, CAN_CONTROLLER_ONLINE);CanIf_SetPduMode(2, CAN_CONTROLLER_ONLINE);CanIf_SetPduMode(3, CAN_CONTROLLER_ONLINE);}10ms任务调度void Bsw_MainFunction10ms(void){Com_MainFunctionTx_ComMainFunctionTx0();Com_MainFunctionRx_ComMainFunctionRx0();PduR_MainFunction();}修改具体的信号后也可以触发式发送一次该信号所属报文。调用函数如下Com_SendSignal(COMCONF_COMSIGNAL_COMIPDU_TX_COMSIGNAL_VEHICLESPEED, speed);总结与注意事项配置要点总结Com层配置取消多核勾选配置ComIPdu_tx的ComTxModeFalse触发式发送和ComTxModeTrue周期性发送合理设置ComIPduGroup注意信号起始位、大小和大小端排序。PduR层配置先在EcuC中添加tx和rx PDU然后在PduR中添加BswModules确保PduRDestPdus_tx和PduRSrcPdus_tx索引同一个PduR信号最后在PduRRoutingPath中完成路由组合。CanIf层配置配置与MCAL层对应的CAN控制器和收发器取消多核勾选根据裸机环境特点取消txbuffer。裸机环境下的特殊处理多核支持在ComGeneral和CanIf配置中都需要取消多核勾选因为裸机环境没有操作系统支持多核调度。缓冲区管理由于GPT中断触发机制的局限性需要取消CanIf的txbuffer每次只发送一帧报文避免缓冲区索引回绕导致发送未初始化数据。任务调度BSW的初始化和报文周期发送需要在GPT中断函数中进行这要求MCAL层已实现裸机任务调度系统。收发器控制CanIf配置的收发器需要MCAL层自行封装接口在控制CAN控制器时同步处理收发器的唤醒和休眠动作。实践建议在配置前确保MCAL层的基础驱动和任务调度系统已正常工作。按照Com→PduR→CanIf的顺序进行配置确保各层间的PDU索引正确对应。对于简单的CAN通信需求可以只配置一个IPduGroup减少配置复杂度。为信号取高分辨度的名称便于后续在代码中查找和维护。在实际项目中需要根据具体的硬件资源和性能要求调整缓冲区大小和发送策略。