本帖最后由 6552918 于 2023-7-4 22:51 编辑
[url=home.php?mod=space&uid=760190]@21小跑堂 #申请原创#[/url] #技术资源#
Rt-thread OS是优秀的国产RTOS,但完成版的rt-thread耗费资源比较大,不太适合AC7802X这款MCU,但rt-thread为小资源的MCU提供了nano版本,可以运行在AC7802X这种小资源的MCU上,使用MDK进行移植还是比较容易得,但有些细节还是需要注意一下。
移植前需要先安装rt-threadnano的支持包
Nano Pack 可以通过在 Keil MDK IDE 内进行安装,也可以手动安装。下面开始介绍两种安装方式。
方法一:在内安装
打开 MDK 软件,点击工具栏的 Pack Installer 图标:
点击右侧的 Pack,展开 Generic,可以找到RealThread::RT-Thread,点击 Action 栏对应的 Install ,就可以在线安装 Nano Pack 了。另外,如果需要安装其他版本,则需要展开RealThread::RT-Thread,进行选择,箭头所指代表已经安装的版本。
方法二:手动安装
我们也可以从官网下载安装文件,RT-Thread Nano离线安装包下载(https://www.rt-thread.org/download/mdk/RealThread.RT-Thread.3.1.5.pack),下载结束后双击文件进行安装:
移植前需要准备一个能够正常运行的工程,我使用的是官方例程的串口例程进行移植的
添加到工程
打开已经准备好的可以运行的裸机程序,将 RT-Thread 添加到工程。如下图,点击 Manage Run-Time Environment。
现在可以在 Project 看到 RT-Thread RTOS 已经添加进来了,展开 RTOS,可以看到添加到工程的文件:
board.c
rtconfig.h
这两个文件是系统的配置文件,修改相关的配置都在这两个文件内修改实现
中断与异常处理
RT-Thread 会接管异常处理函数 HardFault_Handler() 和悬挂处理函数 PendSV_Handler(),这两个函数已由 RT-Thread 实现,所以需要删除工程里中断服务例程文件中的这两个函数,避免在编译时产生重复定义。如果此时对工程进行编译,没有出现函数重复定义的错误,则不用做修改。AC7802的库文件中并没有这两个函数,因此无需处理。
系统时钟配置
需要在board.c中实现 系统时钟配置(为 MCU、外设提供工作时钟)与 os tick 的配置(为操作系统提供心跳 / 节拍)。
在board.c中添加芯片头文件
添加OS Tick Configuration
在board.c内添加系统滴答定时器中断函数,实现系统时钟
内存堆初始化
系统内存堆的初始化在board.c中的rt_hw_board_init() 函数中完成,内存堆功能是否使用取决于宏 RT_USING_HEAP 是否开启,RT-Thread Nano 默认开启内存堆功能,需要关闭此宏,这样可以保持一个较小的体积。
至此,和内核相关的设置就配置完成,接下来我们要处理一些初始化函数,因为在rt-threadnano中的main函数是个线程,原来一些底层初始化再放在这个函数内就不太合适了,需要将初始化函数使用rt-thread的自动初始化功能放到板级初始化过程中,原工程中的延时使用的是滴答定时器,和系统有冲突,需要关闭。
通过进行串口收发测试,收发正常,说明程序已经运行起来了
通过IO翻转测试,证明系统时间正常
在 RT-Thread Nano 上添加控制台与 FinSH
本篇文档分为两部分:
第一部分是添加 UART 控制台(实现打印):用来向控制台对接的终端输出打印信息;该部分只需要实现两个函数,串口初始化和系统输出函数,即可完成 UART 控制台打印功能。
第二部分是移植FinSH 组件(实现命令输入),用以在控制台输入命令调试系统;该部分的实现基于第一部分,只需要添加 FinSH 组件源码并再对接一个系统输入函数即可实现。
下面将对这两部分进行说明。
在 Nano 上添加 UART 控制台(实现打印)
在 RT-Thread Nano 上添加 UART 控制台打印功能后,就可以在代码中使用 RT-Thread 提供的打印函数 rt_kprintf() 进行信息打印,从而获取自定义的打印信息,方便定位代码 bug 或者获取系统当前运行状态等。实现控制台打印(需要确认 rtconfig.h 中已使能 RT_USING_CONSOLE 宏定义),需要完成基本的硬件初始化,以及对接一个系统输出字符的函数,本小节将详细说明。
实现串口初始化
注:此部分为 3.1.5 版本中 #error TODO 2 的部分:#error "TODO 2: Enable the hardware uart and config baudrate."
使用串口对接控制台的打印,首先需要初始化串口,如引脚、波特率等。 初始化的串口函数 uart_init() 有以下两种调用方式,二选一:
方法一:默认使用宏 INIT_BOARD_EXPORT() 进行自动初始化,不需要显式调用,如下所示。
方法二:可以使用显式调用:uart_init() 需要在 board.c 中的 rt_hw_board_init() 函数中调用。
实现rt_hw_console_output
注:此部分为 3.1.5 版本中 #error TODO 3 的部分:#error "TODO 3: Output the string 'str' through the uart."
实现finsh 组件输出一个字符,即在该函数中实现 uart 输出字符:
/* 实现 2:输出一个字符,系统函数,函数名不可更改 */
void rt_hw_console_output(const char *str);
在 Nano 上添加 FinSH 组件(实现命令输入)
RT-Thread FinSH 是 RT-Thread 的命令行组件(shell),提供一套供用户在命令行调用的操作接口,主要用于调试或查看系统信息。
在 RT-Thread Nano 上添加 FinSH 组件,实现 FinSH 功能的步骤主要如下:
添加FinSH 源码到工程。
实现函数对接。
然后在rtconfig.h 中打开 finsh 相关选项,如下图:
实现rt_hw_console_getchar
注:此部分为 3.1.5 版本中 #error TODO 4 的部分:#error "TODO 4: Read a char from the uart and assign it to 'ch'."
要实现FinSH 组件功能:既可以打印也能输入命令进行调试,控制台已经实现了打印功能,现在还需要在 finsh_port.c 中对接控制台输入函数,实现字符输入:
/* 实现 3:finsh 获取一个字符,系统函数,函数名不可更改 */
char rt_hw_console_getchar(void);
rt_hw_console_getchar():控制台获取一个字符,即在该函数中实现 uart 获取字符,可以使用查询方式获取(注意不要死等,在未获取到字符时,需要让出 CPU),
到这里所以的移植就都结束了,实现了内核移植,并使用串口的方式实现了shell收发。
工程包:
01_UART_Polling(rt-thread nano).zip
(1.55 MB)
|