STM32裸机移植letter shell

本文档详细介绍了如何将Linux下的LetterShell命令行工具移植到STM32平台,包括源码获取、数据接口移植、平台配置及启动任务的方法。通过移植,可以在STM32上实现交互式shell,方便项目开发和调试。此外,还展示了如何编写自定义命令和注册命令,以实现功能扩展。
摘要由CSDN通过智能技术生成

在这里插入图片描述

[--------------点击下面,进入总目录索引--------------]
STM32系列精品Demo集 - 总目录


图示:Letter Shell效果演示
在这里插入图片描述

一、为什么要移植Letter shell


  • Linux下强大的命令行工具用起来即为顺手,所以移植一款命令行工具到STM平台非常有意义 。
  • 工程中集成一款交互式shell,为项目开发调试提供便捷,开发者自定义测试命令,使得更加灵活。

二、移植步骤

2.1、获取Letter Shell源码

https://github.com/NevermindZZT/letter-shell

图示:Letter Shell源码结构
在这里插入图片描述
上述源码结构中,若不想深入了解实现机制,只想简单使用起来,后续移植只需关心上述框出文件即可!

2.2、shell_port.c数据源移植

shell_port.c主要用于配置Uart数据通道,说白了就是将shell_port.c中的读写接口移植为STM32平台的Uart发送接收接口。

Shell shell;
char shellBuffer[512];

/**
 * @brief 用户shell写
 *
 * @param data 数据
 */
void userShellWrite(char data)
{
    ControlUartSendData(UART0_CHANNEL, data);
}
/**
 * @brief 用户shell读
 *
 * @param data 数据
 * @return char 状态
 */
signed char userShellRead(char *data)
{
    *data = 0;
    while (!(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET))
    {
    }
    *data = USART_ReceiveData(USART1);
	return 0;  //返回0标识数据已经准备OK
}
/**
 * @brief 用户shell初始化
 *
 */
void userShellInit(void)
{
    char data = 0;
    shell.write = userShellWrite;
    shell.read = userShellRead;
    shellInit(&shell, shellBuffer, 512);
}

2.3、shell_cfg.h平台配置移植

图示:shell_cfg.h配置宏定义
在这里插入图片描述

!!!!!对于上述宏开关,小伙伴们可自行尝试,博主在移植过程中仅关注了下述几个宏,其它保持默认即可。!!!!!

/**
 * @brief 是否使用默认shell任务while循环,使能宏`SHELL_USING_TASK`后此宏有意义
 *        使能此宏,则`shellTask()`函数会一直循环读取输入,一般使用操作系统建立shell
 *        任务时使能此宏,关闭此宏的情况下,一般适用于无操作系统,在主循环中调用`shellTask()`
 */
#define     SHELL_TASK_WHILE            0          /*裸机操作不执行线程,关闭此宏*/
/**
 * @brief 获取系统时间(ms)
 *        定义此宏为获取系统Tick,如`HAL_GetTick()`
 */
#define     SHELL_GET_TICK()            0	       /*裸机操作不实现此接口,关闭此宏*/
/**
 * @brief shell默认用户
 */
#define     SHELL_DEFAULT_USER          "MicroShell" /*修改默认用户名*/

2.4、启动Letter Shell任务
2.4.1、启动方式一

/**
 * @brief shell 任务
 * 
 * @param param 参数(shell对象)
 * 
 */
void shellTask(void *param)
{
    Shell *shell = (Shell *)param;
    char data;
    /* 可以看到shell->read如果返回0,则认为串口有数据,调用shellHandler去处理,所以也就衍生了启动方式二*/
    if (shell->read && shell->read(&data) == 0)
    {
        shellHandler(shell, data);
    }
}
#include "stm32f4xx.h" 
#include "Delay.h"
#include "ControlUart.h"
#include "ModuleConfig.h"
#include "shell_port.h"
#include "shell.h"
int main(void)
{   
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
	delay_init();		     
	ControlUartInit(UART0_CHANNEL,115200);  
	userShellInit();
	while(1)
	{
		shellTask(&shell);
	}
}

2.4.2、启动方式二

/* 自定义接口函数 */
void userShellRun(void)
{
    char data = 0;
    data = 0;
    while (!(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET))
    {
    }
    data = USART_ReceiveData(USART1);
	  shellHandler(&shell,data);
    //delay_ms(10);
}
#include "stm32f4xx.h" 
#include "Delay.h"
#include "ControlUart.h"
#include "ModuleConfig.h"
#include "shell_port.h"
#include "shell.h"
int main(void)
{   
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
	delay_init();		     
	ControlUartInit(UART0_CHANNEL,115200);  
	userShellInit();
	while(1)
	{
		userShellRun();
	}
}

三、Letter Shell简单使用

3.1、编写自定义命令对应的执行接口

  • letter shell 3.x同时支持两种形式的函数定义方式:
  1. Main函数形式:func(int argc, char *agrv[])
  2. 普通C函数形式:func(int i, char *str, ...)
  • main函数形式
/***********************************************************************
 * 函数名称: ShellTestFun0
 * 功能描述: letter:/$ shelltest0 123 'a' "1234"
 * 输入参数: 
 * 输出参数: 
 * 返 回 值: 
 *  其   它: 
 ***********************************************************************/
int  ShellTestFun0(int i, char ch, char *str)
{
    printf("input int: %d, char: %c, string: %s\r\n", i, ch, str);
	//最后必须要加上换行,以避免与shell内置返回打印重叠
	printf("\r\n");
	return 0;
}
  • 普通C函数形式

      普通C函数形式,shell会自动对参数进行转化处理,目前支持二进制,八进制,十进制,十六进制整形,字符,字符串

    /***********************************************************************
     * 函数名称: ShellTestFun1
     * 功能描述: letter:/$ shellest1 "hello world"
     * 输入参数: 
     * 输出参数: 
     * 返 回 值: 
     *  其   它: 
     ***********************************************************************/
    int ShellTestFun1(int argc, char *agrv[])
    {
        printf("%dparameter(s)\r\n", argc);
        for (char i = 0; i <= argc; i++)
        {
            printf("%s\r\n", agrv[i]);
        }
    	//最后必须要加上换行,以避免与shell内置返回打印重叠
    	printf("\r\n");
    	return 0;
    }
    

3.2、注册命令

/***********************************************************************
* 函数名称: #define SHELL_EXPORT_CMD(_attr, _name, _func, _desc)
* 输入参数:
  		_attr :命令属性
  		_name :命令名
  		_func :命令函数
  		_desc :命令描述
* 输出参数:
* 返 回 值:
*  其   它:
***********************************************************************/
/******************************************************************************
* 注册自定义不同形参的测试指令
******************************************************************************/
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), shelltest0, ShellTestFun0, test mode0 parameter);
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), shelltest1, ShellTestFun1, test mode1 parameter);

3.3、命令测试

#终端调用
MicroShell:/$ shelltest0 12 'a' "hello"
input int: 12, char: a, string: hello
Return: 0, 0x00000000
#终端调用
MicroShell:/$ shelltest1 "hello"
2parameter(s)
shelltest1
hello
Return: 0, 0x00000000

附录:Demo源码

https://gitee.com/jiangfengzhang/stm32-f4-letter-shell

图示:工程源码结构
shell_customd_cmd.c(自定义命令源文件)
在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值