最容易访问的设备是什么

是内存!

要读写内存,知道它的地址就可以:


volatile unsigned int *p = 某个地址;
unsigned int val;
*p = val;  /* 写 */
val = *p;  /* 读 */

只有内存能这样简单、方便地使用吗?

不是的,所有的"ram-like"接口设备都可以这样操作。

什么叫"ram-like"接口?

  • 要发出地址:有地址线
  • 要读写数据:有数据线
  • 怎么分辨是读还是写:有读写信号
  • 众多"ram-like"设备共享上面的信号,怎么才能互不影响?每个设备都有自己的片选信号

如下图所示:

PCI PCIe

  • CPU 发出 addr,到达内存控制器,也出现在 RAM、Flash、GPIO 等设备上
  • 使能设备:
  1. 如果 addr 属于 RAM 的地址范围,cs0 就被使能
  2. 如果 addr 属于 Flash 的地址范围,cs1 就被使能
  3. 如果 addr 属于 GPIO 的地址范围,cs2 就被使能
  4. 没有被使能的设备,就相当于没接上去一样,不会影响其他设备
  • 读写数据

关键在于:内存控制器,它会根据地址范围发出对应的片选信号,选中对应的设备。

地址空间的概念

以人类为例:

  • 爷爷生了4个小孩,排行1234
  • 老大又生了4个小孩,排行1234
  • 这两个"1234"辈分不一样,空间不一样

PCI PCIe

嵌入式系统中的地址空间:

  • CPU 发出 addr,可以用来访问 EMMC 控制器
  • 但是 CPU 发出的 addr,不能直接到达 EMMC Flash
  • 想访问 EMMC Flash
  1. 必须用过 EMMC 控制器
  2. 编写 EMMC 控制器驱动程序
  • 如果 CPU 发出的 addr,可以直接到达 EMMC Flash,那就简单了

PCI PCIe

理解 PCI 和 PCIE 的关键

地址空间转换

PCI PCIe

PCI 接口速览

PCI 是并行口,引脚多。其中 Address 和 Data 复用 PIN 脚,因此引脚命名为 AD。

随着速率的提升,并行口引脚之间干扰会加大,无法将速率提升到很高。

PCI PCIe

PCIe 接口速览

PCI-E 是串行口,引脚明显少很多,使用差分信号传输数据。

PCI PCIe

访问 PCI/PCIe 设备的流程

PCI/PCIe 设备的配置信息

PCI/PCIe 设备上有配置空间(配置寄存器),用来表明自己"需要多大的地址空间"。

注意,这是 PCI/PCIe 地址空间。

主机读取设备配置信息、分配空间

主机上的程序访问 PCI/PCIe 设备,读出配置信息。

分配地址空间:注意,分配的是 PCI/PCIe 地址空间。

把地址空间首地址写入设备。

CPU 地址空间和 PCI/PCIe 地址空间怎么转换?

假设 CPU 发出的 addr_cpu,是用来访问 PCI 设备的,转换关系为:


addr_pci  = addr_cpu + offset

在 PCI/PCIe 控制器中,有某个寄存器,有来保存 offset 值。

主机像读写内存一样访问设备

示例代码如下:


volatile unsigned int *p = addr_cpu;
unsigned int val;
*p = val;  /* 写, 硬件会把addr_cpu转换为addr_pci去写PCI/PCIe设备 */
val = *p;  /* 读, 硬件会把addr_cpu转换为addr_pci去读PCI/PCIe设备 */