基于GD32f103c8t6的RT-thread Nano系统移植

最近手上有一个小项目用到了这个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);
		   

	    }
	  else{
	  		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()
//此函数可以在kservies.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_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 irq set*/
	  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 (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中实现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_increase();//set 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为时基,我没有试验过。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值