痞子衡嵌入式:探讨i.MXRT下FlexSPI driver实现Flash编程时对于中断支持问题

news2024/10/4 21:28:57

  大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是i.MXRT下FlexSPI driver实现Flash编程时对于中断支持问题

  前段时间有客户在官方社区反映 i.MXRT1170 下使用官方 SDK 里 FlexSPI 驱动去擦写 Flash 时不能很好地支持全局中断。客户项目里用了两块 NOR Flash,分别挂在不同的 FlexSPI 上,一块 Flash 用于存储 XIP 代码(FlexSPI1),另一块 Flash 用于存储项目资源数据(FlexSPI2),显然这样的设计原理上是没有问题的,那为什么使能了中断会出问题呢?今天痞子衡来分析下这个问题:

  • Note: 客户测试的 SDK 版本为 2.12.1,对应的 FlexSPI driver 版本为 2.3.6

一、为什么擦写Flash时经常需要关全局中断?

  在具体分析客户问题之前,我们先来聊聊嵌入式应用里应对 NOR Flash 的擦写为何大部分情况下都是要关闭全局中断(这里假设执行代码空间与擦写操作空间在同一个 Flash 上,当然是在不同区域),这其实跟如下两个特性有关:

1.1 RWW特性(Read-While-Write)

  RWW 特性的意思是在 Flash 执行擦写命令进入 Busy 状态期间(Flash 内部状态寄存器 WIP 位变状态 1)还能否继续响应非操作区域的读访问。如果 SR[WIP] = 1 时还能够支持读访问,则该 Flash 支持 RWW,反之则不支持 RWW。

  绝大部分 Flash 都是不支持 RWW 特性的,这就是为什么 Flash 擦写操作代码本身是需要重定向到 RAM 里去执行(尤其是回读 SR[WIP] 状态的代码)。对于支持 RWW 特性的 Flash,一般是以 Block 为单位,Flash 擦写操作代码放在 BlockX 里执行,则可以操作 BlockX 以外的其它 Block 区域,且不需要做代码重定向。

  现在你应该知道对于不支持 RWW 的 Flash 为什么擦写时需要关闭全局中断了,因为无法保证中断响应相关代码全都重定向到 RAM 里了,所以干脆在 Flash 擦写期间不响应任何中断。

1.2 SCLK Stop特性

  SCLK Stop 特性的意思是在 Flash 执行写入命令接受主设备传输过来的 Page 数据期间,如果总线上 SCLK 停止(一般情况是 FlexSPI 这一端的 TXFIFO 为空或者触发空条件),则 Flash 能否也暂停接受当前 Page 数据直到 SCLK 继续输出从而继续处理剩下的 Page 数据。

  绝大部分 Flash 是不支持 SCLK Stop 特性的,因此在 MCU 端如果传输 Page 数据,需要一次性连续传输完成,一旦中途被打断,则两次不连续的 Page 数据传输可能无法得到想要的 Page 写入结果。这也是为何 Flash 写入期间我们需要关闭中断。

二、FlexSPI外设写操作设计

  关于 i.MXRT 上的 FlexSPI 外设基本情况,痞子衡有两篇旧文 《FlexSPI支持在Flash XIP原理》、《FlexSPI支持AHB方式写入Flash》,大家先读一下有个初步了解。这里痞子衡想重点说一下 FlexSPI 关于 IPG 方式写操作的设计,下图为 FlexSPI 外设的模块框图,痞子衡用绿色线标出了 IPG 方式写入的通路,这里大家可以看出其中 IP_TX_FIFO 模块起了重要的数据缓冲作用,驱动里往 FLEXSPI->TFDRx 寄存器写入的 Page 数据会先被装载进 IP_TX_FIFO 里,然后再传输出去。

  不同 i.MXRT 型号上 IP_TX_FIFO 大小不一样,目前有三种大小: 128/256/1024 Bytes。对于 QuadSPI/OctalSPI NOR Flash 来说,Page 大小一般是 256 Bytes;对于 HyperBus Flash,Page 大小一般是 512 Bytes。所以在 i.MXRT10xx 上 IP_TX_FIFO 是不足以缓冲整个 Page 的,i.MXRT117x 上可以缓冲 QuadSPI/OctalSPI NOR 类型的 Page,i.MXRT118x/5xx/6xx 上则可以缓冲全部 NOR Flash 类型的 Page。对于 Page 数据不能全部缓冲的情况,则需要一边传输一边缓冲。

型号FlexSPI外设IP TX FIFO大小
i.MXRT118x1 x dual-channel /8-bit
1 x dual-channel /16-bit
1024 Bytes
i.MXRT117x
i.MXRT116x
1 x dual-channel /8-bit
1 x dual-channel /16-bit
256 Bytes
i.MXRT106x
i.MXRT1042
2 x dual-channel /8-bit128 Bytes
i.MXRT105x1 x dual-channel /8-bit128 Bytes
i.MXRT10242 x dual-channel /8-bit128 Bytes
i.MXRT1021
i.MXRT1015
1 x dual-channel /8-bit128 Bytes
i.MXRT10111 x dual-channel /8-bit128 Bytes
i.MXRT6xx1 x dual-channel /8-bit1024 Bytes
i.MXRT5xx2 x dual-channel /8-bit1024 Bytes

  在具体装载数据进 IP_TX_FIFO 时,主要涉及如下三个 FLEXSPI 寄存器,IP_TX_FIFO 一次只能被填入 watermark level 大小的数据,想要把全部 Page 数据填进 IP_TX_FIFO,需要分多次装载。只要 FLEXSPI->INTR[IPTXWE] 标志为 0, 即代表 IP_TX_FIFO 剩余空间大于等于 watermark level,那么就可以继续装载。

FLEXSPI->IPTXFCR[TXWMRK]  -- 设置一次装载进 IP_TX_FIFO 的数据长度(即 watermark level),8 Bytes为单位
FLEXSPI->TFDRx            -- 按 watermark level 长度填入 IP_TX_FIFO 装载数据
FLEXSPI->INTR[IPTXWE]     -- 触发 IP_TX_FIFO 的一次装载

三、客户问题及FlexSPI driver写操作流程

  前面铺垫了这么多,终于来到客户遇到的 FlexSPI 驱动对于中断不支持的问题了。因为客户使用了两片 Flash,所以不存在 RWW 限制问题,那剩下的原因就跟 SCLK Stop 特性有关,即 IP_TX_FIFO 并没有缓冲全部的 Page,导致 Page 传输过程被中断打断了,然后 IP_TX_FIFO 因为缓冲数据全部发完而使 FlexSPI 模块进入了 SCLK Stop 状态。

  我们直接打开 fsl_flexspi.c 驱动文件,找到跟写操作相关的 FLEXSPI_TransferBlocking() 函数,在函数实现里可以发现,启动写传输时序的控制位 FLEXSPI->IPCMD[TRG] 是在 IP_TX_FIFO 填充动作 FLEXSPI_WriteBlocking() 函数之前被开启的,那这样的实现确实是不能够很好地支持中断的。

四、如何改进FlexSPI driver支持中断?

  知道了原因所在,改起来也很简单。如果是 QuadSPI/OctalSPI NOR Flash 类型(Page=256 Bytes),在 i.MXRT117x 上,其 IP_TX_FIFO 大小为 256 Bytes,能够缓冲全部的 Page 大小,则可以先调用 FLEXSPI_WriteBlocking() 装载全部的 Page 数据,然后再开启 FLEXSPI->IPCMD[TRG] 去触发写传输时序,这时候就不怕被中断打断了,如下代码所示。

  当然下面代码只是一个 workaround 式的实现示例,不是一个完整的解决方案,毕竟 FlexSPI 驱动要适配全部 i.MXRT 型号以及全部类型的 NOR Flash,此外还适用 NAND 型 Flash(Page 一般是 2KB),这时候需要根据情况拆分调用多次 FLEXSPI_WriteBlocking() 函数(不管怎样要保证启动写传输时序前,把 IP_TX_FIFO 先装满)。

status_t FLEXSPI_TransferBlocking(FLEXSPI_Type *base, flexspi_transfer_t *xfer)
{
    // 代码略去

    /* Start Transfer. */
    if ((xfer->cmdType == kFLEXSPI_Write) || (xfer->cmdType == kFLEXSPI_Config))
    {
        result = FLEXSPI_WriteBlocking(base, xfer->data, xfer->dataSize);
        base->IPCMD |= FLEXSPI_IPCMD_TRG_MASK;
    }
    else if (xfer->cmdType == kFLEXSPI_Read)
    {
        base->IPCMD |= FLEXSPI_IPCMD_TRG_MASK;
        result = FLEXSPI_ReadBlocking(base, xfer->data, xfer->dataSize);
    }
    else
    {
        base->IPCMD |= FLEXSPI_IPCMD_TRG_MASK;
    }

    // 代码略去
}

  至此,i.MXRT下FlexSPI driver实现Flash编程时对于中断支持问题痞子衡便介绍完毕了,掌声在哪里~~~

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/136591.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

内核解读之内存管理(2)内存管理三级架构之内存结点node

文章目录0、概述1、内存节点node0、概述 结合NUMA的架构,Linux抽象出了三级内存管理架构:内存节点node、内存区域zone和物理页框page。 在NUMA模型中,每个CPU都有自己的本地内存节点(memory node),而且还…

qq录制视频保存到哪了?如何更改qq录屏存储位置

一、查看qq录制视频保存位置如果有录制视频的需求,相信大部分人都是使用qq自带的录屏功能来录制视频。那qq录屏后的视频在哪里去找?今天就给大家分享如何查看qq录制完的视频保存位置操作方法:第一步:电脑上登录qq,在qq…

Cadence PCB仿真 使用Allegro PCB SI为BRD文件创建通用型IBIS模型的方法图文教程

⏪《上一篇》   🏡《总目录》   ⏩《下一篇》 1,概述 本文简单介绍使用Allegro PCB SI软件为BRD PCB设计文件中的元器件创建IBIS模型的方法。 2,创建方法 第1步:确定打开PCB文件的软件是 Allegro PCB SI 如果不是Allegro PCB SI,可执行File→Change Editor…更换软…

尚医通-查询所有子节点-前端整合-更新医院状态(二十三)

目录: (1)医院管理-查询所有子节点接口 (2)医院列表-前端整合 (3)更新医院上线状态-功能实现 (1)医院管理-查询所有子节点接口 先做一个省的查询 在DictContrlller…

数据可视化大屏百度地图GPS轨迹位置感知状态开发实战案例解析(包含缩放控件、点线覆盖物、弹窗、标注图标分类功能)

系列文章目录 1.数据可视化大屏应急管理综合指挥调度系统完整案例详解(PHP-API、Echarts、百度地图) 2.数据可视化大屏百度地图API开发:停车场分布标注和检索静态版 3.百度地图高级开发:map.getDistance计算多点之间的距离并输入…

C语言及算法设计课程实验三:最简单的C程序设计——顺序程序设计(二)

C语言及算法设计课程实验三:最简单的C程序设计——顺序程序设计(二)一、实验目的二、 实验内容2.2、实验内容2:求圆周长、圆面积、圆球表面积、圆球体积、圆柱体积三、 实验步骤3.2、顺序程序设计实验题目2:求圆周长、…

CTF文件隐写总结之图片

1.1 Fastjson反序列化 代码审计 本项目引入的Fastjson版本为1.2.58,该版本存在反序列化漏洞。 已确定了Fastjson版本存在问题,进一步寻找触发Fastjson的漏洞点。 我们关注两个函数JSON.parse()和JSON.parseObject(),并且执行函数内参数用户可控 Edi…

【博客系统】后台设计

文章目录博客系统(使用模板技术)准备工作数据库设计表设计文章表用户表完整SQL封装数据库操作代码创建DBUtil创建Blog类和User类创建BlogDao类和UserDao类实现insert实现selectAll实现selectOne实现delete实现selectByName实现selectByUserId验证数据库代…

Python 操作 MySQL 之 pysql 与 SQLAchemy

一、pymsql pymsql 是 Python 中操作 MySQL 的原生模块,其使用方法和 MySQL 的SQL语句几乎相同 1、下载安装 pip3 install pymysql 2、执行SQL 执行 SQL 语句的基本语法: 需要注意的是:创建链接后,都由游标来进行与数据库的…

CATCTF wp

文章目录ez_jsCat_Jumpmiao~CatCatPeekabooMeowMeowCatchCatCatFlagNepnep 祝你新年快乐啦!ez_js f12搜索score,修改超过分数1即可获得flag 然后获得flag地址 访问即可 Cat_Jump 仿真玩半天不知道怎么解,最后直接搜关键词出的 挺可惜…

唱歌就能画一幅图像? #whisper-to-stable-diffusion

现在热门的不仅是多模态的文本图像生成,前阵子,OpenAI 发布了一个自动语音识别系统 Whispe 。在处理口音、背景噪声以及技术术语方面,Whisper 几乎达到了人类的水准。那么将 Whisper 与 Stable Diffusion 结合,可以直接完成语音生…

回顾 OpenMLDB 2022 之旅 | 开源之路,行将致远

2022年初,OpenMLDB 尚且懵懂稚嫩。彼时的我们刚刚走过开源道路上的第一个秋天,还没有结出丰硕的果实。前进着,期待着,2022的一切徐徐展开: 请旋转手机 和 OpenMLDB 共同回忆 2022 之旅 2022年末,OpenMLDB …

必看!.NET 7 在网络领域的四大更新

最新的 .NET 7 现已发布,我们想介绍一下其在网络领域所做的一些有趣的更改和添加。这篇文章我们将讨论 .NET 7 在 HTTP 空间、新 QUIC API、网络安全和 WebSockets 方面的变化。 HTTP 改进了对连接尝试失败的处理 在 .NET 6 之前的版本中,如果连接池中…

云计算运营—04 FusionSphere OpenStack 6.5方案介绍

FusionSphere OpenStack 6.5方案介绍 OpenStack 系统架构 OpenStack是什么 OpenStack是目前最流行的开源云操作系统: 资源抽象 OpenStack将各类硬件资源,通过虚拟化与软件定义的方式,抽象成资源池 资源分配与负载调度 OpenStack根据管理员…

Ardupilot EKF3核心算法《状态量的协方差矩阵推导》

目录 文章目录 目录摘要1.协方差矩阵推导2.关于 F的计算2.1 计算F的前四维关于四元数的状态方程2.2 计算F 的5-10维关于速度和位置的状态方程3.其他协方差的传播3.1 关于角增量偏差的协方差传播3.2 关于速度增量偏差的协方差传播3.3 关于地理坐标系地磁磁场矢量的协方差传播3.4…

【Vue基本指令】一.什么是Vue;二.Vue开发的方式;三.Vue的基本指令(重点)

目录 一.什么是Vue 1.前端技术的发展(html、CSS、JavaScript) (1)JQuery:是对JavaScript进行了封装,使得操作DOM、事件处理、动画处理、Ajax交互变得非常简洁、方便。是JavaScript的库。 (&a…

《云原生》一文搞懂RocketMQ队列概述

目录 序 概念简述 一、客户端概念 1. Topic-主题 2.ConsumerGroup(消费者组) 概念一览图 二、消息传输模型 三、实践应用 1.配置文件 2.生产者 3.消费者 配置一览图 最后的话 序 接上一篇对rabbitMQ队列进行了梳理 《一文搞懂rabbitMQ消息…

shell技术

退出状态码 Shell 中运行的命令会使用0-255之间的整数值,作为退出状态码,并以此来告知shell该命令执行的状态。 通常情况下,约定0代表命令成功结束,非0代表程序非正常退出。 假如没有指定返回值,那么会用脚本的最后一个命令的执…

华为路由器配置笔记

路由器(Router),是连接因特网中各局域网、广域网的设备,它会根据信道的情况自动选择和设定路由,以最佳路径,按前后顺序发送信号,路由器工作在网络层,用来跨网段通信,路由器具有判断网络地址和选择IP路径的功能,它能在多网络互联环境中,建立灵活的连接,可用完全不同的数据分组和…

巧用数据分析表达式,让数据指标创建更简单

实现数据业务一体化的指标分析 从零售系统进化史get 数据统计的需求变更 零售系统需要的数据统计需求 V1.0 只需要获取当日累计的销售额,于是店老板就用 Excel或者纸质的表格创建了一个表,表中包含销售的日期时间,销售的产品,销…