无缓存下对Flash的AHB读访问竟然是这样!
痞子衡嵌入式 2022-09-19

今天给大家介绍的是实抓Flash信号波形来看i.MXRT的FlexSPI外设下AHB读访问情形

上一篇文章 《i.MXRT中FlexSPI外设对AHB Burst Read特性的支持》 里痞子衡介绍了FlexSPI外设在不开启Prefetch功能下响应AHB master的访问请求完全受AHB总线Burst Read特性决定,这是FlexSPI外设最基础的对Flash访问支持功能,研究这个其实是很有意义的,这可以反映出XiP下最原始的代码执行效率。

我们知道在实际项目中,XiP应用程序常常是在L1 Cache和Prefetch加持下运行的,代码执行效率会得到大大提升,但无论是怎样的缓存策略,极限情况下(比如大数据块搬移,长跳转指令)最终还是拼得FlexSPI最基础的读访问支持。今天痞子衡就从抓Flash信号波形角度带大家真切感受下这最基础的AHB读访问情形(为更清晰地分析结果,本次主要涉及数据总线AHB访问,暂不涉及指令总线AHB访问):

一、实验准备

痞子衡用i.MXRT1050-EVKB来做这个AHB读访问实验,这块板子上的Flash被痞子衡更换过,目前的型号是华邦W25Q64JWS-IQ。我们基于 \SDK_2.9.1_EVKB-IMXRT1050\boards\evkbimxrt1050\demo_apps\led_blinky\iar 例程(记得切换到 flexspi_nor_debug build)来简单修改一下,把启动头FDCB修改如下,设置Flash工作于30MHz Fast Read Quad I/O SDR模式,调成30MHz低速是为了方便后续用示波器抓Flash信号去分析。

const flexspi_nor_config_t qspiflash_config = {    .memConfig =        {            .tag              = FLEXSPI_CFG_BLK_TAG,            .version          = FLEXSPI_CFG_BLK_VERSION,            .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,            .csHoldTime       = 3u,            .csSetupTime      = 3u,            .controllerMiscOption = 0x10,            .deviceType       = kFlexSpiDeviceType_SerialNOR,            .sflashPadType    = kSerialFlash_4Pads,            // Flash工作于30MHz             .serialClkFreq    = kFlexSpiSerialClk_30MHz,            .sflashA1Size     = 8u * 1024u * 1024u,            .lookupTable =                {                    // Quad I/O Fast Read SDR LUTs                     [4*CMD_LUT_SEQ_IDX_READ + 0] = FLEXSPI_LUT_SEQ(CMD_SDR,   FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),                    [4*CMD_LUT_SEQ_IDX_READ + 1] = FLEXSPI_LUT_SEQ(MODE8_SDR, FLEXSPI_4PAD, 0xF0, DUMMY_SDR, FLEXSPI_4PAD, 0x04),                    [4*CMD_LUT_SEQ_IDX_READ + 2] = FLEXSPI_LUT_SEQ(READ_SDR,  FLEXSPI_4PAD, 0x04, STOP,      FLEXSPI_1PAD, 0x00),                    [4*CMD_LUT_SEQ_IDX_READ + 3] = 0,                },        },    .pageSize           = 256u,    .sectorSize         = 4u * 1024u,    .blockSize          = 64u * 1024u,    .isUniformBlockSize = false,};

下图是华邦W25Q64JWS-IQ芯片的Fast Read Quad I/O SDR传输时序图,Dummy Cycle连同MODE8_SDR序列一共6个SCK周期,此外还有个特别注意点,MODE8_SDR序列参数值需要被设成0xFx,我们上面修改的FDCB启动头是符合要求的。

现在让我们把示波器拿出来,四路探头分别连到板载Flash器件的CE#、SCK、SI_IO0、SO_IO1引脚(IO2、IO3因探头有限就不抓取了,IO[1:0]足够我们分析时序了),然后将 led_blinky 工程下载进Flash运行便可以观测结果了。

二、实验代码

因为我们下载的是一个XIP工程,代码的执行本身也会触发Flash中的指令读取,这会影响我们在示波器上观测AHB读数据测试结果,所以我们可以在main()函数里把SysTick初始化去掉(不要中断),并且调用如下ramfunc型函数 test_ahb_read() 来做测试(痞子衡直接利用了IAR软件的特性),这样代码跑起来后,Flash上发生的读访问均来自我们想要测试的AHB读数据操作(这也意味着ICache是否开启对本系列测试结果没有影响,但不管怎么,我们统一关掉):

Note: DCache和Prefetch必须要全部关闭,否则哪怕测试代码里对同一个地方循环读取,但在Flash引脚上根本看不到周期性信号波形,因为系统做了缓存,后续的读取操作可能直接发生在缓存区里(32KB DCache, 1KB AHB RX prefetch buffer)了。

#define AHB_ADDR_START (0x60002400)  #if (defined(__ICCARM__)) #pragma optimize = none __ramfunc  #endif void test_ahb_read(void) {    /* Disable L1 I-Cache*/     SCB_DisableICache();    /* Disable L1 D-Cache*/     SCB_DisableDCache();    /* Disable FlexSPI AHB read prefetch */     FLEXSPI->AHBCR &= ~(FLEXSPI_AHBCR_PREFETCHEN_MASK | FLEXSPI_AHBCR_CACHABLEEN_MASK);        while (1)    {        SDK_DelayAtLeastUs(10, SystemCoreClock);        for (uint32_t i = 1; i <= 8; i++)        {               SDK_DelayAtLeastUs(2, SystemCoreClock);            memcpy((void *)0x20200000, (void *)AHB_ADDR_START, i);        }    } }

因为我们用了memcpy来做Flash数据拷贝,memcpy功能实际上是IAR软件自带库 ABImemcpy.a 里面的 __aeabi_memcpy、__aeabi_memcpy4、__aeabi_memcpy8 等函数实现的,因此我们还需要在工程链接文件里将 ABImemcpy.o 链接到RAM区;并且我们还用了SDK_DelayAtLeastUs()来分隔每次memcpy()波形结果,还需要将这个函数里调用的相关代码放到RAM区(fsl_common.c里)。

initialize by copy { readwrite,                     section .textrw,                     // 确保 memcpy() 相关代码全在RAM里                     object ABImemcpy.o,                     // 确保 SDK_DelayAtLeastUs() 相关代码全在RAM里                     object fsl_common.o,                     object I64DivZer.o,                     object I64DivMod.o                     };do not initialize  { section .noinit };

一切准备就绪后具体测试就是设置不同的AHB_ADDR_START值(这里主要是考虑地址对齐)来观测Flash信号的实际波形。此外为了便于分辨IO[1:0]上的数据,我们最好定义一块特殊const数据区,根据Flash传输时序图,其中数据Byte[4]和Byte[0]是在IO0线上传输、Byte[5]和Byte[1]是在IO1线上传输的,这4bit共有16种不同值组合,我们将这16种不同值放在ahbRdBlock[16]数组中,并将其链接在 0x60002400 - 0x6000240f 地址空间里。

// 在工程源文件中const uint8_t ahbRdBlock[16] @ ".ahbRdBuffer" = {0x00, 0x01, 0x02, 0x03,                                                 0x10, 0x11, 0x12, 0x13,                                                 0x20, 0x21, 0x22, 0x23,                                                 0x30, 0x31, 0x32, 0x33};// 在工程链接文件中keep{ section .ahbRdBuffer };place at address mem:0x60002400 { readonly section .ahbRdBuffer };

三、实验结果

3.1 AHB_ADDR_START = 0x6002400 即八字节对齐

我们先来看AHB_ADDR_START = 0x6002400时抓取一次完整for循环结果的波形(见下图),可以看到在八字节对齐的地址下使用memcpy拷贝1/2/4/8字节,均仅产生一次CS信号有效周期(拉低),在这CS有效期间完成全部所需数据的读取。但是拷贝3/5/6/7字节时,会拆分出多个CS有效周期。

当使用memcpy拷贝3/5/6字节时,会拆分出2个CS有效周期(见下图),这里第一个CS周期看起来似乎是多余的,为什么是这种结果,这需要深入研究AHB机制(痞子衡会另写文章分析);

  • 当拷贝3字节时,第一个CS周期实际读取了前2个字节 [0x60002400, 0x60002401],第二个CS周期读取了全部3字节 [0x60002400, 0x60002402]。
  • 当拷贝5字节时,第一个CS周期实际读取了前4个字节 [0x60002400, 0x60002403],第二个CS周期读取了全部5字节 [0x60002400, 0x60002404]。
  • 当拷贝6字节时,第一个CS周期实际读取了前4个字节 [0x60002400, 0x60002403],第二个CS周期读取了全部6字节 [0x60002400, 0x60002405]。

当使用memcpy拷贝7字节时,会拆分出3个CS有效周期(见下图),这里前两个CS周期看起来似乎都是多余的;

  • 当拷贝7字节时,第一个CS周期实际读取了前4个字节 [0x60002400, 0x60002403],第二个CS周期实际读取了前6个字节 [0x60002400, 0x60002405],第三个CS周期读取了全部7字节 [0x60002400, 0x60002406]。

3.2 AHB_ADDR_START = 0x6002404 即四字节对齐

AHB_ADDR_START = 0x6002404时抓取一次完整for循环结果的波形(见下图),可以看到在四字节对齐的地址下使用memcpy拷贝1/2/4字节,均仅产生一次CS信号有效周期(拉低),在这CS有效期间完成全部所需数据的读取。

但是拷贝3/5/6/7/8字节时,会拆分出多个CS有效周期。不过其中拷贝5/6/8字节,是合理的拆分,并没有冗余读取。

3.3 AHB_ADDR_START = 0x6002401 即奇地址

AHB_ADDR_START = 0x6002401时抓取一次完整for循环结果的波形(见下图),这种情况下CS拆分特别严重,几乎都存在冗余读取。

3.4 AHB_ADDR_START = 0x6002402 即偶地址

AHB_ADDR_START = 0x6002402时抓取一次完整for循环结果的波形(见下图),这种情况下CS拆分特别严重,几乎都存在冗余读取。

3.5 AHB_ADDR_START = 0x6002403

AHB_ADDR_START = 0x6002403时抓取一次完整for循环结果的波形(见下图),这种情况下CS拆分特别严重,几乎都存在冗余读取。

至此,实抓Flash信号波形来看i.MXRT的FlexSPI外设下AHB读访问情形痞子衡便介绍完毕了,掌声在哪里~~~


本文源自微信公众号:痞子衡嵌入式,不代表用户或本站观点,如有侵权,请联系nick.zong@aspencore.com 删除!

声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 【7.24 深圳】2025国际AI+IoT生态发展大会/2025全球 MCU及嵌入式技术论坛


  • 相关技术文库
  • 单片机
  • 嵌入式
  • MCU
  • STM
  • 3AT89C51单片机引脚说明及引脚图

    AT89C51是一种带4K字节闪烁可编程可擦除只读存储器的低电压,高性能CMOS8位微处理器,俗称单片机。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU...

    07-11
  • 51单片机对LCD1602液晶的驱动设计

    51单片机——LCD1602 1、1602液晶读写时序 (1)、读状态 RS=L,R/W=H,E=H。(判断忙完毕后释放总线) (2)、读数据 RS=H,R/W=H,E=H。 (3)、写指令 RS=L,R/W=L,D0~D7=指令码,E=高脉冲 (4)、写数据 RS=H,R/W=L,D0~D...

    07-11
  • 单片机串口如何接收不定长数据的?

    我们在使用其他STM32的单片机的时候,会发现有些困难,会发现常用的方法并不能用,在还没有接收完数据的时候,就解决不了。于是,只能用通用的方法来解决了。 这个通用的方法,其实原理和使用IDLE的原理一样:...

    07-11
  • ARM处理器的选型原则

    鉴于ARM微处理器的众多优点,随着国内外嵌入式应用领域的逐步发展,ARM微处理器必然会获得广泛的重视和应用。但是,由于ARM微处理器有多达十几种的内核结构,几十个芯片生产厂家,以及千变万化的内部功能配置组合,...

    07-10
  • 有哪些低功耗设计方法?单片机系统低功耗设计要点介绍

    功耗,已经是一个老生常谈的话题了。对于功耗,大家多多少少有所了解。目前,很多产品的宣传里便带有低功耗噱头。为增进大家对功耗的认识,本文将基于两点介绍功耗:1.低功耗主要设计方法,2.单片机系统低功耗设计...

    07-10
  • 8位32位MCU如何选择?如何选择合适的MCU?

    MCU,对于普通人而言,是一个高大上的存在。但是,在工业中,MCU确实常见产品。为增进大家对MCU的认识,本文将基于两点介绍MCU:1.8位MCU和32位MCU如何选择?2.如何选择合适的MCU。如果你对MCU具有兴趣,不妨继续往...

    07-09
  • ARM开发:一 ARM微处理器概述

    1.1ARM-Advanced RISC Machines ARM(Advanced RISC Machines),既可以认为是一个公司的名字,也可以认为是对一类微处理器的通称,还可以认为是一种技术的名字。 1991年ARM公司成立于英国剑桥,主要出售芯片设计技术...

    07-08
  • 分析C51单片机的一些误区和注意事项

    简介:常看见初学者要求使用_at_,这是一种谬误,把C当作ASM看待了。在C中变量的定位是编译器的事情,初学者只要定义变量和变量的作 用域,编译器就把一个固定地址给这个变量。怎么取得这个变量的地址?要用指针。 1) C...

    07-08
  • 51单片机几个延时程序

    简介:51单片机几个精确延时程序:在精确延时的计算当中,最容易让人忽略的是计算循环外的那部分延时,在对时间要求不高的场合,这部分对程序不会造成影响. 一. 500ms延时子程序(晶振12MHz,一个机器周期1us.) 程...

    07-08
  • 总结单片机软件抗干扰的几种办法

    简介:在提高硬件系统抗干扰能力的同时,软件抗干扰以其设计灵活、节省硬件资源、可靠性好越来越受到重视。下面以MCS-51单片机系统为例,对微机系统软件抗干扰方法进行研究。 1、软件抗干扰方法的研究 在工程实践中...

    07-08
  • 基于C51单片机实现汽车座椅自动控制系统的软硬件设计

    引言 随着人们生活水平的提高,对汽车座椅的舒适性要求也越来越高,要求对汽车座椅地调节能够更加简单、方便、快捷。目前,汽车座椅位置的调节多采用基于手动调节方式的机械和电动控制两种方式。汽车座椅位置的调节...

    07-02
  • MCS51单片机程序设计时堆栈的计算方法解析

    用C语言进行MCS51系列单片机程序设计是单片机开发和应用的必然趋势。Keil公司的C51编译器支持经典8051和8051派生产品的版本,通称为Cx51。应该说,Cx51是C语言在MCS51单片机上的扩展,既有C语言的共性,又有它自己...

    07-02
下载排行榜
更多
评测报告
更多
广告