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,还是成就感满满的。很感谢有这个机会能接触到这么底层的实验,让原本遥不可及的操作系统变得咫尺可得,我也同样明白这只是前行的一小步,未来的学习道阻且长。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue3 + Echarts堆叠折线图的tooltip不显示问题

问题介绍 使用Echarts在Vue3Vite项目中绘制堆叠折线图的的时候&#xff0c;tooltip总是不显示&#xff0c;经过很长时间的排查和修改&#xff0c;最后发现是在使用上有错误导致的。 错误图片展示 问题原因 由于Vue3底层使用proxy代理创建示例&#xff0c;使用其创建出来的实…

如何监控员工电脑行为?(其实不难,这种方法先码住!)

你的企业有没有面临以下几种问题&#xff1a; 这些问题&#xff0c;不仅影响企业员工的工作效率&#xff0c;更给企业数据带来不少的安全隐患。为了解决这些问题&#xff0c;很多企业采用监控员工电脑行为来解决当下的问题。 但我们需要注意的是&#xff0c;正确的监控不仅可以…

【Oracle】实验三 Oracle数据库的创建和管理

【实验目的】 掌握Oracle数据库的创建方法使用DBCA创建数据库在数据库中装入SCOTT用户及其表 【实验内容】 使用DBCA创建数据库&#xff0c;名为MYDB&#xff0c;找到其初始化文件(文本型和服务器型文件都要找到)&#xff0c;查看各类默认位置并记录下来(包括物理文件所在目…

LabVIEW与ABB工业机器人据监控

​1. 前言 随着工业自动化的发展&#xff0c;工业机器人在制造业中的应用越来越广泛。为了实现对工业机器人的高效监控和控制&#xff0c;本文介绍了利用OPC&#xff08;OLE for Process Control&#xff09;服务器将ABB工业机器人与LabVIEW连接起来的解决方案。通过OPC服务器…

OpenCV和PIL进行前景提取

摘要 在图像处理和分析中&#xff0c;前景提取是一项关键技术&#xff0c;尤其是在计算机视觉和模式识别领域。本文介绍了一种结合OpenCV和PIL库的方法&#xff0c;实现在批量处理图像时有效提取前景并保留原始图像的EXIF数据。具体步骤包括从指定文件夹中读取图像&#xff0c…

TQZC706开发板教程:在ZC706+ADRV9009硬件平台运行ADI Linux

本教程使用2024-06-18的ADI镜像文件&#xff0c;创建ZC706ADRV9009的linux工程进行测试。 首先需要下载ADI的镜像文件下载地址如所示&#xff1a; https://wiki.analog.com/resources/tools-software/linux-software/adi-kuiper_images/release_notes#r2_patch_1 烧写完成后若…

JAVA毕业设计147—基于Java+Springboot的手机维修管理系统(源代码+数据库)

基于JavaSpringboot的手机维修管理系统(源代码数据库)147 一、系统介绍 本项目分为用户、管理员、维修员三种角色 1、用户&#xff1a; 注册、登录、新闻公告、售后申请、申请列表、意见反馈、个人信息、密码修改 2、管理员&#xff1a; 用户管理、用户管理、栏目管理、网…

SpringSecurity中文文档(Servlet Authorize HttpServletRequests)

Authorize HttpServletRequests SpringSecurity 允许您在请求级别对授权进行建模。例如&#xff0c;对于 Spring Security&#xff0c;可以说/admin 下的所有页面都需要一个权限&#xff0c;而其他所有页面只需要身份验证。 默认情况下&#xff0c;SpringSecurity 要求对每个…

6、Redis系统-数据结构-04-Hash

四、哈希表&#xff08;Hashtable&#xff09; 哈希表是一种高效的键值对数据结构&#xff0c;通过散列函数将键映射到表中的位置&#xff0c;实现快速的插入、删除和查找操作。Redis 广泛使用哈希表来实现 Hash 对象和数据库的键值存储。以下将从结构设计、哈希冲突与链式哈希…

快速测试electron环境是否安装成功

快速测试electron环境是否安装成功 测试代码正确运行的效果运行错误的效果v22.4.1 版本无法使用v20.15.1版本无法使用v18.20.4 版本无法使用 终极解决办法 测试代码 1.npx create-electron-app my-electron-app 2.cd my-electron-app 3.npm start 正确运行的效果 环境没问题…

Android系统设置kernel log level的方法

Android log相关文档索引&#xff1a; 使用ADB命令控制logcat日志本地存储功能-CSDN博客 Android系统通过属性设置来控制log输出的方案-CSDN博客 Android系统设置kernel log level的方法-CSDN博客 Android系统设置kernel log level的方法 背景 kernel log内容过多/过少会影…

oak相机使用oak官网方式标定

目录 一、depthai ROS驱动 一、depthai ROS驱动 &#xff08;1&#xff09;驱动下载地址&#xff1a;2. C 开发快速上手 — DepthAI Docs 0.3.0.0 documentation sudo apt install ./depthai_2.17.1_arm64.deb //运行 Python3 utilities/cam_test.py -mres 400 -cams rgb,m …

Wireshark 对 https 请求抓包并展示为明文

文章目录 1、目标2、环境准备3、Wireshark 基本使用4、操作步骤4.1、彻底关闭 Chrome 进程4.2、配置 SSLKEYLOGFILE [核心步骤]4.3、把文件路径配置到 Wireshark 指定位置4.4、在浏览器发起请求4.5、抓包配置4.6、过滤4.6.1、过滤域名 http.host contains "baidu.com4.6.2…

AIGC时代创意设计师从“创作”向“智作”升级

随着人工智能技术的飞速发展&#xff0c;AIGC&#xff08;AI Generated Content&#xff0c;即人工智能生成内容&#xff09;时代已经到来&#xff0c;为创意设计领域带来了前所未有的变革。在这一时代背景下&#xff0c;创意设计师们正经历着从传统的“创作”向“智作”的转型…

FreeRTOS 队列

队列是一种任务到任务、任务到中断、中断到任务数据交流的一种机制。在队列中可以存 储数量有限、大小固定的多个数据&#xff0c;队列中的每一个数据叫做队列项目&#xff0c;队列能够存储队列项 目的最大数量称为队列的长度&#xff0c;在创建队列的时候&#xff0c;就需要指…

html5——CSS基础选择器

目录 标签选择器 类选择器 id选择器 三种选择器优先级 标签指定式选择器 包含选择器 群组选择器 通配符选择器 Emmet语法&#xff08;扩展补充&#xff09; 标签选择器 HTML标签作为标签选择器的名称&#xff1a; <h1>…<h6>、<p>、<img/> 语…

在pycharm中使用jupyter

在pycharm中使用jupyter 前置条件&#xff1a;你的环境中应该有juptyer &#xff0c;没有的话 pip install jupyter 点击项目目录&#xff0c;右键->new->jupyter notebook 打开file settings 找到 jupyter server &#xff08;按照默认的用代理服务器就行&#xff09; P…

ollama + lobechat 搭建自己的多模型助手

背景 人工智能已经推出了快2年了&#xff0c;各种模型和插件&#xff0c;有渐渐变成熟的趋势&#xff0c;打造一个类似 hao123网站的人工智能模型入口&#xff0c;也变得有需求了。用户会去比较多个ai给出的答案&#xff0c;作为程序员想拥有一台自己的GPU服务器来为自己服务。…

react启用mobx @decorators装饰器语法

react如果没有经过配置&#xff0c;直接使用decorators装饰器语法会报错&#xff1a; Support for the experimental syntax ‘decorators’ isn’t currently enabled 因为react默认是不支持装饰器语法&#xff0c;需要做一些配置来启用装饰器语法。 step1: 在 tsconfig.js…

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;后续在…