HNU-2024操作系统实验-Lab9-Shell

一、 实验目的

  1. 理解Shell程序的原理、底层逻辑和Shell依赖的数据结构等

  2. 在操作系统内核MiniEuler上实现一个可用的Shell程序

  3. 能够根据相关原理编写一条可用的Shell指令

二、 实验过程

首先从底层出发,实现Shell程序

1.在src/include目录下新建prt_shell.h头文件:

在这里插入图片描述

这个板块中主要定义了shell能够显示的最大长度以及文件路径的最大值,然后定义了ShellCB控制块,用于Shell的管理,其中包含对用户输入、输入命令的历史的管理以及维护当前工作目录等,此处的ShellBuf是作为Shell的缓冲区,输入的指令会存放在缓冲区内,经过解析得到最终应该执行的操作。

2.向src/bsp目录下的print.c文件中的PRT_UartInit 添加初始化代码,使其支持接收数据中断。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

由于我们的操作系统内核MiniEuler不能使用标准输入输出流,所以需要通过串口交互的方式来实现往Shell的缓冲区中写入字符,在此板块中首先定义了一系列串口的配置位和掩码,如:TXE是串口的第9位(从0开始),在实验二中也进行过类似的操作,接着定义了一个用于UART串口接收数据时使用的信号量sem_uart_rx,最后进行串口的初始化,首先禁用UART,清空中断状态,设定中断mask(允许接收中断),并设置波特率相关寄存器(UARTIBRD和UARTFBRD)。

然后读取Line Control Register(LCR)的当前配置,将其与一组掩码进行或操作来设置数据位、奇偶校验和停止位的配置,然后写回寄存器。这里使用的配置是8个数据位、无奇偶校验、1个停止位,并启用FIFO。最后通过设置控制寄存器(UART Control Register)来启用UART,并使能接收和发送。串口配置完成后,调用OsGicIntSetConfig,OsGicIntSetPriority,OsGicClearInt,OsGicEnableInt函数来配置UART接收中断,最后创建数据接收信号量。

3.在src/bsp目录中的print.c文件中实现 OsUartRxHandle()处理接收中断

在这里插入图片描述

该中断处理函数首先读取UART的状态寄存器,然后检查flag中的第4位(接收FIFO空标志)是否为0,为0则表示UART接收到的字符非空,将接收到的字符读入shell的缓冲区,使用Offset表示写入字符在缓冲区中的偏移(用于定位),当偏移超出shell缓冲区的最大长度时,将其重置为0,从而实现循环缓冲区的效果,最后调用PRT_SemPost函数,发送信号量sem_uart_rx,通知其他可能在等待UART接收数据的任务已经读入新的字符。

4.在src/bsp目录下的prt_exc.c文件中修改中断激活函数:

在这里插入图片描述

当接收到的中断处理号为33时,调用接受处理函数

5.在src/kernel/task目录下的prt_task.c文件中加入display函数

在这里插入图片描述

这个函数主要是用于后续Shell的top指令对应的实际操作函数,依次遍历g_runQueue队列,按照优先级打印出所有任务。

6.在src/kernel/tick目录下的prt_tick.c文件中加入display函数

在这里插入图片描述

用于后续Shell的tick指令的实际操作,打印出当前已经进行的时钟中断次数。

7.在src/shell目录下新建shmsg.c文件

OS_SEC_TEXT void ShellTask(uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4)
{U32 ret;char ch;char cmd[SHELL_SHOW_MAX_LEN];U32 idx;ShellCB *shellCB = (ShellCB *)param1;while (1) {PRT_Printf("\nminiEuler # ");idx = 0;for(int i = 0; i < SHELL_SHOW_MAX_LEN; i++){cmd[i] = 0;}while (1){PRT_SemPend(sem_uart_rx, OS_WAIT_FOREVER);// 读取shellCB缓冲区的字符ch = shellCB->shellBuf[shellCB->shellBufReadOffset];cmd[idx] = ch;idx++;shellCB->shellBufReadOffset++;if(shellCB->shellBufReadOffset == SHELL_SHOW_MAX_LEN)shellCB->shellBufReadOffset = 0;PRT_Printf("%c", ch); //回显if (ch == '\r'){// PRT_Printf("\n");if(cmd[0]=='t' && cmd[1]=='o' && cmd[2]=='p'){OsDisplayTasksInfo();} else if(cmd[0]=='t' && cmd[1]=='i' && cmd[2]=='c' && cmd[3]=='k'){OsDisplayCurTick();}break;}}}
}

这段代码的功能很简单,首先输出Shell命令行的提示符“minieuler #”,然后根据Shell缓冲区内的字符(即为输入的指令)进行相应的操作,本实验已经实现的有top指令和tick指令,功能实现在前文中已经详细解释,top指令按照优先级打印出队列中的所有任务,tick指令打印出当前已经执行的时钟中断数,新增加的指令会在后文的作业中详细阐述。

OS_SEC_TEXT U32 ShellTaskInit(ShellCB *shellCB){U32 ret = 0;struct TskInitParam param = {0};_// task 1__// param.stackAddr = 0;_param.taskEntry = (TskEntryFunc)ShellTask;param.taskPrio = 9;_// param.name = "Test1Task";_param.stackSize = 0x1000; _//__固定4096,参见prt_task_init.c的OsMemAllocAlign_param.args[0] = (uintptr_t)shellCB;TskHandle tskHandle1;ret = PRT_TaskCreate(&tskHandle1, &param);if (ret) {return ret;}ret = PRT_TaskResume(tskHandle1);if (ret) {return ret;}}

这个函数主要目的是使用给定的参数初始化并启动一个新的ShellTask任务。

至此,Shell的底层初始化已经全部完成。

三、 测试及分析

在这里插入图片描述

能够正常运行本实验自带的两条Shell指令

四、 Lab9作业

在实现完Shell的底层原理之后,我们还需要在main函数中启动Shell程序:

在这里插入图片描述

引用外部文件中定义的一系列初始化文件,同时定义本实验中的shellCB控制块

在这里插入图片描述

然后调用初始化函数对Shell进行初始化,就可以顺利启动Shell程序了

这里实现了三条额外的指令:第一条是Shell程序中不可或缺的help指令,可以打印出当前所有的可用指令以及指令用途:

在这里插入图片描述

第二条是清屏操作Clear:

在这里插入图片描述

第三条是退出操作exit:

在这里插入图片描述

演示:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

五、心得体会

通过这个实验,我更深入地理解了命令行Shell的工作原理和底层实现,也顺利实现自己写的两条指令;至此,操作系统课程的所有实验落下帷幕,我本人是感慨万分的,从最开始的什么都看不懂、到处找资料、实验代码一看一整天、实验环境一配一整天,到顺利完成所有的实验,实现了一个自己的简单操作系统内核:MiniEuler,还是成就感满满的。很感谢有这个机会能接触到这么底层的实验,让原本遥不可及的操作系统变得咫尺可得,我也同样明白这只是前行的一小步,未来的学习道阻且长。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/45034.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

产线工控安全怎么做

随着工业自动化的推进&#xff0c;工控系统在现代生产线中的应用越来越广泛&#xff0c;但随着网络安全威胁的不断演变&#xff0c;产线工控系统的安全也面临着前所未有的挑战。面对这种情况&#xff0c;可以使用MCK主机加固&#xff08;深信达&#xff09;解决方案为产线工控安…

ROS基础学习-ROS运行管理

ROS运行管理 目录 1. ROS运行管理简述2. ROS元功能包2.1 概念2.2 作用2.3 实现 3. ROS-launch文件3.1. ROS节点管理launch文件3.1.1 概念3.1.2 作用3.1.3 使用 3.2 launch文件标签 1. ROS运行管理简述 ROS是多进程(节点)的分布式框架&#xff0c;一个完整的ROS系统实现&#x…

C++ 入门08:运算符重载

往期回顾&#xff1a; C 入门05&#xff1a;类和对象-CSDN博客 C 入门06&#xff1a;类的进阶&#xff08;构造函数的重载与拷贝构造函数&#xff09;-CSDN博客 C 入门07&#xff1a;静态成员和常量成员-CSDN博客 一、前言 在前面的文章学习中&#xff0c;我们学习了类和对象的…

在Spring Boot项目中集成分布式追踪系统

在Spring Boot项目中集成分布式追踪系统 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在复杂的分布式系统中&#xff0c;定位和解决问题是一项挑战。分布式追踪系统通过跟踪请求的调用链&#xf…

基于搭载 DJYOS 的 STM32H730 的低空无人驾驶无人机解决方案探究

摘要&#xff1a;本文详细阐述了一种基于搭载 DJYOS 的 STM32H730 开发的低空无人驾驶无人机解决方案。通过对其硬件配置、飞控系统、传感器应用、动力与续航以及操控方式等方面的深入分析&#xff0c;展现了该方案在低空无人驾驶领域的创新性和优势&#xff0c;为相关技术的发…

最新 Kubernetes 集群部署 + Contranerd容器运行时 + flannel 网络插件(保姆级教程,最新 K8S 1.28.2 版本)

资源列表 操作系统配置主机名IP所需插件CentOS 7.92C4Gk8s-master192.168.60.143flannel-cni-plugin、flannel、coredns、etcd、kube-apiserver、kube-controller-manager、kube-proxy、 kube-scheduler 、containerd、pause 、crictlCentOS 7.92C4Gk8s-node01192.168.60.144f…

VScode代码对齐快捷键

解决复制过来代码对齐格式问题。 左对齐&#xff1a;Ctrl[ 右对齐&#xff1a;Ctrl]

always块敏感列表的相关报错,

在综合的时候&#xff0c;报错如下 Synthesis synth_1 [Synth 8-91] ambiguous clock in event control ["E:/FPGA/FPGA_project/handwrite_fft/handwrite_fft.srcs/sources_1/new/reg_s2p.v":140] 猜测报错原因&#xff08;暂时没有时间寻找原因&#xff0c;后续在…

web自动化环境搭建[基于Chrome]+常用元素定位方式

下载chrome&#xff1a;可以使用电脑自带软件[HUES,360等]下载 下载chromedriver&#xff1a; 老版本地址:http://chromedriver.storage.googleapis.com/index.html,选择点击进去&#xff0c;有个notes.txt文件查看支持版本 最新版本:https://googlechromelabs.github.io/chro…

mac python

1. 默认在 /usr/bin/ 目录&#xff0c;安装目录在 /Users/wangjun/Library/Python/3.9/lib/python/site-packages 2. 安装自己的python。 无需理会上面的版本。 访问 Python Release Python 3.12.4 | Python.org 安装即可 使用 python3 pip3 /usr/local/bin

AI虚拟医生重塑医患关系

如今&#xff0c;越来越多的企业开始选择用AI虚拟数字人播报员替代真人出镜&#xff0c;这不仅有助于企业实现降本增效的目标&#xff0c;更能让广告传播趋向多样化和个性化。对于普通人而言&#xff0c;也摆脱了真人出镜的种种烦恼&#xff0c;让表达更加自由与便捷。AI虚拟数…

一个简单的基于Qt的MVC框架

如下是一个简单的基于Qt的MVC框架示例&#xff0c;其中模型&#xff08;Model&#xff09;中的操作会在子线程中处理。这个示例将包括一个基本的视图&#xff08;View&#xff09;、控制器&#xff08;Controller&#xff09;和模型&#xff08;Model&#xff09;。 1. 项目结…

5,智能合约(react+区块链实战)

5&#xff0c;智能合约&#xff08;react区块链实战&#xff09; 5-1 智能合约5-2 metamask安装及私有链搭建互相联动5-3 solidity数据类型-布尔-数字-地址&#xff08;owner区别&#xff09;5-4 solidity 数组和映射&#xff08;代币转账&#xff09;5-5 solidity结构体与枚举…

视频怎么压缩变小?最佳视频压缩器

即使在云存储和廉价硬盘空间时代&#xff0c;大视频文件使用起来仍然不方便。无论是存储、发送到电子邮件帐户还是刻录到 DVD&#xff0c;拥有最好的免费压缩软件可以确保您快速缩小文件大小&#xff0c;而不必担心视频质量下降。继续阅读以探索一些顶级最佳 免费视频压缩器选项…

排序(二)——快速排序(QuickSort)

欢迎来到繁星的CSDN&#xff0c;本期内容包括快速排序(QuickSort)的递归版本和非递归版本以及优化。 一、快速排序的来历 快速排序又称Hoare排序&#xff0c;由霍尔 (Sir Charles Antony Richard Hoare) &#xff0c;一位英国计算机科学家发明。霍尔本人是在发现冒泡排序不够快…

【操作系统】单例模式

目录 单例模式一. 什么是单例模式二. 饿汉模式三. 懒汉模式四. 多线程下的懒汉模式 单例模式 一. 什么是单例模式 在接下来的学习中我会依次为大家介绍以下几种设计模式&#xff1a; 单例模式工厂模式适配器模式门面模式代理模式 单例模式简单来说就是多次调用只有这一个对…

oracle 23ai新的后台进程bgnn介绍

前言 昨天发文研究了哪些oracle 后台不能杀 具体文章如下链接 oracle哪些后台进程不能杀&#xff1f;-CSDN博客 其中23ai中新增了一个后台进程bgnn 但是在oracle 23ai database reference中并没有找到该后台进程 有点不甘心就开了个SR&#xff0c;找oracle 官方来看看这个后…

构建工具webpackvite

1. webpack 使用步骤: 1.初始化项目yarn init -y&#xff08;也可以是npm其他包管理工具&#xff09; 2.安装依赖webpack webpack-cli&#xff1a;yarn add -D webpack webpack-cli&#xff08;-D是只用于开发时候加&#xff09; 3.在项目中创建src目录&#xff0c;然后编写代…

开发编码规范笔记

前言 &#xff08;1&#xff09;该博客仅用于个人笔记 格式转换 &#xff08;1&#xff09;查看是 LF 行尾还是CRLF 行尾。 # 单个文件&#xff0c;\n 表示 LF 行尾。\r\n 表示 CRLF 行尾。 hexdump -c <yourfile> # 单个文件&#xff0c;$ 表示 LF 行尾。^M$ 表示 CRLF …

element-ui操作表格行内容如何获取当前行索引?

需求&#xff1a; 根据每个用户的提交次数、撤回次数&#xff0c;动态计算出实际次数&#xff0c;并且提交次数不能小于撤回次数 <template><div><el-table:data"tableData"style"width: 80%"border><el-table-columnprop"date&…