这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【原创】RTThread操作系统移植finsh组件--from壮

共2条 1/1 1 跳转至

【原创】RTThread操作系统移植finsh组件--from壮

工程师
2024-12-20 20:08:25     打赏

RT-Thread Nano 是一个极简版的硬实时内核,它是由 C 语言开发,采用面向对象的编程思维,具有良好的代码风格,是一款可裁剪的、抢占式实时多任务的 RTOS。其内存资源占用极小,功能包括任务处理、软件定时器、信号量、邮箱和实时调度等相对完整的实时操作系统特性。适用于家电、消费电子、医疗设备、工控等领域大量使用的 32 ARM 入门级 MCU 的场合。

下图是 RT-Thread Nano 的软件框图,包含支持的 CPU 架构与内核源码,还有可拆卸的 FinSH 组件:

图片2.png

Nano 上添加 UART 控制台(实现打印)

RT-Thread Nano 上添加 UART 控制台打印功能后,就可以在代码中使用 RT-Thread 提供的打印函数 rt_kprintf() 进行信息打印,从而获取自定义的打印信息,方便定位代码 bug 或者获取系统当前运行状态等。实现控制台打印(需要确认 rtconfig.h 中已使能 RT_USING_CONSOLE 宏定义),需要完成基本的硬件初始化,以及对接一个系统输出字符的函数,本小节将详细说明。

 

 

实现串口初始化

使用串口对接控制台的打印,首先需要初始化串口,如引脚、波特率等。 初始化的串口函数 uart_init() 有以下两种调用方式,二选一:

1. 方法一:默认使用宏 INIT_BOARD_EXPORT() 进行自动初始化,不需要显式调用,如下所示。

2. 方法二:可以使用显式调用:uart_init() 需要在 board.c 中的 rt_hw_board_init() 函数中调用。

示例代码:如下是基于 HAL 库的 STM32F103 串口驱动,完成添加控制台的示例代码,仅做参考。

 

 

static UART_HandleTypeDef UartHandle; static int uart_init(void) { 

/* 初始化串口参数,如波特率、停止位等等 */ 

UartHandle.Instance = USART1; 

UartHandle.Init.BaudRate = 115200; 

UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;

 UartHandle.Init.Mode = UART_MODE_TX_RX;

 UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;

 UartHandle.Init.WordLength = UART_WORDLENGTH_8B;

 UartHandle.Init.StopBits = UART_STOPBITS_1;

 UartHandle.Init.Parity = UART_PARITY_NONE; /* 初始化串口引脚等 */

 if (HAL_UART_Init(&UartHandle) != HAL_OK) 

{

 while(1); 

}

  return 0;

 } 

INIT_BOARD_EXPORT(uart_init); 

/* 默认选择初始化方法一:使用宏 INIT_BOARD_EXPORT 进行自动初始化 */

 

/* board.c */ 

 初始化方法二:可以选择在 rt_hw_board_init 函数中直接调用 串口初始化 函 */

void rt_hw_board_init(void) {

 .... 

uart_init(); /*

 .... 

}

实现 rt_hw_console_output

实现 finsh 组件输出一个字符,即在该函数中实现 uart 输出字符:

/* 实现 2:输出一个字符,系统函数,函数名不可更改 */

 void rt_hw_console_output(const char *str);

void rt_hw_console_output(const char *str)

{

rt_size_t i = 0, size = 0;

char a = '\r';

__HAL_UNLOCK(&UartHandle);

size = rt_strlen(str);

for (i = 0; i < size; i++) 

{

if (*(str + i) == '\n') 

{

HAL_UART_Transmit(&UartHandle, (uint8_t *)&a, 1, 1); 

}

HAL_UART_Transmit(&UartHandle, (uint8_t *)(str + i), 1, 1);

}

}

结果验证

在应用代码中编写含有 rt_kprintf() 打印的代码,编译下载,打开串口助手进行验证。如下图是一个在 main() 函数中每隔 1 秒进行循环打印 Hello RT-Thread 的示例效果:

图片3.png

添加 FinSH 源码到工程

RTT官网下载finsh源码

cmd.c

msh.c

shell.c

finsh_port.c

添加到源码中

rtconfig.c添加#define RT_USING_FINSH

图片4.png

实现 rt_hw_console_getchar

要实现 FinSH 组件功能:既可以打印也能输入命令进行调试,控制台已经实现了打印功能,现在还需要在 board.c 中对接控制台输入函数,实现字符输入:

/* 实现 3finsh 获取一个字符,系统函数,函数名不可更改 */ char rt_hw_console_getchar(void);

· rt_hw_console_getchar():控制台获取一个字符,即在该函数中实现 uart 获取字符,可以使用查询方式获取(注意不要死等,在未获取到字符时,需要让出 CPU),推荐使用中断方式获取。

示例代码:如下是基于 STM32F103 HAL 串口驱动对接的 rt_hw_console_getchar(),完成对接 FinSH 组件,其中获取字符采用查询方式,示例仅做参考,可自行实现中断方式获取字符。

char rt_hw_console_getchar(void) 

{ 

int ch = -1;

 if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET)

 {

 ch = UartHandle.Instance->DR & 0xff; 

} 

Else

 {

 if(__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_ORE) != RESET)

 { 

__HAL_UART_CLEAR_OREFLAG(&UartHandle); 

}

 rt_thread_mdelay(10); 

}

 return ch;

 }

编译下载代码,打开串口助手,可以在串口助手中打印输入 help 命令,回车查看系统支持的命令:

图片5.png


工程师
2024-12-21 08:43:11     打赏
2楼

厉害了。


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]