操作系统课程设计 键盘驱动Word文档下载推荐.docx
- 文档编号:7260049
- 上传时间:2023-05-08
- 格式:DOCX
- 页数:20
- 大小:425.68KB
操作系统课程设计 键盘驱动Word文档下载推荐.docx
《操作系统课程设计 键盘驱动Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《操作系统课程设计 键盘驱动Word文档下载推荐.docx(20页珍藏版)》请在冰点文库上搜索。
linux/config.h>
//内核配置头文件。
定义键盘语言和硬盘类型(HD_TYPE)可选项。
在这里还可以定义你的键盘类型:
KBD_FINNISH是芬兰键盘、KBD_US是美式键盘、KBD_GR是德式键盘、KBD_FR是法式键盘。
如#defineKBD_US表示定义美式键盘。
通常,Linux能够在启动时从BIOS中获取驱动器德参数,但是若由于未知原因而没有得到这些参数时,会使程序束手无策。
对于这种情况,你可以定义HD_TYPE,其中包括硬盘的所有信息。
HD_TYPE宏应该象下面这样的形式:
#defineHD_TYPE{head,sect,cyl,wpcom,lzone,ctl}
对于有两个硬盘的情况,参数信息需用逗号分开:
#defineHD_TYPE{h,s,c,wpcom,lz,ctl},{h,s,c,wpcom,lz,ctl}
如果你想让BIOS给出硬盘的类型,那么只需不定义HD_TYPE。
这是默认操作。
四、数据结构的分析
1、数组tty_table[]
使用了一个数组tty_table[]来保存系统中键盘的信息。
每个数组项是一个数据结构tty_struct,用来保存键盘当前状态和正在处理的数据。
用C语言描述如下:
externstructtty_structtty_table[];
//tty结构数组
2、tty_struct数据结构
该终端驱动程序主要使用了一个tty_struct数据结构,在该结构中含有三个功能不同的字符缓冲队列。
一个缓冲队列read_q用来存放用户键入(读入)的原始字符数据;
一个缓冲队列write_q用来存放输出到终端(写到终端)去的数据;
还有一个缓冲队列secondary用来存放已经“加工”过的读入数据,这是在行规则程序把原始数据中的特殊字符如删除(backspace)字符变换后的“熟”(cooked)输入数据。
tty数据结构用C描述如下:
structtty_struct{
structtermiostermios;
//终端io属性和控制字符数据结构。
intpgrp;
//所属进程组。
intstopped;
//停止标志。
void(*write)(structtty_struct*tty);
//tty写函数指针。
structtty_queueread_q;
//tty读队列。
structtty_queuewrite_q;
//tty写队列。
structtty_queuesecondary;
//tty辅助队列(存放规范模式字符序列),
//可称为规范(熟)模式队列。
};
3、tty等待队列数据结构
tty等待队列数据结构用C语言描述如下:
structtty_queue{
unsignedlongdata;
//等待队列缓冲区中当前数据指针(字符数[?
?
])。
//对于串口终端,则存放串口端口地址。
unsignedlonghead;
//缓冲区中数据头指针。
unsignedlongtail;
//缓冲区中数据尾指针。
structtask_struct*proc_list;
//等待进程列表。
charbuf[TTY_BUF_SIZE];
//队列的缓冲区。
4、各个数据结构间的关系图
五、函数的分析
1、采用中断驱动的I/O设备键盘的循环周期
键盘是通过中断来实现的,每当键盘控制器接收到用户的一个键盘操作时,就会向中断控制器发出一个键盘中断请求信号IRQ1.当CPU响应请求就会执行键盘中断处理程序,对于整个系统其流程如下图所示:
2、键盘中断处理程序
这是键盘中断处理程序的入口处,该中断处理程序首先从端口0x60读取当前按键的扫描码。
然后判断该扫描码是否是0xe0或0xe1,如果是的话就立刻对键盘控制器作出应答,并向中断控制器发送中断结束(EOI)信号,以允许键盘控制器能继续产生中断信号,从而让我们来接收后续的字符。
如果接收到的扫描码不是这两个特殊扫描码,我们就根据扫描码值调用按键跳转表key_table中相应按键处理程序,把扫描码对应的字符放入字符缓冲队列read_q中。
然后,在对键盘控制器作出应答并发送EOI信号之后,调用函数do_tty_interrupt()(实际上是调用copy)_to_cooked())把read_q中的字符经过处理后放到secondary辅助队列中。
源程序见keyboard.s的27—71行,程序流程如下图:
3、ctrl和alt键的处理
对于用于具有相同功能的左右ctrl、allt键,它们被按下时,发送的码子是不一样的。
比如:
左控制键ctrl位置是0x1d(对于PC/XT),则右边的控制键就是0xe0,0x1d。
因此,若有ctrl或alt键按下则要分别设置模式标志中相应位。
如果该扫描码之前收到过0xe0扫描码(e0标志置位),则说明按下的是键盘右边的ctrl或alt键,则对应设置ctrl或alt在模式标志mode中的比特位。
源程序见keyboard.s的101—108行,程序流程如下图:
当接收到ctrl或alt键松开的扫描码,对应复位模式标志mode中的比特位。
在处理时要根据e0标志是否置位来判断是否是键盘右边的ctrl或alt键。
源程序见keyboard.s的109—117行,程序流程如下图:
4、caps、scroll、num键的处理
当接收到caps键按下的扫描码时,通过mode中位7可以知道caps键当前是否正处于在按下状态。
若是则返回,否则就翻转mode标志中caps键按下的比特位(位6)和leds标志中caps—lock比特位(位2),设置mode标志和中caps键已按下标志位(位7),并调用set_led开启或关闭LED指示器。
当接收到scroll键按下的扫描码时,翻转leds中对应位(位0),并且根据leds标志重新开启或关闭LED指示器。
当接收到num键按下的扫描码时,翻转leds中对应位(位1),并且根据leds标志重新开启或关闭LED指示器。
源程序见keyboard.s的132—152行,程序流程如下图:
子程序kb_wait用于等待键盘控制器缓冲空。
不存在超时处理-如果缓冲永远不空的话,程序就会永远等待(死掉).源程序见keyboard.s的393—399行,程序流程如下图:
5、数字小键盘的处理
把字符放到缓冲队列是通过子程序put_queue实现的该子程序把ebx:
eax中的最多8个字符添入缓冲队列中。
(edx是所写入字符的顺序al,ah,eal,eah,bl,bh...直到eax等于0。
源程序见keyboard.s的78—99行,程序流程如下图:
重启是通过调用子程序reboot实现的,该子程序通过设置键盘控制器,向复位线输出负脉冲,使系统复位重启(reboot)。
源程序见keyboard.s的404—409行,程序流程如下图:
6、减号键的处理
7、功能键的处理
8、do_self的处理
do_self用于处理“普通”键,也即含义没有变化并且只有一个字符返回的键,源程序见keyboard.s的274—305行,程序流程如下图:
9、左,右shift键的处理
当接收到左或右shift键按下的扫描码,对应置位模式标志mode中的比特位。
当接收到左或右shift键松开的扫描码,对应复位模式标志mode中的比特位。
Shift键处理程序
六、分析体会及亮点说明
这次我分析的这段代码keyboard.s是用AT汇编写的,而我们以前接触的都是Intel汇编,通过老师的指导和查阅一些相关资料我对这两种汇编语言有了一定的了解,因此我读键盘的那段内核代码还比较轻松,我在读代码的时候也发现了一些问题,最初我对caps键的处理有些疑惑,我认为caps键和num键的处理应该是一样的,可是在Linux0.11中caps键作了特殊处理,开始我怀疑代码错了,后来查阅了一些资料,上面都是这样处理的,后来仔细想想,发现我忽略了一个问题,当caps键正处于按下状态时候,我们按下键盘上的字母键,输入的字母就是大写的,这个功能对于num而言是没有的,因此在mode中要设置标志位7表示caps是否正处于按下状态。
相应地,当接收到caps键扫码进行处理。
通过mode中位7可以知道caps键当前是否正处于在按下状态。
在这次课程设计的过程中,使我更加懂得“细致”对于我们学习知识相当重要。
此外,为了说明我对按键处理过程的理解,下面我举例两个例子说明一下:
1、考虑在caps键未锁定的情况下我们按下字母键a时,会触发哪些事件?
按下键a时,键盘控制器会向中断控制器发出一个中断请求信号IRQ1,并将该键对应的键扫码0x1e送入输入缓冲器(端口地址0x60),CPU响应中断,进入键盘的中断服务处理程序_keyboard_interrupt,该处理程序首先从端口0x60读取这个键的扫描码0x1e,由于这个键扫码不等于0xe0且不等于0xe1,所以直接调用按键跳转表key_table中1E对应的子程序do_self,do_self会检测到alt和shift键均位按下,就到普通映射表key_map中根据扫描码取出相应的ASCII码’a’,由于alt键都未按下,caps也未锁定,所以直接将‘a’放到读缓冲队列(read_q)中,然后返回到_keyboard_interrupt中断服务子程序中,向中断控制器发送中断结束信号,将收到的数据转换成规范模式并保存在规范字符缓冲队列中(call_do_tty_interrupt)。
具体流程如下图:
当‘a’键松开时,也会产生中断,并产生0x90扫描码。
调用键盘中断处理程序_keyboard_interrupt,它根据键扫码进行相应操作;
不过此时的在跳转表中对应是none的地址,不做任何事就返回到_keyboard_interrupt,进行与前面键按下相同的操作。
2、考虑同时按下右shift和“@2”键时,会触发哪些事件?
右边的shift被按下时,会发送0xe0和其对应的键扫码0x36,在接收到0xe0时将设置e0标志为0,再向中断控制器发送中断结束信号,将收到的数据转换成规范模式并保存在规范字符缓冲队列中(call_do_tty_interrupt)。
接下来接收到的是键扫码0x36,由于这个键扫码不等于0xe0且不等于0xe1,跳转表key_tabke中对应的是rshift子程序的入口地址,调用rshift子程序设置mode中的1位后返回到_keyboard_interrupt,向中断控制器发送中断结束信号,将收到的数据转换成规范模式并保存在规范字符缓冲队列中(call_do_tty_interrupt)。
然后收到”@2”键按下的中断,根据接收到的键扫码0x02调用按键跳转表key_table中0x02对应的子程序do_self,do_self通过mode标志检测到有shift键同时按下,便根据映射表基址shift_map获取对应的ASCII码‘@’,将‘@’放到读缓冲队列(read_q)中,然后返回到_keyboard_interrupt中断服务子程序中,向中断控制器发送中断结束信号,将收到的数据转换成规范模式并保存在规范字符缓冲队列中(call_do_tty_interrupt)。
七、参考文献
《Linux0.11内核完全注释》赵 炯著
《操作系统概念》AbrahamSilberschatz[美]PeterBaerGalvin著
高等教育出版
《操作系统原理及应用LINUX》王红主编中国水利水电出版
网站http:
//www.oldlinux.org/
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统课程设计 键盘驱动 操作系统 课程设计 键盘 驱动