文章目录
前言
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