【问题标题】:Difference between Memory Mapped I/O and Programmed I/O内存映射 I/O 和编程 I/O 之间的区别
【发布时间】:2017-05-17 05:35:45
【问题描述】:

在学习计算机体系结构时,我学到了不同的控制 I/O 设备的方法,这些方法是,

  1. 可编程 I/O
  2. 中断 I/O
  3. DMA

我学会了所有三种方法。
但是我遇到了另一个术语Memory Mapped I/O

Programmed I/O 和 Memory Mapped I/O 之间有什么关系吗?
我对这两个感到困惑。它们相似吗?

【问题讨论】:

    标签: computer-science cpu-architecture


    【解决方案1】:

    这些术语大多是独立的,并不相互排斥。
    下面我将使用伪汇编代码使示例更清晰,它是演示代码,而不是真实代码。

    如何访问设备?

    如果设备可在专用地址空间中访问,独立于地址空间或内存,则 IO 类型称为 端口映射 IO隔离 IO .

    如果设备可作为唯一地址空间的一部分访问,内存也位于该地址空间,则 IO 类型称为 内存映射 IO

    例如一些嵌入式控制器和一些主流架构有特殊的指令来访问IO地址空间。

    in r0, 0x34          #Read address 0x34 from IO address space
    ld r0, 0x34          #Read address 0x34 from memory address space
    

    在上面的示例中,两个地址 0x34 生成两个不同的总线地址,然后以不同的方式处理它们。
    请注意,ld 类型的指令与用于访问内存的指令相同,因此例如 ld r1, 0x1000 可以访问内存而不是设备。

    如何从设备中读取数据?

    这也适用于将数据写入设备。

    如果强制软件显式读取数据的每个字节/字,则 IO 的类型为programmed IO

    如果设备可以被告知启动操作并将数据自主传输到内存,那么 IO 的类型是 Direct Memory Access IO

    例如,从软件可以读取的磁盘中读取一个扇区,比如 512 字节

    #Setup read parameters omitted
    
    movi r0, $0x20      #r0 = 0x20 (say it's READ_SECTORS command)
    out 0x102, r0       #Tell the device to start reading
    
    movi r1, 512 / 4    #r1 = number of words in a sector
    _read:
     in r0, 0x103        #Read a word (32-bit)
     ...
     decbnz r1, _read        #Decrement r1 and branch back if not zero
    

    使用 DMA 可以执行相同的读取操作

    #Setup read parameters omitted
    
    movi r0, $0x21      #r0 = 0x21 (say it's READ_DMA_SECTORS command)
    out 0x102, r0       #Tell the device to start reading
    
    #Done, the software can do something else
    

    如何获得事件通知?

    操作的完成和新数据的到达是软件可能希望收到通知的两个事件示例。

    如果设备使用中断来通知CPU一个事件,则IO的类型称为interruptdriven IO

    如果设备只有一个状态寄存器,软件必须定期检查,IO的类型称为polling IO

    例如,为了检查 UART 是否有新数据,软件可以使用中断

    #Setup isr
    la r0, myISR
    call setup_isr
    
    #Example of device configuration
    
    in r0, 0x100
    or r0, 0x80
    out 0x100, r0        #Set bit7 to enable generation of interrupt
    
    #Done, myISR is called whenever new data arrives
    

    如果 IO 正在轮询,则软件必须定期检查

    _check_data:
     in r0, 0x102              #Say 102 is a status resister
     btbz r0, 7, _check_data   #Test if bit7 of r0 is set, if not jump back
    
     #New data is available
    

    例如,一个 IO 可以是内存映射的 DMA 中断驱动的 IO
    这实际上是 x86 架构上通常使用的 PCI(e) 设备。

    端口映射的 DMA 中断驱动 IO(读取样本时)和端口映射的编程轮询 IO(向 DSP 发出命令时)的真实示例,你可以check my answer about programming the sound-card to playback a wave file

    【讨论】:

      【解决方案2】:

      寻址 I/O 设备有两种不同的方法。 1.隔离I/O - 它将有关于 I/O 操作的特殊说明。 - 与内存相比,I/O 设备在单独的域中处理。 - 内存应用程序允许总共 1mb 的地址空间。 - 为了最大化 I/O 操作(隔离),总是提供单独的指令来执行这些操作。 -.缺点之一是数据传输只发生在I/O口和AL、AX寄存器之间。

      2.内存映射I/O - 在这个汇编语言程序中可以寻址 I/O 设备。 - I/O 的设备仅被视为内存的一部分。 - 不能使用完整的 1mb 内存,因为它们是内存的一部分。 - 在内存映射 I/O 操作的情况下,不需要外部单独的指令。 - 在内存映射指令的情况下存在数据传输限制。 - 内存映射 I/O 的优点是它使指令集很小。

      【讨论】:

      • 内存映射 I/O 是否与编程 I/O 有任何关系...隔离 I/O 也可以编程 I/O 吗?
      • @laura 我认为“编程 I/O”意味着 CPU 必须读取和写入 I/O 端口(例如,与 DMA 相比)。换句话说,任何事情都由 CPU 负责,无论这些 I/O 端口是什么。这些 I/O 端口是什么?只需从 CPU 到设备的电线;它们可以与其他电线分开,因此我们有一个 I/O 总线,或者它们可以共享用于其他目的(如内存)的部分或全部电线。然后,CPU 可以以相同或不同的方式读取或写入这些线路,这取决于架构。
      【解决方案3】:

      Programmed I/O 是一种读取/写入 I/O 设备的方式,其中 CPU 使用特殊程序(驱动程序)来执行这些操作。假设 CPU 需要从 I/O 设备读取数据。 CPU 发出读取请求并定期轮询接口以获取数据。这种方法速度很慢,因此引入了中断和 DMA。

      内存映射 I/O 是一种 CPU 和 I/O 设备共享相同地址空间的技术。将此视为扩展 RAM,(您有常规 RAM 和额外 RAM 以容纳 I/O 设备)都映射到一个虚拟地址空间。现在 CPU 不需要任何特殊指令来访问 I/O 设备。地址在物理 RAM 范围内的加载指令将从物理 RAM 加载,地址在分配给 I/O 的范围内的加载指令将从 I/O 设备加载。

      【讨论】:

        猜你喜欢
        • 2017-06-08
        • 2016-05-27
        • 2011-01-19
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 2011-12-15
        • 1970-01-01
        相关资源
        最近更新 更多