计算机原理与嵌入式系统笔记:第八篇
输入/输出设备
输入输出设备(I/O Devices)通常有一些模拟元件或非电子元件(比如磁盘驱动器),但与CPU的接口通常是数字逻辑——一组寄存器。
对于IO编程支持,有两种办法:IO指令和内存映射IO:
- I/O指令为I/O设备提供了单独的地址空间。
- 内存映射I/O是最普遍的方法,即使是提供I/O指令的CPU也不排除使用内存映射I/O。
- 内存映射I/O是为每个I/O设备的寄存器提供一个地址。
- 程序使用普通的CPU读写内存命令来与设备通信。
如: 在C语言中定义和使用一个变量时,编译器隐藏了变量地址,可以使用指针来操纵I/O设备的地址。
1 | // 读取任意存储单元的函数peek |
数据传送方式
CPU与IO设备间的数据传送方式
- 程序传送方式
- 无条件传送
- 程序查询传送(忙等I/O)
- 中断传送方式
- DMA传送方式
忙等I/O
忙等I/O是程序中访问I/O设备的最基本方法。I/O设备一般比CPU慢,需要多个时钟周期来完成一项操作,通过读取I/O设备的状态寄存器来询问I/O设备是否空闲,这样的操作通常被称为轮询(polling)。
然而,忙等I/O的效率非常低:
- I/O事务未完成时,CPU除测试设备状态什么都不能做。
- 无法将其他操作与I/O事务并行执行。
因此,我们使用中断机制来提高效率。
中断I/O
中断最初是作为处理器与外部设备交换信息的一种控制方式提出的。由此,最初的中断全部是对外部设备而言的,称为外部中断或硬件中断。随着计算机技术的发展,中断的范围也随之扩大,出现了内部软件中断的概念,它是为解决处理器内部运行时出现的异常以及为编程方便而提出的。
外部中断或硬件中断通常称为中断(Interrupt),软件中断或异常中断通常称为异常(Exception)。
中断机制允许I/O设备发送信号到CPU,并强制执行一段特定代码。它使得CPU能够在不同的上下文之间切换(例如多个I/O设备之间)。
中断发生时,PC指向I/O设备中一个管理设备的中断处理子程序(中断服务程序或设备驱动程序)。中断机制保留了系统被中断时的PC值,以便CPU能够返回到被中断的程序。
中断处理过程
不论哪种中断都遵循同样的中断处理过程。收到中断请求之后,处理器暂停执行当前程序,转而执行中断服务程序,处理完毕后再返回到程序断点处,继续执行原来的程序。
1 | // 输入输出处理程序 |
缓冲区
1 | // 弹性缓冲区 |
1 | // 输入处理程序的代码 |
BUF_SIZE
是缓冲区的大小,io_buf
是缓冲区本身,buf_head
和buf_tail
分别是缓冲区的头部和尾部指针。empty_buffer()
函数检查缓冲区是否为空,即头部和尾部指针是否相等。full_buffer()
函数检查缓冲区是否已满,即尾部指针的下一个位置是否是头部指针。nchars()
函数返回缓冲区中的字符数量。add_char(char achar)
函数将一个字符添加到缓冲区的尾部,然后更新尾部指针。remove_char()
函数从缓冲区的头部移除一个字符,然后更新头部指针。input_handler()
是输入中断处理程序。当缓冲区未满时,它从输入设备读取一个字符并添加到缓冲区。如果缓冲区已满,它将设置错误标志。如果这是缓冲区中的第一个字符,它将触发输出设备。output_handler()
是输出中断处理程序。当缓冲区不为空时,它从缓冲区移除一个字符并发送到输出设备。
中断与调试
在中断处理程序中,任何一个寄存器在被改写前必须保存原来的值,并且在中断处理程序结束前恢复其原来的值。由中断处理程序造成的前台程序出错很难调试,因为错误的形式取决于中断发生的时间,不具有重复性。
因此,在调试程序时,我们可以选择使用忙等驱动I/O而非中断驱动I/O。
中断的优先级
中断之间,亦有差距。如何让电脑正确区分这些中断呢?有两种解决方法:
- 中断优先级(interrupt priority):能让CPU辨认出比其他中断更加重要的一些中断。
- 中断向量(interrupt vector):允许中断设备指定其中断处理程序。
屏蔽(masking):优先级机制必须确保处理高优先级中断时,不发生低优先级中断。换句话说,低优先级的中断会被屏蔽掉。
不可屏蔽中断(non-maskable interrupt, NMI):NMI不能断开,具有最高的优先级。它通常是为由电源故障引发的中断准备的,是一个可以监测危险低电压的简单电路。
中断向量
有时候我们会更在乎中断的处理方法而非其本身的重要性。因此,我们引入了中断向量的概念:
在设备的请求或应答之后,通过中断向量线将中断向量发送到CPU,CPU将向量号作为存储在内存中的中断向量表的索引,设备端存储自己的向量号,提供灵活性。
说白了就是用不同的向量代表不同的处理方法。中断向量可以提供中断程序服务的入口地址。
小练习:下面关于中断的叙述,哪个是不正确的?
- A、一旦有中断请求出现,CPU立即停止当前指令的执行转而去受理中断请求。
- B、CPU响应中断时暂停运行当前程序,自动转移到中断服务程序。
- C、中断方式一般适用于随机事务的出现。
- D、为了保证中断服务程序执行完毕后,能正确返回到被中断的断点继续执行程序,必须进行现场保存操作。
答案
A。显然只能选A吧?因为有优先级的存在。
管态与陷阱
特权模式又称作管态。 复杂的系统经常由几个相互通信的程序来实现。我们希望能够提供硬件检查来确保程序之间没有互相干扰。可以使用CPU提供的管态来避免内存误操作,MMU控制通常只留给管态使用。 但很多DSP都没有管态,通常也没有MMU。
陷阱(trap),也称为软件中断(software interrupt),是一种显式产生异常状态的指令。
- 陷阱最通常的用法是进入管态。
- ARM为软件中断提供了SWI指令:
SWI CODE_1
,这个指令将使CPU进入管态。 - 一个能被处理程序读取的操作码
CODE_1
嵌入到这条指令中。
异常与中断
异常(exception) 是一种内部可以检测到的错误。通常可以将异常当做中断的一种变体。
异常必须有优先级,因为一个操作可能产生不只一个异常。异常的优先级一般由CPU体系结构决定。
中断是异步事件,异常是同步事件!
- 中断是异步事件
- 可能随时发生,与处理器正在执行的内容无关。
- 中断主要由I/O设备产生,可以被启用或禁止。
- 异常是同步事件
- 它是某一特定指令执行的结果,在相同条件下,异常可以重现。
- 内存访问错误、被零除等是典型的异常。
功耗
CMOS VLSI功耗的计算公式:
其中λ为电平翻转比率。
节省功耗的办法
- 降低供电电压
- 以较低的时钟频率运行
- 降低功率消耗而不是能量消耗
- 通过控制线关闭某些当前执行不需要的功能单元
- 时钟门控技术(clock gating)
- 允许部分CPU完全与电源断开以消除泄漏电流
- 电源门控技术(power gating)
下一章就该进入MIPS的学习了……好难啊……