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开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

C#图表开发之Chart详解

《C#图表开发之Chart详解》C#中的Chart控件用于开发图表功能,具有Series和ChartArea两个重要属性,Series属性是SeriesCollection类型,包含多个Series对... 目录OverviChina编程ewSeries类总结OverviewC#中,开发图表功能的控件是Char

鸿蒙开发搭建flutter适配的开发环境

《鸿蒙开发搭建flutter适配的开发环境》文章详细介绍了在Windows系统上如何创建和运行鸿蒙Flutter项目,包括使用flutterdoctor检测环境、创建项目、编译HAP包以及在真机上运... 目录环境搭建创建运行项目打包项目总结环境搭建1.安装 DevEco Studio NEXT IDE

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设