写在前面
由于实习的项目中,选择的是一款S32K142芯片作为控制器,在汽车电子的开发中CAN是非常用重要的,因为针对在项目中对CAN的底层开发(目前只是针对于SDK版本内容,后续会更新基于FreeRTOS、MCAL)的底层配置内容。整体软件架构设计中对CAN的Canif软件设计内容。(进行一个大致的总结)
flexCAN简介
CAN总线是一种应用十分广泛的串行通信总线,由于具备差分接受和发送的特点,使得在其抗干扰以及错误检测方面的性能大大提高。FlexCAN 模块是 CAN 协议的一个高完成度版本,带有动态数据率(Flexible Data rate,CAN FD)协议和 CAN 2.0 B 版本协议,支持标准和拓展数据帧和长达 64 字节的数据传输,频率最大可达到 8Mbps。数据缓冲器存在于中一个嵌入FlexCAN的 RAM 中。S32K1xx FlexCAN符合CAN 2.0B标准,支持全功能的CAN FD ,支持标准帧、扩展数据帧,最大64字节的数据长度,可编程位速率以及内容相关寻址。对其邮箱可灵活配置成为0、8、16、32、64位数据长度,可配置成为传输或者接收,支持其标准和扩展帧。
FlexCAN模块的组成由以下模块组成:
Proyocol Engine (PE) 协议引擎子模块管理CAN总线上的串行通信,负责请求RAM访问以接收和发送消息帧、对接收消息进行验证、执行错误处理、检验CAN FD消息。
BIS InterfaceUnit 总线接口单元主要是对内部接口总线的访问,建立与CPU和其他模块的连接,访问时钟、地址、数据总线、中断输出,所以在SDK中CAN组件的配置当中,也可以选择其外设时钟,应该是由于该单元可以对时钟进行访问的基础。
Controller Host Interface 控制主机接口 主要是对接收和发送消息缓冲区的选择,负责对CAN FD和非CAN FD消息格式的仲裁以及ID匹配算法。
FlexCAN接收和发送流程框图
传输 仲裁 移动 匹配 接收。
FlexCAN有多种工作模式,普通模式、冷冻模式、回环模式、只听模式、CANFD模式等,需要让其工作起来需要进行一些配置,比如时钟的配置、使能初始化模块、配置工作模式、配置波特率、配置发送帧、配置接收帧格式等,这些在底层实现中均是需要结合对应的数据手册来实现相关配置,当然在目前的开发过程中可以过程会以SDK配置为例子在下文进行说明。
FlexCAN 的 Message Buffer 结构
Message Buffer是可以配置成发送和接收数据,支持存储CAN 2.0标准帧和扩展帧,可以配置成为不同的字节长度比如(8+8、8+16、8+32 8+64)等,前八位位报文帧头信息,后面位数据,根据选择不同的数据长度,会有对应不同个数的MB。(下图来源于论坛文章截图),另外我们也可以通过Rx FIFO来接收报文,发送报文还是只使用MB的方式来发送。
S32K1XX SDK中提供的两个Flex CAN驱动组件
can_pal组件
首先需要对GPIO进行设置,在Components里面
并且在时钟配置中,配置对应的外设时钟,
Number of buffers 缓冲数 范围是0-32
模式 :普通 回环 使能
PE clock source :晶振时钟 外设时钟
是否使能CAN FD
Buffer payload size 报文内容 8 16 32 64
void CAN0_Callback_Func (uint32_t instance,can_event_t event,uint32_t buffIdx,void *flexcanState)
{
(void)flexcanState; //此处防止警报
(void)instance;
(void)buffIdx;
CAN_Receive(&can_pal0_instance, RX_MAILBOX_CAN0, &recvMsg_CAN0); //接收报文并重新注册回调函数
switch(event) //回调事件
{
case CAN_EVENT_RX_COMPLETE: //接收完成 事件
IRQ_CAN0_RX =1;
break;
case CAN_EVENT_TX_COMPLETE: //发送完成事件
break;
default:
break;
}
}
void CAN0_Init(void)//初始化函数
{
CAN_Init(&can_pal0_instance, &can_pal0_Config0);//CAN0的初始化 直接拖入
can_buff_config_t Rx_buffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};//接收缓存
can_buff_config_t Tx_buffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};//发送缓存
CAN_ConfigRxBuff(&can_pal0_instance, RX_MAILBOX_CAN0, &Rx_buffCfg, Rx_Filter); //注册接收配置和MSGID过滤器(如过滤器配置为0x1,则只接受msgid 0x1发来的报文)
CAN_ConfigTxBuff(&can_pal0_instance, TX_MAILBOX_CAN0, &Tx_buffCfg); //配置发送
/*设置MSGID的掩码,掩码粗略可以理解为对11bit MSGID地址的过滤
如果某bit位需要过滤设置为1,不过滤设置为0,例如掩码设置为0x7ff则过滤全部标准id,如果设置为0x7fe,这只能接受0x01的报文(不存在0x0的地址)*/
CAN_SetRxFilter(&can_pal0_instance,CAN_MSG_ID_STD,RX_MAILBOX_CAN0,0); //设置MSGID掩码,
CAN_InstallEventCallback(&can_pal0_instance,&CAN0_Callback_Func,(void*)0); //注册回调函数
CAN_Receive(&can_pal0_instance, RX_MAILBOX_CAN0, &recvMsg_CAN0); //*****重点****此函数不只有接收作用 还有续订回调函数的作用.
}
针对于flexcan组件的配置内容有对应文章介绍的十分详细,S32KSDKCAN组件详解-CANPAL-FLEXCAN,学习S32K系列CAN组件的使用和原理_S32K3的CAN节点地址资源-CSDN文库
软件程序中CAN底层到上层软件设计
后续再进行更新。。。。。。