1. 项目概述:为什么我们需要GPMC的预取与写后置引擎?
在嵌入式系统开发中,尤其是基于ARM Cortex-A系列处理器的应用处理器(如TI的AM335x、AM437x等),我们常常需要连接外部存储器。通用内存控制器(GPMC)就是这样一个负责桥接处理器与外部NOR Flash、NAND Flash、SRAM等设备的IP核。然而,当面对NAND Flash时,一个核心矛盾就出现了:处理器的运行频率动辄几百MHz甚至GHz,而典型的异步NAND Flash的页读取或编程时间却在几十微秒量级。这意味着,如果处理器直接通过GPMC去读写NAND,它绝大部分时间都在“空转”等待,系统性能会被严重拖累。
想象一下,你需要从仓库(NAND)搬运一大批货物到生产线(处理器)。如果每次只搬一箱,并且每次搬运都要亲自跑到仓库、等待装货、再跑回来,那效率将极其低下。GPMC的预取与写后置引擎,本质上就是在仓库和生产线之间建立了一个智能的“中转缓冲区”(FIFO)和一组“自动搬运机器人”。在读取数据时(预取模式),机器人会预测你的需求,提前把货物从仓库搬到缓冲区,你直接从缓冲区取货,几乎无需等待。在写入数据时(写后置模式),你只需把货物放到缓冲区,机器人就会在后台默默地将它们运回仓库,你放下货物后就可以立刻去处理其他任务。
这个引擎并非一个独立的地址生成器或复杂的命令序列控制器,它是一个专注于“数据流”传输的简化请求器。它不关心你要读写的具体地址是什么(这部分由软件驱动预先配置好),它的任务只有一个:在软件启动后,以最高效的方式,在处理器(或DMA)与NAND的数据端口之间,搬运指定数量的字节。它通过一个64字节的FIFO、可编程的中断/DMA触发阈值,以及与GPMC访问引擎的优先级仲裁机制,实现了对NAND访问延迟的有效隐藏。对于任何需要在嵌入式Linux、RTOS或裸机环境下高效管理NAND存储的工程师来说,理解并正确配置这个引擎,是提升系统I/O性能、确保实时响应性的关键一步。
2. 引擎核心架构与工作原理深度解析
要驾驭这个引擎,不能只停留在“它有个FIFO”的层面,必须深入其内部工作机制和与系统其他部分的交互方式。
2.1 引擎在GPMC中的定位与数据流
GPMC模块本身是一个复杂的系统,它一端通过L3互连总线与处理器内核、DMA控制器等主设备相连,另一端则通过引脚控制器驱动外部存储器的各类信号线(地址、数据、控制信号)。预取与写后置引擎,是GPMC内部一个特殊的“客户端”或“请求者”。
它的工作流程可以概括为以下几个核心环节:
- 软件配置与启动:MPU(微处理器单元,即CPU)上的NAND驱动首先需要完成对NAND设备的初始化和页操作命令(如读命令
0x00-0x30或写命令0x80-0x10)的发送,并将正确的数据起始地址指针设置好。这是引擎工作的绝对前提,因为引擎本身不具备发送NAND命令和地址的能力。 - 引擎配置:随后,软件配置引擎的相关寄存器,包括工作模式(读/写)、关联的片选(Chip-Select)、传输总字节数(
TRANSFERCOUNT)、FIFO触发阈值(FIFOTHRESHOLD)以及同步模式等。 - 请求发起:当软件置位
STARTENGINE位后,引擎开始工作。它根据模式,向GPMC的访问引擎(Access Engine)发起数据访问请求。关键点在于:引擎的请求只携带目标片选ID,访问引擎会将其与来自L3总线的其他主机访问请求进行仲裁。 - 仲裁与访问:默认情况下,引擎的请求优先级是最低的。这意味着,如果系统总线繁忙,有来自CPU或DMA的其他内存访问(即使是访问其他片选),引擎的请求会被挂起,以保证高优先级任务的实时性。当然,也可以启用轮询仲裁(Round-Robin)模式,为引擎保证一定的带宽。
- 数据缓冲:所有通过引擎读写的数据,都会流经其内部的64字节FIFO。这是性能提升的核心。
- 同步机制:FIFO的空/满状态通过中断或DMA请求通知主机。在预取模式,当FIFO中数据量达到阈值,会触发事件告知主机“可以来取数据了”;在写后置模式,当FIFO有足够空余空间,会触发事件告知主机“可以来送数据了”。
2.2 关键限制与设计考量
理解引擎的限制与设计考量,能帮助我们在实际应用中避开陷阱:
- 单上下文引擎:引擎内部只有一个共享的FIFO和一套控制逻辑。因此,同一时间,它只能服务于一个片选(Chip-Select),并且只能处于一种模式(要么读,要么写)。你不能同时配置它从一个NAND预取数据,又向另一个NAND写后置数据。在多NAND或混合读写的复杂场景中,需要软件进行上下文切换。
- 仅支持线性数据流访问:引擎是为连续、顺序的大块数据访问(如读写一个完整的NAND页,通常是512字节+备用区)而优化的。它不支持随机访问,也不处理NAND的命令周期和地址周期。这些必须由软件驱动通过标准的NAND命令寄存器(
GPMC_NAND_COMMAND_i,GPMC_NAND_ADDRESS_i)来手动完成。 - FIFO的访问重定向:当引擎使能(
ENABLEENGINE=1)后,主机对该引擎关联片选的内存区域进行的任何访问,都会被重定向到FIFO,而不是直接访问NAND设备。这意味着,如果你想绕过引擎直接操作NAND(例如读取ID、发送复位命令),必须通过前面提到的专用NAND命令/地址/数据寄存器,而不能通过映射的内存地址。 - 无下溢/上溢错误报告:这是一个需要特别注意的细节。在预取模式下,如果FIFO已空(
FIFOPOINTER=0),主机再进行读操作,读回的数据将是FIFO中最后一个字节的重复值。在写后置模式下,如果FIFO已满(FIFOPOINTER=0),主机再进行写操作,新写入的数据会覆盖FIFO中最后一个字节的位置。硬件不会报告错误,如果软件同步机制(中断/DMA)设计不当,可能导致数据静默错误。
3. 预取模式:化被动等待为主动供给
预取模式是针对NAND读取操作优化的核心。其目标是将处理器从漫长的tR(读数据到缓存时间)等待中解放出来。
3.1 配置流程与寄存器详解
一个完整的预取模式配置,通常遵循以下步骤,下表梳理了关键寄存器位域:
| 步骤 | 关键操作 | 对应寄存器位域 | 配置要点与解释 |
|---|---|---|---|
| 1. 前置条件 | 确保引擎处于可配置状态 | GPMC_PREFETCH_CONTROL[0] STARTENGINE | 必须为0。在引擎运行时修改大部分配置是未定义行为。 |
| 2. 基础链接 | 关联目标NAND设备 | GPMC_PREFETCH_CONFIG1[26-24] ENGINECSSELECTOR | 填写NAND设备所连接的GPMC片选编号(0-7)。 |
| 3. 模式选择 | 设置为读模式 | GPMC_PREFETCH_CONFIG1[0] ACCESSMODE | 清除为0,选择预取模式。 |
| 4. 传输设定 | 设定总传输字节数 | GPMC_PREFETCH_CONFIG2[13-0] TRANSFERCOUNT | 核心参数。设定引擎需要从NAND读取的总字节数。对于8位NAND,按字节数设置;对于16位NAND,按字数设置,但引擎内部仍按字节管理。 |
| 5. 同步配置 | 选择启动同步方式 | GPMC_PREFETCH_CONFIG1[3] SYNCHROMODEGPMC_PREFETCH_CONFIG1[5-4] WAITPINSELECTOR | SYNCHROMODE=0:立即启动。软件需自行确保在置位STARTENGINE时,NAND已处于就绪状态(通过轮询R/B#引脚)。SYNCHROMODE=1:硬件同步启动。引擎等待指定的gpmc_wait引脚出现下降沿(有效到无效的跳变)后才开始预取。这需要正确配置NAND的R/B#引脚连接到GPMC的某个wait引脚,并配置好边沿检测。这种方式更可靠,能避免NAND未就绪时发起访问。 |
| 6. 阈值设定 | 设定FIFO事件触发阈值 | GPMC_PREFETCH_CONFIG1[14-8] FIFOTHRESHOLD | 设定一个阈值(字节数)。当FIFO中累积的数据量大于等于此阈值时,会触发中断或DMA请求。最佳实践:将TRANSFERCOUNT设置为FIFOTHRESHOLD的整数倍,这样可以通过固定次数的中断/DMA完成传输,逻辑最清晰。 |
| 7. 优化使能 | 启用访问周期优化 | GPMC_PREFETCH_CONFIG1[27] ENABLEOPTIMIZEDACCESSGPMC_PREFETCH_CONFIG1[30-28] CYCLEOPTIMIZATION | 设置为1以启用。CYCLEOPTIMIZATION定义了在连续访问(背靠背访问)时,可以从标准读/写周期时间中减去的时钟周期数。这能进一步提升连续读写的带宽。 |
| 8. 引擎使能 | 激活引擎 | GPMC_PREFETCH_CONFIG1[7] ENABLEENGINE | 设置为1。此时,对该片选的内存区域访问将被重定向到FIFO。 |
| 9. 启动引擎 | 开始预取操作 | GPMC_PREFETCH_CONTROL[0] STARTENGINE | 设置为1。引擎根据SYNCHROMODE开始或等待启动。传输完成后,此位会自动清零。 |
注意:如果系统中使用了ECC引擎,必须在启动预取引擎之前,完成对ECC引擎的复位、配置和使能。这样,从NAND读出的数据在流经GPMC时,才会自动进行ECC校验计算,结果存入对应的ECC结果寄存器,供软件后续进行纠错。
3.2 FIFO控制与主机交互策略
FIFO是引擎与主机(MPU或DMA)之间的数据交换枢纽。主机如何高效、无误地排空(Drain)FIFO,是预取模式编程的关键。
1. MPU(CPU)轮询与中断模式:在MPU直接操作的模式下,软件有两种方式感知FIFO状态:
- 轮询:不断读取
GPMC_PREFETCH_STATUS[30-24] FIFOPOINTER字段,它实时指示FIFO中可读的字节数。当数值大于0时,即可读取相应数量的数据。这种方式简单,但占用CPU资源。 - 中断:这是更高效的方式。使能
GPMC_IRQENABLE[0] FIFOEVENTENABLE中断。当FIFO中数据量达到FIFOTHRESHOLD时,GPMC_IRQSTATUS[0] FIFOEVENTSTATUS置位并产生中断。在中断服务程序(ISR)中,软件应读取至少FIFOTHRESHOLD字节的数据,然后清除FIFOEVENTSTATUS位。一个关键细节:必须在启动引擎(STARTENGINE=1)之后,再使能FIFO事件中断,以避免陈旧的中断事件被误触发。
2. DMA模式:为了彻底解放CPU,DMA模式是首选。配置步骤如下:
- 设置
GPMC_PREFETCH_CONFIG1[2] DMAMODE = 1。 - 配置一个DMA通道,其源地址(Source Address)设置为该引擎关联片选的内存映射地址(即FIFO的访问端口),目标地址为系统内存中的缓冲区。
- 在DMA通道配置中,将每次传输的字节数(Burst Size)设置为
FIFOTHRESHOLD的值。 - 将GPMC产生的DMA请求信号连接到该DMA通道。
- 在启动引擎(
STARTENGINE=1)之后,再使能该DMA通道。
当FIFO中数据达到阈值,GPMC会向DMA控制器发出请求,DMA控制器自动从FIFO搬运FIFOTHRESHOLD字节的数据到系统内存。该请求会一直保持有效,直到指定数量的字节被搬完。在此期间,GPMC不会发出新的DMA请求。
3. 传输完成判断:除了FIFO事件,还需要知道整个预取传输何时结束。可以通过监控GPMC_PREFETCH_STATUS[13-0] COUNTVALUE字段,它表示剩余待传输的字节数。当其为0时,表示预取完成。也可以使能终端计数中断(GPMC_IRQENABLE[1] TERMINALCOUNTEVENTENABLE),在传输完成时收到通知。
实操心得:在DMA模式下,如果
TRANSFERCOUNT不是FIFOTHRESHOLD的整数倍,最后一个DMA请求传输的字节数会少于设定的阈值。你需要通过TERMINALCOUNT中断或检查COUNTVALUE来感知传输结束,并在DMA配置中处理这个“残段”(Remainder)。一种稳健的做法是,在DMA传输完成回调函数中,检查COUNTVALUE,如果不为零,则用MPU读取剩余数据。
4. 写后置模式:让数据写入“消失”在后台
写后置模式是预取模式的镜像,它优化的是NAND的编程操作。处理器将数据快速“倾倒”到FIFO中,然后就可以继续执行其他任务,引擎在后台负责将数据写入缓慢的NAND。
4.1 配置流程与核心差异
写后置模式的配置流程与预取模式高度相似,但方向相反。主要差异点如下:
| 配置项 | 预取模式 (读) | 写后置模式 (写) | 说明 |
|---|---|---|---|
ACCESSMODE | 0 | 1 | 核心模式选择位。 |
SYNCHROMODE | 可为0或1 | 必须为0 | 写后置模式不支持硬件同步启动,引擎在STARTENGINE置位且FIFO非空时立即开始写操作。 |
FIFOTHRESHOLD | 触发“数据可读”事件 | 触发“空间可写”事件 | 在写后置模式下,当FIFO中空闲空间大于等于此阈值时,触发中断/DMA请求,通知主机可以写入更多数据。 |
FIFOPOINTER | 表示FIFO中有效数据字节数 | 表示FIFO中空闲空间字节数 | 状态寄存器字段的含义随模式改变,编程时务必注意。 |
| 主机操作 | 从FIFO读取数据 | 向FIFO写入数据 | 数据流方向相反。 |
| 结束流程 | 读完后,数据即用。 | 引擎写完FIFO数据后,必须由软件发送NAND编程确认命令(如0x10),并等待NAND编程完成。 | 这是最关键的差异。写后置引擎只负责将数据从FIFO搬运到NAND的页缓存,最终的“编程”操作需要软件发命令启动。 |
关键时序陷阱:在写后置模式下,STARTENGINE位的置位时机需要小心。手册指出,如果STARTENGINE在NAND地址周期(即发送页编程命令0x80和列/行地址)之后才设置,那么该设置只有在NAND命令周期实际完成后才生效。在此期间,如果FIFO是空的,GPMC可能会被挂起。因此,推荐的做法是:在启动DMA填充FIFO之前,就置位STARTENGINE。确保DMA通道在NAND地址周期完成之后才被使能。这样,一旦地址周期结束,FIFO中已有数据,引擎能立即开始工作。
4.2 数据填充与ECC处理
与读模式类似,写后置模式的数据填充也可以通过MPU或DMA进行。DMA模式同样是高吞吐量场景下的首选。
ECC的集成:如果使用了GPMC内部的硬件ECC引擎,必须在启动写后置引擎之前,完成对ECC引擎的配置和使能。这样,所有通过引擎写入NAND的数据,在流经GPMC时,会自动计算ECC校验值。这些校验值通常需要由软件在发送最终的编程确认命令前,写入NAND页的备用区(Spare Area)。因此,你的软件驱动需要协调好数据流:先启动ECC引擎和写后置引擎,然后用DMA填充主数据区的FIFO,在DMA完成中断中,再计算或读取ECC值,并将其通过标准的NAND数据寄存器写入备用区对应的FIFO位置(注意地址偏移),最后再发送编程确认命令。
注意事项:在写后置模式下,无论主机写入FIFO时的字节使能(Byte Enable)信号如何,FIFO中存储的所有字节都会被引擎写入NAND设备。这意味着,即使你进行32位字访问只更���了其中1个字节,引擎也会将该字所在的4字节全部写入NAND。这通常不是问题,因为NAND编程以页为单位。
5. 性能调优与高级特性
仅仅让引擎工作起来还不够,要榨干其性能,还需要理解并运用其高级特性。
5.1 访问周期优化
这是提升连续读写带宽的利器。当ENABLEOPTIMIZEDACCESS使能后,对于引擎发起的、访问同一NAND片选的、背靠背的请求,GPMC访问引擎会自动优化时序。
- 原理:在标准的NAND读周期中,包含多个时间参数,如
RDCYCLETIME(读周期时间)、RDACCESSTIME(访问时间)等。在第一次访问后,如果片选信号(nCS)保持有效(即连续访问),后续访问可以省去一些建立和保持时间。 - 配置:
CYCLEOPTIMIZATION字段(3位)定义了可以从上述时序参数中减去的GPMC功能时钟(GPMC_FCLK)周期数。例如,将其设置为3,意味着在第一次访问之后的所有连续访问中,相关时序参数都减少3个时钟周期。 - 效果:这显著缩短了连续数据访问的周期时间,从而提高了数据传输的峰值带宽。限制:此优化仅对引擎发起的访问有效。MPU通过内存映射或NAND寄存器直接发起的访问无法享受此优化。
5.2 仲裁策略与优先级管理
默认情况下,引擎的请求优先级低于所有通过L3互连总线发起的直接访问请求。这是一种保守且安全的策略,确保CPU或DMA对其它内存(如SDRAM、其他片选)的访问不会被引擎的长时间NAND操作阻塞。
然而,在某些实时性要求高、需要保证NAND数据流带宽的场景下,这种“饥饿”引擎的策略可能不可取。GPMC提供了可选的加权轮询仲裁机制。
- 启用:设置
GPMC_PREFETCH_CONFIG1[23] PFPWENROUNDROBIN = 1。 - 工作原理:当引擎和主机同时请求访问外部总线时,仲裁器先服务一个主机请求,然后服务引擎请求。
GPMC_PREFETCH_CONFIG1[19-16] PFPWWEIGHTEDPRIO字段定义了引擎在获得总线控制权后,可以连续进行的访问次数。之后,总线控制权会交还给主机请求方,如此轮转。 - 示例:假设
PFPWWEIGHTEDPRIO = 2,且引擎和主机持续有请求。仲裁顺序将是:主机1次 -> 引擎3次(权重2+1)-> 主机1次 -> 引擎3次 -> ...。这为引擎提供了有保障的最小带宽。 - 应用场景:在需要稳定NAND读写带宽的流媒体记录或播放应用中,启用此功能可以避免因系统总线繁忙导致的数据流卡顿。
6. 实战配置指南与常见问题排查
理论最终要落地到代码。下面以一个典型的异步NAND Flash页读取(2048字节+64字节备用区)为例,展示如何配置预取引擎并结合DMA。
6.1 示例:使用DMA的NAND页预取
假设我们使用Cortex-A8处理器,NAND连接在GPMC的CS0上,数据宽度为8位,页大小为2048字节,备用区64字节,我们使用DMA通道0来搬运数据。
// 1. 前置准备:配置GPMC的NAND基础时序、命令/地址/数据寄存器映射等(此处省略) // 2. 发送NAND读命令(0x00)和地址周期(Column, Row)到 GPMC_NAND_COMMAND_0/ADDRESS_i // 3. 发送读确认命令(0x30)到 GPMC_NAND_COMMAND_0 // 4. 等待NAND R/B# 引脚变高(就绪) // 5. 配置预取引擎 // 禁用引擎以进行配置 HWREG(GPMC_BASE + GPMC_PREFETCH_CONTROL) &= ~GPMC_PREFETCH_CONTROL_STARTENGINE; // 链接到 CS0 uint32_t config1 = 0; config1 |= (0 << GPMC_PREFETCH_CONFIG1_ENGINECSSELECTOR_S); // CS0 // 预取模式 (ACCESSMODE=0) config1 &= ~GPMC_PREFETCH_CONFIG1_ACCESSMODE; // 设置FIFO阈值:例如64字节(FIFO大小)。DMA每次搬64字节。 config1 |= (64 << GPMC_PREFETCH_CONFIG1_FIFOTHRESHOLD_S); // 启用DMA模式 config1 |= GPMC_PREFETCH_CONFIG1_DMAMODE; // 立即启动模式(假设已通过轮询确保NAND就绪) config1 &= ~GPMC_PREFETCH_CONFIG1_SYNCHROMODE; // 启用访问优化,并设置优化周期数(例如2个周期) config1 |= GPMC_PREFETCH_CONFIG1_ENABLEOPTIMIZEDACCESS; config1 |= (2 << GPMC_PREFETCH_CONFIG1_CYCLEOPTIMIZATION_S); // 使能引擎 config1 |= GPMC_PREFETCH_CONFIG1_ENABLEENGINE; HWREG(GPMC_BASE + GPMC_PREFETCH_CONFIG1) = config1; // 6. 设置总传输字节数:主数据区2048字节 HWREG(GPMC_BASE + GPMC_PREFETCH_CONFIG2) = 2048; // TRANSFERCOUNT // 7. 配置DMA通道0 // 源地址:GPMC CS0 的内存映射起始地址(即FIFO访问端口) // 目标地址:系统内存中的缓冲区 // 传输数量:总字节数 / FIFO阈值 = 2048 / 64 = 32 次突发传输 // 链接GPMC的DMA请求信号到该通道(平台相关,需查阅芯片手册) // 此处为伪代码 setup_dma_channel(0, SRC_ADDR, DEST_ADDR, 64, 32, GPMC_DMA_REQ); // 8. 启动预取引擎 HWREG(GPMC_BASE + GPMC_PREFETCH_CONTROL) |= GPMC_PREFETCH_CONTROL_STARTENGINE; // 9. 在STARTENGINE置位后,再使能DMA通道,避免陈旧的DMA请求 enable_dma_channel(0); // 10. 等待DMA传输完成中断或轮询DMA状态 // 11. DMA完成后,预取引擎可能还未完成(因为DMA只搬了主数据区) // 检查 COUNTVALUE,如果为0,则主数据区读取完成。 // 12. 接下来,需要禁用引擎,然后通过标准NAND数据寄存器读取64字节的备用区(含ECC)。 // 注意:读取备用区时,不能通过引擎的FIFO,因为ENABLEENGINE=1时访问被重定向了。 // 需要直接读 GPMC_NAND_DATA_i 寄存器。6.2 常见问题与排查技巧
在实际调试中,你可能会遇到以下问题:
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| 数据读取错误(全0xFF或固定值) | 1. 引擎未正确启动或配置。 2. NAND命令/地址未正确发送。 3. ENABLEENGINE=1但试图直接读NAND数据寄存器。 | 1. 检查STARTENGINE位是否在传输期间保持为1,检查COUNTVALUE是否在递减。2. 用逻辑分析仪或示波器抓取GPMC引脚,确认NAND的读命令序列(0x00, 地址, 0x30)是否正确发出。 3. 确认在 ENABLEENGINE=1时,读取的是CS对应的内存映射地址(访问FIFO),而不是GPMC_NAND_DATA_i。 |
| DMA/中断无法触发 | 1. FIFO阈值设置不当。 2. 中断/DMA未使能或使能时机不对。 3. 寄存器位域理解错误。 | 1. 确认TRANSFERCOUNT和FIFOTHRESHOLD设置正确。对于读模式,FIFOTHRESHOLD是触发“数据可读”的阈值。2.关键:对于中断,必须在 STARTENGINE=1之后才置位FIFOEVENTENABLE,并先清除FIFOEVENTSTATUS。对于DMA,必须在STARTENGINE=1之后才使能DMA通道。3. 写后置模式下, FIFOTHRESHOLD触发的是“空间可写”事件,FIFOPOINTER表示空闲空间,与读模式相反。 |
| 系统访问其他内存变慢或卡顿 | 引擎正在进行长时间的NAND访问,且其默认低优先级阻塞了总线。 | 1. 检查是否因NAND访问导致系统总线延迟增加。可以尝试启用加权轮询仲裁(PFPWENROUNDROBIN),为其他访问保留带宽。2. 优化NAND时序参数,减少单次访问周期时间。 3. 考虑将大的NAND传输任务放在低优先级线程或任务中。 |
| 写入NAND的数据校验失败 | 1. 写后置流程不完整,缺少编程确认命令。 2. ECC处理错误。 3. FIFO下溢(写太快)或上溢(写太慢)。 | 1.务必确认在引擎完成数据传输(COUNTVALUE=0)后,发送了NAND的页编程确认命令(如0x10),并等待编程完成。2. 检查ECC引擎是否在写后置引擎启动前已使能。确认软件正确地将计算出的ECC值写入了NAND页的备用区对应位置。 3. 调整DMA速率或中断处理频率,确保生产者和消费者的速度匹配。监控 FIFOPOINTER状态。 |
| 优化模式未生效 | 1.ENABLEOPTIMIZEDACCESS未使能。2. 访问被其他片选请求打断。 | 1. 确认已置位ENABLEOPTIMIZEDACCESS并设置了CYCLEOPTIMIZATION。2. 优化仅对引擎发起的、背靠背的、且无其他片选访问穿插的请求有效。如果期间有CPU访问其他设备,优化会中断。 |
调试建议:
- 善用状态寄存器:
FIFOPOINTER和COUNTVALUE是洞察引擎内部状态的最直接窗口。在调试初期,可以轮询它们,观察其变化是否符合预期。 - 分阶段验证:先使用MPU轮询模式实现最基本的读写功能,确保NAND基础命令、引擎配置、数据通路是正确的。然后再引入复杂的中断和DMA机制。
- 逻辑分析仪是关键:对于时序问题、命令序列错误、总线仲裁异常,没有比逻辑分析仪抓取GPMC实际引脚波形更有效的调试手段了。重点关注
nCE,nWE,nRE,nWP,nALE,nCLE,WAIT以及数据总线上的信号。