第17天 命令行窗口

第17天 命令行窗口

2020.4.19

1. 闲置任务(harib14a)

  • 在harib13e中,如果任务B0~B2没有启动,只有任务A启动,当任务A进入休眠状态,程序就会因为找不到其他的任务而导致运行出现异常。

    • 在harib13e的bootpack.c的HariMain中将代码:
      task_run(task_b[i], 2, i + 1);
      
      注释掉。
    • make后用VMware运行:
  • 当出现上面的情况的时候,最好的办法就是让CPU执行HLT休息。

  • 让HLT成为一个任务,放在最下层的LEVEL中。 这样,即便任务A进入休眠状态,CPU也会切换到这个HLT任务,这样就不会因为找不到任务而出错了。这个HLT任务,美名其曰:闲置任务(idle task)

    • 闲置任务task_idle(mtask.c中):
      void task_idle(void)
      {
          for (;;) {
              io_hlt();
          }
      }
      
    • 这个闲置任务其实就是"哨兵"。
  • 修改task_init,将闲置任务放到最底层LEVEL即可:

    struct TASK *task_init(struct MEMMAN *memman)
    {
        int i;
        struct TASK *task, *idle;
        ……
        idle = task_alloc();
        idle->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024;
        idle->tss.eip = (int) &task_idle;
        idle->tss.es = 1 * 8;
        idle->tss.cs = 2 * 8;
        idle->tss.ss = 1 * 8;
        idle->tss.ds = 1 * 8;
        idle->tss.fs = 1 * 8;
        idle->tss.gs = 1 * 8;
        task_run(idle, MAX_TASKLEVELS - 1, 1); /*priority=1*/
    
        return task;
    }
    
  • 修改HariMain,将代码task_run(task_b[i], 2, i + 1);注释掉。然后make并在VMware上运行:

    • 没有出现错误,顺利运行。

2. 创建命令行窗口(harib14b)

  • 命令行窗口不属于任务A,而是作为一个新的任务独立存在。将任务B稍加修改就可以创建命令行窗口了。

  • 修改HariMain:

    void HariMain(void)
    {
        ……
        /* sht_cons */
        sht_cons = sheet_alloc(shtctl);
        buf_cons = (unsigned char *) memman_alloc_4k(memman, 256 * 165);
        sheet_setbuf(sht_cons, buf_cons, 256, 165, -1); 
        make_window8(buf_cons, 256, 165, "console", 0);
        make_textbox8(sht_cons, 8, 28, 240, 128, COL8_000000);
        task_cons = task_alloc();
        task_cons->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024 - 8;
        task_cons->tss.eip = (int) &console_task;
        task_cons->tss.es = 1 * 8;
        task_cons->tss.cs = 2 * 8;
        task_cons->tss.ss = 1 * 8;
        task_cons->tss.ds = 1 * 8;
        task_cons->tss.fs = 1 * 8;
        task_cons->tss.gs = 1 * 8;
        *((int *) (task_cons->tss.esp + 4)) = (int) sht_cons;
        task_run(task_cons, 2, 2); /* level=2, priority=2 */
        ……
        sheet_slide(sht_back,  0,  0);
        sheet_slide(sht_cons, 32,  4);
        sheet_slide(sht_win,  64, 56);
        sheet_slide(sht_mouse, mx, my);
        sheet_updown(sht_back,  0);
        sheet_updown(sht_cons,  1);
        sheet_updown(sht_win,   2);
        sheet_updown(sht_mouse, 3);
        ……
    }
    
  • 添加命令行任务console_task:

    void console_task(struct SHEET *sheet)
    {
        struct FIFO32 fifo;
        struct TIMER *timer;
        struct TASK *task = task_now(); /*获取当前命令行任务*/
    
        int i, fifobuf[128], cursor_x = 8, cursor_c = COL8_000000;
        fifo32_init(&fifo, 128, fifobuf, task);
    
        timer = timer_alloc();
        timer_init(timer, &fifo, 1);
        timer_settime(timer, 50);
    
        for (;;) {
            io_cli();
            if (fifo32_status(&fifo) == 0) {
                task_sleep(task); /*命令行任务休眠*/
                io_sti();
            } else {
                i = fifo32_get(&fifo);
                io_sti();
                if (i <= 1) { /* 光标定时器 */
                    if (i != 0) {
                        timer_init(timer, &fifo, 0); 
                        cursor_c = COL8_FFFFFF;
                    } else {
                        timer_init(timer, &fifo, 1);
                        cursor_c = COL8_000000;
                    }
                    timer_settime(timer, 50);
                    boxfill8(sheet->buf, sheet->bxsize, cursor_c, cursor_x, 28, cursor_x + 7, 43);
                    sheet_refresh(sheet, cursor_x, 28, cursor_x + 8, 44);
                }
            }
        }
    }
    
    • 每一个任务都有一个自己的FIFO缓冲区。
    • 命令行任务需要休眠,当执行到console_task时,说明正在CPU上运行的是命令行任务,因此可以通过task_now函数获取命令行任务本身
  • make后在VMware上运行:

    • 命令行窗口的雏形做好了!

3. 切换输入窗口(harib14c)

  • harib14b中,无论如何输入字符,都是在task_a中输入。现在,需要解决的问题是:向命令行窗口输入字符。

  • 向命令行窗口输入字符,首先要选中命令行窗口。使用Tab键在命令行窗口和任务A之间切换

  • 切换窗口:先暂时将窗口标题栏的颜色改一改。也就是,当按Tab时,命令行窗口和任务A的窗口标题栏的颜色发生变化。(以此来告诉用户选中了那个窗口)

  • harib14b中的make_window8函数完成了两个功能:1.描绘窗口标题栏;2.描绘窗口剩余部分。

  • 将make_window8函数改写一下,将描绘标题栏的部分独立出来形成一个新的函数make_wtitle8。:

    void make_window8(unsigned char *buf, int xsize, int ysize, char *title, char act)
    {
        boxfill8(buf, xsize, COL8_C6C6C6, 0,         0,         xsize - 1, 0        );
        boxfill8(buf, xsize, COL8_FFFFFF, 1,         1,         xsize - 2, 1        );
        boxfill8(buf, xsize, COL8_C6C6C6, 0,         0,         0,         ysize
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值