75-76-77 - Shell任务的实现

---- 整理自狄泰软件唐佐林老师课程

查看所有文章链接:(更新中)深入浅出操作系统 - 目录

1. 问题

  • 驱动键盘之后能做什么?

2. Shell任务简介

  • Shell的 本质是一个 任务(执行于用户态)
  • 简单的命令行用户界面
    • 提供用户与系统交互的接口
  • 命令解释器,解释用户输入的命令
    • 根据用户命令启动相应的系统功能

2.1 实现Shell任务的关键

  • 获取键盘输入的字符

在这里插入图片描述

2.2 思考

  • 当Shell请求用户输入时,用户是否正在输入字符?
    不一定正在输入字符 ==> shell任务等待 ==> 可执行态切换为等待状态
  • 当多个任务请求用户输入时,哪个任务应该获得输入的字符?

在这里插入图片描述

2.3 解决方案设计

  • 定义内核中 事件 的概念
  • 当任务请求输入时(调用ReadKey()时)产生事件
    • 事件产生:任务进入等待状态
    • 事件销毁:任务进入可执行状态
  • Task模块根据 事件描述 执行具体的调度动作
    • 如:操作哪一个等待队列

2.4 事件机制的设计

  • 事件定义:触发任务在 可执行态等待状态 之间切换的因素
    在这里插入图片描述

  • type:描述事件类型(为什么发生状态切换?)

    • 比如:
      • 命名KeyEvent,获取用户输入,用户并没有真的输入时进入等待的场景
      • 命名MutexEvent,由于获取互斥锁不成功而进入等待状态的场景
      • 命名TaskEvent,触发任务进入等待状态的事件
  • id:事件标识信息(调度的关键)

  • param1:事件参数(可选)

  • param2:事件参数(可选)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 事件 - 来统一任务需要等待的情况
    • 事件产生:进入等待
    • 再次进入可执行态:事件销毁

3. 模块重构

  • Task模块
    EventSchedule(action, event):根据事件执行调度
    WaitTask(name):通过事件让任务进入等待状态
  • Mutex模块
    为每个互斥锁增加一个等待队列
    无法获取锁的任务进入该锁的等待队列

3.1 Task模块重构

在这里插入图片描述

  • 不同事件不同处理
    在这里插入图片描述

3.2 Mutex模块重构

在这里插入图片描述

3.3 编程实验:模块重构

【参看链接】:75-76-77 - Shell任务的实现 / 75

在这里插入图片描述

3.4 思考

  • Shell任务如何实现?系统调用uint ReadKey()如何实现?

4. Shell实现流程

用户界面 - 交互 - 输入命令
在这里插入图片描述

4.1 关键问题

  • 当Shell请求用户输入时,用户是否正在输入字符?
    • 大概率此时用户并没有正在输入 ==> 等待
  • 当多个任务请求用户输入时,哪个任务应该获得输入的字符?
    • 每个任务都应该获得输入

4.2 解决方案

在这里插入图片描述

4.3 解决方案实现

在这里插入图片描述
在这里插入图片描述

4.4 编程实验:Shell任务的实现(主要是输入部分)

【参看链接】:75-76-77 - Shell任务的实现 / 76

在这里插入图片描述

4.5 思考

  • 如何实现Shell任务的用户接口功能? – 交互

5. Shell任务界面设计

在这里插入图片描述

5.1 Shell任务的完善

  • 支持 删除键(Backspace)和 回车键(Enter)
    • Backspace:修改已输入命令中的字符
    • Enter:确认命令输入完毕
  • 命令类型
    • 启动型命令 - 启动任务
    • 应用级命令 - 由shell实现,如clean
    • 内核级命令 - shell依赖系统调用

5.2 缓存用户输入

  • 思考:用户输入存储在哪?
    • 定义全局字符缓冲区 gKBuf
    • 存储用户输入的字符
    • 定义全局变量 gKIndex
    • 记录新字符在缓冲区中的位置

在这里插入图片描述

5.3 删除键(Backspace)的支持

  1. 从后向前删除命令行字符
  2. 删除字符后光标回退到上一个位置
  3. 获取PROMPT(即下图中的“D.T.OS >> ”打印)的长度
    在这里插入图片描述
  4. 获取当前光标横坐标
    • 当光标横坐标大于PROMPT长度时:
      • 将光标前一个位置输出空格
      • 将光标移动到前一个位置

在这里插入图片描述

5.4 回车键(Enter)的支持

  1. 在字符缓冲区gKBuf中添加 0结束符
  2. 执行命令对应的功能
    在这里插入图片描述

5.5 编程实验:Backspace & Enter

【参看链接】:75-76-77 - Shell任务的实现 / 77 / 00BackspaceAndEnter

在这里插入图片描述

5.6 命令映射设计

命令字符串功能(入口函数) 之间的映射

  • 将命令和命令入口进行映射(命令注册
    1. 用户输入命令后,查找命令入口并执行
    2. 无法找到命令入口时,执行无效命令入口

在这里插入图片描述

5.6.1 命令注册

在这里插入图片描述

5.6.2 未知命令入口函数

在这里插入图片描述

5.7 编程实验:Shell任务的完善

【参看链接】:75-76-77 - Shell任务的实现 / 77 / 01命令映射

在这里插入图片描述

5.8 思考

  • 内核级命令如何实现?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

uuxiang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值