0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

擦写Flash时一定不能开启系统全局中断吗?

痞子衡嵌入式 来源:痞子衡嵌入式 2023-02-10 14:27 次阅读

大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是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。

85961c98-a879-11ed-bfe3-dac502259ad0.png

绝大部分 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 写入期间我们需要关闭中断。

85afacd0-a879-11ed-bfe3-dac502259ad0.png

二、FlexSPI外设写操作设计

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

85b9d016-a879-11ed-bfe3-dac502259ad0.png

不同 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.MXRT118x 1 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-bit 128 Bytes
i.MXRT105x 1 x dual-channel /8-bit 128 Bytes
i.MXRT1024 2 x dual-channel /8-bit 128 Bytes
i.MXRT1021
i.MXRT1015
1 x dual-channel /8-bit 128 Bytes
i.MXRT1011 1 x dual-channel /8-bit 128 Bytes
i.MXRT6xx 1 x dual-channel /8-bit 1024 Bytes
i.MXRT5xx 2 x dual-channel /8-bit 1024 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 的一次装载
85c79b60-a879-11ed-bfe3-dac502259ad0.png

三、客户问题及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() 函数之前被开启的,那这样的实现确实是不能够很好地支持中断的。

85d164c4-a879-11ed-bfe3-dac502259ad0.png

四、如何改进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_tFLEXSPI_TransferBlocking(FLEXSPI_Type*base,flexspi_transfer_t*xfer)
{
//代码略去

/*StartTransfer.*/
if((xfer->cmdType==kFLEXSPI_Write)||(xfer->cmdType==kFLEXSPI_Config))
{
result=FLEXSPI_WriteBlocking(base,xfer->data,xfer->dataSize);
base->IPCMD|=FLEXSPI_IPCMD_TRG_MASK;
}
elseif(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编程时对于中断支持问题痞子衡便介绍完毕了,掌声在哪里~~~

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FlaSh
    +关注

    关注

    10

    文章

    1551

    浏览量

    146699
  • 存储
    +关注

    关注

    12

    文章

    3863

    浏览量

    84674
  • 编程
    +关注

    关注

    88

    文章

    3441

    浏览量

    92415
  • 中断
    +关注

    关注

    5

    文章

    884

    浏览量

    41029
  • SDK
    SDK
    +关注

    关注

    3

    文章

    966

    浏览量

    44719

原文标题:擦写Flash时一定不能开启系统全局中断吗?

文章出处:【微信号:pzh_mcu,微信公众号:痞子衡嵌入式】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    华大单片机如何开启或关闭全局中断

    华大单片机如何开启或关闭全局中断
    发表于 03-25 13:38

    如何提高MSP430G系列单片机的Flash擦写寿命?

    Flash 与EEPROM 在擦写寿命上存在一定差距,所以在实际应用中,这种应用方式并不能够满足所有客户的需求。本应用笔记介绍了使用代码区域Flas
    发表于 09-23 08:31

    MSP430G系列单片机的Flash擦写寿命怎么提高?

    Flash,可用于存储非易失性数据,但是由于 Flash 与 EEPROM 在擦写寿命上存在一定差距,所以在实际应用中,这种应用方式并不能
    发表于 10-18 09:00

    开启WWDG 片内flash写异常

    擦写过程中,中断程序是无法执行的,擦写过程触发喂狗中断失败,导致系统复位。如果flash
    发表于 02-22 19:33

    为什么在UCOSIII外部中断服务函数中不能开启已经创建的软件定时器?

    个外部中断服务函数中,开启个已经创建的软件定时器,会开启不成功返回的错误码:OS_ERR_TMR_ISR错误码说明:if the ca
    发表于 06-02 14:13

    FLASH擦写时间

    STM32f0301. FLASH擦写时间2. FLASH擦写次数和数据保存年限只能擦写1000次,有点少。非必要,不要
    发表于 08-05 06:46

    如何对HCS12单片机的FLASH进行擦写

    由于在我的项目中,需要实现对HCS12单片机的FLASH进行擦写,所以难免会遇到对全局地址的操作,因为对FLASH擦写操作是必须使用
    发表于 03-02 06:20

    stm8中断不能随意关闭或使能全局中断

    调试STM8遇到的问题在调试STM8L051的单片机时,使用的多个外部中断,当进入某外部中断中断服务函数后,原来是想进入这个中断时,不再响应其他
    发表于 11-23 17:51 10次下载
    stm8<b class='flag-5'>中断</b>中<b class='flag-5'>不能</b>随意关闭或使能<b class='flag-5'>全局</b><b class='flag-5'>中断</b>

    STM32F0F1F4内部flash擦写时间和寿命

    STM32f0301. FLASH擦写时间2. FLASH擦写次数和数据保存年限只能擦写1000次,有点少。非必要,不要
    发表于 12-01 20:36 14次下载
    STM32F0F1F4内部<b class='flag-5'>flash</b><b class='flag-5'>擦写</b>时间和寿命

    APM32F103RCT6_Flash_擦写失败

    APM32F103RCT6_Flash_擦写失败
    发表于 11-09 21:03 0次下载
    APM32F103RCT6_<b class='flag-5'>Flash</b>_<b class='flag-5'>擦写</b>失败

    I.MXRT FreeRTOS环境下擦写外部Flash

    在FreeRTOS环境下,如果外部擦写 Flash,禁用指令缓存以避免在多个任务中使用来自Flash 的分支预测和应用程序同步操作 Flash的缓存预加载指令。因为代码是XIP,所以向
    的头像 发表于 01-30 09:18 1364次阅读

    探讨i.MX RT下FlexSPI driver实现Flash编程时对于中断支持问题

    前段时间有客户在官方社区反映i.MX RT1170下,使用官方SDK里FlexSPI驱动去擦写Flash不能很好地支持全局中断。 客户项目
    的头像 发表于 02-06 15:09 759次阅读

    什么是全局中断

    什么是全局中断全局中断使能位控制着“所有”中断,它如果关闭的话会屏蔽其它中断,有人经常关闭它,
    的头像 发表于 06-14 18:25 1846次阅读

    语音芯片的型号有哪些?为什么强烈推荐使用flash型可擦写

    语音芯片的型号有哪些?为什么强烈推荐使用flash型可擦写的芯片。这里我们简单描述一下如下常见类容: 1、他们都有什么特点?以及发展的历程简介 2、常见的语音芯片有哪些? 3、为什么推荐使用flash型可以重复
    的头像 发表于 08-14 11:05 449次阅读
    语音芯片的型号有哪些?为什么强烈推荐使用<b class='flag-5'>flash</b>型可<b class='flag-5'>擦写</b>的

    什么是可重复擦写Flash型)语音芯片?

    什么是可重复擦写Flash型)语音芯片?可重复擦写Flash型)语音芯片是一种嵌入式语音存储解决方案,采用了Flash存储技术,使得语音
    的头像 发表于 12-14 10:08 237次阅读
    什么是可重复<b class='flag-5'>擦写</b>(<b class='flag-5'>Flash</b>型)语音芯片?