一、背景介绍
RT-Thread 背景介绍
RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是多核,64位的ARM Cortex-A,MIPS32/64处理器的功能丰富系统。
GD32F310G8 背景介绍
GD32F310系列采用Arm Cortex-M4内核,主频达到72MHz,配备了16KB到64KB的嵌入式闪存及4KB到8KB的SRAM。片上集成了多达5个16位通用定时器、1个16位基本定时器和1个多通道DMA控制器,还集成了1个12位2.6M SPS采样率的高性能ADC。通用接口包括2个USART、2个SPI、2个I2C、1个I2S。
二、移植前准备
- 由于GD32F310评估版内部集成了调试模块用于模拟 DAP 调试器,不需要再外接 J-Link 等调试器。
- 通过官方网站可以下载到 GD32F3x0_Addon_V3.0.0.zip,安装其中的
GigaDevice.GD32F3x0_AddOn.3.0.0.ex_(需改为exe)
和GigaDevice.GD32F3x0_AddOn.3.0.0.pack
。打开例程,确认可以正常编译下载。 - 下载最新的 RealThread.RT-Thread.3.1.5.pack 并安装。
三、开始移植 RT-Thread
- 新建一个项目,以
GD32F310G8
作为Device
。 - 确保项目是用
Keli v5
创建的,如果是由Keil v4
创建的需要在Project
->Manage
->Migrate to Version 5 Format
进行迁移。 在工具栏中有一个
Manage Run-Time Environment
的按钮,点击后在其中选择RT-Thread
检查右侧项目中是否出现
RTOS
- 编辑
board.c
,修改rt_hw_board_init
函数,新增systick_config()
。
void rt_hw_board_init(void) { #include "systick.h" systick_config(); /* * TODO 1: OS Tick Configuration * Enable the hardware timer and call the rt_os_tick_callback function * periodically with the frequency RT_TICK_PER_SECOND. */ /* Call components board initial (use INIT_BOARD_EXPORT()) */ #ifdef RT_USING_COMPONENTS_INIT rt_components_board_init(); #endif #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP) rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get()); #endif }
- 编辑
修改
board.c
中的堆栈大小,避免链接时报错。#define RT_HEAP_SIZE (1024) static rt_uint8_t rt_heap[RT_HEAP_SIZE];
在
board.c
中新增SysTick_Handler()
void SysTick_Handler() { rt_os_tick_callback(); }
- 注释
gd32f3x0_it.c
中的HardFault_Handler
、PendSV_Handler
和SysTick_Handler
。 在
main()
函数中编写点灯程序int main(void) { rcu_periph_clock_enable(RCU_GPIOA); gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_1 | GPIO_PIN_2); gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1 | GPIO_PIN_2); gpio_bit_reset(GPIOA, GPIO_PIN_1 | GPIO_PIN_2); while(1) { gpio_bit_write(GPIOA, GPIO_PIN_1, SET); gpio_bit_write(GPIOA, GPIO_PIN_2, RESET); rt_thread_mdelay(1000); gpio_bit_write(GPIOA, GPIO_PIN_2, SET); gpio_bit_write(GPIOA, GPIO_PIN_1, RESET); rt_thread_mdelay(1000); } }
- 下载,观察是否正常点灯。
四、移植RT-Thread Shell
- 确保第三步中选择了
RT-Thread
中的shell
模块。 修改
rtconfig.h
,在最后一行新增#include "finsh_config.h"
修改
finish_port.c
文件,增加 UART 接收部分RT_WEAK char rt_hw_console_getchar(void) { /* Note: the initial value of ch must < 0 */ int ch = -1; if(RESET != usart_flag_get(USART0, USART_FLAG_TC) && RESET != usart_flag_get(USART0, USART_FLAG_RBNE)) ch = usart_data_receive(USART0); return ch; }
- 修改
board.c
,新增 UART 发送部分
#ifdef RT_USING_CONSOLE
void usart0_gpio_config(void)
{
/* enable COM GPIO clock */
rcu_periph_clock_enable(RCU_GPIOA);
/* connect port to USARTx_Tx */
gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_9);
/* connect port to USARTx_Rx */
gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_10);
/* configure USART Tx as alternate function push-pull */
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_9);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_9);
/* configure USART Rx as alternate function push-pull */
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_10);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_10);
}
/*!
\brief configure the USART0
\param[in] none
\param[out] none
\retval none
*/
void usart0_config(void)
{
/* enable USART clock */
rcu_periph_clock_enable(RCU_USART0);
/* USART configure */
usart_deinit(USART0);
usart_word_length_set(USART0, USART_WL_8BIT);
usart_stop_bit_set(USART0, USART_STB_1BIT);
usart_parity_config(USART0, USART_PM_NONE);
usart_baudrate_set(USART0, 115200U);
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
usart_enable(USART0);
}
/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
usart_data_transmit(USART0, (uint8_t) ch);
while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
return ch;
}
static int uart_init(void)
{
usart0_gpio_config();
usart0_config();
return 0;
}
INIT_BOARD_EXPORT(uart_init);
void rt_hw_console_output(const char *str)
{
printf("%s",str);
}
#endif
在 Keil 中修改编译选项,新增
RT_USING_CONSOLE
下载,连接 PA9(TX) 与 PA10(RX) 至串口(115200),观察发送数据。