MM32F3273G8P火龙果开发板MindSDK开发教程20 - letter shell 的移植

news2024/11/27 22:43:54

MM32F3273G8P火龙果开发板MindSDK开发教程20 - letter shell 的移植

1、Letter Shell

犹如linux下的命令行,或者更像是uboot下的命令行,可以输入命令,执行相对应的函数。

2、Letter Shell移植(GCC 环境)

解压后,将相关文件拷贝到我们的工程,并新建shell_port.c shell_prot.h文件,整体代码视图如下:
在这里插入图片描述
shell_prot.c里面主要完成一个write函数,read函数我们不在这里定义,我们在串口收数据的中断里,调用
shellHandler函数。所以在串口的初始化中,要使能串口的收中断。

a、串口初始化函数

static void BOARD_InitUartPins(void)
{
    /* Pb6 - UART1_TX. */
    GPIO_Init_Type gpio_init;
    gpio_init.Pins  = CONSOLE_TX_GPIO_PIN;
    gpio_init.PinMode  = GPIO_PinMode_AF_PushPull;
    gpio_init.Speed = GPIO_Speed_50MHz;
    GPIO_Init(CONSOLE_GPIO_PORT, &gpio_init);
    GPIO_PinAFConf(CONSOLE_GPIO_PORT, gpio_init.Pins, GPIO_AF_7);

    /* Pb7 - UART1_RX. */
    gpio_init.Pins  = CONSOLE_RX_GPIO_PIN;
    gpio_init.PinMode  = GPIO_PinMode_In_Floating;
    gpio_init.Speed = GPIO_Speed_50MHz;
    GPIO_Init(CONSOLE_GPIO_PORT, &gpio_init);
    GPIO_PinAFConf(CONSOLE_GPIO_PORT, gpio_init.Pins, GPIO_AF_7);
}

void BOARD_InitDebugConsole(void)
{
    UART_Init_Type uart_init;
	BOARD_InitUartPins();

    uart_init.ClockFreqHz   = CLOCK_APB2_FREQ;
    uart_init.BaudRate      = 115200U;
    uart_init.WordLength    = UART_WordLength_8b;
    uart_init.StopBits      = UART_StopBits_1;
    uart_init.Parity        = UART_Parity_None;
    uart_init.XferMode      = UART_XferMode_RxTx;
    uart_init.HwFlowControl = UART_HwFlowControl_None;
    uart_init.XferSignal    = UART_XferSignal_Normal;
    uart_init.EnableSwapTxRxXferSignal = false;
    UART_Init(BOARD_DEBUG_UART_PORT, &uart_init);

        /* Enable RX interrupt. */
    UART_EnableInterrupts(BOARD_DEBUG_UART_PORT, UART_INT_RX_DONE, true);
    NVIC_EnableIRQ(UART1_IRQn);

    UART_Enable(BOARD_DEBUG_UART_PORT, true);
}

b、中断处理函数

uint8_t recv_buf = 0;

void app_uart_rx_isr_hook(void)
{
    if (   (0u != (UART_INT_RX_DONE & UART_GetEnabledInterrupts(BOARD_DEBUG_UART_PORT)))
        && (0u != (UART_INT_RX_DONE & UART_GetInterruptStatus(BOARD_DEBUG_UART_PORT))) )
    {
        recv_buf = UART_GetData(BOARD_DEBUG_UART_PORT); /* read data to clear rx interrupt bits. */

        //调用shell处理数据的接口
		shellHandler(&shell, recv_buf);
    }
}

/* BOARD_DEBUG_UART_IRQHandler ISR entry. */
void UART1_IRQHandler(void)
{
    app_uart_rx_isr_hook();
}

c、shell_port.c中完善写函数

#include "shell_port.h"

#include "shell.h"
#include "hal_uart.h"
#include "shell_port.h"

Shell shell;
char shell_buffer[512];

short userShellWrite(char *data, unsigned short len)
{
    uint32_t i;
	for (i = 0; i < len; i++)
	{
	    while ( 0u == (UART_STATUS_TX_EMPTY & UART_GetStatus(UART1)) )
        {}
        UART_PutData(UART1, (uint8_t)(data[i]));
	}
    return len;
}

void User_Shell_Init(void)
{
    shell.write = userShellWrite;
    shellInit(&shell, shell_buffer, 512);
}

其中write定义 signed short (*write)(char *, unsigned short);
shell_cfg.h内容如下:

/**
 * @file shell_cfg.h
 * @author Letter (nevermindzzt@gmail.com)
 * @brief shell config
 * @version 3.0.0
 * @date 2019-12-31
 * 
 * @copyright (c) 2019 Letter
 * 
 */
 
#ifndef __SHELL_CFG_H__
#define __SHELL_CFG_H__
 
 
/**
 * @brief 是否使用默认shell任务while循环,使能宏`SHELL_USING_TASK`后此宏有意义
 *        使能此宏,则`shellTask()`函数会一直循环读取输入,一般使用操作系统建立shell
 *        任务时使能此宏,关闭此宏的情况下,一般适用于无操作系统,在主循环中调用`shellTask()`
 */
#define     SHELL_TASK_WHILE           0
 
/**
 * @brief 是否使用命令导出方式
 *        使能此宏后,可以使用`SHELL_EXPORT_CMD()`等导出命令
 *        定义shell命令,关闭此宏的情况下,需要使用命令表的方式
 */
#define     SHELL_USING_CMD_EXPORT      1
 
/**
 * @brief 是否使用shell伴生对象
 *        一些扩展的组件(文件系统支持,日志工具等)需要使用伴生对象
 */
#define     SHELL_USING_COMPANION       0
 
/**
 * @brief 支持shell尾行模式
 */
#define     SHELL_SUPPORT_END_LINE      0
 
/**
 * @brief 是否在输出命令列表中列出用户
 */
#define     SHELL_HELP_LIST_USER        0
 
/**
 * @brief 是否在输出命令列表中列出变量
 */
#define     SHELL_HELP_LIST_VAR         0
 
/**
 * @brief 是否在输出命令列表中列出按键
 */
#define     SHELL_HELP_LIST_KEY         0
 
/**
 * @brief 是否在输出命令列表中展示命令权限
 */
#define     SHELL_HELP_SHOW_PERMISSION     0//1
 
/**
 * @brief 使用LF作为命令行回车触发
 *        可以和SHELL_ENTER_CR同时开启
 */
#define     SHELL_ENTER_LF              0//1
 
/**
 * @brief 使用CR作为命令行回车触发
 *        可以和SHELL_ENTER_LF同时开启
 */
#define     SHELL_ENTER_CR              1
 
/**
 * @brief 使用CRLF作为命令行回车触发
 *        不可以和SHELL_ENTER_LF或SHELL_ENTER_CR同时开启
 */
#define     SHELL_ENTER_CRLF            0
 
/**
 * @brief 使用执行未导出函数的功能
 *        启用后,可以通过`exec [addr] [args]`直接执行对应地址的函数
 * @attention 如果地址错误,可能会直接引起程序崩溃
 */
#define     SHELL_EXEC_UNDEF_FUNC       0
 
/**
 * @brief shell命令参数最大数量
 *        包含命令名在内,超过16个参数并且使用了参数自动转换的情况下,需要修改源码
 */
#define     SHELL_PARAMETER_MAX_NUMBER      8
 
/**
 * @brief 历史命令记录数量
 */
#define     SHELL_HISTORY_MAX_NUMBER    5
 
/**
 * @brief 双击间隔(ms)
 *        使能宏`SHELL_LONG_HELP`后此宏生效,定义双击tab补全help的时间间隔
 */
#define     SHELL_DOUBLE_CLICK_TIME     0//200
 
/**
 * @brief 快速帮助
 *        作用于双击tab的场景,当使能此宏时,双击tab不会对命令进行help补全,而是直接显示对应命令的帮助信息
 */
#define     SHELL_QUICK_HELP            0//1
 
/**
 * @brief 保存命令返回值
 *        开启后会默认定义一个`RETVAL`变量,会保存上一次命令执行的返回值,可以在随后的命令中进行调用
 *        如果命令的`SHELL_CMD_DISABLE_RETURN`标志被设置,则该命令不会更新`RETVAL`
 */
#define     SHELL_KEEP_RETURN_VALUE     0
 
/**
 * @brief 管理的最大shell数量
 */
#define     SHELL_MAX_NUMBER            5
 
/**
 * @brief shell格式化输出的缓冲大小
 *        为0时不使用shell格式化输出
 */
#define     SHELL_PRINT_BUFFER          128
 
/**
 * @brief shell格式化输入的缓冲大小
 *        为0时不使用shell格式化输入
 * @note shell格式化输入会阻塞shellTask, 仅适用于在有操作系统的情况下使用
 */
#define     SHELL_SCAN_BUFFER          0
 
/**
 * @brief 获取系统时间(ms)
 *        定义此宏为获取系统Tick,如`HAL_GetTick()`
 * @note 此宏不定义时无法使用双击tab补全命令help,无法使用shell超时锁定
 */
#define     SHELL_GET_TICK()            0
 
/**
 * @brief 使用锁
 * @note 使用shell锁时,需要对加锁和解锁进行实现
 */
#define     SHELL_USING_LOCK            0
 
/**
 * @brief shell内存分配
 *        shell本身不需要此接口,若使用shell伴生对象,需要进行定义
 */
#define     SHELL_MALLOC(size)          0
 
/**
 * @brief shell内存释放
 *        shell本身不需要此接口,若使用shell伴生对象,需要进行定义
 */
#define     SHELL_FREE(obj)             0
 
/**
 * @brief 是否显示shell信息
 */
#define     SHELL_SHOW_INFO             1
 
/**
 * @brief 是否在登录后清除命令行
 */
#define     SHELL_CLS_WHEN_LOGIN        1
 
/**
 * @brief shell默认用户
 */
#define     SHELL_DEFAULT_USER          "Max"
 
/**
 * @brief shell默认用户密码
 *        若默认用户不需要密码,设为""
 */
#define     SHELL_DEFAULT_USER_PASSWORD ""
 
/**
 * @brief shell自动锁定超时
 *        shell当前用户密码有效的时候生效,超时后会自动重新锁定shell
 *        设置为0时关闭自动锁定功能,时间单位为`SHELL_GET_TICK()`单位
 * @note 使用超时锁定必须保证`SHELL_GET_TICK()`有效
 */
#define     SHELL_LOCK_TIMEOUT          0//0 * 60 * 1000
 
#endif

其中 #define SHELL_USING_CMD_EXPORT 1时编译报错,要修改Ld文件如下:
在这里插入图片描述
shell_port.h内容如下:

#ifndef __SHELL_PORT_H__
#define __SHELL_PORT_H__
#include "shell.h"

extern Shell shell;
void User_Shell_Init(void);
#endif

3、调用以及现象

在main函数中调用代码如下:

#include <stdint.h>
#include <stdio.h>
#include "clock_init.h"
#include "hal_rcc.h"
#include "hal_gpio.h"
#include "hal_uart.h"
#include "led.h"
#include "uart.h"
#include "systick.h"
#include "key.h"
#include "timer.h"
#include "multi_button.h"
#include "shell_port.h"

struct Button btn1;

void BTN1_PRESS_DOWN_Handler(void* btn)
{
	//do something...
	printf("BTN1_PRESS_DOWN_Handler \r\n");
}

void BTN1_PRESS_UP_Handler(void* btn)
{
	//do something...
	printf("BTN1_PRESS_UP_Handler \r\n");
}

int test(int i)
{
    printf("input int: %d \r\n", i);

    return 0;
}

SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), test, test, test);

int main(void)
{
	BOARD_InitBootClocks();  // ³õʼ»¯Ê±ÖÓ
	BOARD_InitDebugConsole();
	BOARD_UserKeyInit();
	LED_Init();
	BOARD_TIM6_Init();

	// for mutilbutton init
	button_init(&btn1, read_button_GPIO, 0, btn1_id);
	button_attach(&btn1, PRESS_DOWN,       BTN1_PRESS_DOWN_Handler);
	button_attach(&btn1, PRESS_UP,         BTN1_PRESS_UP_Handler);
	button_start(&btn1);

	BOARD_TIM7_Init();

	BOARD_Delay1Ms(1000);
	User_Shell_Init();
	while(1)
	{

	}	
}

我们添加了一个test命令,如下:
在这里插入图片描述

现象:
在这里插入图片描述

4、代码

代码下载

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虹科干货 | BI软件如何实时连接本地Excel?—以HK-Domo商业智能工具为例

由于资源和人才的限制&#xff0c;很多中小微企业目前在数据收集和数据应用上还处于比较落后的阶段&#xff0c;没有合适的方法处理数据。最典型的情况就是通过Excel收集数据&#xff0c;然后频繁的手动生成报告。这样会导致数据质量差&#xff0c;流程重复&#xff0c;还可能增…

读财报丨长期主义指引下,蔚来“下半年月均交付2万+”能否实现?

新能源汽车的互联网属性正在加速消解&#xff0c;工业产品的特质开始贯穿行业始终。 首先是过去几年风头无两的造车新势力&#xff0c;与传统车企在产品层面的边界越来越模糊。与此同时&#xff0c;新能源汽车的利润水平也在大幅下降&#xff0c;趋近燃油车。 行业整体的风格…

计算机组成原理(第三版)唐塑飞 答案 第三章

3.1什么是总线?总线传输有何特点?为了减轻总线的负载,总线上的部件都应具备什么特点&#xff1f; 答&#xff1a; ① 总线是连接多个部件的信息传输线,是个部件共享的传输介质。 ② 总线传输特点:在某一时刻,只允许有一个部件向总线发送信息,而多个部件可以同时从总线上接受相…

20年不变的初心,亚马逊云科技为初创企业的独角兽梦想加速赋能!

廿年初心不改&#xff0c; 为初创企业打造增长飞轮 【全球云观察 &#xff5c; 热点关注】20年前&#xff0c;亚马逊现任CEO Andy Jassy观察到&#xff0c;在亚马逊内部新业务的孵化过程中工程师需要花大量的时间&#xff0c;投入在一些重复性高却不产生附加价值的基础设施建设…

【UE 从零开始制作坦克】1-控制坦克视角

UE版本&#xff1a;4.26 效果 步骤 1. 在虚幻商城中下载如下资产导入到工程中 导入成功后可以在工程中看到如下文件夹 2. 接下来开始制作一下控制坦克视角的逻辑 首先在项目设置中添加轴映射 新建一个蓝图&#xff0c;父类为“WheelVehicle(轮式载具)” 这里就命名为“TankZ…

科一容易忘、容易混的点(二)

注意落石 高速应急车道用途&#xff1a;主要用于发生事故或故障时停车&#xff0c;以及专为救险所用的车道&#xff0c;被誉为高速公路的“生命通道” 注意 注意 扣9份场景&#xff1a; 城市快速路上 违法停车&#xff1b; 注意 交通事故逃逸&#xff0c; 不一定吊销驾驶证&a…

Python的type内置类详解

目录导览 欢迎来到本文Type简介Type的常见用法用法1-获取对象的类型用法2-创建新的类 Type做为元类&#xff08;metaclass&#xff09;元类的作用如何自定义元类 欢迎来到本文 Type简介 在Python中&#xff0c;type是一个内建的类&#xff0c;它是用于表示对象的类型的类。ty…

(九)枚举器和迭代器(2)

一、Enumerator 接口 实现了 IEnumerator 接口的枚举器包含3个函数成员&#xff1a;Current、MoveNext 以及 Reset。 1&#xff09;Current&#xff1a; 返回序列中当前位置项的属性。 只读属性。返回 Object 类型。可以返回对应的可枚举类型。 2&#xff09;MoveNext&…

牛客网基础语法41~50题

牛客网基础语法41~50题&#x1f618;&#x1f618;&#x1f618; &#x1f4ab;前言&#xff1a;今天是咱们第五期刷牛客网上的题目。 &#x1f4ab;目标&#xff1a;熟练用数学知识来解决编程问题&#xff0c;会利用每种循环。 &#x1f4ab;鸡汤&#xff1a;压抑了&#xff0…

8 个身份自动化模版,帮你提升企业身份治理效率

中大型企业的信息化建设已经成为了当前企业的主流趋势。随着日益增长的业务需求&#xff0c;中大型企业的信息系统逐渐发展成为一个拥有众多应用和数据库支撑的复杂体系。由于中大型企业员工众多&#xff0c;部门繁杂&#xff0c;且存在大量员工入、转、调、离等情况&#xff0…

springboot集成quartz

文章目录 前言一、Quartz是什么&#xff1f;难易程度 二、核心思想三、使用步骤1.引入依赖2.创建相应类 总结 前言 引用上一篇博客的说法 springboot整合xxl-job ,集群模式下,定时任务会造成很严重的事故,其次普通的任务也无法做到像xxl-job与Quartz 一样,及时启停,修改等;上一…

文心一言 VS 讯飞星火 VS chatgpt (41)-- 算法导论5.4 5题

五、在大小为n的集合中&#xff0c;一个k字符串构成一个k排列的概率是多少?这个问题和生日悖论有什么关系? 文心一言&#xff1a; 在大小为n的集合中&#xff0c;一个k字符串构成一个k排列的概率是1/k!&#xff0c;这是由于排列的总数是k!&#xff0c;而每个字符串被选中的…

十大开源 ChatGPT 替代品:弥合对话式 AI 的差距

聊天机器人彻底改变了企业与客户互动的方式。由 OpenAI 开发的最先进的 GPT-4 是该领域的主导者。但是&#xff0c;它不是开源的&#xff0c;这限制了开发人员复制结果或开发自己的类似于 GPT-4 的聊天机器人。 为了填补这一空白&#xff0c;开源社区已经开始提供 GPT-4 的替代…

Qt6.5.1+WebRTC学习笔记(十二)环境搭建流媒体服务器(ubuntu22.04+SRS)

前言 若只是实现一对一通信&#xff0c;仅使用webrtc就足够了。但有时间需要进行多个人的直播会议&#xff0c;当人比较多时&#xff0c;建议使用一个流媒体服务器&#xff0c;笔者使用的是SRS。 这个开源项目资料比较全&#xff0c;笔者仅在此记录下搭建过程 一、准备 1.操…

移远通信率先完成多场5G NTN技术外场验证,为卫星物联网应用落地提速

近日&#xff0c;由中国电信卫星公司牵头&#xff0c;移远通信联合紫光展锐、鹏鹄物宇等行业上下游合作伙伴&#xff0c;针对现有蜂窝通信在信号覆盖盲区&#xff0c;信息监测数据无法实时回传等痛点问题&#xff0c;以领先行业的速度开展了一系列的5G NTN&#xff08;non-terr…

Unity入门7——物理系统之碰撞检测

一、刚体 Rigid Body ​ 刚体利用体积&#xff08;碰撞器 Collider&#xff09;进行碰撞计算&#xff0c;模拟真实的碰撞效果&#xff0c;产生力的作用 ​ 碰撞产生的必要条件&#xff1a; 两个物体都有碰撞器 Collider至少一个物体有刚体 Mass&#xff1a;质量 默认为千克&a…

postman自动化实战总结

Postman实战总结 简介 本次实战内容主要包括如下几点&#xff1a; l 背景介绍 l Postman使用&#xff0c;侧重于自动化实现&#xff0c;基础使用不做介绍 l 可视化Newman介绍 l 框架特色 l 实战中的坑 背景 随着国内软件技术的高速发展&#xff0c;越来越多的手工测试…

Qgis2threejs

three.js是JavaScript编写的一个开源的3D图形库&#xff0c;它可以用于创建各种各样的交互式3D应用程序和动画。该库提供了一系列的工具和功能&#xff0c;使得在Web浏览器中创建高质量的3D图形变得更加容易。 使用three.js&#xff0c;您可以轻松地创建3D场景&#xff0c;包括…

GoogleNet

Introduction 得益于深度学习的优势和更强大的卷积神经网络的出现&#xff0c;图像分类和目标检测的准确率发生了令人意想不到的进步。在2014年的ILSVRC比赛中&#xff0c;GoogLeNet取得了第一名的成绩&#xff0c;所用模型参数不足AlexNet&#xff08;2012年冠军&#xff09;…

基于Java医院住院管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…