【嵌入式】开源shell命令行的移植和使用(1)——nr_micro_shell

目录

一 背景说明

二 移植准备

三 移植过程

四 实际使用


一 背景说明

        在进行调试和维护时,常常需要与单片机进行交互,获取、设置某些参数或执行某些操作,nr_micro_shell正是为满足这一需求,针对资源较少的MCU编写的基本命令行工具。虽然RT_Thread组件中已经提供了强大的finsh命令行交互工具,但对于ROM、RAM资源较少的单片机,finsh还是略显的庞大,在这些平台上,若仍想保留基本的命令行交互功能,nr_micro_shell是一个不错的选择。

        nr_micro_shell具有以下优点:

        1.占用资源少,使用简单,灵活方便。使用过程只涉及两个shell_init()和shell()两个函数,无论是使用RTOS还是裸机都可以方便的应用该工具,不需要额外的编码工作。

        2.交互体验好。完全类似于linux shell命令行,当串口终端支持ANSI(如Hypertrm终端)时,其不仅支持基本的命令行交互,还提供Tab键命令补全,查询历史命令,方向键移动光标修改功能。

        3.扩展性好。nr_micro_shell为用户提供自定义命令的标准函数原型,只需要按照命令编写命令函数,并注册命令函数,即可使用命令。

二 移植准备

【1】nr_micro_shell下载地址:

nr_micro_shell: shell for MCU. 单片机命令行交互。

【2】文件目录结构:

名称说明
docs文档目录,包含演示的GIF图片等
examples例子目录,包括命令函数示例: nr_micro_shell_commands.c 和RT_Thread下使用示例 nr_micro_shell_thread.c
inc头文件目录
src源代码目录

【3】提前准备好芯片UART串口的初始化以及收发接口;

三 移植过程

【1】目录移植:将下载好的nr_micro_shell文件解压到自己的工程目录下,并在IDE中包含所需的src源文件以及inc头文件(其中 nr_micro_shell_commands.c 文件位于examples文件夹中,也一并移过来方便移植)

        此时编译一下,会出现报错,这就需要修改以下配置

【2】修改配置文件 nr_micro_shell_config.h :

        (i)把下面第44、45行包含了 RT-Thread 的头文件给注释掉,或者自己定义 NR_MICRO_SHELL_SIMULATOR 这个宏进行头文件包含屏蔽也可以:

        (ii)根据自己的shell运行终端配置 NR_SHELL_END_OF_LINE 宏,这个宏配置的是指令是以空格结尾还是换行结尾有效。我这边用的SecureCRT,这边改成1:

        (iii)将上面 shell_printf 宏 改成自己的 printf 打印或者重定向fputc使得printf输出用的是串口的输出接口,我这边用的后一种方式:

int32_t fputc(int32_t ch, FILE *f)
{(void)f;  /* Prevent unused argument compilation warning */return (Ok == Uart_SendDataPollTimeOut(M0P_UART0, (char)ch, SystemCoreClock/DBG_PRINTF_BAUDRATE)) ? ch: -1;
}

        (iv)可以修改 NR_SHELL_USER_NAME 以使用自定义的用户名。

【3】基本配置完成之后,就完成输出了。下面接着实现串口接收的移植:要实现交互,就需要串口接收中断函数调用 shell() 这个宏(根据自己程序,在串口接收中断函数处接收数据,传递给 shell() 这个宏,也可以使用轮询的机制),我这边是在串口中断中调用的

/**************************************************************************
* 函数名称: Uart0_IRQHandler
* 功能描述: 串口接收中断
**************************************************************************/
void Uart0_IRQHandler(void)
{uint8_t ch;if(Uart_GetStatus(M0P_UART0, UartRC))       //UART0数据接收{Uart_ClrStatus(M0P_UART0, UartRC);      //清中断状态位ch = Uart_ReceiveData(M0P_UART0);       //接收数据字节shell(ch);}if(Uart_GetStatus(M0P_UART0, UartTC))         //UART0数据发送{Uart_ClrStatus(M0P_UART0, UartTC);        //清中断状态位}
}

【4】在程序初始化的时候调用串口的初始化以及shell初始化接口(shell_init()),上电之后即可看到shell的logo,按TAB键即可看到注册的几个命令:

#include "nr_micro_shell.h"int main(void)
{//串口初始化Dbg_Init();Dbg_Cfg();//命令行初始化shell_init();while(1){}
}

【5】自定义命令的注册:

        参考 nr_micro_shell_commands.c 中的命令模板,实现自定义的命令,并放在 static_cmd 中进行注册(注意:这边的 {"\0", NULL} 不能删除)。

void shell_show_cmd(char argc, char *argv)
{shell_printf("show cmd \r\n");
}void shell_set_cmd(char argc, char *argv)
{shell_printf("set cmd \r\n");
}#ifdef NR_SHELL_USING_EXPORT_CMD
NR_SHELL_CMD_EXPORT(ls, shell_ls_cmd);
NR_SHELL_CMD_EXPORT(test, shell_test_cmd);
#else
const static_cmd_st static_cmd[] ={{"ls", shell_ls_cmd},{"show", shell_show_cmd},{"set", shell_set_cmd},{"\0", NULL}};
#endif

        至此,移植结束。

四 实际使用

        实际使用的效果如下:

补充几个别人遇到的问题以及自己遇到的问题待查:

(i)nr_micro_shell 还不支持一些特殊的按键,如果按下了这些特殊按键会导致程序崩溃。而且在使用方向键获取历史命令的时候,会把前导符 ”:“ 给覆盖掉,所以还是有些需要完善的地方的;

(ii)在xshell终端输入指令,nr_micro_shell没有反馈回来指令字母,需要完成一条指令按回车才有反馈,输入指令过程中没有反馈,查看了一下源码,需要在此处修改一下代码,将上面NR_MICRO_SHELL_SIMULATOR这个宏判断去掉,如下:

(iii)在使用TAB键补充的时候,会出现程序崩溃,需要在TAB处理函数处加入一下代码:

(iv)自己调试的时候遇到一个问题:实际使用shell的时候,有时候按空格或者退格键会使得程序直接重启,更换了串口波特率9600为115200之后,问题解决。具体原因不明,希望有大神看到能够帮忙解惑。

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

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

相关文章

9.二维数组——打印出杨辉三角形(要求打印出10行)

文章目录 前言一、题目描述 二、题目分析 三、解题 程序运行代码 前言 本系列为二维数组编程题&#xff0c;点滴成长&#xff0c;一起逆袭。 一、题目描述 打印出杨辉三角形&#xff08;要求打印出10行&#xff09;。 二、题目分析 三、解题 程序运行代码 #include<s…

Linux - 动静态库(上篇)

Linux 当中的 内存管理模块 不管是操作系统对于进程之间的管理&#xff0c;还是 对于文件的访问和修改等等的操作&#xff0c;都是要把数据加载到内存当中的&#xff0c;所以&#xff0c;所有的工作都离不开 内存管理模块。 内存的本质其实是对数据的一种临时存储&#xff0c…

智慧农田可视化大数据综合管理平台方案,EasyCVR助力农业高质量发展

一、背景需求 我国是农业大国&#xff0c;农业耕地面积达到20亿亩。随着物联网、大数据、人工智能等新一代信息技术与农业农村加速融合&#xff0c;以及国家对农业的重视&#xff0c;智慧农业对于我国农业现代化建设和实施乡村振兴战略具有重大引领与推动作用。在传统农田生产…

【每日一题】设计前中后队列

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;双指针 写在最后 Tag 【设计类】【队列】【数组】【2023-11-28】 题目来源 1670. 设计前中后队列 题目解读 设计一个队列&#xff0c;可以实在在前、中、后三个位置的 push 和 pop 操作。 解题思路 维护一个数组&am…

建筑红模板尺寸规格

红模板是建筑施工中常用的一种模板材料&#xff0c;具有较好的承重能力和稳定性。在建筑工程中&#xff0c;正确选择合适的红模板尺寸规格对于施工质量和效率至关重要。本文将介绍一些关于红模板尺寸规格的信息&#xff0c;帮助您更好地了解和选择适合的红模板。 以下是关于红模…

Apache2.4 AliasMatch导致301重定向问题?

环境&#xff1a;ubuntu18.04-desktop apache2版本&#xff1a; rootubuntu:/etc/apache2# apache2ctl -v Server version: Apache/2.4.29 (Ubuntu) Server built: 2023-03-08T17:34:33apache配置&#xff1a; DocumentRoot /var/www/html # Alias就没事 # Alias "/my…

Docker | 自定义Docker镜像

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a;Docker系列 ✨特色专栏&#xff1a; My…

Leetcode刷题之设计循环队列(C语言版)

Leetcode刷题之设计循环队列&#xff08;C语言版&#xff09; 一、题目描述二、题目示例三、题目解析Ⅰ、typedef structⅡ、MyCircularQueue* myCircularQueueCreate(int k)Ⅲ、bool myCircularQueueIsEmpty(MyCircularQueue* obj)Ⅳ、bool myCircularQueueIsFull(MyCircularQ…

Vue3-admin-template 导入模板功能

先看效果&#xff1a; 直接上代码&#xff1a; 1.绑定事件&#xff1a; <el-button type"primary" click"templates">模板导入</el-button> 2.写结构样式 <!-- 模板导入 --><el-dialog v-model"Statusimprot" title&quo…

2023年通过已经认证的微信公众号注册微信小程序

登录已经认证的微信公众号 注册完成后&#xff0c;打开微信公众平台的网址&#xff0c;用账号密码的方式登录

与 PCIe 相比,CXL为何低延迟高带宽?

文章目录 前言1. LatencyPCIE 生产者消费则模型结论Flit 包PCIE/CXL.ioCXL.cace & .mem总结 2. BandWidth常见开销CXL.IO Link efficiencyPCIe Link efficiencyCXL.IO bandwidthCXL.mem/.cache bandwidth 参考 前言 CXL 规范里没有具体描述与PCIe 相比低延时高带宽的原因&…

视频文案怎么写,媒介盒子支招

近几年短视频成为风口&#xff0c;各行各业都想分一杯羹&#xff0c;但是一头热的你&#xff0c;是否知道短视频的相关文案怎么写呢?正所谓兵马未动&#xff0c;文案先行&#xff0c;一个合适的文案是上热门的秘密武器&#xff0c;今天媒介盒子就来和大家聊聊&#xff1a;视频…