GeekOS project0

来源:互联网 发布:平板电脑windows系统 编辑:程序博客网 时间:2024/05/18 16:38

 

GeekOSproject0

  • 话说

记得自己前几天做GeekOS的实验时,总以为没有什么,看什么都是粗粗一逛。虽然开始很顺利,但上天总是不会让我养成如此的习惯的,

扔了一个砖头给我,搞的我好几天头蒙蒙的。后来才知道,自己只是因为少看了一行“最没必要”看的。后悔莫及,害我苦苦想了N天只有“天才”(分析Linux内核)才会去思考的问题。结果只花了吃饭的时间就搞定了那个问题。


GeekOSproject0说白了就是先让你练练手,以免对它产生畏惧。所以在作这个实验的过程中,有再大的困难也要忍住,坚持一下,未来海阔天空。

  • 简述

GeekOSproject0是让自己实现一个类似于DosLinux字符界面的效果,当然,功能只有简单的输入输出。


我们着重说“输入输出”,因为我们是在说它吗!哈哈!开始喽!


输入设备:键盘,标准输入端

输出设备:屏幕,标准输出端

所以,我们要用到的源文件是:keyboard.cscreen.c。当然少不了main.c


先凭自己的想像,想像以下输入输出的过程:

1、在开机,并且电脑上操作系统可以至少实现键盘输入字符和屏幕输出字符的前提下!!;

2、按键;

3、按键产生的电流解析为二进制串(应该至少有8位,一个字节,字符就占一个字节),二进制串通过查键盘扫描码表(先记住有这个东西就成了,不要计较,就是这样定的),找到对应的字符。

但是我们的键盘上还有其他伟大的键呢!ShiftCtrlAltCapsLockDelInsEscHomePgUp……他们呢?再说键1还有!的附加功能呢?我们把他们归类吧。有附加功能的一般是通过ShiftFn(目前不会用到,我也不会啊,哈哈),CapsLock键是个特例,其他键我还没研究,不过DelInsDel键是一个不错的对象。因此我们可以再扩展以下二进制串的位数,把上面的键也加进去,当作标示位,后面的自然就是字符位了,所以二进制串应该为16位,也就是两个字节。

4、将字符放入“某个地方”,GeekOS中是缓冲区(队列或栈)。

5、将字符从“某个地方”取出,输出到屏幕上。

以上只是把按键输出到屏幕上,没有DelIns之类的操作。若要实现DelIns,则要用到源文件screen.c


上面就是输入输出的简单过程。其实在project0中,我们的任务只是把“某个地方”的字符输出到屏幕上,并且已经提供了所有的函数,我们只是简单的把函数组装以下罢了。但了解更多也不错!哈哈!


  • 实现

在头文件keyboard.h中,定义了我们将会用到的一切(除非你认为你有必要了解或领悟或扩展其他的功能,否则你可以忽略它的存在):

·定义键盘的I/O端口(状态和数据);

……

·定义“释放按键”(当我们按键的时候会触发两个事件——按下和释放(弹起)事件,我们一般只接收按下事件(习惯问题));

·定义标示位(就是上面所说的Shift之类的特殊按键,还有功能键,还有按键是否释放);

·对每一个特殊按键以及功能键的定义;

……

·定义函数头;

在源文件keyboard.c中,定义了两个数组,分别是按下或未按下Shift键时,二进制串与字符的对应关系,一看就会明白的。还有一些其他的:

·字符队列(用来存储从键盘输入的字符),还有对队列处理的一些函数,如判断对空或堆满,入队出队;

·处理键盘终端的函数(中断的概念百度就可以了,理解最好)——理解这个函数不是很困难哦,现在只要知道它将按键字符插入了字符队列就可以了;

·初始化函数(不去管它,只要知道它的功能就可以了);

·函数boolRead_Key(Keycode* keycode)和函数KeycodeWait_For_Key(void)的功能是相仿的,它们是我们将要用到的函数。功能是在“字符队列”中读取一个字符,就是出队操作。我们要做的就是把出队的字符打印到屏幕,用Print函数就可以实现。


main.c函数中,开始是几个初始化函数,下面是打印函数Print。函数TODO是一个死循环,所以要注释掉。我们要做的就是实现一个函数,从Wait_For_KeyRead_Key获取字符,用Print输出按键是“按下状态”(未释放)的非特殊字符。

代码贴出:


#defineEND_PRINT ('D' | KEY_SHIFT_FLAG | KEY_CTRL_FLAG)


voidPrintf(ulong_t arg)

{

Keycodekey;


while(1)

{

if(Read_Key(&key))

{

if(key== END_PRINT)

{

Exit(1);

}

else

{

if(!( (key & KEY_SPECIAL_FLAG) || (key & KEY_RELEASE_FLAG) ) )

{

if(key== '/r')

{

Print("/n");

}

else

{

Print("%c",key);

}

}

}

}

}

}


长篇大论也许就这一段有用,哈哈!

希望大家实现更丰富的功能,例如删除和插入、大写功能等等功能键。

我会时刻更新的,也希望大家多多提供好的意见,好的实现。




 

 

 

 

原创粉丝点击