云途 CAN FD 介绍
MailBox
之前对MB理解有误,在芯片参考手册中,MB有两种意思,一种是MessageBuff,一种是Mailbox。云途ME0芯片CAN0~2有64MBs,CAN3~5有32MBs,这里的MB指的是MailBox。另外此芯片CAN0~2有20个ERF(Ehanced RX FIFO),而且每个都是64Bytes Payload的,在FD模式下要用Rx Fifo 必须用它。
The Legacy Rx FIFOs cannot be used in CAN FD mode. The Enhanced Rx FIFO, if implemented, can be used in CAN FD mode
8Byte Payload MailBox每个邮箱占用16字节,此芯片CAN0~2由两个512Bytes RAM Block组成,所以总共是64个 8 Byte Payload MailBox。
邮箱是RAM区域,在使用前需要初始化邮箱(写初始值),防止首次读取时ECC错误。在CAN模块中除了邮箱还有很多其他的寄存器也是在RAM中,需要先写再读防止ECC错误,参考文档中介绍了RAM Initialization,这些RAM区域都是从寄存器的地址被访问到,我主要用的是两种如下,一个是标准CAN,一个是CANFD开启ERF:
Message Buffer
MessageBuffer是CAN中发送或接收一帧存放的消息缓冲区,MessageBuffer是由一个或多个MailBox组成,发送还是接收需要配置MessageBuffer中的Code,Code描述如下图:
在初始化MessageBuffer过程中,要设置为发送就将code初始化为8,要设为接收就初始化为4。
那么我们要如何分配MailBox,配成各种MessageBuffer呢?
在S32K1中,开启了FD不能使用RX FIFO,为了设计简单,且能防止接收到多帧报文在读取时顺序错误,所以就只配置了1个MessageBuffer用于接收,其余用于发送。
其实也可以根据MessageBuffer中的时间戳来分析哪个先收到,目前还没做,每次MB中断时还要看看其他MB时间戳,感觉效率不是很高。
以下是初始化MessageBuffer的代码:
1 | CanFdMb = (CANFD_MB_TYPE *)p_mcuCanTable[channel].p_can->RAMn; |
云途芯片CAN资源比S32K1丰富很多,开启FD后还能使用ERF,可缓存20个64Bytes Payload的报文并通过FIFO读取没有顺序错误问题。MailBox总共可以配14个64Bytes Payload的MessageBuffer全部用于发送报文,两块MailBox的RAM也可以配置成不同长度的MessageBuffer,如下FDCTRL寄存器:
Rx Filter Elements
云途的ERF必须要配置Filter才可以用,因为默认就会开1个Filter,不配置的话可能收不到拓展帧,于是我配置了1个标准帧Filter(占4字节)和1个拓展帧Filter(占8字节),配置为Mask模式,Mask都为0,就是都不过滤。代码如下:
1 | p_mcuCanTable[channel].p_can->ERFCR |= CAN_ERFCR_NEXIF(1) | CAN_ERFCR_NFE(1); // 1 extended id filter element, 1 standard id filter element |
标准帧和拓展帧的 Rx Filter Elements 结构体定义如下:
CAN FD 调试问题
- MessageBuffer 配成64Bytes Payload时,RAM区最后一个MessageBuffer结束地址和下一个MessageBuffer起始地址不连续,导致发送,初始化时操作部分MessageBuff时地址不对。
- 发送存在错误帧,波特率配置对,但采样率不对。
- 接收不到,手册说ERF写0使能,找FAE确认没问题,但就是写1使能。
- 初始化28个MessageBuffer进Hardfault,实际没28个,FAE确认说有28个,最后在应用笔记上找到是14个。
- 接收不到拓展帧,需要配ERF Filter,1个拓展帧,1个标准帧。
- 要使用pll后时钟,配时钟源无效。
- 发送使用14个MessageBuffer,会导致发送的时候顺序乱,使用7个正常,可能是因为2个ram block不同步。