有些设备像内存芯片一样连接到处理器的地址总线和数据总线,正因为地址线和数据线上可以挂多个设备和内存芯片所以才叫“总线”,但不同的设备和内存应该占不同的地址范围。
访问这种设备就像访问内存一样,按地址读写即可,和访问内存不同的是,往一个地址写数据只是给设备发一个命令,数据不一定要保存,从一个地址读出的数据也不一定是先前保存在这个地址的数据,而是设备的某个状态。
设备中可供读写访问的单元通常称为设备寄存器(注意和CPU的寄存器不是一回事),操作设备的过程就是对这些设备寄存器做读写操作的过程,比如向串口发送寄存器里写数据,串口设备就会把数据发送出去,读串口接收寄存器的值,就可以读取串口设备接收到的数据。
访问设备和访问内存不同。内存只是保存数据而不会产生新的数据,如果CPU不去读它,它也不需要主动提供数据给CPU,所以内存总是被动地等待被读或被写。而设备往往会自己产生数据,并且需要主动通知CPU来读这些数据,例如敲键盘产生一个输入字符,用户希望计算机马上响应自己的输入,这就要求键盘设备主动通知CPU来读这个字符并做相应处理,给用户响应。这是由中断(Interrupt)机制实现的,每个设备都有一条中断线,通过中断控制器连接到CPU,当设备需要主动通知CPU时就引发一个中断信号,CPU正在执行的指令将被打断,程序计数器会设置成某个固定的地址(这个地址由体系结构定义),于是CPU从这个地址开始取指令(或者说跳转到这个地址),执行中断服务程序(ISR,Interrupt Service Routine),完成中断处理之后再返回先前被打断的地方执行后续指令。比如某种体系结构规定发生中断时跳转到地址0x0000 0010执行,那么就要事先把一段ISR程序加载到这个地址,ISR程序是由内核代码提供的,中断处理的步骤通常是先判断哪个设备引发了中断,然后调用该设备驱动程序提供的中断处理函数(Interrupt Handler)做进一步处理。