0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于APM32F4移植使用letter-shell命令行终端

Geehy极海半导体 来源:Geehy极海半导体 2023-11-03 17:23 次阅读

1. letter-shell简介

letter shell是一个C语言编写的,可以嵌入在程序中的嵌入式shell,主要面向嵌入式设备。

说得直白点他就是一个命令行交互软件,可以读取用户输入的命令,找到并执行命令对应的函数。

letter-shell的功能十分强大,目前主要功能有:

命令自动补全

快捷键功能定义

命令权限管理

用户管理

变量支持

代理函数和参数代理解析

下面是letter-shell运行起来的效果图:

db90204a-7a28-11ee-939d-92fbcf53809c.jpg

2. 获取源码

我们是要把letter-shell,移植到极海APM32F4的MCU上面运行,所以我们需要获取到极海的APM32F4的SDK包,以及letter-shell的源码。

letter-shell 开源项目源码:

可以到简介,给出的作者的github官网下载。如果因为网速的原因,也可以到gitee上面下载,gitee也有很多关于letter-shell的源码,

3. APM32F4上移植letter-shell过程

3.1 准备一份可以通过串口打印信息的工程

我们把官网的APM32F4 SDK下载下来后,然后我们选择一个串口中断的例程,如下:

db96e358-7a28-11ee-939d-92fbcf53809c.jpg

然后,把这个例程不需要的代码去掉,只留下串口相关的初始化代码,还有printf重定向的代码就行了。

编译下载到板子之后,可以看到串口正常输出打印信息,就说明代码正常。

3.2 向工程添加letter-shell源码

letter-shell源码目录如下:

dbad8cc0-7a28-11ee-939d-92fbcf53809c.jpg

我们只需要把src目录下的源码复制到对应工程目录下即可。

我这里就复制到对应工程的 Middlewaresletter-shell 目录下。

3.3 在keil-MDK中添加源码和文件包含路径

打开keil的项目管理窗口,然后添加我们刚刚复制的letter-shell的源码目录src的所有文件:

dbbafcb6-7a28-11ee-939d-92fbcf53809c.jpg

添加文件之后,再添加letter-shell的文件包含路径:

dbd5d69e-7a28-11ee-939d-92fbcf53809c.jpg

点击OK,退出。这个时候源码相当于添加完成,这是编译是可以通过的,没警告和错误。但是还不能正常使用letter-shell,因为还没有添加移植的接口函数。

3.4 添加shell_port.c文件,提供读写接口函数

我们还需要提供letter-shell的读写接口函数,这样letter-shell才能通过串口输出字符,或者通过串口获取输入字符。

在letter-shell的源码目录下,demo目录中,已经提供了基于stm32 freeRTOS的读写接口,我们可以把该文件复制到我们的工程目录下,然后在该文件基础上进行改写:

dbedcd76-7a28-11ee-939d-92fbcf53809c.jpg

1、在shell_port.c中,我们主要实现shell的写函数即可,代码如下:

/**

* [url=home.php?mod=space&uid=247401]@brief[/url] 用户shell写

*

* @param data 数据

* @param len 数据长度

*

* [url=home.php?mod=space&uid=266161]@return[/url] short 实际写入的数据长度

*/

short userShellWrite(char *data, unsigned short len)

{

unsigned short temp = len;

while (temp--)

{

/* send a byte of data to the serial port */

USART_TxData(USART1, *data++);

/* wait for the data to be send */

while (USART_ReadStatusFlag(USART1, USART_FLAG_TXBE) == RESET);

}

return len;

}

2、关于读函数,我们可以不用实现,因为我们使用的是串口中断方式接收字符,不需要实现读函数。我们只需要在串口中断函数中,调用shellHandler即可。串口中断代码如下:

/*!

* [url=home.php?mod=space&uid=247401]@brief[/url] This function handles USART1 RX interrupt Handler

*

* @param None

*

* @retval None

*

* @note

*/

void USART1_IRQHandler(void)

{

uint8_t ch;

if (USART_ReadIntFlag(USART1, USART_INT_RXBNE) == SET)

{

ch = USART_RxData(USART1);

shellHandler(&shell, ch);

}

}

3、提供letter-shell的初始化函数,该函数其实主要就是初始化shell结构体。因为我们只用到写函数,所以只提供了写接口。具体代码如下:

Shell shell;

char shellBuffer[512];

/**

* [url=home.php?mod=space&uid=247401]@brief[/url] 用户shell初始化

*

*/

void userShellInit(void)

{

shell.write = userShellWrite;

shellInit(&shell, shellBuffer, 512);

}

3.5 main函数初始化letter-shell

当我们把接口函数都提供了之后,就只需要在main函数调用 letter-shell 的初始化函数 userShellInit 即可。main函数代码如下:

/*!

* [url=home.php?mod=space&uid=247401]@brief[/url] Main program

*

* @param None

*

* @retval None

*/

int main(void)

{

/* USART Initialization */

USART_Config_T usartConfigStruct;

usartConfigStruct.baudRate = 115200;

usartConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;

usartConfigStruct.mode = USART_MODE_TX_RX;

usartConfigStruct.parity = USART_PARITY_NONE;

usartConfigStruct.stopBits = USART_STOP_BIT_1;

usartConfigStruct.wordLength = USART_WORD_LEN_8B;

APM_EVAL_COMInit(COM1, &usartConfigStruct);

APM_EVAL_COMInit(COM2, &usartConfigStruct);

/* Enable USART1 RXBNE interrput */

USART_EnableInterrupt(EVAL_COM1, USART_INT_RXBNE);

USART_ClearStatusFlag(EVAL_COM1, USART_FLAG_RXBNE);

NVIC_EnableIRQRequest(EVAL_COM1_IRQn,1,0);

userShellInit();

while(1)

{

}

}

主要就是初始化串口之后,就调用 userShellInit 初始化letter-shell。

到这里,我们就完成了letter-shell的移植了,编译下载可以看到如下效果:

dc08cde2-7a28-11ee-939d-92fbcf53809c.jpg

可以看到letter-shell支持了一些默认命令。

3.6 letter-shell的配置文件shell_cfg.h

该文件也是在letter-shell的src目录下,shell_cfg.h文件中包含了所有用于配置shell的宏,在使用前,可根据需要进行配置。我们工程是使用的默认配置,基本的功能也有,要想使用其他功能,可能需要先打开某个配置宏,定义的含义如下:

dc15c81c-7a28-11ee-939d-92fbcf53809c.jpg

4. 自定义自己的命令

4.1 与导出自定义命令相关的宏

letter-shell支持定义自己的命令,并且把该命令导出到shell终端中,以供我们在命令行下使用自定义的命令。

在使用letter-shell自定义命令时,要先检查 shell_cfg.h 文件是否开启了命令导出功能。

/**

* [url=home.php?mod=space&uid=247401]@brief[/url] 是否使用命令导出方式

* 使能此宏后,可以使用`SHELL_EXPORT_CMD()`等导出命令

* 定义shell命令,关闭此宏的情况下,需要使用命令表的方式

*/

#define SHELL_USING_CMD_EXPORT 1

就是这个宏需要定义为 1 。开启了这个宏,我们就可以编写自己的命令函数,然后导出到shell终端了。

导出自定义命令的宏在 shell.h 文件中定义,其代码如下:

/**

* [url=home.php?mod=space&uid=247401]@brief[/url] shell 命令定义

*

* @param _attr 命令属性

* @param _name 命令名

* @param _func 命令函数

* @param _desc 命令描述

*/

#define SHELL_EXPORT_CMD(_attr, _name, _func, _desc)

const char shellCmd##_name[] = #_name;

const char shellDesc##_name[] = #_desc;

SHELL_USED const ShellCommand

shellCommand##_name SHELL_SECTION("shellCommand") =

{

.attr.value = _attr,

.data.cmd.name = shellCmd##_name,

.data.cmd.function = (int (*)())_func,

.data.cmd.desc = shellDesc##_name

}

这里作者加入了命令属性的参数,主要就是定义该命令的权限,类型,是否使用返回值输出等等(详细的属性定义可以去看源码),其他参数就是命令名,对应的命令函数名,已经该命令的描述。

4.2 编写一个命令测试函数

这里我编写一个测试命令函数,代码如下:

/* 自定义命令测试函数 */

int test_func(int a, char *str)

{

printf("%d ", a);

printf("%s ", str);

return 0;

}

/* 导出到命令列表里 */

SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), test_cmd, test_func, test cmd);

然后编译运行,可以看到多了一个test_cmd命令:

dc31dbd8-7a28-11ee-939d-92fbcf53809c.jpg

可以看到我们运行这个命令的时候,输出了我们代码的打印内容。

根据作者的reamme文件,目前 letter shell 3.x 版本,命令函数参数只支持整数,字符,字符串参数,以及在某些情况下的浮点参数直接传递给执行命令的函数。浮点型参数是在哪些情况才支持,可以阅读作者的文档。

另外,参数的个数,是有一个宏配置的:

/**

* [url=home.php?mod=space&uid=247401]@brief[/url] shell命令参数最大数量

* 包含命令名在内,超过16个参数并且使用了参数自动转换的情况下,需要修改源码

*/

#define SHELL_PARAMETER_MAX_NUMBER 8

默认只支持8个参数,当然我们可以修改支持更多参数个数。







审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5036

    文章

    18768

    浏览量

    297645
  • C语言
    +关注

    关注

    180

    文章

    7573

    浏览量

    133594
  • Shell
    +关注

    关注

    1

    文章

    359

    浏览量

    23177

原文标题:APM32芯得 EP.25 | 基于APM32F4移植使用letter-shell命令行终端

文章出处:【微信号:geehysemi,微信公众号:Geehy极海半导体】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    在STM32实现命令行

    工作中的开发环境都是基于linux命令行交互,作为命令行的重度使用者,玩单片机也要使用命令行工具,百度了一些命令行工具,有几个不错的开源 cmd 交互工具,主要看了 finsh
    发表于 12-09 11:32 2061次阅读

    Shell命令行记录

    Shell命令行Tips整理【持续更新】
    发表于 10-21 06:36

    Shell脚本命令行解析

    Shell脚本解析命令行参数——Argparse(填坑)
    发表于 04-03 11:34

    STM32HAL如何移植功能强大letter-shell开源库?

    STM32HAL如何移植功能强大letter-shell开源库?
    发表于 11-26 06:19

    Mini shell命令行调试工具的相关资料分享

    @mini shell命令行调试工具介绍Mini shell 命令行调试工具(单片机、c语言)Mini shell是一个特别适合低内存的单片
    发表于 01-24 08:15

    【CW32饭盒派开发板试用体验】+ 串口letter-shell 移植

    本次主要移植letter-shell过程。 letter shell是一个C语言编写的,可以嵌入在程序中的嵌入式shell,主要面向嵌入式设
    发表于 06-11 12:20

    caxa命令行中的应用

    caxa命令行中的应用 命令行对于大多用户来说往往只是输入数据的作用,但是其中的奥妙还有很多,下面就给大家
    发表于 10-18 18:18 2254次阅读

    mini shell命令行调试工具(单片机、c语言)

    @mini shell命令行调试工具介绍Mini shell 命令行调试工具(单片机、c语言)Mini shell是一个特别适合低内存的单片
    发表于 11-29 10:21 9次下载
    mini <b class='flag-5'>shell</b><b class='flag-5'>命令行</b>调试工具(单片机、c语言)

    Shell命令行解释器简介

    Shell 是一个命令行解释器,Shell 为用户提供了与设备进行命令行交互的方式,用户通过串口、以太网、无线等方式将命令传输给具有
    的头像 发表于 08-19 17:20 3000次阅读

    Linux命令行shell脚本编写

    Linux命令行shell脚本编写
    发表于 01-11 16:50 4次下载

    AN023 如何在GD平台移植Letter shell

    AN023 如何在GD平台移植Letter shell
    发表于 02-27 18:25 1次下载
    AN023 如何在GD平台<b class='flag-5'>移植</b><b class='flag-5'>Letter</b> <b class='flag-5'>shell</b>

    linux命令行shell编程实战

    Linux命令行Shell编程实战主要涉及以下内容: Linux命令行基础:学习Linux命令行的基本操作,如文件管理、进程管理、网络配置等。熟悉使用
    的头像 发表于 11-08 10:57 611次阅读

    linux虚拟机怎么调出命令行

    快捷键组合Ctrl+Alt+F1 6来切换到命令行界面。如果系统在虚拟机中,则可以使用Ctrl+Alt+shift+F1 6组合键来切换到命令行界面。在
    的头像 发表于 11-08 11:28 2391次阅读

    linux切换到命令行模式

    在Linux中,可以通过以下步骤切换到命令行模式: 打开终端。可以在应用菜单中找到终端命令行终端。 在
    的头像 发表于 11-13 16:47 1420次阅读

    pycharm命令行终端运行代码

    Python是一种非常流行的编程语言,许多开发者使用它来编写各种应用程序和脚本。为了方便开发者编写和测试代码,PyCharm是一种集成开发环境(IDE),它提供了许多功能和工具,其中包括命令行终端
    的头像 发表于 11-22 11:20 3045次阅读