23.键盘

【README】

1.本文内容总结自 B站 《操作系统-哈工大李治军老师》,内容非常棒,墙裂推荐;

2.键盘 是输出型外设;


【1】外设工作原理

【图解】外设工作原理:

  • 步骤1:Cpu向外设控制器发出指令(如写命令),向外设控制器中的寄存器(或存储器)读写数据;如显卡控制器;
  • 步骤2:写入完成后,外设控制器发出中断请求通知cpu写入完成;
  • 步骤3:cpu处理外设中断;

补充:外设驱动主要做3件事情(外设就包括了显示器,键盘,鼠标等)

  • 事情1: cpu向外设控制器的寄存器或端口发出读写指令(out指令),最核心的部分;
  • 前提是cpu需要知道硬件端口,数据格式等细节,而这些细节非常麻烦;
  • 事情2: 操作系统为了隐藏细节,做了一个统一的文件视图,把外设抽象为文件,文件inode结构体就封装了外设端口,数据格式等细节;
  • 事情3:cpu处理外设中断(外设控制器在完成相应操作后会向cpu发出中断) ;

补充2: 其他外设工作原理类似,同上述外设驱动的3件事情;


【2】键盘驱动代码实现

1)键盘中断初始化

 【图解】
1)0x21号中断是键盘中断,键盘中断处理程序为 keyboard_interrupt ;
2) _keyboard_interrupe 代码

_keyboard_interrupt:
	// 把0x60端口里的数据读入到al寄存器; 
	inb $0x60, %al 
	// 调用 key_table + eax*4 
	call key_table(, %eax, 4)

3)处理扫描码 key_table + eax*4  

【图解】
调用 do_self 函数找到键盘按键对应的ASCII码;

3)从 key_map 取出 ASCII 码

 【图解】

  • 说明1)key_map: .byte 0, 27 .ascii “1234567890-=” ...
  • 说明2)shift_map: .byte 0, 27 .ascii “!@#$%^&*()_+” ...  // 按住shift键
  • 说明3)Movb(%ebx, %eax), %al // 把找到键盘按键的ASCII 送入al寄存器
  • 说明4) call put_queue 把ASCII 送入缓冲区(或队列)

4)put_queue 把 ASCII 放入缓冲区 con.read_q

 

【图解】
con.read_ q 中 con 指的是 console 控制器;
Read_q 指的是 读缓冲区;

补充:回显(可显示字符才会回显)


// 字符回显(打出在显示器)
void copy_to_cooked(struct tty_struct* tty) 
{
	GETCH(tty_read_q,c);
	// 判断是否需要回显 
	if (L_ECHO(tty)) {
		PUTCH(c, tty->write_q);
		// 立刻显示在屏幕上 
		tty->write(tty); 
	}
	PUTCH(c, tty->secondary); 
	... 
}

 


【3】键盘处理总结

【3.1】键盘工作步骤

【图解】键盘工作步骤

  • 步骤1:操作系统启动时初始化键盘中断;
  • 步骤2:敲下键盘,发出键盘中断,cpu响应中断,执行键盘中断处理程序 keyboard_interrupt ;
  • 步骤3:keyboard_interrupt 程序从键盘控制器端口读取数据到al寄存器;
  • 步骤4:调用 do_self 函数找到键盘按键对应的ASCII码
  • 步骤5:把 ASCII 放入缓冲区 con.read_q
  • 步骤6:判断字符是否需要回显,若需要,则回显到屏幕上; 

【3.2】操作系统输入输出外设工作原理

把键盘处理流程与显示器处理流程合并在一起,如下图。
因为键盘是输出型外设,显示器是输入型外设;


【图解】
1)外设对外暴露的都是文件接口;
2)Tty设备读函数是 tty_read,tty设备写函数是  tty_write ; 分别操作 read_q 队列,write_q队列;(队列可以理解为缓冲区)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值