ImageVerifierCode 换一换
你正在下载:

keyboard.docx

[预览]
格式:DOCX , 页数:51 ,大小:38.35KB ,
资源ID:10270603      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/10270603.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(keyboard.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

keyboard.docx

1、keyboard键盘体系author: sniff 从什么开始说比较合理呀?就从硬件开始把:严格来说称不上什么键盘体系,但由于键盘的driver code比较的涩晦,所以就称之为键盘体系了。后注:什么叫后注?也就是写完后想说点什么的意思呀!这篇文挡太长了(本来想写的更长,真的,还有一些文件都没有写上去呀),大家还是用“文挡结构图”来看把,厉害把,这么多,全部手写呀。硬件相关硬件,其实有一些内容,但我实在不想一段段的翻译,大家想要的话,我把english文挡发给大家好了。Keyboard Key 键盘代码键盘模式键盘模式有4种, 在Linux 下你可以用kbd_mode -参数 来设置和显示你的

2、模式:1) Scancode mode (raw )raw模式:将键盘端口上读出的扫描码放入缓冲区2) Keycode mode (mediumraw) mediumraw模式:将扫描码过滤为键盘码放入缓冲区3) ASCII mode (XLATE ) XLATE模式:识别各种键盘码的组合,转换为TTY终端代码放入缓冲区4) UTF-8 MODE (UNICODE) Unicode 模式:UNICODE模式基本上与XLATE相同,只不过可以通过数字小键盘间接输入UNICODE代码。键盘模块的上层漫游:键盘模块的最上层严格的说应该是TTY设备,这在以后描述。对于使用者而言,keyboard.c是

3、我们的最上层。在keyboard.c中,不涉及底层操作,也不涉及到任何体系结构,他主要负责:键盘初始化、键盘tasklet的挂入、按键盘后的处理、keymap的装入、scancode的转化、与TTY设备的通信。Keyboard.c是一个大杂烩,包含了大多数keyboard的key的处理,因此代码才变的庞大和复杂,我们可以修改它,让他变的很小(但这样做并不会使空间节省,因为keyboard.c的许多代码是动态加载的)。Keyboard.c中的int _init kbd_init(void) 函数是键盘代码执行的开始点,但keyboard.c并非是一定执行的,你必须先定义CONFIG_VT(Cha

4、racter devices - Virtual terminal)才有效,为什么?因为kbd_init()是在tty_io.c 的 tty_init()中被调用的。 Kbd_init()在进行一些基本初始化后,执行kbd_init_hw(),此函数可以看做是一个统一的上层界面,对于不同的体系或相同体系下不同的board,他们的kbd_init_hw()的实现代码是不同的(同过CONFIG_XXX_XXX来实现),他的实现代码就是操作硬件。 kbd_init_hw()会:检查硬件及有效性、分配资源和中断、操作寄存器的实现函数调用。 初始化一完成,就把keyboard_tasklet放到CPU

5、tasklet中(注意到keyboard_tasklet 是开放出来的,等下可以看到怎么使用它)。 现在就等你按键了,当有按键时,会调用键盘中断处理函数,一般都是体系下的keyboard_interrupt(),此函数会调用到keyboard.c中的handle_scancode() 。 handle_scancode()就是我们的重点,这个函数最终决定了我们按下的key如何处理,在下面会分析他的流程,他主要做:与TTY的通信、keymap的装入、按键的处理。 handle_scancode()处理的结果就是把你按下的key发到不同的处理函数中,一般的,这些函数离最终的结果已经很近了。这其中,

6、大多数的函数都会调用put_queue() 函数。 put_queue()的工作原理就是利用TTY, 它将经过转换的键盘功能码用tty_insert_flip_char()放入到当前TTY的flip buffer中,然后将缓冲区输出任务函数(flush_to_ldisc)添加到控制台任务队列(con_task_queue)并激活控制台软中断执行该任务函数. flush_to_ldisc()翻转读写缓冲区,将缓冲区接收数据传递给tty终端规程的n_tty_receive_buf()接收函数,n_tty_receive_buf()处理输入字符,将输出字符缓冲在终端的循环缓冲区(read_buf)之

7、中.用户通过tty规程的read_chan()读取read_buf中的字符.当多个进程同时读取同一终端时, 使用tty-atomic_read信号灯来竞争读取权.Kbd_init()开始点:int _init kbd_init(void) int i; struct kbd_struct kbd0; /* 定义一个kbd_struct, 他用于保存当前键盘LED灯状态、缺省keymap表、键盘复合锁定状态、一些功能灯的定义、键盘模式定义、及modeflags模式*/ extern struct tty_driver console_driver; /* console_driver这个全局变量

8、是很重要的,他维护着庞大的TTY/Console对象,承当TTY对外的输入和输出 */ kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS; /* 缺省不亮灯 */ kbd0.ledmode = LED_SHOW_FLAGS; /* 缺省,用于显示flags */ kbd0.lockstate = KBD_DEFLOCK; /* 缺省,表示用key_map的第一个表,即没有lock键*/ kbd0.slockstate = 0; /* 没有粘键 */ kbd0.modeflags = KBD_DEFMODE; /* modef

9、lags=0 */ kbd0.kbdmode = VC_XLATE; /* ASCII模式 */ for (i = 0 ; i MAX_NR_CONSOLES ; i+)/* 为每个控制台分配一个KBD的结构 */ kbd_tablei = kbd0; ttytab = console_driver.table; /* ttytab是一个很重要的指针,他维护着当前各个控制台的tty_struct表(即相当于一个2维表),tty_struct可看成/dev/tty*的输入设备,只有在/dev/tty*打开时它才接收输入数据*/* 以下就是涉及到硬件的操作,由于我们没有KBD硬件,因此我们可能希望

10、屏蔽所产生的error信息*/#ifdef CONFIG_SA1100_ROSETTA button_setup(); /* initialize button hardware */#else kbd_init_hw(); /*下面会分析他*/#endif /* 我们希望把keyboard_tasklet 挂到CPU的运行队列中去,下面就是 */ tasklet_enable(&keyboard_tasklet); tasklet_schedule(&keyboard_tasklet); /* 下面register一个电源管理的KBD设备?操作函数为NULL? */ pm_kbd = pm_

11、register(PM_SYS_DEV, PM_SYS_KBC, NULL); return 0;kbd_init_hw()函数:我们已经说了,kbd_init_hw() 相当与一个统一的界面,不同硬件操作代码是不同的,因为是涉及硬件的操作。 对arm体系而言,目前的kbd_init_hw() 提供了4种硬件代码,象如果是ADS板,就要提供ADS的相应代码。 SA1100体系的此函数放在文件include/asm-arm/arch-sa1100/keyboard.h 中。大家可以看到在这个文件中除了kbd_init_hw() 外,还有kbd_setkeycode() / kbd_getkeyc

12、ode()/ kbd_translate()/ 等函数都是函数名相同,处理代码不同。而这些函数都会在keyboard.c中被调用到。 SA1100定义了“CONFIG_SA1100_BRUTUS / CONFIG_SA1100_GRAPHICSCLIENT/ CONFIG_SA1111 / other board”4种已知硬件的操作代码,对于Assabet就会调用other board的代码,也就是无论什么函数都为NULL(因为没有这个硬件呀!),CONFIG_SA1100_GRAPHICSCLIENT也就是ADS板的处理代码(SmartIO芯片决定的),CONFIG_SA1111也有自己的一

13、块KBD芯片,而且功能居然和PC的差不多。 那现在我们怎么办呀(我们的板不知道有没有KBD模块芯片)?我们来挑一个最复杂的来分析把。那就是SA1111了。 我们从kbd_init_hw() 进入把:void _init sa1111_init_hw(void) kbd_request_region(); /* 分配kbd端口,其实根本就不用分配了,对PC来说,0x600x68就是KBD的IO口,对sa1100更不用分配了,所以此函数为NULL*/SKPCR |= (16); /* 即0x4000,0000+0x0200处的register操作 */* 以下初始化KBD的4个register,以

14、便开始下面的test工作 */ KBDCLKDIV = 0; KBDPRECNT = 127; KBDCR = 0x08; mdelay(50); KBDDATA = 0xff; mdelay(50); /* Flush any pending input. */ kbd_clear_input(); if (kbd_startup_reset) /* int kbd_startup_reset =1,所以肯定执行 */ char *msg = initialize_kbd(); /* initialize_kbd() 真正开始init 硬件,出错会return错误message,显示在系统启

15、动的时候 */ if (msg) printk(KERN_WARNING initialize_kbd: %sn, msg); #if defined CONFIG_PSMOUSE psaux_init();#endif /* allocate the IRQ, keyboard_interrupt 是处理函数 */ kbd_request_irq(keyboard_interrupt);#if 0 /*/ for (;) if (KBDSTAT & KBD_STAT_RXF) printk(K_%.2x , KBDDATA & 0xff); if (MSESTAT & MSE_STAT_RX

16、F) printk(M_%.2x , MSEDATA & 0xff); #endif#if 0 /*/ timer_tableCOMTROL_TIMER.fn = pckbd_timer; timer_tableCOMTROL_TIMER.expires = jiffies + 2*HZ/100; timer_active |= 1 driver_data) /* 我们如果直接操作tty是危险的,因为我们不知道tty是否被打开了,所以我们通过tty-driver_data来判断,tty打开的时候,tty-driver_data是被设置的,tty关闭的时候,他被clear */ /* * We

17、touch the tty structure via the ttytab array * without knowing whether or not tty is open, which * is inherently dangerous. We currently rely on that * fact that console_open sets tty-driver_data when * it opens it, and clears it when it closes it. */ tty = NULL; kbd = kbd_table + fg_console; /*kbd_table是kbd的指针,所以kbd就是当前tty的kbd_struct的指针 */ if (raw_mode = (kbd-kbdmode = VC_RAW) /* 我们判断当前的kbd模式是否为VC_RAW,我们知道如果是的话,我们就可以把scancode 直接放到tty_flip_buffe

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1