NXP S32K3系列学习笔记——FlexCAN驱动开发

2023-11-21 06:59

本文主要是介绍NXP S32K3系列学习笔记——FlexCAN驱动开发,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

“点点的学习日记”

前言

一、FlexCAN是什么?

1.概括

2.  邮箱结构   

二、通信波特率设置

三、FlexCAN模块初始化

四、发送、接收与匹配过程

1. 发送过程

2. 接收过程

3. 匹配过程

五、特殊功能

1. 邮箱锁机制

2. MCR[SRXDIS] 自接收功能


前言

学习NXP S32K3系列芯片笔记,内容大多通过阅读官方RM手册与自我理解得出,小白笔记,如有错误请谅解。

一、FlexCAN是什么?

1.概括

        FlexCAN 模块是 CAN 协议的一个高完成度版本,带有动态数据率(Flexible Data rate,CAN FD)协议和 CAN 2.0 B 版本协议,支持标准和拓展数据帧和长达 64 字节的数据传输,频率最大可达到 8Mbps。数据缓冲器存在于中一个嵌入FlexCAN的 RAM 中。

上图为FlexCAN各模块关系,其功能如下:
        协议引擎Protocol Engine (PE)用于管理CAN总线上的串行通讯:请求RAM访问用于接收、发送消息帧;验证接收的消息;运行错误处理;探测CAN FD帧。
        控制器主机接口Controller Host Interface (CHI)用于管理接收、发送的消息缓存邮箱(Message Muffers),负责仲裁和ID匹配。
        总线接口单元Bus Interface Unit (BIU)用于控制访问内部总线,建立与CPU和其他模块的联系。包括时钟、寻址、数据总线、中断、DMA的访问都是通过BIU。

2.  邮箱结构   

        本文开发基于S32K344芯片,介绍下K344的资源,如下图所示,其具有6个CAN模块,均支持CAN FD。在传统模式下CAN0~CAN5分别具有96、64与32个邮箱。

邮箱结构如下:地址偏移0h~4h为CS控制字段,主要存储报文属性与邮箱状态CODE码。地址偏移4h~8h为ID字段,用于存储报文ID或设置接收邮箱的专用ID。

CODE --邮箱代码 代表该邮箱状态,由4位组成。可通过访问CODE段得知邮箱状态或操控邮箱。

EDL --扩展数据长度
该位用于区分CAN格式帧和CAN FD格式帧。对于配置为RANSWER的代码字段1010b的消息缓冲区,不能设置EDL位。
BRS --bit速率开关
该位定义了是否在CAN FD格式帧内切换码率。
ESI --错误状态指示
该位表示发送节点是错误主动还是错误被动。

二、通信波特率设置

        CAN模块进行通信需要相同的波特率才可以进行正常的通信。在CAN的底层协议里,CAN数据的每一位时间(CAN Bit Time)被分为若干份时间,其组成为:

位同步时间(Tsync)、时间段1(Tseg1 = PROPSEG + PSEG1 + 2)、时间段2(Tseg2 +1)

        位同步时间固定为1份,时间段1与时间段2可在一定范围内调整。

符合博世CAN 2.0B标准的位段设置范围如图所示:

 注意一点:在设置时间位段数量时,必须要确保位时间设置符合CAN协议标准(ISO 11898-1)。

        当确定了位段时间数量后,通过计算单位时间的长度Tq即可知道CAN单帧时间,进而可以得到波特率。CAN模块的时钟设置这里不再介绍。

Tq = \frac{PRESDIV + 1}{fCANCLK}

波特率设置公式如下:

CAN Bit Time = (Tsync + Tseg1 +Tseg2) * Tq

Baud = \frac{1}{ CAN Bit Time}

根据下图所示,SYNC+SEG+(PROP_SEG+PSEG1+2)+(PSEG2+1)就是总的Tq,因此FlexCAN 的波特率就是CAN时钟频率除以Tq的数量:

CAN Baud=\frac{f_{Tq}}{TqQuantity}

如上图所示,采样点位于 Tseg1与Tseg2之间。计算方式为:

\frac{Tsync + Tseg1}{Tsync + Tseg1 +Tseg2}*100%

例如,假设Tsync = 1,Tseg1 = 14,Tseg2 = 5。那么采样点为:

((1+14) / 20)*100% = 75%

部分配置代码:

	numPresDivUB = (CAN_NUM_BAUDRATE_FREQ/(20*numBRUI))-1;/*SYNCSEG[1] | 	  TSEG1[2,16]  	 |采样点| TSEG2[2,8]*//*SYNCSEG	 | (PROPSEG+PSEG1+2) |采样点| (PSEG2+1)*//* 该配置采样点约为75%位置 */infoCanRegPS->CTRL1 |= FLEXCAN_CTRL1_PSEG2(4);	/*TSEG2=5=4+1*/infoCanRegPS->CTRL1 |= FLEXCAN_CTRL1_PSEG1(5);	/*TSEG1=14=PROPSEG+PSEG1=7+5+2*/infoCanRegPS->CTRL1 |= FLEXCAN_CTRL1_PROPSEG(7);infoCanRegPS->CTRL1 |= FLEXCAN_CTRL1_PRESDIV(numPresDivUB);

三、FlexCAN模块初始化

        对于FlexCAN模块的设置,初始化或更改配置都需要将FlexCAN设置为Freeze模式。注意,每次重置后都需要初始化模块。
下面是FlexCAN模块的通用初始化步骤:
1. 初始化模块配置寄存器(MCR)。
        a. 通过设置IRMQ启用每MB单独过滤和接收队列特性。
        b. 通过设置WRNEN使能警告中断。
        c. 如果需要,可以通过设置SRXDIS来禁用帧自接收。
        d. 通过配置RFEN使能Legacy Rx FIFO,通过配置ERFEN使能Enhanced Rx FIFO
        e. 如果使能了Legacy Rx FIFO或Enhanced Rx FIFO且需要使用DMA,则需要设置DMA。
        f. 通过设置AEN使能终止机制。
        g. 通过设置LPRIOEN使能本地优先级特性。
2. 初始化控制1寄存器(CTRL1)和CAN位定时寄存器(CBT)。如果使用CANFD,还需要初始化CAN FD、CAN位定时寄存器(FDCBT):
        a. 确定位定时参数:PROPSEG、PSEG1、PSEG2和RJW。
        b. 可选择位定时参数:EPROPSEG、EPSEG1、EPSEG2、ERJW。
        c. 确定CAN FD位定时参数:FPROPSEG、FPSEG1、FPSEG2、FRJW。
        d. 通过编程PRESDIV字段和可选的EPRESDIV字段来确定比特率。
        e. 通过编程FPRESDIV字段确定CAN FD比特率。
        f. 确定内部仲裁方式(LBUF)。
3. 如果ECC (Error Code Correction)使能,必须初始化所有FlexCAN内存。
4. 初始化邮箱。
        a. 所有邮箱的CS字段必须初始化。
        b. 如果使能了Rx FIFO,则需要对ID过滤表进行初始化。
        c. 每个邮箱中的其他条目应根据需要初始化。
5. 初始化Rx单个掩码寄存器(RXIMRn)。
6. 设置所需的中断掩码位

        •IMASK寄存器 (用于所有邮箱中断)
        •CTRL1 / CTRL2寄存器 (用于总线断开和错误中断)
7. 将MCR(HALT)失能。
在完成上面的初始化步骤后,FlexCAN将会尝试同步到CAN总线。

四、发送、接收与匹配过程

1. 发送过程

要想传输一条消息,需要准备一个消息缓冲区(MB),然后执行以下步骤:

1. 检查相应的中断位是否设置,同时清除中断标志。
2. 检查邮箱是否为活动邮箱,如果邮箱是活动的,将中止代码(1001b)写入CODE字段,请求中止      该邮箱传输。
3. 等待相应的IFLAG位变化。再次读取CODE字段,检查确认传输是否被中止。
4. 清除相应的中断标志。
5. 向ID段寄存器写入ID。
6. 写入数据字节(DATA)。
7. 向CS字段写入控制配置。
        a. MB_CS[IDE]——设置报文ID。
        b. MB_CS[RTR]——设置远程传输请求帧(如果需要的话)。
        c. MB_CS[DLC]——设置数据长度,以字节为单位。
        d. MB_CS[CODE]——设置邮箱CODE字,激活邮箱并发送。

/* 在程序中,建议将CS字段中的所有配置只配置在一次32位写操作中,可以提高性能。如果是单独写入,CS[CODE]必须是C/S字中最后一个写入 */

当邮箱被激活时,它会参与仲裁过程,并最终根据它的优先级进行传输。在成功发送之后:
        运行计时器的值会被写入时间戳Time Stamp字段。
        更新CS字段中的CODE字。
        更新CRC和FDCRC寄存器
        在中断标志寄存器中设置中断标志。
        如果相应的中断掩码寄存器位允许,产生中断。

2. 接收过程

对于Can消息的接收,可以采用以下的方式完成消息接收功能,具体步骤如下:

1. 首先检查邮箱是是否为活动邮箱(CODE为0100b),若是活动邮箱需要将邮箱停用(CODE段置0000b),建议使用安全停用邮箱的方式进行停用。
2. 将ID字段写入邮箱。
3. 将EMPTY代码(0100b)写入邮箱CS字段中CODE位以激活邮箱。CS段内的EDL、BRS和ESI位不需要设置,它们会被接收到的CAN报文中各自对应的位字段覆盖掉。
4. 在邮箱被激活后,它将能够接收到与程序设置的滤波器(MASK)相匹配的帧。在成功接收结束时,邮箱将通过移入过程更新(由FlexCAN模块执行,此更新过程CODE[0]=1,CPU无法访问)。

当FlexCAN成功接收CAN消息并移入对应邮箱后,官方参考手册中建议的CPU处理(读取)邮箱接收到的帧的方法如下:
        a. 读取该邮箱的控制和状态字(CS字段)。
        b.检查BUSY位是否被取消(CODE[0]),表示邮箱被锁定。在中断时重复步骤1。
        c. 读取邮箱的内容。在邮箱被锁定后,邮箱内容将不会被FlexCAN的Move-in进程修改。
        d. 在IFLAG寄存器确认标志位状态。
        e. 读取空闲运行计时器以解锁邮箱。

3. 匹配过程

待补充

五、特殊功能

1. 邮箱锁机制

-----邮箱锁机制-----

        除了邮箱失活以外,FlexCAN还有另一种在接收过程中保护数据一致性的机制。当CPU读取如果一个接收邮箱(Rx MB)的CS字段中CODE代码为FULL或OVERRUN时。FlexCAN假设CPU想要在一个操作中读取整个MB。因此,它为该MB设置了一个内部锁标志。当CPU读取空闲运行计时器(全局解锁操作)时,或者当它读取另一个MB的CS字段时,不管它的代码是什么,锁就会被释放。CPU写入C/S字也会解锁MB,但这个过程不建议用于普通解锁,因为它会取消正在处理的移入过程,可能会丢失接收到的消息。当CPU正在读取邮箱时,邮箱锁机制可以防止新接收到的帧写入邮箱。

        邮箱锁定机制只适用于不属于Legacy Rx FIFO的接收邮箱,并且与CODE字段中INACTIVE (0b0000)或EMPTY[1] (0100b)代码功能不同。注意,发送邮箱不能被锁定

举个例子:假设Legacy Rx FIFO功能被禁用,2号邮箱与5号邮箱使用相同的ID,且FlexCAN已经接收并存储CAN消息到这两个邮箱中。

        假设现在CPU决定读取5号邮箱,同时另一条具有相同ID的信息到达。当CPU读取5号邮箱的控制状态字,这个邮箱就会被锁定。当新消息到达时,FlexCAN匹配算法发现没有空闲的接收邮箱,因此它决定覆盖5号邮箱。但是5号邮箱是锁定的,因此不能在5号邮箱写入新消息。它将留在Rx SMB临时RX邮箱中,等待邮箱被解锁,然后才会被写入邮箱

        如果MB没有及时解锁,而另一个具有相同ID的新消息到达,那么新消息将覆盖Rx SMB上的消息,在MB的CODE字段或CS字段中都不会有丢失消息的指示。此时Rx SMB中丢失的消息将不会有任何的提示。当消息从Rx SMB移动到MB时,将置位CODE字段上的BUSY位。当CPU读取CS字段发现BUSY位显示正忙,应推迟访问邮箱,直到BUSY位被取消。

2. MCR[SRXDIS] 自接收功能

        在MCR寄存器中,具有一个可以设置自接收功能的位。这个位定义了是否允许FlexCAN接收自己传输的帧(自发自收)。如果这个位被设置启用,不管邮箱是否被设置为与发送帧相匹配的ID,FlexCAN模块发送的帧都不会被存储在任何MB中。而且,信息帧的接收不会产生中断标志或中断信号。注意,这个位只能在冻结模式下进行写入。

0b     /*  启用自接收  */
1b     /* 自接收被禁用 */

这篇关于NXP S32K3系列学习笔记——FlexCAN驱动开发的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/400626

相关文章

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

利用Python开发Markdown表格结构转换为Excel工具

《利用Python开发Markdown表格结构转换为Excel工具》在数据管理和文档编写过程中,我们经常使用Markdown来记录表格数据,但它没有Excel使用方便,所以本文将使用Python编写一... 目录1.完整代码2. 项目概述3. 代码解析3.1 依赖库3.2 GUI 设计3.3 解析 Mark

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件

基于Python开发批量提取Excel图片的小工具

《基于Python开发批量提取Excel图片的小工具》这篇文章主要为大家详细介绍了如何使用Python中的openpyxl库开发一个小工具,可以实现批量提取Excel图片,有需要的小伙伴可以参考一下... 目前有一个需求,就是批量读取当前目录下所有文件夹里的Excel文件,去获取出Excel文件中的图片,并

基于Python开发PDF转PNG的可视化工具

《基于Python开发PDF转PNG的可视化工具》在数字文档处理领域,PDF到图像格式的转换是常见需求,本文介绍如何利用Python的PyMuPDF库和Tkinter框架开发一个带图形界面的PDF转P... 目录一、引言二、功能特性三、技术架构1. 技术栈组成2. 系统架构javascript设计3.效果图

基于Python开发PDF转Doc格式小程序

《基于Python开发PDF转Doc格式小程序》这篇文章主要为大家详细介绍了如何基于Python开发PDF转Doc格式小程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用python实现PDF转Doc格式小程序以下是一个使用Python实现PDF转DOC格式的GUI程序,采用T

使用Python开发一个图像标注与OCR识别工具

《使用Python开发一个图像标注与OCR识别工具》:本文主要介绍一个使用Python开发的工具,允许用户在图像上进行矩形标注,使用OCR对标注区域进行文本识别,并将结果保存为Excel文件,感兴... 目录项目简介1. 图像加载与显示2. 矩形标注3. OCR识别4. 标注的保存与加载5. 裁剪与重置图像

Android开发中gradle下载缓慢的问题级解决方法

《Android开发中gradle下载缓慢的问题级解决方法》本文介绍了解决Android开发中Gradle下载缓慢问题的几种方法,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、网络环境优化二、Gradle版本与配置优化三、其他优化措施针对android开发中Gradle下载缓慢的问