基于GD32f103c8t6的RT-threadNano系统移植
最近⼿上有⼀个⼩项⽬⽤到了这个GD32的芯⽚。裸机开发已经完成了,于是就是想要加⼊⼀个实时操作系统。⽤了国产的芯,那就⽤下国产的操作系统吧!
于是开始了解rt-thread系统,由于这款芯⽚的内存有限,运存有限,因此不能移植标准版的系统,仅仅可以移植Nano版本的系统。
⾸先要说明⼏个问题。
⾸先你得有⼀个基础程序吧,⾥⾯有你⾃⼰的main函数,有标准库函数,有弄好的外设驱动吧
采⽤iar 8.30 编译,,C库选 full
rtthread nano加⼊到iar⼯程中,要新建⼀个rtthread⽂件夹
加⼊下载的include、libcpu、src⽂件夹
把borard.c、rtcongfig.h也加⼊
然后开始按照官⽅移植的步骤开⼯。
第⼀步 void HardFault_Handler()、void PendSV_Handler(void)、void SysTick_Handler(void)系统已经实现,请在
gd32f10x_it.c中注释掉这三个函数
//void HardFault_Handler(void)
//{
// /* if Hard Fault exception occurs, go to infinite loop */
// while (1){
// }
//}
//void PendSV_Handler(void)
//{
//}
//void SysTick_Handler(void)
//{
// delay_decrement();
//}
第⼆步 在board.c中,实现以下两个函数,假定使⽤usart0作为控制台串⼝
//⽤于finish输⼊
char rt_hw_console_getchar(void){
int ch =-1;
if( usart_flag_get(USART0,USART_FLAG_RBNE) != RESET)
{
ch = (uint8_t)usart_data_receive(USART0);
}
el{
if ( usart_flag_get(USART0,USART_FLAG_ORERR) != RESET)
{
usart_flag_clear(USART0, USART_FLAG_RBNE);
//rt_thread_mdelay(10);
}
}
return ch;
}
//⽤于finish打印,实现rt_ktprintf()
/
/此函数可以在krvies.c中实现
RT_WEAK void rt_hw_console_output(const char *str)
{
// printf(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));
}
}
第三步 实现usart0的初始化,新建usart0.c和usart0.h两个⽂件并加⼊到iar⼯程。详细代码如下:usart0.c
//此处不使⽤中断接收,建议尝试中断接收或者DMA接收
void usart0_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_word_length_t(USART0, USART_WL_8BIT);
usart_stop_bit_t(USART0, USART_STB_1BIT);
usart_parity_config(USART0, USART_PM_NONE);
usart_baudrate_t(USART0, 115200U);
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
/
*USART irq t*/
nvic_irq_enable(USART0_IRQn, 0,0);
#if _using_interrupt_recevie
//usart_interrupt_enable(USART0, USART_INT_RBNE);//enable USART0 receive interrupt */
#endif
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;
}
void USART0_IRQHandler(void)
{
}
usart0.h
#include "gd32f10x.h"
#include "systick.h"
#include <stdio.h>
#include <stdarg.h>
void usart0_init(void);
void USART0_IRQHandler(void);
第四步 修改rt_hw_board_init()
按照如下的进⾏修改,主要是添加usart0_init()函数。此处的gd32systick变量是为了实现延时函数⽽声明的全局变量。
void rt_hw_board_init()
{
/* System Clock Update */
gd32systick=0;
SystemCoreClockUpdate();
/* System Tick Configuration */
_SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);//1 us 1 tick
usart0_init();
timer1_config();
/* Call components board initial (u 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中实现SysTick_Handler(void)、uint32_t _SysTick_Config(rt_uint32_t ticks)以实现*微妙延时*和*rt_thread_mdelay*延时
/*
step 1: 在原gd32的标准库中的systic.c和systick.h中注释void systick_config(void)函数,并将_SysTick_Config(rt_uint32_t ticks)中的内容去掉。
step 2:将如下代码段复制到_SysTick_Config(rt_uint32_t ticks)中,此时要包含头⽂件“gd32f10x.h”
*/
_SysTick_Config(rt_uint32_t ticks){
if(SysTick_Config(SystemCoreClock / ticks)){
/* capture error */
while (1){
}
}
/* configure the systick handler priority */
NVIC_SetPriority(SysTick_IRQn, 0x00U);
}
//ticks可以写死为 1000000U,以便实现微妙延时
/*
step 3:在board.c中按照如下⽅式实现SysTick_Handler,这样可以保证rt_thread的tick保持为1ms.但是要添加头⽂件“systick.h”
*/
void SysTick_Handler(void)//1 us
{
/* enter interrupt */
delay_decrement();// 1us
gd32systick++;
if(gd32systick == 1000){
gd32systick=0;
rt_interrupt_enter();
rt_tick_increa();//t 1 ms
rt_interrupt_leave();
}
}
//step 4:在systick.c中实现下⾯两个函数
void delay_1ms(uint32_t count)
{
delay = count*1000;
while(0U != delay){
}
}
void delay_1us(uint32_t count)
{
delay = count;
while(0U != delay){
}
}
//此时可以实现cpu独占式的延时函数delay_1us()、delay_1ms().也可以实现让出CPU时间的rt_thread_mdelay()。是否可以改进为rtthread nano 系统以1us为时基,我