计算机编程基础之二:IO编程

时间:2021-07-14
本文章向大家介绍计算机编程基础之二:IO编程,主要包括计算机编程基础之二:IO编程使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

概述

所有I/O设备与CPU之间都是异步操作。换句话说,所有的IO设备都是独立于CPU而单独工作的。因此IO设备的数据情况,需要某种方法去通知CPU。

CPU访问外部设备的方式

轮询

方法:CPU通过不断地查询外部设备的状态,如果外设准备好了,就可以向其读写数据。也就是CPU主动去问设备
缺点:CPU利用率太低,响应时间也不固定。

中断

方法:当外部设备准备好了,能过中断信号主动告知CPU可以进行操作了。
特点:CPU利用率高,外部数据处理及时,适合小量数据处理。

DMA

中断方式虽然效率很高,但是对于大批量数据传输就不行了。假如接收一个很大的文件放到内存,外设每收到一包数据就会向CPU发一个中断,大量的中断会导致CPU忙于处理中断反而降低了系统的运行效率。
更好办法是,对于这种大量数据传输不通过CPU搬运,从设备直接传输到内存,这种方式叫做直接内存访问(Direct Memory Access),简称DMA。
其工作方工是,外部设备在数据准备好之后只需要向DMA控制器发一个命令,把数据的地址大小传过去,由DMA控制负责把数据从外部设备直接存放到内存。

M3 I/O硬件

X86 CPU 使用不同的指令来访问内存和外设。
而M3使用内存映射体系结构,这就为内存和IO建立起了统一的地址空间,从而允许CPU通过一般的LDR(load register)STR(store register)指令来访问IO。

CPU的两种工作模式:线程和异常

在主程序或线程执行期间,CPU处在线程模式(thread mode)
在异常处理程序执行期间,CPU处在异常模式(handler mode)
线程模式和异常处理模式以处理器状态寄存器(PSR,Processor Status Register)的0到8位来进行区分。在线程模式下,这些位均为0;在异常处理模式下,通过非0数字来标识不同的异常类型。

进入异常处理程序

当CPU识别出异常时,CPU硬件会自动执行如下操作:
1.压栈:依次压入PSR,当前程序返回地址,LR,R12,R3,R2,R1,R0

2.在进行压栈操作的同时,处理器识别异常,并将异常号记录下来,然后使用该数字从向量表(vector table)中找到相应的异常处理程序地址,赋值给PC。
3.LR的最低4位为全1,表明CPU处于handler mode.
4.handler mode enable. thread SP切换为 handler SP
5.异常处理程序开始执行。

执行行上描述步骤所用的时间,被称为中断延时

为了加快中断响应时间,CPU在设计时会考虑尽可能短地减少中断延时。如:

  • 挂起或放弃当前指令执行;
  • 迟到中断处理
  • 尾链
  • 中断优先级与中断抢占

中断模式下的编程

由于IO与CPU是独立的,所以可以用ISR来收集数据,并放到一个buffer中。等CPU有空了,就来处理buffer中的数据。
最常见的buffer,就是FIFO 形式的,称为队列。
在任何时刻,队列中的数据量依赖于IO数据来的速度和处理程序清掉数据的速度。
队列的这种“弹性”属性,可以对增加数据的任务清除数据的任务进行时间解耦,各干各个的。

DMA模式下的编程

周期性的DMA通常用于较大数据块的搬移,在本次搬移未完成之前,CPU是不能对此缓冲区进行操作的。处理过程如下图:

由此可以看出,CPU处理数据的速度是受限于DMA搬运数据的速度的。

尽管可以使用队列的方式来实现两个异步线程代码进行解耦,但是在使DMA的情况下,每次使用的内存都会很大。常见的用于DMA方式的是双缓冲区(double buffering)

使用方法是:两个缓冲区,DMA与CPU交错使用,使CPU等待数据填充的时间大大缩短,比单缓冲方式将处理速度提高了两倍。

原文地址:https://www.cnblogs.com/hanyli/p/14987505.html