IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 哈工大李治军老师操作系统实验七----终端设备控制 -> 正文阅读

[嵌入式]哈工大李治军老师操作系统实验七----终端设备控制

实验内容

当按下F12时,控制端所有字母变成* ,再按一次则恢复,以此类推…

实验目的

  • 加深对操作系统设备管理基本原理的认识,实践键盘中断、扫描码等概念
  • 通过实践掌握Linux0.11对键盘终端和显示器终端的处理过程。

实验需要具备的基本知识

键盘I/O是一种典型的中断驱动事件,既然是中断就对应需要:1. 中断号 2. 中断处理函数。中断号实验手册已经通过set_trap_gate函数告诉我们是0x21 (十进制的33) ,中断处理函数也已经告诉我们是keyboard_interrupt函数。因此我们就搞清楚了我们需要进行修改的地方。

键盘输入与显示器显示整体流程

这里先给出一张图(来源Linux内核0.11完全注释),这张图展示了整个过程。
在这里插入图片描述

当用于在键盘上键入一个字符时,随即引起键盘中断,中断处理程序负责从键盘控制器读取对应的键盘扫描码,然后采用映射表译成相应字符并放入tty读队列read_q。 然后通过中断处理程序do_tty_interrupt() 调用copy_to_cooked() 对该字符进行过滤处理,并放到tty辅助队列secondary 中,同时也把字符放入tty写队列write_q 当中并调用写控制台函数con_write() ,此时如果该终端的回显(echo )属性是设置了的,那么会直接显示到屏幕上。

do_tty_interrupt() 以及copy_to_cooked() 函数在tty_io.c 中实现。

con_write() 函数是在console.c文件当中实现

总结来说:

主要涉及两个程序:键盘中断处理程序(keyboard.S )负责把用户键入的字符放到read_q缓冲队列当中;另外一个是屏幕显示处理程序(console.c )用于从write_q队列当中取出字符并显示到屏幕上。

基于以上认识,你就能明白大部分教程里面都有一张图,这张图展示了三个缓冲队列以及函数之间的关系,如下所示:

在这里插入图片描述

从键盘键入的数据可以写入文件,也可以回显到屏幕当中。我们只关心回显那条路。通过图中分析可知,我们只需要对console.c 文件(/linux/kernel/chr_drv 目录下)当中负责给终端写入字符的con_write 函数加以修改就OK。那么如何修改?

con_write() 函数往屏幕缓冲区写入的数据取决于是否按下f12, 因此我们需要时时刻刻监控是否按下f12。为此,我们可以定义一个全局变量switch_show_char_flag来检测当前f12的状态,以及一个能够修改这个全局变量的回调函数。(这个回调函数不就是我们按下f12之后的中断相应函数么?)

keyboard.S 当中定义了f12响应函数:

.long none,none,do_self,func	/* 54-57 sysreq ? < f11 */
.long func,none,none,none		/* 58-5B f12 ? ? ? */
.long none,none,none,none		/* 5C-5F ? ? ? ? */
.long none,none,none,none		/* 60-63 ? ? ? ? */
//可知func函数是f12处理函数

我们可以把func函数替换成我们自定义的函数用于更新全局变量switch_show_char_flag

自此实验思路就有了!

实验过程

通过以上分析,我们可以将实验分为以下几个步骤。

  1. 设置监控变量S
  2. 重写f12响应函数func用来修改S
  3. 根据S判断con_write函数是否写入*
  • 在include/linux/tty.h当中声明监控变量S以及响应函数(这个可以自定义,比如我定义为press_f12_handle

    extern int switch_show_char_flag;
    void press_f12_handle(void);
    
  • kernel/chr_drv/tty_io.c末尾添加,用来定义设置监控变量S以及响应函数

    int switch_show_char_flag=0;
    void press_f12_handle(void)
    {
       switch_show_char_flag=1-switch_show_char_flag;
    }
    
  • linux 0.11/chr_drv/keyboard.S 中将我们自定义的响应函数替代默认的func函数

    .long none,none,do_self,func	/* 54-57 sysreq ? < f11 */
    //.long func,none,none,none		/* 58-5B f12 ? ? ? */
    .long press_f12_handle,none,none,none		/* 58-5B f12 ? ? ? */
    .long none,none,none,none		/* 5C-5F ? ? ? ? */
    .long none,none,none,none		/* 60-63 ? ? ? ? */
    
    
  • 最后在Linux 0.11/kernel/chr_drv/console.c 当中修改con_write函数

    ......
    ......
    if (c>31 && c<127) {
    	if (x>=video_num_columns) {
    		 x -= video_num_columns;
    		 pos -= video_size_row;
    		 lf();
    			 }
        /*加入一段判断语句就OK*/
    			 if(switch_show_char_flag==1)
    			 {
    		  if((c>='A'&& c<='Z')||(c>='a'&&c<='z')||(c>='0'&&c<='9'))   c='*';
    			 }
        
    		    __asm__("movb attr,%%ah\n\t"
    			        "movw %%ax,%1\n\t"
    					 ::"a" (c),"m" (*(short *)pos)
    				   );
    		       pos += 2;
    			   x++;
    		     } 
    ......
    ......
    

实验结束,编译运行看看结果吧!

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-09-04 17:42:22  更:2021-09-04 17:44:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 2:01:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码