草庐IT

痞子衡嵌入式:RT-MFB - 一种灵活的i.MXRT下多串行NOR Flash型号选择的量产方案

<font>痞子衡嵌入式 2023-03-28 原文

  大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是一种灵活的i.MXRT下多串行NOR Flash型号选择的量产方案

  对于以 i.MXRT 这类没有内部 NVM (Non-Volatile Memory) 的 MCU 为主控的项目来说,为其选配一颗 NVM 作为代码存储器是头等大事,而串行 NOR Flash 是最常见的 NVM 选择。串行 NOR Flash 要能被 i.MXRT 正常启动,其固定偏移处(0x0/0x400)一般要求放置一个配套启动头(FDCB),系统上电 BootROM 会用 30MHz 1bit SPI SDR 时序模式去读取这个启动头来获取当前 Flash 的相关属性(主要是用户设定的时序模式)从而进一步配置片内 FlexSPI 模块以指定的时序模式去启动 Flash 里的固件应用程序。

  到了项目量产阶段,尤其是出货量大的消费类产品,我们往往不会仅选择某一 Flash 厂商产品(价格因素,供货因素等),这时候就不得不考虑一个问题,如果选择的是特性不完全一致的两颗 Flash,那么下载进 Flash 的固件应用程序能不能保持一样(其实主要就是下图中的 FDCB1/2 差异问题怎么解决)?今天痞子衡就跟大家讨论一下这个问题:

  • Note:本文主要针对的是普通四线 QuadSPI / 八线 OctalSPI 类型的串行 NOR Flash。

一、影响多Flash型号量产的因素

  我们知道导致下载进不同 Flash 里的固件程序有差异的主要原因是 i.MXRT 配套启动头(FDCB),这个 FDCB 描述了 Flash 的基本信息(Device 容量、速度、读模式命令等),Flash 属性不同,FDCB 也会跟着变化,所以我们先来介绍下有哪些可能的因素会影响 FDCB 内容:

1.1 QE bit位置

  首先是 QE bit 使能操作的差异。很多 Flash 出厂时 QE bit 并没有被使能,量产过程中烧录器有时候也未必去使能 QE bit(一线模式编程相比 Multi I/O 模式编程对量产时间影响不大),这种情况在 FDCB 里需要加上使能 QE bit 操作,而 QE bit 在 Flash 内部寄存器里的定义以及写入命令有好几种,详见痞子衡旧文《影响下载/启动的常见因素之QE bit》

1.2 READ命令中Dummy Cycles数

  使能 QE bit 是为了能让 Flash 工作在 Multi I/O Fast READ 模式,但这时候 READ 时序里会有 Dummy Cycles 周期(即 Flash 接收到主设备发来的读命令从而准备相应数据的反应时间)。Flash 的不同工作频率对应的最小 Dummy Cycles 不同,不同厂商关于 Dummy Cycles 数要求也不同,此外如果 Flash 里的默认 Dummy Cycle 不是对应最高工作频率的话,要想让 Flash 工作在最高频率还需要额外设置 Flash 相应寄存器来修改 Dummy Cycle(这里的设置方法也不同),这些 Dummy Cycle 设定都要体现在 FDCB 里,详见痞子衡旧文《调整Flash工作频率也需同步设Dummy Cycle》

1.3 地址3B/4B模式切换

  对于不高于 16MB 容量的 Flash,在 READ 时序里一般使用三字节地址就行了,但是超过 16MB 的 Flash ,对其访问就会涉及三字节地址以及四字节地址选择问题,因此避不可免地要考虑 Flash 地址模式切换问题,不同厂商的地址模式设计以及切换操作也略有不同,FDCB 里同样要考虑这些,详见痞子衡旧文 《16MB以上NOR Flash使用注意》

1.4 QPI/OPI模式进入

  如果为了追求极限执行性能,一般还会考虑将 Flash 从 SPI 模式切换到 QPI/OPI 模式,这里不同厂商的模式切换设计也可能略有不同,FDCB 也要负责这个工作,详见痞子衡旧文《使能串行NOR Flash的QPI/OPI模式》

1.5 DTR/Continuous read性能模式

  当然还有一些其它关于 Flash 性能模式考量,比如 DTR 模式、Continuous read 模式,要想使能这些模式也都需要在 FDCB 里做文章,详见痞子衡旧文 《使能串行NOR Flash的DTR模式》《使能串行NOR Flash的Continuous read模式》

二、多Flash型号量产的解决方案

  上一节介绍了有很多因素会导致 FDCB 不同,这些因素都是多 Flash 型号量产路上的拦路虎,我们有什么方法能规避这些因素差异带来的问题呢?主要有如下两个方案:

2.1 BootROM自识别方案

  第一个方案是利用 i.MXRT 芯片 BootROM 里的功能,详见痞子衡旧文 《自识别特性(Auto Probe)可以无需FDCB也能从NOR Flash启动》。这个特性可以让我们不用提供 FDCB,芯片也能正常从 Flash 里启动固件应用程序,这样也就自然不存在量产过程中不同 Flash 里固件差异问题。但是这个方案也有几个明显的缺点:

  • 缺点一:Auto Probe 特性在 i.MXRT1010/1020/1050 上不可用,仅在 i.MXRT1060/1170/500/600 上可以用。
  • 缺点二:Auto Probe 特性对于不同 Flash 的支持(尤其是 OctalSPI Flash)可能需要通过烧写 i.MXRT 芯片 OTP 来实现,这样实际上是把 FDCB 差异转化到 OTP 差异上了。
  • 缺点三:Auto Probe 特性仅能处理基本的 FDCB 差异(比如 QE,比如 Dummy Cycle),但是一些性能模式相关的差异不能很好地处理,拓展性不足。

2.2 一线模式FDCB启动+二级Configurer程序

  第二个方案主要是为了解决方案一里的全部缺点,即使用通用的一线低速模式的 FDCB 启动头给 BootROM 去读取启动,然后再设计一个二级的 Configurer 程序(被 BootROM 启动的代码),在这个 Configurer 程序里去做 Flash 差异化的相关事情并将 FlexSPI 模块配置到指定时序模式,最后再由这个 Configurer 程序去启动固件应用程序。

  这里的 Configurer 程序设计是关键,而其中最核心的是如何识别当前 Flash 型号,这里要感谢 JEDEC 组织,目前几乎全部主流 Flash 都支持一线模式下 Read JEDEC 命令(0x9F),返回的 Manufacturer ID 就是每个 Flash 厂商向 JEDEC 组织申请的识别码,然后 Memory Type 是各厂商自己定义的型号系列分类。Configurer 程序结合这两个参数就可以识别当前 Flash 具体型号,底下就是做不同的代码分支去处理不同的 Flash 配置即可。

  二级 Configurer 程序说起来很简单,其实具体设计起来还是有很多细节要考量的(比如 FlexSPI 多次配置中系统时钟切换问题、应用程序跳转等),因此痞子衡开源了这个项目(RT-MFB),并且会长期维护下去,希望将来能支持尽可能多的 Flash 型号。第一版是以 MIMXRT595-EVK 上的两颗 Flash 为原型(IS25WP064A / MX25UW51345G)来做的。

  至此,一种灵活的i.MXRT下多串行NOR Flash型号选择的量产方案痞子衡便介绍完毕了,掌声在哪里~~~

欢迎订阅

文章会同时发布到我的 博客园主页CSDN主页知乎主页微信公众号 平台上。

微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

有关痞子衡嵌入式:RT-MFB - 一种灵活的i.MXRT下多串行NOR Flash型号选择的量产方案的更多相关文章

  1. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  2. ruby - Rails 3 的 RGB 颜色选择器 - 2

    状态:我正在构建一个应用程序,其中需要一个可供用户选择颜色的字段,该字段将包含RGB颜色代码字符串。我已经测试了一个看起来很漂亮但效果不佳的。它是“挑剔的颜色”,并托管在此存储库中:https://github.com/Astorsoft/picky-color.在这里我打开一个关于它的一些问题的问题。问题:请建议我在Rails3应用程序中使用一些颜色选择器。 最佳答案 也许页面上的列表jQueryUIDevelopment:ColorPicker为您提供开箱即用的产品。原因是jQuery现在包含在Rails3应用程序中,因此使用基

  3. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  4. ruby-on-rails - Rails 单选按钮 - 模型中多列的一种选择 - 2

    我希望用户从一个模型的三个选项中选择一个。即我有一个模型视频,可以被评为正面/负面/未知目前我有三列bool值(pos/neg/unknown)。这是处理这种情况的最佳方式吗?为此,表单应该是什么样的?目前我有类似的东西但显然它允许多项选择,而我试图将它限制为只有一个..怎么办? 最佳答案 如果要使用字符串列,让我们说rating。然后在你的表单中:#...#...它只允许一个选择编辑完全相同但使用radio_button_tag: 关于ruby-on-rails-Rails单选按钮-模

  5. ruby-on-rails - CarrierWave - PDF - 只选择第一页 - 2

    我的Rails应用程序中安装了carrierwave。但是,当用户上传多页pdf时,我只希望应用程序获取文档中的第一页并将其转换为jpeg。这可能吗?用什么命令?这是我的uploader。#encoding:utf-8classImageUploader[200,300]##defscale(width,height)##dosomething#end#Createdifferentversionsofyouruploadedfiles:version:thumbdoprocess:resize_to_fill=>[150,210]process:convert=>:jpgdefful

  6. ruby-on-rails - ActiveAdmin 自定义选择过滤器下拉名称 - 2

    对于用户模型,我有一个过滤器来检查用户的预订状态,该状态由整数值(0、1或2)表示。UserActiveAdmin索引页上的过滤器是通过以下代码实现的:filter:booking_status,as::select然而,这会导致下拉选项为0、1或2。当管理员用户从下拉列表中选择它们时,我更愿意自己将它们命名为“未完成”、“待定”和“已确认”之类的名称。有没有办法在不改变booking_status在模型中的表示方式的情况下做到这一点? 最佳答案 假设booking_status是模型中的枚举字段,您可以使用:过滤器:booking

  7. Ruby 守护进程和 JRuby - 备选方案 - 2

    我有一个应用程序正在从Ruby迁移到JRuby(由于需要通过Java提供更好的Web服务安全支持)。我使用的gem之一是daemons创建后台作业。问题在于它使用fork+exec来创建后台进程,但这对JRuby来说是禁忌。那么-是否有用于创建后台作业的替代gem/wrapper?我目前的想法是只从shell脚本调用rake并让rake任务永远运行......提前致谢,克里斯。更新我们目前正在使用几个与Java线程相关的包装器,即https://github.com/jmettraux/rufus-scheduler和https://github.com/philostler/acts

  8. ruby-on-rails - 多次选择一个随机数,但绝不会两次选择相同的随机数 - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:HowdoIgeneratealistofnuniquerandomnumbersinRuby?我想做的事:Random.rand(0..10).timesdoputsRandom.rand(0..10)end但如果随机数已经显示过,则无法再次显示。如何最轻松地做到这一点?

  9. ruby - mixin方法名冲突时如何选择调用方法? - 2

    当你在类中包含方法名冲突的模块时,它会使用类定义的方法。有没有办法选择我想运行的?moduleBdefself.hello"helloB"endendclassAincludeBdefself.hello"helloA"endendA.hello#=>thisprints"helloA",whatifIwant"helloB"? 最佳答案 Ben,当你在Ruby中调用一个方法(比如hello)时,会发生以下情况:如果接收者的特征类有一个名为hello的方法,它将被调用。如果不是:如果接收者的类有一个名为hello的实例方法,它将被调

  10. ruby - 更快的 n 选择 k 来组合数组 ruby - 2

    在尝试解决“网格上的路径”问题时,我编写了代码defpaths(n,k)p=(1..n+k).to_ap.combination(n).to_a.sizeend代码工作正常,例如ifn==8andk==2代码返回45,这是正确的路径数。但是,当使用较大的数字时,代码非常慢,我正在努力想出如何加快这个过程。 最佳答案 与其构建组合数组只是为了计算它,不如编写function定义组合的数量。我敢肯定还有包含此功能和许多其他组合函数的gem。请注意,我使用的是gemDistribution对于Math.factorial方法,但这是另一种

随机推荐