博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自制操作系统Antz day11——实现shell(下)命令响应
阅读量:6256 次
发布时间:2019-06-22

本文共 10071 字,大约阅读时间需要 33 分钟。

我已经规范了系统代码风格,类似于按照linux分包,把各部分功能区分开了

在之前的任务中,我们已经通过直接操作显卡驱动完成了简单的图形化。

需要了解之前的部分:

直接操作显卡请参考day03

简单图形化的实现请参考day09

键盘按键中断响应请参考day10

Makefile

项目目录

s

一 . 如何实现命令缓存

在之前已经完成了键盘的响应工作,但这种响应却是有很大的问题,比如说对于一次按键的两次中断处理。后来我把两种中断都加入了响应判断中,这样就不会有之前第10天所提到的bug了。

* 在替换函数中完成识别。修改如下

char* replace_char(char s[40]){    char *chr = "$" ;    if((strcmp(s,"1E")==0)||(strcmp(s,"9E")==0)){            chr = "a" ;    }else if((strcmp(s,"30")==0)||(strcmp(s,"B0")==0)){            chr = "b" ;    }    ... // 省略    return chr ;

* 这里是一些功能按键的识别修改

// Enter  -> 回车键 响应之前缓存的命令 换行    if((strcmp(s,"1C")==0)||(strcmp(s,"9C")==0)){            action_command(binfo);  //响应命令            write_x = 58 ;   //下面是换行            write_y += 19 ;            putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "AntzOS>");    }     // F1 -> 终端刷新  类似于clear命令    else if((strcmp(s,"3B")==0)||(strcmp(s,"BB")==0)){  //关于F1的响应中断            sprintf(command,"%s","");  // 命令缓存清空            flag = 0 ;  // 按键模式回复默认,这个看第10天,本质目的是为了处理一次按键的两次终端            new_pe(binfo);  // 通过操作显存直接刷新当前终端            putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "AntzOS>");    }    //  Backspace -> 删格键    else if(strcmp(s,"0E")==0){            // 回退            write_x -= 8 ;            boxfill8(binfo->vram, binfo->scrnx , COL8_000000,  write_x,     write_y,     write_x+19, write_y+19);            if(write_x<=58){                write_x = 146 ;                write_y -= 19 ;            }    }

这些就是按键识别上目前修改的内容了。

接下来我们要添加一个功能,在每次按键之后,不但在屏幕上显示这个键,而且将他缓存在缓冲区,在下次回车的时候进行识别,并清空。

先来看一个简单的demo

// command数组就是命令缓存区char  command[100]  = "";void add_command(char *s)  {     sprintf(command,"%s%s",command,s); }void action_command(){    // 响应}

二 . 实现

command就是一个命令缓存数组,每次按键之后调用add_command()命令将这次的按键保存。

sprintf()这个函数是字符串格式化命令,主要功能是把格式化的数据写入某个字符串中。sprintf 是个变参函数。使用sprintf 对于写入buffer的字符数是没有限制的,这就存在了buffer溢出的可能性。

我们使用sprintf函数直接在command后面添加了s字符。

那么在下次按下Enter的时候,我们只需要调用action_command,并且在里面识别是什么命令,然后做出合适的响应即可。

来看看完整的命令缓冲区实现。

// 指令缓存,但是因为中断响应的时间问题,终端输入速度要非常慢char  command[100]  = "";void add_command(char *s)  {            if(strcmp(s," ")==0){        sprintf(command,"%s%s",command,"");    }else if(strcmp(s,"$")){        //忽略这种错误输入    }else {        sprintf(command,"%s%s",command,s);      } }void action_command(struct BOOTINFO *binfo){        // action command 响应命令        // ls命令        // data命令        if(strcmp(command,"data")==0){            // get new data;            write_y += 19 ;            putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "AntzOS in 2018");        }else if(strcmp(command,"cls")==0){            flag = 0 ;            new_pe(binfo);        }else if(strcmp(command,"version")==0){            write_y += 19 ;            putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "Antz.version.1.1");        }else if(strcmp(command,"help")==0){            // help内容过多,显示在图形化界面区域                    }else if(sizeof(command)>=1){                write_y += 19 ;                putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "Not Found");        }        // 命令缓存清除        sprintf(command,"%s","");}

现在使用Makefile来生成这个支持命令的img镜像。

make img

使用虚拟机打开镜像,结果如下

os

终端主要代码如下:

int write_x = 55 ;int write_y = 57 ;char* replace_char(char s[40]){    char *chr = "$" ;    if((strcmp(s,"1E")==0)||(strcmp(s,"9E")==0)){            chr = "a" ;    }else if((strcmp(s,"30")==0)||(strcmp(s,"B0")==0)){            chr = "b" ;    }else if((strcmp(s,"2E")==0)||(strcmp(s,"AE")==0)){            chr = "c" ;    }else if((strcmp(s,"20")==0)||(strcmp(s,"A0")==0)){            chr = "d" ;    }else if((strcmp(s,"12")==0)||(strcmp(s,"92")==0)){            chr = "e" ;    }else if((strcmp(s,"21")==0)||(strcmp(s,"A1")==0)){            chr = "f" ;    }else if((strcmp(s,"22")==0)||(strcmp(s,"A2")==0)){            chr = "g" ;    }else if((strcmp(s,"23")==0)||(strcmp(s,"A3")==0)){            chr = "h" ;    }else if((strcmp(s,"17")==0)||(strcmp(s,"97")==0)){        chr = "i" ;    }else if((strcmp(s,"24")==0)||(strcmp(s,"A4")==0)){        chr = "j" ;    }else if((strcmp(s,"25")==0)||(strcmp(s,"A5")==0)){        chr = "k" ;    }else if((strcmp(s,"26")==0)||(strcmp(s,"A6")==0)){        chr = "l" ;    }else if((strcmp(s,"32")==0)||(strcmp(s,"B2")==0)){        chr = "m" ;    }else if((strcmp(s,"31")==0)||(strcmp(s,"B1")==0)){        chr = "n" ;    }else if((strcmp(s,"18")==0)||(strcmp(s,"98")==0)){        chr = "o" ;    }else if((strcmp(s,"19")==0)||(strcmp(s,"99")==0)){        chr = "p" ;    }else if((strcmp(s,"10")==0)||(strcmp(s,"90")==0)){        chr = "q" ;    }else if((strcmp(s,"13")==0)||(strcmp(s,"93")==0)){        chr = "r" ;    }else if((strcmp(s,"1F")==0)||(strcmp(s,"9F")==0)){        chr = "s" ;    }else if((strcmp(s,"14")==0)||(strcmp(s,"94")==0)){        chr = "t" ;    }else if((strcmp(s,"16")==0)||(strcmp(s,"96")==0)){        chr = "u" ;    }else if((strcmp(s,"2F")==0)||(strcmp(s,"AF")==0)){        chr = "v" ;    }else if((strcmp(s,"11")==0)||(strcmp(s,"91")==0)){        chr = "w" ;    }else if((strcmp(s,"2D")==0)||(strcmp(s,"AD")==0)){        chr = "x" ;    }else if((strcmp(s,"15")==0)||(strcmp(s,"95")==0)){        chr = "y" ;    }else if((strcmp(s,"2C")==0)||(strcmp(s,"AC")==0)){        chr = "z" ;    }else if((strcmp(s,"39")==0)||(strcmp(s,"B9")==0)){        chr = " " ;    }    return chr ;}int flag = 1 ;// 指令缓存,但是因为中断响应的时间问题,终端输入速度要非常慢char  command[100]  = "";void add_command(char *s)  {/*if(strcmp(s," ")==0){    sprintf(command,"%s%s",command,"");}else    if(strcmp(s,"$")){                //忽略这种错误输入        }else {    }*/        sprintf(command,"%s%s",command,s);}void action_command(struct BOOTINFO *binfo){        // action command        // ls        // data        if(strcmp(command,"data")==0){            // get new data;            write_y += 19 ;            putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "AntzOS in 2018");        }else if(strcmp(command,"cls")==0){            flag = 0 ;            new_pe(binfo);        }else if(strcmp(command,"version")==0){            write_y += 19 ;            putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "Antz.version.1.1");        }else if(strcmp(command,"help")==0){            // help内容过多,显示在图形化界面区域        }else if(sizeof(command)>=1){                write_y += 19 ;                putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "Not Found");        }        // 命令缓存清除        sprintf(command,"%s","");}void key(struct BOOTINFO *binfo,char s[40]){    if((strcmp(s,"1C")==0)||(strcmp(s,"9C")==0)){            action_command(binfo);            write_x = 58 ;            write_y += 19 ;            putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "AntzOS>");    }else if((strcmp(s,"3B")==0)||(strcmp(s,"BB")==0)){  //关于F1的响应中断            sprintf(command,"%s","");            flag = 0 ;            new_pe(binfo);            putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "AntzOS>");    }else if(strcmp(s,"0E")==0){            // 回退            write_x -= 8 ;            boxfill8(binfo->vram, binfo->scrnx , COL8_000000,  write_x,     write_y,     write_x+19, write_y+19);            if(write_x<=58){                write_x = 146 ;                write_y -= 19 ;            }    }else {            //putfonts8_asc(binfo->vram, binfo->scrnx,  write_x,  write_y, COL8_FFFFFF, s);            putfonts8_asc(binfo->vram, binfo->scrnx,  write_x,  write_y, COL8_FFFFFF, replace_char(s));            add_command(replace_char(s));            write_x += 8 ;            // 添加响应区            //清除            //boxfill8(binfo->vram, binfo->scrnx, COL8_008400 , 300    ,240    ,310    ,250);            //打印字符 Only use debug            //putfonts8_asc(binfo->vram, binfo->scrnx,  300,  240 ,COL8_000000, s) ;    }    if(write_x>148){        write_x = 58 ;        write_y += 19 ;        //putfonts8_asc(binfo->vram, binfo->scrnx, 4, 57, COL8_FFFFFF, "AntzOS>");    }    if(write_y>180){         new_pe(binfo);        putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "AntzOS>");    }}void main(void){    struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;    char s[40], mcursor[256], keybuf[32], mousebuf[128];    int mx, my, i;    init_gdtidt();    init_pic();    io_sti(); /* PIC的初始化已经完成*/    fifo8_init(&keyfifo, 32, keybuf);    fifo8_init(&mousefifo, 128, mousebuf);    io_out8(PIC0_IMR, 0xf9); /* 开放PIC1和键盘中断(11111001) */    io_out8(PIC1_IMR, 0xef); /* 开放鼠标中断(11101111) */    init_keyboard();    init_palette();    init_screen8(binfo->vram, binfo->scrnx, binfo->scrny);    putfonts8_asc(binfo->vram, binfo->scrnx,  0,  0, COL8_FFFFFF, "Terminal-Antz");    putfonts8_asc(binfo->vram, binfo->scrnx,  0,  0, COL8_000000, "Terminal-Antz");    putfonts8_asc(binfo->vram, binfo->scrnx,  107,  0, COL8_000000, "|-|o|x|");    putfonts8_asc(binfo->vram, binfo->scrnx, 4, 19, COL8_FFFFFF, "AntzOS> SayHello()");    putfonts8_asc(binfo->vram, binfo->scrnx, 4, 38, COL8_FFFFFF, "Hello My AntzOs.");    putfonts8_asc(binfo->vram, binfo->scrnx, 4, 57, COL8_FFFFFF, "AntzOS>_");     for (;;) {        io_cli();        if (fifo8_status(&keyfifo) + fifo8_status(&mousefifo) == 0) {            io_stihlt();        } else {            if (fifo8_status(&keyfifo) != 0) {                i = fifo8_get(&keyfifo);                io_sti();                sprintf(s, "%02X", i);                if (flag){                    key(binfo,s);                }                if(flag==1){                    flag = 0 ;                }else {                    flag = 1 ;                }            }          }    }}void new_pe(struct BOOTINFO *binfo){    write_x = 58 ;    write_y = 19 ;    // 右边并没有保存    init_screen8(binfo->vram, binfo->scrnx, binfo->scrny);    putfonts8_asc(binfo->vram, binfo->scrnx,  0,  0, COL8_FFFFFF, "Terminal-Antz");    putfonts8_asc(binfo->vram, binfo->scrnx,  0,  0, COL8_000000, "Terminal-Antz");    putfonts8_asc(binfo->vram, binfo->scrnx,  107,  0, COL8_000000, "|-|o|x|");    // 此处保留此输出,交给调用者自己    //    putfonts8_asc(binfo->vram, binfo->scrnx, 4, write_y, COL8_FFFFFF, "AntzOS>");}
你可能感兴趣的文章
在Windows Server 2008 R2上安装Exchange 2013过程中遇到的一些问题
查看>>
Maven POM入门
查看>>
codeforces 6A. Triangle
查看>>
仿CSDN Blog返回页面顶部功能
查看>>
【HTML5游戏开发小技巧】RPG情形对话中,令文本逐琢夸出
查看>>
ORA-04031:
查看>>
早晚有一天,我们都会成为自己当初讨厌的人
查看>>
基于SMTP协议的CMD命令邮件发送
查看>>
九度笔记之 1209最小邮票数
查看>>
Java中swap解惑
查看>>
HDU 2068 RPG的错排
查看>>
操作数有自增操作时复合表达式的陷阱
查看>>
从WW中剥离一个三维场景框架
查看>>
ASP.NET网页动态添加、更新或删除数据行
查看>>
vbs获取当前主机IP
查看>>
IIS7中的站点、应用程序和虚拟目录详细介绍
查看>>
为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆栈
查看>>
对Map按key和value分别排序
查看>>
知名第三方编译版tete009 Firefox 24.0
查看>>
java反射生成ORM
查看>>