欢迎访问欧博亚洲(Allbet Game)!

首页科技正文

痞子衡嵌入式:16MB以上NOR Flash使用不当可能会造成软复位后i.MXRT无法正常启动

admin2020-07-2543

  人人好,我是痞子衡,是正经搞手艺的痞子。今天痞子衡给人人分享的是i.MXRT上使用16MB以上NOR Flash软复位无法正常启动问题的剖析解决履历

  痞子衡这几天在支持一个i.MXRT1050客户项目,客户遇到了软复位无法从32MB NOR Flash重新启动的问题。这个客户是做医疗装备的,已经基于i.MXRT做出一款乐成的产物了,以是客户实在有厚实的i.MXRT使用履历。现在调试的项目是客户的第二款产物,这个软复位无法启动问题已经困扰他们良久,但问题究竟不是稀奇紧要,不影响他们开发进度,以是拖延至今。这次客户趁着出差苏州加入劳特巴赫TRACE32调试器培训机遇,让痞子衡现场帮他们定位问题,经由一番调试和剖析,痞子衡终于乐成地解决了问题,特此将问题解决的全过程记录下来,供人人参考。

一、问题形貌

  在形貌问题前,首先给人人先容下客户的项目设计,底下是客户硬件简图。客户选用的i.MXRT1052作为主控,挂载了两个QSPI Flash,FlexSPI接口毗邻的32MB Flash用于启动和存放静态图片资源(只需要读即可),LPSPI接口毗邻的1MB Flash用于存放运行时状态数据(需要读写),此外板子毗邻了一个显示屏,以是还挂载一片SDRAM用于显示缓存,实在SDRAM除了显示缓存功效之外,还用于执行App(QSPI Flash里的App会自加载到SDRAM执行)。

  有需要重点先容下QSPI Flash启动设计细节,客户选用的Flash型号是ISSI的IS25WP256D,这是一款容量256Mb的四线串行Flash。客户启动流程设计的挺庞大,芯片上电之后,BootROM卖力从Flash中XIP启动L2 loader程序,L2 loader运行后从Flash中选出最新的一份Boot程序(A/B是双备份),将其加载到SDRAM中执行。Boot程序运行后做一些系统初始化事情,然后直接跳转到App中执行(XIP),App才是最终的客户应用程序,这个应用程序会完成往SDRAM的自拷贝以及跳转执行。

  客户的App现实巨细靠近5MB,对于嵌入式程序来说,这个体量相当大了,这也是为什么客户需要借助专业的劳特巴赫TRACE32调试器来剖析定位程序逻辑设计问题。从下图还可以看到从0x60800000最先,Flash中还存放了一些静态图片资源,客户项目有显示屏,Flash里放一些牢固图片数据利便UI切换。

  先容完客户的项目设计,现在形貌客户的软复位无法重新启动问题。实在这个问题征象很简朴,就是每次重新上电启动,程序都是可以正常运行的,然则一旦使用按键软复位(ONOFF Reset),系统就会有一定概率起不来(概率很大,很容易复现),调试器连上去会发现PC停留在BootROM里,这意味着此时BootROM没能正常启动L2 loader。

二、问题剖析

  让我们来剖析一下问题,这个问题要从两方面来思量:一、板子上芯片的POR和软复位的区别;二、软复位无法启动是概率性的,因此痞子衡想到了如下四处疑点:

  1. 两种复位下主芯片内部非易失寄存器状态的区别是否对BootROM运行产生了影响?
  2. 两种复位下主芯片内FlexSPI这个模块状态是否有区别?
  3. 两种复位下外挂Flash芯片状态是否有区别?
  4. 客户App代码里是否有某种操作导致了概率性问题的发生?

  由于每次都是软复位重新启动出问题,以是客户板级供电设计不在疑点局限内。虽然问题都表现在BootROM没法加载L2 loader执行,但BootROM自己缺陷也不是我们主要思量的偏向,究竟BootROM是固化在芯片内部的,可靠性有一定保证。我们首先要把疑点放在概率性以及两种复位的差异上,那么我们从那里最先着手测试?

  痞子衡想的是先从第4个疑点最先下手,缘故原由是前3个疑点本质上都由第4个疑点引起的,客户代码的执行可能会改主芯片内部非易失性寄存器,也同时会操作FlexSPI模块去接见外部Flash,它是问题的引爆点。

三、最先测试

3.1 对比非易失性寄存器

  i.MXRT内部有一些非易失性寄存器(好比IOMUXC_GPR寄存器组,SRC寄存器等),这些寄存器仅在POR时才会被复位,而通俗软复位是不会改变其状态的。客户App代码近5MB,若是是去肉眼排查是否操作了非易失性寄存器,难免有疏漏。最简朴的方式就是在正常启动和非正常启动时分别用调试器将这些寄存器的值所有保留下来,然后使用文本工具去对比。经测试,两种情况下,这些非易失性寄存器并无区别,因此这个疑点被清扫。

3.2 逐步精简App代码

  现在我们最先逐步精简App代码,由于客户代码涉及秘密,以是精简的事情由客户来做,固然客户也最清晰若何去精简他们自己的代码。一番测试下来,我们发现App代码里只要不去读存在Flash里的静态图片数据,就不会存在软复位无法重新启动问题,看起来我们已经找到线索了。

四、缘故原由剖析

  问题出在App代码里读存在Flash里的静态图片数据,这意味着App里可能用了特殊的读Flash方式改变了Flash状态,而且这个Flash状态是非易失性的。谜团靠近解开了,痞子衡让客户宣布了他们的L2 loader里的FDCB设置头以及App里的读Flash图片的代码实现:

4.1 L2 loader的FDCB

  先来看客户的FDCB启动头,客户仅让BootROM设置Flash事情于50MHz,而且是1bit SDR Fast Read(下令是0x0B),这是尺度3字节地址读,因此设置乐成后通过AHB总线最大可接见16MB以内的Flash空间。由于客户的L2 loader很小,且存储在Flash的起始地址,以是这样的设置对于启动而言没有问题。

痞子衡嵌入式:16MB以上NOR Flash使用不当可能会造成软复位后i.MXRT无法正常启动 第1张

4.2 App读Flash实现

  再来看客户实现的读Flash函数BigCapRead(),凭据前面的先容,静态图片数据是从0x60800000处最先存储的,因此0x60800000 - 0x60FFFFFF局限内的8MB数据是可以直接AHB读,然则0x61000000地址之后的数据在上述BootROM的设置下无法直接接见,这也是为什么客户写了BigCapRead()函数,这个函数会凭据传入的地址局限来判断数据是在低16MB空间照样高16MB空间,然后对地址空间做了一个切换。

#define FLASH_BIG_CAP_SIZE (0x1000000)

static status_t flexspi_nor_select_segment(uint32_t base, uint8_t seg)
{
    qspi_transfer_t flashXfer;
    status_t status = Success;
    uint32_t writeValue = 0x00;
    uint32_t readValue = 0x00;

    flexspi_nor_write_enable(base, 0, true);

    flexspi_nor_read_volatilebankaddr_reg(base, &readValue);
    if ((readValue & 0x01) == (seg & 0x1))
    {
        return Success;
    }

    writeValue = seg & 0x1;
    flexspi_nor_write_volatilebankaddr_reg(base, writeValue);

    flexspi_nor_read_volatilebankaddr_reg(base, &readValue);
    if (readValue != writeValue)
    {
        return Failure;
    }

    flexspi_nor_wait_bus_busy(base);
    return Success;
}

static UINT32 BigCapRead(struct flash_dev* dev, UINT32 start_addr, UCHAR *buffer, UINT32 size)
{
    UINT32 tempLen = 0;
    UINT32 result = 0;
    if (start_addr >= FLASH_BIG_CAP_SIZE)
    {
        flexspi_nor_select_segment(dev->base, 1);
        start_addr = start_addr - FLASH_BIG_CAP_SIZE;
        result = Read(dev, start_addr, buffer, size);
    }
    else
    {
        if (start_addr + size < FLASH_BIG_CAP_SIZE)
        {
            flexspi_nor_select_segment(dev->base, 0);
            result = Read(dev, start_addr, buffer, size);
        }
        else
        {
            tempLen = FLASH_BIG_CAP_SIZE - start_addr;
            flexspi_nor_select_segment(dev->base, 0);
            result = Read(dev, start_addr, buffer, tempLen);
            flexspi_nor_select_segment(dev->base, 1);
            result = Read(dev, 0, buffer + tempLen, size - tempLen);
        }
    }
    return result;
}

4.3 关于Flash的3/4字节地址

  对于16MB以上空间的Flash,总会面临3/4字节地址接见的问题,JESD216划定了3/4字节地址接见尺度下令,对于3字节地址Fast Read,其下令是FRD(0x0B);而对于四字节地址Fast Read,其下令是4FRD(0x0C)。对于一个32MB的Flash,若是仅需要接见低16MB空间,可以使用FRD;若是需要接见高16MB空间,则需要使用4FRD。

痞子衡嵌入式:16MB以上NOR Flash使用不当可能会造成软复位后i.MXRT无法正常启动 第2张

  4FRD相比FRD多传输了一字节地址,对于地址延续的大块数据接见,这个1字节地址影响不太,然则若是是执行代码或者非延续数据接见,4FRD相比FRD照样有用率上的降低的,对于这个问题,差别的厂家提供了差别的解决方案。

  客户选用的这款Flash来自ISSI,ISSI的解决方案是在Flash内部增添一个Bank Address Register,其bit0用于实时切换低Bank和高Bank(而且这个位是非易失性的,仅POR才会复位,引脚reset无法复位!),当bit0值为0时,FRD下令接见的是低16MB空间,而bit0置1后,FRD下令此时现实接见的是高16MB空间(从AHB地址上看不出这个转变)。

痞子衡嵌入式:16MB以上NOR Flash使用不当可能会造成软复位后i.MXRT无法正常启动 第3张

痞子衡嵌入式:16MB以上NOR Flash使用不当可能会造成软复位后i.MXRT无法正常启动 第4张

4.4 解决方案

  看到这,这个软复位无法重启问题真相大白了,是由于这颗Flash里的内部非易失寄存器BAR[0]的操作导致的,若是软复位时间点恰幸亏App读了高16MB空间(Bank1)里的数据之后,此时Bank发生了切换,软复位后BootROM去启动时无法读到存在低16MB空间(Bank0)的有用的L2 loader。若是软复位时间点发生在App正在读低16MB空间的数据,那下次照样可以正常启动,这就是概率性启动失败的缘故原由。

  缘故原由观察清晰了,问题解决方式就很简朴了,将L2 loader里的FDCB头用4FRD取代FRD,这样BootROM设置完成之后,可以直接AHB读所有的32MB空间,不需要切换Bank,因此App里的BigCapRead()函数里的Bank切换操作可以删掉。

  这个履历也告诉了我们,当使用16MB以上Flash作为启动装备时,一定要小心处理好3/4字节地址接见问题,否则就可能泛起启动问题。

  至此,i.MXRT上使用16MB以上NOR Flash软复位无法正常启动问题的剖析解决履历痞子衡便先容完毕了,掌声在那里~~~

迎接订阅

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

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

痞子衡嵌入式:16MB以上NOR Flash使用不当可能会造成软复位后i.MXRT无法正常启动 第5张

,

Us apple developer accounts for sale

Appledeveloper.io is a reputed website selling apple developer account, providing us, China and worldwide developer individual accounts for sale. It's at low price and good quality. Always provides satisfying services!

转载声明:本站发布文章及版权归原作者所有,转载本站文章请注明文章来源:欧博亚洲(Allbet Game)!

本文链接:https://www.qzkaishanjx.com/post/1036.html

网友评论

最新评论

  • 联博开奖 09/23 说:

    欧博allbet客户端欢迎进入欧博allbet客户端(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。被戳中内心

  • 联博开奖 09/23 说:

    欧博allbet客户端欢迎进入欧博allbet客户端(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。被戳中内心

  • 欧博亚洲电脑版下载 09/22 说:

    AllbetGmaing手机版下载欢迎进入AllbetGmaing手机版下载(www.aLLbetgame.us):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。很简单不俗的剧情

  • 环球UG注册 09/22 说:

    Allbet客户端下载欢迎进入Allbet客户端下载(www.aLLbetgame.us):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。真的甜吗

  • AllbetGmaing下载 09/21 说:

    联博开奖www.326681.com采用以太坊区块链高度哈希值作为统计数据,联博以太坊统计数据开源、公平、无任何作弊可能性。联博统计免费提供API接口,支持多语言接入。弄个交流群

  • UG环球代理 09/21 说:

    Allbetwww.aLLbetgame.us欢迎进入Allbet平台(Allbet Gaming):www.aLLbetgame.us,欧博平台开放欧博(Allbet)开户、欧博(Allbet)代理开户、欧博(Allbet)电脑客户端、欧博(Allbet)APP下载等业务。实在是舍不得移开眼

  • AllbetGmaing客户端下载 09/20 说:

    AllbetGmaing客户端下载欢迎进入AllbetGmaing客户端下载(www.aLLbetgame.us):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。水一下,我在看

  • AllbetGmaing客户端下载 09/20 说:

    AllbetGmaing客户端下载欢迎进入AllbetGmaing客户端下载(www.aLLbetgame.us):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。水一下,我在看