对世界大多数人而言,人生一无意义,二无价值。 – 季羡林
准备工作
移植 RT-Thread
实现RT-Thread的基本功能
其实更方便的是通过安装 RT-Thread Nano pack 的方式去实现:《基于 Keil MDK 移植 RT-Thread Nano》。 但是为了更好地理解在构建工程中RT-Thread的组成以及构建中不同芯片需要的文件,所以我选择手动添加的方式。
- 在工程文件夹目录下新建名为
rtthread 的文件夹,拷贝如下文件到该目录: - 添加RT-Thread 内核所有通用的代码到 keil 工程(同样需要新建一个名为 rtthread 的分组),如下图所示:
添加工程下 rtthread/src/ 文件夹中所有文件到工程; 添加 rtthread/ 文件夹下的 board.c 。 - 添加对应芯片的内核的 CPU 移植文件及上下文切换文件
由于本次的芯片 GDF103C8T6 属于 ARM 的 Cortex-M3系列,所以需要添加对应系列的文件:内核的 CPU 移植文件及上下文切换文件: cpuport.c (针对具体芯片架构,比如Cortex-M3)以及 context_rvds.S (针对芯片架构和ide,这个是在keil上使用的)。 - 增加
rtthread 的头文件路径: - 编译工程,发现三个错误
原因在于这三个中断函数在RT-Thread已经定义好了,我们把 gd32f10x_it.c 文件夹中重复的函数删即可。 根据编译的错误提示,删除 void SysTick_Handler(void) 、void PendSV_Handler(void) 、void HardFault_Handler(void) ,再编译发没有错误了。 - 至此,RT-Thread 的基础工程就完成了,在
main.c 码入如下代码,可以看到 LED 灯闪烁着跳动的光,这心脏般的跳动说明工程已经完成了基本的功能,可以开始愉快的玩耍了。
#include <rtthread.h>
int main(void)
{
rcu_periph_clock_enable(RCU_GPIOC);
gpio_init(GPIOC, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13);
while(1)
{
gpio_bit_set(GPIOC, GPIO_PIN_13);
rt_thread_mdelay(500);
gpio_bit_reset(GPIOC, GPIO_PIN_13);
rt_thread_mdelay(500);
}
}
添加控制台与 FinSH
添加 UART 控制台
该功能其实实现的是打印功能,其实类似我们平时使用的 printf 函数,我们可以通过这个功能对外发送信息,方便调试代码。 一般使用串口作为打印的传输接口。 那么将其在 RT-Thread 上面实现就很简单了:串口初始化和系统输出函数。
- 串口初始化
使能 RT_USING_CONSOLE 宏定义 注释掉多余的宏定义(下面的宏定义和rtconfig.h 重复了)
在 boart.c 文件加入如下代码即可实现输出打印功能
static int uart_init(void)
{
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_USART0);
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
usart_deinit(USART0);
usart_baudrate_set(USART0, 115200);
usart_word_length_set(USART0, USART_WL_8BIT);
usart_stop_bit_set(USART0, USART_STB_1BIT);
usart_parity_config(USART0, USART_PM_NONE);
usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);
usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
usart_enable(USART0);
return 0;
}
INIT_BOARD_EXPORT(uart_init);
void rt_hw_console_output(const char *str)
{
rt_size_t i = 0, size = 0;
char a = '\r';
size = rt_strlen(str);
for (i = 0; i < size; i++)
{
if ( *(str+i) == '\n')
{
usart_data_transmit(USART0,a);
while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
}
usart_data_transmit(USART0, *(str+i));
while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
}
}
效果如下:
添加 FinSH 组件(实现命令输入)
RT-Thread FinSH 是 RT-Thread 的命令行组件(shell),提供一套供用户在命令行调用的操作接口,主要用于调试或查看系统信息。它可以使用串口 / 以太网 / USB 等与 PC 机进行通信。其实就是多了个交互功能,以前只能被动查看输出,现在可以通过输入主动去获取一些东西。
- 将RT-Thread 源代码中的 FinSh 文件拷贝到目标工程
添加入工程 在 rtconfig.h 中使能 #define RT_USING_FINSH 宏定义,在该文件加入 #defined RTE_USING_FINSH 。 - 实现 rt_hw_console_getchar函数
char rt_hw_console_getchar(void)
{
int ch = -1;
if (usart_flag_get(USART0, USART_FLAG_RBNE) != RESET)
{
ch = usart_data_receive(USART0);
}
else
{
rt_thread_mdelay(10);
}
return ch;
}
效果如下:
参考资料
|