
存储器这里我们先先充几个核心 “映射” 概念这是存储器访问的基础再讲解存储器和 SRAM 的地址映射表芯片里的资源内存、寄存器、外设要被访问必须先 “编门牌号”这就是 “映射” 的本质地址映射给芯片里的所有资源分配唯一的 “数字门牌号”即系统地址比如 SRAM 的门牌号从 0x20000000 开始、ROM 从 0x00000000 开始。内核 / DMA 通过 “门牌号” 就能精准找到要访问的资源相当于 “资源与门牌号的对应表”寄存器映射是地址映射的子集 给芯片里的寄存器存配置、状态的小内存分配门牌号比如 “0x40008000 对应 UART 的波特率寄存器”软件写这个地址就能配置 UART相当于 “寄存器功能与门牌号的对应表”重映射是 “重新分配门牌号”—— 比如原本 A 门牌号对应内存重映射后 A 门牌号可以对应外设灵活调整资源的访问地址适配不同场景。STM32 寄存器版的基础知识—内存映射【经验分享】STM32 入门系列-STM32 外设地址映射单片机内存及内存映射本地地址逻辑地址全局地址存储器的访问完全基于地址映射下面具体看 RP2040 的存储器RP2040 有内置的 ROM 和 SRAM并通过 QSPI 接口访问外部 Flash。1.ROM16kB 的只读内存ROM地址 0x00000000。ROM 中的内容在芯片被制造后是固定的相当于 “芯片自带的预装工具包”它包含初始化启动引导例程闪存启动顺序闪存编程例程支持 UF2 的大容量存储设备 USB实用程序库如快速浮点数ROM 启动程序可在该链接中下载https://github.com/raspberrypi/pico-bootrom该 ROM 提供单周期只读总线访问并且是在一个专用的 AHB-Lite 仲裁器上因此它可以与其他内存设备同时访问试图写入 ROM 没有任何效果不会生成总线故障。2.SRAM片上 SRAM 共计 264kB。在物理上这被划分为六个 bank这可以极大地提高了多个主服务器的内存带宽即让多个总线主机比如 Core0、Core1、DMA能 “同时访问不同 bank”避免抢资源但对于软件来说可以将其视为一个 264kB 的内存区域进行读写访问但物理 bank 的访问是通过地址映射实现的。对每个 bank 中存储的内容没有限制可以放应用程序、数据缓冲区等。bank 可以分为四个 16kx32 位每个 64kB和两个 1kx32 位每个 4kB。每个 SRAM bank 都可以通过一个专用的 AHB-Lite 仲裁器进行访问。这意味着不同的总线主机可以并行访问不同的 SRAM bank因此每个系统时钟周期最多可以进行 4 个 32 位的 SRAM 访问每个主机一个。在内存映射中SRAM 的起始地址为 0x20000000具体每个 bank 的基地址如下图 2.19 RP2040 SRAM Bank 系统地址与字地址映射表我们可以看到这个映射表中包含以下信息ystem address系统地址SRAM 的 “门牌号”内核 / DMA 通过这个地址访问 SRAM比如 0x20000000 是 SRAM 的第一个门牌号SRAM BankSRAM 物理分区SRAM 实际的物理存储块这里显示了 Bank0~Bank3另外还有 2 个 4kB 的小 bankSRAM word addressSRAM 字地址“字” 是 32 位对应 4 个字节这个地址是该 bank 内部的偏移门牌号比如 “字地址 0” 是 bank 里的第一个 32 位数据。我们可以看到系统地址每增加 4因为 32 位 4 字节会按 “Bank0→Bank1→Bank2→Bank3” 的顺序轮询不同 bank然后再回到 Bank0 递增 “字地址”—— 比如0x20000000门牌号→ Bank0、字地址 00x200000044→ Bank1、字地址 00x20000010再 4→ 回到 Bank0、字地址 1。这种映射的好处是当多个模块同时访问不同的系统地址时其实是在访问不同的物理 bank—— 比如 Core0 访问 0x20000000Bank0DMA 访问 0x20000004Bank1两者不会互相干扰实现 “并行访问”极大提升了 SRAM 的读写速度。此外SRAM 里还有 2 个 4kB 的小 bank地址从 0x20040000 开始可以专门分给两个核心用比如存堆栈、高频执行的代码—— 因为它们是独立 bank核心访问时不会被其他模块卡住保证了运行效率。除了片上的 SRAM 外还有两个专用 RAM 块可在某些情况下使用如果禁用 flash XIP cache则 cache 缓存将从 0x15000000 开始如果不使用 USBUSB data DPRAM 可以用作 4kB 内存从 0x50100000 开始3.Flash这里我们先引入两个关键概念QSPI 接口芯片和外部 Flash之间的 “高速数据线”比普通 SPI 快负责芯片和外部 Flash 的通信。XIPExecute In Place字面是 “在原地执行”—— 不用把外部 Flash 里的程序复制到片上 SRAM直接访问外部 Flash 就能运行程序相当于把外部 Flash 当成 “扩展内存” 用省了 SRAM 空间。图 2.20 RP2040 外部 Flash XIP本地执行硬件架构框图整个结构的核心是让外部 Flash 能像内部内存一样被访问同时用缓存提速还要保证通信稳定SSI 模块直接连接 QSPI 接口是和外部 Flash 通信的 “物理层”—— 负责发送 / 接收 QSPI 信号实际和外部 Flash 传数据的就是它。Atomic RWType Interposer 原子操作保护器保证对 Flash 的读写操作是“完整不中断” 的比如读一个 32 位数据时不会被其他操作打断避免数据读错 / 写乱。Mux 多路选择器相当于 “数据路径开关”选择数据是从 Cache缓存 里读还是直接从 Flash 里读优先走 Cache更快。Read-only Cache 只读缓存因为外部 Flash 速度比片上 SRAM 慢Cache 会把 Flash 里常用的内容比如频繁执行的程序指令存在这里内核访问时先查 Cache有就直接读不用等慢 Flash大幅提升 XIP 的速度。Streaming FIFO 连续数据缓冲区当要从 Flash 读大量连续数据比如一大段程序、大文件时数据会先存在这个 FIFO 里再传给内核避免数据传输 “断断续续”让连续访问更流畅。Decode and Config 地址解析配置单元解析内核发来的地址确定这个地址对应的是外部 Flash 的哪个位置管理整个 XIP 硬件的配置比如打开 / 关闭 Cache、设置 QSPI 的通信速度、配置 FIFO 的大小等。Main AHBL Slave / Aux AHBL Slave这个 XIP 硬件连接到系统总线AHBL的 “接口”Main 接口负责常规的 Flash 访问比如读零散的指令 / 数据Aux 接口只负责Streaming FIFO 的高速连续数据传输专门服务大流量场景。AHBL-APB Bridge for SSI Configuration是 SSI 的配置接口内核通过 APB 总线给 SSI 模块设置参数比如 QSPI 的时钟频率、传输模式让 SSI 能和不同型号的外部 Flash 匹配通信。当内核要读外部 Flash 里的程序指令时内核发地址给 Decode and Config解析出是 Flash 的哪个位置Mux 先查 Read-only Cache如果 Cache 里有这个地址的内容直接返回给内核如果 Cache 里没有就通过 SSI 模块用 QSPI 从外部 Flash 读数据读回的数据先存到 Cache 里方便下次读同时传给内核如果是读一大段连续指令数据会先存到 Streaming FIFO 里再批量传给内核。总而言之外部 Flash 可以通过 QSPI 接口使用本地执行XIP硬件进行访问。这允许系统像访问内部内存一样寻址和访问外部闪存。