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

相关文章

SpringBoot开发中十大常见陷阱深度解析与避坑指南

《SpringBoot开发中十大常见陷阱深度解析与避坑指南》在SpringBoot的开发过程中,即使是经验丰富的开发者也难免会遇到各种棘手的问题,本文将针对SpringBoot开发中十大常见的“坑... 目录引言一、配置总出错?是不是同时用了.properties和.yml?二、换个位置配置就失效?搞清楚加

Python中对FFmpeg封装开发库FFmpy详解

《Python中对FFmpeg封装开发库FFmpy详解》:本文主要介绍Python中对FFmpeg封装开发库FFmpy,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、FFmpy简介与安装1.1 FFmpy概述1.2 安装方法二、FFmpy核心类与方法2.1 FF

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部

使用Python开发一个现代化屏幕取色器

《使用Python开发一个现代化屏幕取色器》在UI设计、网页开发等场景中,颜色拾取是高频需求,:本文主要介绍如何使用Python开发一个现代化屏幕取色器,有需要的小伙伴可以参考一下... 目录一、项目概述二、核心功能解析2.1 实时颜色追踪2.2 智能颜色显示三、效果展示四、实现步骤详解4.1 环境配置4.

Python使用smtplib库开发一个邮件自动发送工具

《Python使用smtplib库开发一个邮件自动发送工具》在现代软件开发中,自动化邮件发送是一个非常实用的功能,无论是系统通知、营销邮件、还是日常工作报告,Python的smtplib库都能帮助我们... 目录代码实现与知识点解析1. 导入必要的库2. 配置邮件服务器参数3. 创建邮件发送类4. 实现邮件

基于Python开发一个有趣的工作时长计算器

《基于Python开发一个有趣的工作时长计算器》随着远程办公和弹性工作制的兴起,个人及团队对于工作时长的准确统计需求日益增长,本文将使用Python和PyQt5打造一个工作时长计算器,感兴趣的小伙伴可... 目录概述功能介绍界面展示php软件使用步骤说明代码详解1.窗口初始化与布局2.工作时长计算核心逻辑3

python web 开发之Flask中间件与请求处理钩子的最佳实践

《pythonweb开发之Flask中间件与请求处理钩子的最佳实践》Flask作为轻量级Web框架,提供了灵活的请求处理机制,中间件和请求钩子允许开发者在请求处理的不同阶段插入自定义逻辑,实现诸如... 目录Flask中间件与请求处理钩子完全指南1. 引言2. 请求处理生命周期概述3. 请求钩子详解3.1

如何基于Python开发一个微信自动化工具

《如何基于Python开发一个微信自动化工具》在当今数字化办公场景中,自动化工具已成为提升工作效率的利器,本文将深入剖析一个基于Python的微信自动化工具开发全过程,有需要的小伙伴可以了解下... 目录概述功能全景1. 核心功能模块2. 特色功能效果展示1. 主界面概览2. 定时任务配置3. 操作日志演示

JavaScript实战:智能密码生成器开发指南

本文通过JavaScript实战开发智能密码生成器,详解如何运用crypto.getRandomValues实现加密级随机密码生成,包含多字符组合、安全强度可视化、易混淆字符排除等企业级功能。学习密码强度检测算法与信息熵计算原理,获取可直接嵌入项目的完整代码,提升Web应用的安全开发能力 目录