嵌入式知识-ARM裸机-学习笔记(13):搭建简单的shell框架

嵌入式知识-ARM裸机-学习笔记(13):搭建简单的shell框架

一、shell原理

1. 什么是shell?

shell中文是壳的意思,在计算机中经常提到shell是用户操作接口的意思。因为计算机程序本身很复杂,里面的实现和外面的调用必须分开。接口本身就是对内部复杂的实现的一种封装,外部只需要通过接口就可以很容易的实现效果,但是却不用理会内部实现的复杂性和原理。

操作系统运行起来后都会给用户提供一个操作界面,这个操作界面就叫shell。用户可以通过shell来调用操作系统内部的复杂实现。shell编程就是在shell层次上进行编程。譬如linux中的脚本编程、windows中的批处理。

2. 两种shell:GUI和cmdline

GUI(图形用户界面),特点是操作简单、易学易用,适合使用电脑来工作的人。
在这里插入图片描述
cmdline(命令行界面),譬如linux的终端和windows的cmd,特点是不易用易学,优点是可以进行方便的shell编程,适合做开发的人。
在这里插入图片描述

3. shell运行原理

我们主要分析命令行shell的运行原理。 命令行shell其实就是一个死循环。这个死循环包含3个模块,这3个模块是串联的,分别是命令接收、命令解析、命令执行
命令行有一个标准命令集,用户在操作的时候必须知道自己想要的操作用通过哪个命令来实现,不能随便输入命令。如果用户输入了一个不是标准命令的命令(不能识别的命令),提示用户这不是一个合法命令,然后重新回到命令行让用户输入下一个命令。
用户输入命令的界面是一个命令行,命令行的意思就是用户输入的命令是以行为单位的,更好理解的说用户输入的命令在用户按下回车键之后就算是结束了,shell可以开始接收了。

二、搭建简单的shell框架

1. 命令列表的搭建

首先要先宏定义存储命令列表的数组,标准命令,以及与数组相关的参数。
在这里插入图片描述

2. 命令的接收

sheel框架是一个循环的状态,一直在检测是否有命令的输入,一旦有输入,将会按照一定格式去接收命令,并将命令暂存到buf中,这里的buf数组中存的是你输入的所有字符,之后会通过buf数组对你输入的信息进行解析。
通过getchar() 函数来实现串口的接收,即获取用户从键盘输入的信息。利用一个while循环一直进行判断,直到遇到回车符标志结束,这也符合命令行的规则,以回车符表示一行命令的结束。
在获取用户输入的同时,利用putchar() 函数进行显示,即实现打印一个字符就在输出处显示出打印的该字符,这又称为回显
通过一个*p指针,来对数组中的位置进行索引,从而将输入的内容存储在buf数组中。
在这里插入图片描述

3. 命令的解析

在进行命令解析时,用到了两个数组,一个是g_cmdset:该数组中存储了标准的命令集,另一个是cmd:该数组中是通过buf数组解析出来的用户输入的命令。命令的解析其实就是对比用户输入的命令和事先定义好的命令集,如果相同则执行对应的命令操作,如果不相同则返回错误并提示相应信息。
在解析命令时,由于buf数组中是用户输入的一长串内容,其中可能包含了多个子命令,所以在最开始首先要对用户输入的信息进行命令的分割,从中提取出多个子命令并放入到cmd数组中的对应位置。
两个数组的第一维度都是用来存放第几个子命令,第二维度用来存放该命令的内容,两个维度相配合即可实现多个命令内容的存储

在这里插入图片描述

4. 命令的执行

在执行命令时,通过cmd[0] 的内容可以知道是g_cmdset数组中的哪个命令,然后通过cmd_index这个索引去判断对应的那个命令执行函数。之后跳转到相应的命令执行函数,再解析接下来的子命令,通过cmd[1] 能够解析出第二个子命令,并结合第一个子命令执行相应的操作,这里对应的操作应当是最开始设定好的。
在这里插入图片描述

5. shell初始化和循环

shell框架首先要初始化shell,其中包括定义cmdset数组内的命令集,初始化串口,初始化硬件(这里指的是编写好对应命令下的执行操作),初始化看门狗等。
紧接着是shell大循环,再循环中反复检测用户输入的信息,并且执行命令接收、命令解析和命令执行这三步骤,最终实现能够通过命令去执行对应的硬件操作,从而符合shell这种API式的框架。
在这里插入图片描述

三、分析shell命令控制硬件的过程

1. 输入命令

当你不输入命令时,shell的大循环则一直等待你输入命令,此时键入led off即可关闭LED灯,以led为例来介绍shell框架执行流程。
在这里插入图片描述
整个输入命令可以分为2步,第一步通过串口将用户输入的字符串“led off \n”接收进来并暂存在buf数组中,并设计回显的功能通过串口输入打印出来。第二步是将buf数组中的命令进行多个子命令的分割,并将分割后的多个子命令存在cmd数组中,并从中解析出来对应的cmd_index号为0,用于后续的命令执行。

2. 执行命令

执行命令则通过输入的命令去做对应的操作,此时命令为lef off,则应去执行对应的关闭led的操作。
在这里插入图片描述
通过命令解析时得到的cmd_index=0,可以对应到do_cmd_led()函数,进而实现第二条子命令的判断,由于cmd[1]中存入的命令为’off’,所以将2者搭配起来使用,进而实现了led的关闭。

发布了66 篇原创文章 · 获赞 83 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qq_42826337/article/details/104834441