zoukankan      html  css  js  c++  java
  • 理解操作系统对中断的处理

    File:      ThinkInt.txt
    Name:      理解操作系统对中断的处理
    Author:    zyl910
    Blog:      http://blog.csdn.net/zyl910/
    Version:   V1.01
    Updata:    2006-6-20


      以前看《操作系统》时,总觉得书上说得太抽象,理解不了。但最近编写一个键盘处理的小程序时,慢慢的理解了操作系统对中断的处理的那些概念。

      本来我是使用 Int 16h 中断来接收键盘输入的,但是该方法不能很好的解析组合键,而且无法获知某个按键是否按下。所以后来我决定 挂接IRQ0、访问60h端口,自己解析扫描码来处理键盘输入。


    一、中断时只接收数据

      最开始时为了研究扫描码,我在中断例程中用printf显示扫描码。但很快发现,会因printf带来的重入性问题导致程序出现许多莫名其妙的问题,而且在中断时占用太多时间会影响系统运行效率。
      于是我修改了设计,定义了一个扫描码队列,每次中断发生时向扫描码队列添加项目。然后在主函数循环检查扫描码队列,并进行处理。


    二、系统分层

      最开始看到《操作系统》关于系统分层时总有点不太理解,觉得那是将简单的事情搞复杂。但是这次处理键盘扫描码时发现:必须分层!
      有两个原因。一是因为扫描码牵涉到底层细节,比如 Ex 是扩展按键前导字节,x表示后面有几个字节的数据,处理起来极其复杂。二是由于中断时修改了扫描码队列,所以访问扫描码队列必须关中断,如果老是直接访问扫描码队列会影响系统运行效率,甚至可能会导致中断丢失。

      最后觉得至少得分四层:
        扫描码队列:底层的键盘扫描码。
        键盘按键状态:记录每个键盘按键的状态。注意是指单独的按键,类似DirectInput的DK的按键处理。比如:方向键上与小键盘8是不同的按键。
        功能按键队列:解析按键功能含义,类似Windows的虚拟键码。比如:无论是方向键上,还是小键盘8都是指“上”这个功能。
        字符消息:字符消息是用于文本输入的,比如CapsLock、Shift用于切换字母大小写。为了支持多语言输入和输入法,建议使用DWord来存放31位Unicode编码。


    三、内核线程

      有两种按键状态,一种是键盘按键状态,一种是输入按键状态。先前我们按队列方式实现的实际上是输入按键状态,表示当前输入队列环境下的的按键状态;而键盘按键状态是指当前键盘上的按键状态。
      比如当按下空格键时,空格键的扫描码进入扫描码队列。当程序分析扫描码队列时,肯定认为空格键时按下的,所以“输入按键状态”认为空格键处于按下状态。但是此时在键盘上的空格键很可能已经释放了,所以“键盘按键状态”认为空格键处于未按下状态。
      所以我们需要在中断后立即分析数据,以实现“键盘按键状态”。
      注意是8259发送EOI以通知中断事务结束的,所以我们可以在发送EOI后处理数据,然后再使用iret指令从中断例程中返回。
      在发送EOI后的数据操作代码是什么?就是所谓的内核线程。内核态与用户态的定义并不是那么绝对,我们可以这样定义——非中断时的操作为用户态,在中断例程中的操作为内核态。其实保护模式跟这个差不多的,只不过它有明确的“环”概念及权限保护机制。
      怎么解决内核线程重入问题呢,需要仔细设计。

    变量:
    bkbinkmd:处于键盘内核线程中

    中断例程{
     取得按键扫描码
     向扫描码队列填充数据
     if (bkbinkmd) {
      发送EOI
      /* 仍然由内核线程处理数据 */
      iret
     }else{
      发送EOI
      bkbinkmd = TRUE
      call 键盘处理函数 //内核线程
      iret
     }
    }


    键盘处理函数{
     do{
      cli
       取走扫描码队列中的所有数据。假设数据长度为cbBuf
       if (cbBuf > 0) bkbinkmd = FALSE
      sti
      分析数据
     }while(cbBuf > 0) // 尝试重复,因为中断可能修改了数据
    }

    四、总结

      《操作系统》教材太过于浓缩,只讲设计思路,不讲设计细节。只有真正接触具体设计时,才能真正明白那些设计思路的作用。

    Updata
    ~~~~~~
    [V1.01]2006-6-20
    重写“内核线程”部分

    [V1.00]2006-6-17
    基本内容

    作者:zyl910
    版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0.
  • 相关阅读:
    【WPF】wpf image控件加载网络图片不显示问题,
    【VS】vs修改大小写快捷键
    【C#】菜单功能,将剪贴板JSON内容或者xml内容直接粘贴为类
    【异常】调用的目标发生了异常
    【MySQL】函数IFNULL、设置默认时间
    【Kindle】pdf转mobi适合kindle查看格式
    【WPF】中的文字修饰——上划线,中划线,基线与下划线
    vscode使用Eslint + prettier + beautify 格式化vue 代码不换行
    Office文件转PDF
    MSSQL同步刷新视图字段长度和源表保持一致
  • 原文地址:https://www.cnblogs.com/zyl910/p/2186640.html
Copyright © 2011-2022 走看看