shell编程基础实验报告

源码地址:https://github.com/NevermindZZT/letter-shell

1 Letter shell简介

熟悉Linux的朋友的都知道,shell包裹在内核之外的人机交互界面,用于用户和内核之间打交道的功能,类似于windows CMD。 通过Shell将输入的命令与内核通讯,好让内核可以控制硬件开正确无误的操作工作。Shell有着不同的分类,比如Bourne shell(sh),Korn shell(ksh)、C shell (csh)、Bourne-again shell(bash)、tcsh。其中最常用的有csh和bash。Shell本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的。

然而在嵌入式中,由于资源有限,自然很少使用shell,但随着MCU的资源越来越丰富,一些适用于嵌入式的shell工具也就问世了,本问将要介绍的是Letter shell,Letter shell是一个体积极小的嵌入式shell,当前最新版本是3.X。

shell编程基础实验报告

Letter shell有如下功能:

  • 命令自动补全,使用TAB键补全命令
  • 命令帮助,使用help 显示命令帮助
  • 帮助补全,输入命令后双击TAB键补全命令帮助指令
  • 快捷键,支持使用CTRL+A~Z组合按键直接调用函数
  • shell变量,支持在shell中查看和修改变量值,支持变量作为命令参数
  • 登录密码,支持在shell中使用登录密码,支持超时自动锁定

2 Letter shell移植

Shell是一个命令行交互式形式存在,那最常规的就是使用MCU的串口资源了,当然也可使用USB模拟的虚拟串口。

Letter shell的移植比较简单,既然需要占用串口资源,那么首先要准备一个裸机工程,该工程需要事先串口的收发,关于串口的实现请参看逼着文章:

标准库:https://bruceou.blog.csdn.net/article/details/79341769

HAL库:https://bruceou.blog.csdn.net/article/details/109190370

笔者本文以标准库为例讲解。

1.复制源码

首先下载letter-shell,然后在工程中新建Letter_shell目录,将letter-shell目录下的src的文件复制到工程目录Middlewares/Letter_shell中。

shell编程基础实验报告

2.新建接口文件

在工程用户目录下新建shell_port.c和shell_port.h文件,当然也可以放在User目录。

3.配置工程

打开Keil,添加相应的文件。

shell编程基础实验报告

然后添加相应的头文件路径。

shell编程基础实验报告

接下来就是实现Letter shell的收发。

发送代码如下:

/** * @brief 用户shell写 * * @param data 数据 */ void userShellWrite(char data) { USART_SendData(USART1, (uint8_t) data); /* 等待发送完毕 */ while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); }

接收采用中断的方式,代码如下:

/** * @brief This function handles USART1 Handler. * @param None * @retval None */ void USART1_IRQHandler(void) { uint8_t ch; //接收中断缓冲 if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { ch = USART_ReceiveData(USART1); //ch = USART1->DR; //调用shell处理数据的接口 shellHandler(&shell, ch); } }

还需要实现Letter shell初始化接口。

/** * @brief 用户shell初始化 * */ void userShellInit(void) { shell.write = userShellWrite; shellInit(&shell, shellBuffer, 512); }

最后在主函数中初始化即可。

/** * @brief mian * @param None * @retval int */ int main(void) { /* 配置SysTick 为10us中断一次 */ SysTick_Init(); /* USART1 配置模式为 115200 8-N-1,中断接收 */ USART1_Config(); userShellInit(); for(;;) { Delay_ms(50); } }

好了,这就移植完成了,编译、下载,连接串口1,使用xshell等工具,打印信息如下:

shell编程基础实验报告

很简单吧。

3 Letter shell应用

3.1 Letter shell宏定义

在开发Letter shell应用前,需要知道Letter shell的宏定义,其宏定义在shell_cfg.h文件。

define __SHELL_CFG_H__ /** * @brief 是否使用默认shell任务while循环,使能宏`SHELL_USING_TASK`后此宏有意义 * 使能此宏,则`shellTask()`函数会一直循环读取输入,一般使用操作系统建立shell * 任务时使能此宏,关闭此宏的情况下,一般适用于无操作系统,在主循环中调用`shellTask()` */ define SHELL_USING_CMD_EXPORT 1 /** * @brief 是否使用shell伴生对象 * 一些扩展的组件(文件系统支持,日志工具等)需要使用伴生对象 */ define SHELL_SUPPORT_END_LINE 0 /** * @brief 是否在输出命令列表中列出用户 */ define SHELL_HELP_LIST_VAR 0 /** * @brief 是否在输出命令列表中列出按键 */ define SHELL_HELP_SHOW_PERMISSION 1 /** * @brief 使用LF作为命令行回车触发 * 可以和SHELL_ENTER_CR同时开启 */ define SHELL_ENTER_CR 1 /** * @brief 使用CRLF作为命令行回车触发 * 不可以和SHELL_ENTER_LF或SHELL_ENTER_CR同时开启 */ define SHELL_EXEC_UNDEF_FUNC 0 /** * @brief shell命令参数最大数量 * 包含命令名在内,超过8个参数并且使用了参数自动转换的情况下,需要修改源码 */ define SHELL_HISTORY_MAX_NUMBER 5 /** * @brief 双击间隔(ms) * 使能宏`SHELL_LONG_HELP`后此宏生效,定义双击tab补全help的时间间隔 */ define SHELL_MAX_NUMBER 5 /** * @brief shell格式化输出的缓冲大小 * 为0时不使用shell格式化输出 */ define SHELL_SCAN_BUFFER 0 /** * @brief 获取系统时间(ms) * 定义此宏为获取系统Tick,如`HAL_GetTick()` * @note 此宏不定义时无法使用双击tab补全命令help,无法使用shell超时锁定 */ define SHELL_MALLOC(size) 0 /** * @brief shell内存释放 * shell本身不需要此接口,若使用shell伴生对象,需要进行定义 */ define SHELL_SHOW_INFO 1 /** * @brief 是否在登录后清除命令行 */ define SHELL_DEFAULT_USER "letter" /** * @brief shell默认用户密码 * 若默认用户不需要密码,设为"" */ 34;" /** * @brief shell自动锁定超时 * shell当前用户密码有效的时候生效,超时后会自动重新锁定shell * 设置为0时关闭自动锁定功能,时间单位为`SHELL_GET_TICK()`单位 * @note 使用超时锁定必须保证`SHELL_GET_TICK()`有效 */ endif

shell_cfg.h文件已经注释了,笔者就不再赘述了。

3.2 Letter shell内置命令

在 Letter shell中默认内置了一些 shell命令,在 shell中输入 help 后回车或者直接按下 Tab 键,就可以打印当前系统支持的所有命令。

按下 Tab 键后可以列出当前支持的所有命令。以下为按下 Tab 键后打印出来的当前支持的所有显示Letter shell中的命令,左边是命令名称,右边是关于命令的描述:

shell编程基础实验报告

  • 自定义 shell命令

自定义的 shell命令,可以在 shell模式下被运行,将一个命令导出到 shell模式可以使用如下宏接口:

SHELL_EXPORT_CMD(_attr, _name, _func, _desc)

参数

描述

_attr

命令属性

_name

命令名

_func

命令函数

_desc

命令描述

原型如下:

_name; \ const char shellDesc_name = #_desc; \ const ShellCommand \ shellCommand_name SECTION("shellCommand") = \ { \ .attr.value = _attr, \ .data.cmd.name = shellCmd_name, \ .data.cmd.function = (int (*)())_func, \ .data.cmd.desc = shellDesc_name \ }

导出无参数命令时,函数的入参为 void,示例如下:

void hello(void) { printf("hello letter shell!\n"); } //导出到命令列表里 SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), hello, hello, hello);

系统运行起来后,在 shell控制台按 tab 键可以看到导出的命令,运行 hello 命令,运行结果如下所示:

shell编程基础实验报告

导出有参数的命令时,还可传入参数。导出有参数命令示例如下:

void parameter_test (int num, char *str) { printf("parameter test: num = %d, str = %s !\r\n", num, str); } //导出到命令列表里 SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), parameter_test, parameter_test, parameter test);

系统运行起来后,在 shell控制台按 tab 键可以看到导出的命令,运行parameter_test命令,运行结果如下所示:

shell编程基础实验报告

值得注意的是,命令参数的最大个数在中shell_cfg.h配置,默认最大是8,但是命令占了一个参数,因此用户可用的应该是7个。

/** * @brief shell命令参数最大数量 * 包含命令名在内,超过8个参数并且使用了参数自动转换的情况下,需要修改源码 */ #define SHELL_PARAMETER_MAX_NUMBER 8

Letter shell不仅可以使用命令的方式运行程序,还可像Linux的终端一样,还能通过上下键能选择历史命令,历史命令的个数默认最大为5个。

/** * @brief 历史命令记录数量 */ #define SHELL_HISTORY_MAX_NUMBER 5

非常的方便,Letter shell很强大,还有很多功能可玩,本文先讲到这里,后面再深入讲解Letter shell的设计思想。

本文【shell编程基础实验报告】由作者: Web服务 提供,本站不拥有所有权,只提供储存服务,如有侵权,联系删除!
本文链接:https://www.cuoshuo.com/blog/4276.html

(0)
上一篇 2023-03-12 08:16:22
下一篇 2023-03-12 08:22:46

相关推荐

  • php实例化对象是什么意思

    译:https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/ 在内部渗透测试期间,我在 PHP 应用程序 LAM(LDAP 帐户管理器)中发现了一个未经身份验证的任意对象实例化漏洞。 PHP 的任意对象实例化是一个缺陷,攻击者可以在其中创建任意对象。这个缺陷可以有各种形状…

    2023-03-13
    400
  • 科大讯飞语音库怎么用

    最近在测试一些语音识别库,然后国内几家语音识别的公司有,科大讯飞、云知声等企业。今天主要是测试一下科大讯飞离线语音识别的sdk。目前产品需求是:用户说出关键命令词,比如拍照、录影、关机等。相机识别出命令关键词,执行相应的命令操作。科大讯飞语音提供识别方式有离线识别和在线识别。针对产品需求场景,我们使用科大讯飞离线命令词识别功能。 离线识别语音SDK: Lin…

    2023-03-19
    000
  • 301重定向和302重定向,301跳转和302跳转区别

    我们经常使用HTTP 3xx的返回码帮助我们重定向网页,他们的作用的都非常类似,帮忙重新跳转到另外一个URL。但重定向也还是有需要深入探讨的地方。 返回码不仅有我们经常使用301和303还有302 307 308 它们有啥区别呢。可以按照是否缓存和重定向后请求的方法,两个维度去拆分。具体对比如下: 如果是永久重定向那么浏览器客户端就会缓存此次重定向结果,下次…

    2023-03-13
    300
  • 系统信息无法打开此.nfo文件,无法打开nfo文件

    打开文件时,windows提示:无法打开此文件,(如图)那应该怎么才能打开呢? 如果遇到这种情况,可以用下面的方法来试试。 1、显示文件的后辍名 点击资源管理器中菜单栏上的工具–文件夹选项–查看标签–高级设置把隐藏已知文件类型的扩展名前面的勾去掉。如图 2、然后我们可以看到文件的后辍名为zei,在搜索引擎中输入zei文件如…

    2023-03-14
    200
  • cad转jpg线条不明显怎么办

    CAD文件转JPG图片如何转才能非常清晰呢?大家都知道CAD图纸设计出来,是需要拿出来进行实地参考和浏览的,将它转换成图片会让我们在外面观看时方便很多。但是很多种转换方法转换出来的图片都不怎么清晰,今天教大家两种能够清晰转换的方法,有需要的小伙伴快来一起学习吧。 方法一:在线网站转换 使用在线网站转换文件格式,有时候可以帮助我们解决燃眉之急。CAD在线转换器…

    2023-03-16
    100
  • 天正建筑教程pdf(天正建筑教学)

    ↓↓↓↓ 点击获取T20天正建筑软件V9.0体验地址 软件安装学习教程 T20 天正建筑软件 V9.0 支持 64 位 AutoCAD2010-2023 平台。 软件新功能及改进: 1. 支持 64 位 AutoCAD2023 平台。 2. 注释系统: 1) 支持块内的天正文字及包含文字的其它天正对象,在不分解块的情况下做镜像,镜像后文字方向保持 不变; 2…

    2023-03-18
    200
  • 怎样清除浏览器缓存数据,电脑浏览器如何清理缓存

    经常使用电脑的人都知道,在电脑上安全不同的浏览器,当使用这些浏览器浏览网页、看视频等,用了一段时间后感觉电脑反应速度越来越慢。这是因为使用浏览器浏览网页会存在一些缓存,日积月累电脑的反应速度就慢了。不知道如何清除浏览器缓存的朋友看过来,本文介绍各种浏览器清理缓存的方法。 浏览器缓存是什么? 缓存的英文文件就是Cookies,就是我们使用浏览器浏览页面后放在我…

    2023-03-12
    400
  • shell编程入门

    Shell脚本编程难,难于上青天!这话不假,尤其很多程序员新人,学了几个月Shell脚本写得还是一塌糊涂,但闻道有先后,术业有专攻,他人能学好Shell脚本编程只是因为比我们早些接触而已。 作为一名优秀的程序员,懂得Shell脚本是基本功,要想后续站得更稳,这个基本功必须得打牢。 今天给大家分享从基础到进阶的Shell脚本编程,共两册,适合不同学习进度的朋友…

    2023-03-09
    2700
  • 配对t检验典型例题及答案_配对样本的典型例子

    配对样本均数t检验公式 例题 某研究评估咖啡因对运动者心肌血流量的影响,先后测定了12名男性志愿者饮用咖啡前后运动状态下的心肌血流量,数据如表所示,问饮用咖啡前后运动者的心肌血流量有无差异。 解析 配对设计资料具有对子内数据一一对应的特征,研究者应关心对子的效应差值而不是各自的效应值。因此进行配对t检验时,首先应计算各对数据间的差值d,将d作为变量计算均数。…

    2023-03-20
    100
  • 贝叶斯定理在生活中的应用_贝叶斯决策生活中的例子

    贝叶斯定理提供的是一种逆条件概率的方法,本文简单总结了贝叶斯定理是什么,贝叶斯定理应用的理解,以及贝叶斯定理在AI场景下的应用,目的是希望产品经理了解到这个定理的能力后,在设计相关推荐或是具有推理功能的应用场景,能通过贝叶斯定理来解决。 一、贝叶斯定理介绍 其中: P(B|A)表示:在事件A发生的前提下,发生事件B的概率; P(A|B)表示:在事件B发生的前…

    2023-03-10
    200

发表回复

登录后才能评论
返回顶部
错说博客上线啦!