RT-Thread Nano实战2-msh配置与运行

msh配置与运行

之前已经完成GD32F150上RT-Thread Nano的内核运行,为了在产品中方便调试除错,RT-Thread的shell是非常实用且必不可少的一个功能的。其实RT-Thread Nano的keil pack也是可以支持shell中的msh功能的,只需要完成一些配置及串口驱动编写等工作就可以正常使用msh。
同时RT-Thread官方也在STM32L0及LPC824这2个芯片上提供了“bink”和“msh”示例来演示Nano的基本使用和msh的使用。这次先学习example示例工程安装、学习,而后完成GD32F150上Nano的msh功能开发。

1. 示例安装

  1. 打开keil5主界面上的“Pack Installer”按钮,进入Pack安装界面。
    Pack_installer.png
  2. 在“Devices”栏中的“Search”中输入“STM32L0”或“LPC824”,在右侧“Examples”中可以找到“bink”和“msh”示例,如未发现,请点击“Packs”->“Check For Updates”.

STM32L0 example

stm_example.png

LPC824 example

824_example.png

点击“copy”按钮即可安装。这次我们选择的是STM32L0的“rtthread msh example”。


copy_example.png

如按钮为灰色“Install”,请先右键点击“rtthread msh example”并选择“cancel actions”即可点击“Install”进行安装。
下载的example已完成全部配置可正常编译运行。example工程含有msh功能必需的串口驱动“uart.c”和“uart.h”,在后面将按照这个uart驱动模版来完成自己芯片的串口驱动。

2. msh功能配置与运行

2.1 加载msh相关文件

要使用msh,除了上次使用的kernel外,还必须加载Pack中的shell和device drivers。

nano.png

选中前部3个功能后,可以在Project栏中看到已加载shell及device drivers相关文件。
file.png

2.2 keil工程配置

在keil中要正确使用RT-Thread的shell功能,必须在keil的“Options”->“Linker”页面下的“Misc controls”栏中加入--keep *.o(.rti_fn.*) --keep *.o(FSymTab)

linker.png

2.3 串口驱动编写

msh功能必须依赖串口,串口驱动编写可参考example中的uart.c和uart.h模板来完成。uart主要用到了RT-Thread的device驱动组件和ringbuffer组件。和RT-Thread标准版bsp下的serial驱动有一些区别,具体可参照第5部分.相关阅读

2.3.1 串口初始化函数:

RT-Thread常使用rt_hw_usart_init()函数,也可自定义函数名。同时为了让Nano msh能正确使用,必须使用INIT_BOARD_EXPORT(rt_hw_usart_init);来完成串口驱动初始化。

int rt_hw_usart_init(void)
{
    struct gd32_uart *uart;
    
#ifdef RT_USING_UART1
    uart = &uart1_device;
    
    uart->parent.type = RT_Device_Class_Char;
    uart->uart_base = USART1;
    uart->uart_irq = USART1_IRQn;

    rt_ringbuffer_init(&uart->rx_rb, uart->rx_buffer, sizeof(uart->rx_buffer));

    uart->parent.init = rt_uart_init;
    uart->parent.open = rt_uart_open;
    uart->parent.close = rt_uart_close;
    uart->parent.read = rt_uart_read;
    uart->parent.write = rt_uart_write;
    uart->parent.control = RT_NULL;
    uart->parent.user_data = RT_NULL;

    rt_device_register(&uart->parent, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
#endif

    return 0;
}
INIT_BOARD_EXPORT(rt_hw_usart_init);

在该函数内用到了自定义gd32_uart的结构体指针变量, 该结构体变量内包含rt_device设备控制块、环形队列、gd32串口设备号、中断号、串口接收buffer等。

#define UART_RX_BUFSZ 8

struct gd32_uart
{
    struct rt_device parent;
    struct rt_ringbuffer rx_rb;

    USART_TypeDef* uart_base;
    IRQn_Type uart_irq;
    
    rt_uint8_t rx_buffer[UART_RX_BUFSZ];
};
2.3.2 GD32F150串口驱动:

串口驱动需完成init/open/close/read/write函数,其中:

  1. init函数内完成GPIO配置、USART使能、NVIC中断使能等工作。
  2. 在open/close函数内主要是对NVIC中断进行了开/关操作,如不需要对中断操作,这2个函数可不实现。
  3. 在write函数内实现串口数据发送操作。
  4. 在read函数内实现串口ringbuffer数据读取。

具体代码实现可参照example

2.3.3 串口中断处理:

中断处理依然使用的是GD32的中断处理函数,在中断处理函数中完成ringbuffer的串口数据写入。同时需要在中断处理函数中插入rt_interrupt_enter();/rt_interrupt_leave();通知RT-Thread内核当前处于中断模式。

static gd32_uart_recv_handler(struct gd32_uart *uart)
{
    if(USART_GetIntBitState(uart->uart_base, USART_INT_RBNE) != RESET)
    {
        rt_ringbuffer_putchar_force(&(uart->rx_rb), (rt_uint8_t)USART_DataReceive(uart->uart_base));
        if(uart->parent.rx_indicate != RT_NULL)
        {
            uart->parent.rx_indicate(&uart->parent, rt_ringbuffer_data_len(&uart->rx_rb));
        }
    }
}

void USART1_IRQHandler(void)
{
    rt_interrupt_enter();

    gd32_uart_recv_handler(&uart1_device);

    rt_interrupt_leave();
}

2.3.4 串口宏定义修改:

由于我使用的是GD32F150的usart1作为msh串口,还需要将rtconfig.h文件第186行的#define RT_USING_UART2修改为#define RT_USING_UART1

uart1.png

同时将rtconfig.h文件第148行的#define RT_CONSOLE_DEVICE_NAME "uart2"修改为#define RT_CONSOLE_DEVICE_NAME "uart1"

device_name.png

正确完成以上配置后,msh就可以正常运行了。


start.png

3. msh使用

msh命令与linux下bash类似,在msh命令行下输入help命令可获取当前已支持的全部msh命令行

help.png

同时我们如需将自己编写的函数导出到msh命令行,只需要加入MSH_CMD_EXPORT
如RT-Thread内置的version指令

#include "finsh.h"
int hello_world(void)
{
    rt_kprintf("%s\n", "hello world!");

    return 0;
}
MSH_CMD_EXPORT(hello_world, printf hello world);
user.png

4. Nano资源占用对比

只使用Nano Kernel的资源占用:FLASH:6.08K,RAM:1.305K

kernel.png

增加msh功能后的资源占用:FLASH:14.48K,RAM:2.375K

msh.png

通过对比可以发现,RT-Thread Nano添加了UART及msh功能后,资源占用依然比较小的,FLASH增大了8.4K,RAM只增大了1.07K。

5.相关阅读

1. RT-Thread编程手册第6章:I/O设备管理https://www.rt-thread.org/document/site/zh/1chapters/06-chapter_device/
2. GD32F150实战RT-Thread Nano:http://blog.csdn.net/flyingcys/article/details/78923352
3. RT thread 设备驱动组件之USART设备:http://www.cnblogs.com/King-Gentleman/p/4653011.html
4.剥洋葱:从RT-Thread的串口到内核对象:https://mp.weixin.qq.com/s/Nd5QRBcYyarjx38wme7Z7Q

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341