《30天自制操作系统》学习笔记_day07

1. 获取按键编码

改进一下int.c中的inthandler21函数
在这里插入图片描述
这里io_out8(PIC0_OCW2,0x61)函数的目的是通知PIC在中断发生以后继续监视IRQ1中断是否发生,这样我们就可以在按下第一次按键后还能按下第二次。如果不通知PIC继续监视,那么不管下次键盘输入什么信息,系统都无法感知了。
在这段函数前面有这样一句定义:#define PORT_KEYDAT 0x0060 0x0060设备是键盘。
将从键盘获得的信息赋值给data,然后写入内存,进一步输出。
make run一下:
在这里插入图片描述
可以显示每个按键的编码,并且松开后也会显示一个数字,既能监测按下键,还能监测松开键。

2.加快中断处理

中断处理应当尽可能迅速,在处理中断期间,其他的操作都不能进行,如果处理时间太长,会导致运行不连贯。
在上段程序中,我们将字符显示程序写在了中断处理程序中,而字符显示程序要耗费大量的运算。因此正确的做法是先将按键的编码接收下来,保存到变量当中。然后HairMain去查看这个变量,如果有数据那么就显示。
打开haribote04b 在int.c中可以看到:

在这里插入图片描述
我们在bootpacl.h中定义了一个结构体:
在这里插入图片描述
flag变量用于表示缓冲区是否为空,如果为0表示缓冲区为空,那么我们就向里面存入数据。
最后在bootpac.c最后的io_halt无线循环中加入:
在这里插入图片描述
首先用io_cli指令屏蔽中断,防止在执行后面的处理时突然有中断进来。
如果flag=0说明键还没有被按下,所以继续执行所以干脆继续执行io_hlt
如果flag=1 首先会将data的值存入变量i,然后通过io_sti开放中断,再显示字符。

试着make run一下:
在这里插入图片描述
会发现按下右crtl键时,不论按下还是松开都是显示E0。
作者在这里讲解了这个原因:
在这里插入图片描述
在这里插入图片描述
简单来说就是数据被舍弃导致接收的数据不完整。

3.制作FIFO缓冲区

在第二代最后出现的问题可以通过制作更大空间的缓冲区解决。
打开harib04c的int.c可以看到:
在这里插入图片描述
在这里插入图片描述
制作了32个字节的缓冲区,这样就能存放多个数据。
取出数据的程序如下:
在这里插入图片描述
我们试着make run一下:
按下右ctrl后在这里插入图片描述
已经可以正常接收数据。

4.改善FIFO缓冲区

第三点的FIFO缓冲区通过不断地移送数据来获得新的写入位置,当数据多时最多需要移动32个,在禁止中断期间耗费时间进行数据移送会导致系统性能下降。

改善FIFO的数据读入读出思路,作者参考双向链表的思路对代码进行了改进。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
再次make run以后能够正常运行,缓冲区既能够记录大量数据,而且执行速度还快。

5.整理FIFO缓冲区

为了使FIFO缓冲区具有更好的通用性,能够用于鼠标等中断的处理,将结构进一步优化:
在harib04e中
首先是FIFO结构体,打开bootpack.c可以看到:
在这里插入图片描述
buf是缓冲区的地址,size是缓冲区的大小,free用于保存缓冲区里没有数据的字节数的个数。p和q分别代表读入和读出地址。
打开fifo.c:
可以看到缓冲区的初始化函数,我们的缓冲区没有预定义大小,而是可变的,通过参数size进行设定。
在这里插入图片描述
然后是缓冲区的读入函数:
注意这里是有返回值的函数。
在这里插入图片描述
以及从缓冲区中读出的函数:
在这里插入图片描述
作者新增加了一个用于查看缓冲区状态的函数:
在这里插入图片描述
使用以上函数在int.c中写成:
在这里插入图片描述

在bootpack.c中写成:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
程序还是很好理解的,在这里我差不多明白了缓冲区的意义,每按下一次键都会产生两个中断,如果在没有使用缓冲区时,会导致第二次中断的数据因为无法存入变量而被丢弃,使用了缓冲区,只要没有溢出,可以保存每次中断的数据。在HariMain中再将这些数据输出。

如果再make run一下,发现运行完好。

6.鼠标

书中已经告诉了我们鼠标的背景,我们需要设置两个地方 鼠标的控制电路和鼠标本身 才能让操作系统正确的支持鼠标。
鼠标控制电路包含在键盘控制电路里,如果键盘控制电路初始化正常完成,那么鼠标电路控制器也就能正常完成。
打开harib04f
在这里插入图片描述
函数wait_KBC_sendready的作用是让键盘控制电路做好准备,等待控制指令的到来。
从书里可以看到
在这里插入图片描述
在这里插入图片描述
接下来是init_keyboard函数,他的作用是一边确认是否可以向键盘控制电路中传送信息,一边发送模式设定指令。
在这里插入图片描述
在预定义中可以看到这些值。
模式设定的指令是0x60,利用鼠标的模式号码是0x47。

接下来发送鼠标激活指令,归根到底还是向键盘控制器发送指令。
在这里插入图片描述
如果向键盘控制电路发送0x64下一个数据就会发个鼠标。
从这里可以看到 0x00641其实就是键盘控制电路

鼠标收到信息以后,会立即向cpu发送答复信息,也就是0xfa。
在这里插入图片描述
在HariMain中调用这两个函数,就完成了鼠标控制电路的初始化和鼠标本身的激活。

我们make run一下:
在这里插入图片描述
可以正常显示鼠标中断,可能读者到这里不知道为什么会显示信息,其实在int.c中我们就有定义中断的处理函数。
在这里插入图片描述
在nasfunc.nas有完整调用这个函数的汇编指令
在这里插入图片描述
然后我们将这个中断注册到了PIC中
在这里插入图片描述

7.接收鼠标数据

取出鼠标的中断数据和键盘原理几乎相同,我们更改中断处理函数:
在这里插入图片描述
不同的是在这里我们既要告诉从PIC第4号也就是IQR12中断已经受理完成,还要告诉主从连接的PIC2号中断已经受理完成,否则主PIC就会忽略从PIC的下一个中断请求。

鼠标相比键盘会有更多的数据,所以鼠标的缓冲区为128字节。
取得的数据中,如果键盘和鼠标的FIFO都空了,那么就执行HLT,如果不是两者都空,就先检查keyinfo,然后检查mouseinfo。
在这里插入图片描述
如果细心一点可以发现,处理按键中断和鼠标中断的函数获取data数据指令一模一样,都是来自设备0x0060。这是因为鼠标的控制电路就在键盘中,如果想区分数据是来自鼠标还是键盘,还是要靠中断号来区分,不同的中断会调用这两个函数中的一个,从而将数据写进正确的缓冲区。
在这里插入图片描述
我们make run一下:

随便移动鼠标就会产生中断,并且显示出来。
在这里插入图片描述
并且最开始的内容确实是FA,也就是鼠标激活的时候,鼠标向cpu发送的信息。
在这里插入图片描述
如果按下键盘,会像之前一样进行响应。
在这里插入图片描述

今天的内容就是这样,收工!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值