RT-Thread学习笔记(3):RT-Thread控制台Finsh功能的实现


前言

Finsh控制台是RT-Thread的特色组件,能够让我们通过命令行方便地调试和查看系统运行信息,本章我们将通过设备注册的方式即DEVICE框架,实现控制台功能。


一、添加系统Finsh文件

1.添加Finsh Group

在这里插入图片描述

2.添加Finsh源文件

在这里插入图片描述
在这里插入图片描述

3. 添加头文件声明

在这里插入图片描述

二、修改rtconfig

1. 启用CONSOLE

在这里插入图片描述

2. 启用Finsh

在这里插入图片描述

3. 启用SERIAL

在这里插入图片描述

三、添加库函数

1. 添加串口相关库函数

在这里插入图片描述

在这里插入图片描述

2. 修改CONF, 启用相关功能

在这里插入图片描述

在这里插入图片描述

四、编写串口设备驱动

1. 创建drv_usart.h

#ifndef __DRV_USART_H__
#define __DRV_USART_H__

#include <rtthread.h>
#include <rthw.h>
#include <rtdevice.h>
#include <drv_common.h>

void rt_hw_usart_init(void);

#endif

2. 创建drv_usart.c

#include "board.h"
#include "drv_usart.h"
#include "string.h"

UART_HandleTypeDef huart1;

rt_err_t rt_uart_init(rt_device_t dev)
{
	huart1.Instance 				= USART1;
  huart1.Init.BaudRate 				= 115200;
  huart1.Init.WordLength 			= UART_WORDLENGTH_8B;
  huart1.Init.StopBits 				= UART_STOPBITS_1;
  huart1.Init.Parity 				= UART_PARITY_NONE;
  huart1.Init.Mode 					= UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl 			= UART_HWCONTROL_NONE;
  huart1.Init.OverSampling 		    = UART_OVERSAMPLING_16;
	
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    return RT_ERROR;
  }
	
	return RT_EOK;
}

rt_err_t rt_uart_open(rt_device_t dev, rt_uint16_t oflag)
{
	return rt_uart_init(dev);
}

static rt_size_t rt_uart_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
	rt_size_t i = 0;
	char a = '\r';
	const char *val = 0;
	
	val = (const char *)buffer;
	
	__HAL_UNLOCK(&huart1);
	
	for(i = 0; i < size; i++)
	{
		if(*(val + i) == '\n')
		{
			HAL_UART_Transmit(&huart1, (uint8_t *)&a, 1, 0xff);
		}
		HAL_UART_Transmit(&huart1, (uint8_t *)(val + i), 1, 0xff);
	}
	
	return 1;
}

static rt_size_t rt_uart_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{	
	while(1)
	{
		if(HAL_UART_Receive(&huart1, buffer, size, 0xff) == HAL_OK)
		{
			return size;
		}
		
		rt_thread_delay(1);
	}
}

struct rt_device my_serial;

void rt_hw_usart_init(void)
{
	my_serial.init = rt_uart_init;
	my_serial.open = rt_uart_open;
	my_serial.read = rt_uart_read;
	my_serial.write = rt_uart_write;
	
	rt_device_register(&my_serial, "uart1",
										 RT_DEVICE_FLAG_RDWR);
}
INIT_BOARD_EXPORT(rt_hw_usart_init);

3. 添加串口硬件初始化

在stm32f1xx_hal_msp.c中添加串口相关硬件初始化

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(uartHandle->Instance==USART1)
  {
    __HAL_RCC_USART1_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();

    GPIO_InitStruct.Pin = GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  }
}

void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{

  if(uartHandle->Instance==USART1)
  {
    __HAL_RCC_USART1_CLK_DISABLE();

    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
  }
}

4. 添加drv_usart.c

在这里插入图片描述

四、添加相关声明

1. drv_common添加头文件声明

在这里插入图片描述

2. application添加初始化声明(重要)

在这里插入图片描述

3. 修改优先级

由于先前工程 thread2 的线程优先级设为了20, 与shell线程即msh输入线程优先级相同,若不修改优先级会发生线程冲突,因此需要修改 thread2 的优先级,只要比20小即可

在这里插入图片描述

五、编译运行

在这里插入图片描述

在这里插入图片描述


总结

通过以上步骤我们就实现了RT-Thread的Finsh控制台功能

如果是想移植NANO内核的控制台功能,RT-Thread官方有相关教程 官方教程

如果是通过别的工程或教程进行移植,最后发现控制台只能输出没有办法输入,即 msh->命令行没有显示的话, 请根据4.2的步骤手动将shell线程初始化即可

STM32_RTTHRED_Finsh工程 提取码:xmp5

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值