理想三旬 · 2022年11月18日 · 广东

【GD32F427开发板试用】+rtt-thread nano+finsh极简开发

引言

在工作闲暇之际,逛逛论坛,无意间看到GD的试用活动,一如既往的积极,在官方还没发布时就申请了,也如愿的收到了板子,感谢官方和社区给了探索这块板子的机会。

Why rtt

RT-Thread Nano 是一个极简版的硬实时内核,它是由 C 语言开发,采用面向对象的编程思维,具有良好的代码风格,是一款可裁剪的、抢占式实时多任务的 RTOS。其内存资源占用极小,功能包括任务处理、软件定时器、信号量、邮箱和实时调度等相对完整的实时操作系统特性。只需内核与Finsh就足够使用,简单方便,个人不喜欢太复杂。

资源

  • GD32F427VKT6
  • 32位Arm®Cortex®-M4处理器内核
  • 高达200 MHz的工作频率
  • 3072K Flash
  • 256k SRAM
  • 4个USART和4个UART,3个I2C,6个SPI,2个I2S,2个CAN2.0B
  • 1个SDIO接口、1个10/100M以太网控制器
  • 3个采样率高达2.6M SPS的12位高速ADC和2个12位DAC,
  • 单循环乘法和硬件除法器
  • 浮点单元(FPU)
  • 集成DSP指令
  • 集成嵌套矢量中断控制器(NVIC)
  • 24位SysTick定时器

    板载:

  • GDlink(可惜只能作为下载,没有串口)
  • 复位按键和用户按键
  • 一个用户LED
  • USB_HS、USB_FS等

    开发前准备

  • 资料下载地址:

https://aijishu.com/a/1060000000356925

  • 安装芯片包
    芯片包.jpg
  • keil安装rtt包
    rtt.jpg

    rtt移植

  • 打开LED工程
    led.jpg
  • 添加rtt源码
    源码.jpg
  • board.c处理
    添加.jpg
  • 屏蔽"gd32f4xx_it.c"中HardFault_Handler、PendSV_Handler、 SysTick_Handler函数
  • 将裸机的延时函数换成操作系统的延时函数
    延时.jpg

添加Finsh

  • 在添加Finsh前先准备串口
    这里一点需要注意的地方,先上原理图在解释,PA9和PA3已经被占用,使用串口跳过这两个引脚
    串口7.jpg

    #include "usart.h"
    #include <stdio.h>
    #include <rtthread.h>
    
    
    //int fputc(int ch, FILE *f)
    
    //{
    
    //        /* 将Printf内容发往串口 */
    
    //        usart_data_transmit(USART1, (unsigned char) ch);
    
    ////        while (!(USART1->SR & USART_FLAG_TXE));
    
    //        while( usart_flag_get(USART1,USART_FLAG_TC)!= SET);        
    
    //        return (ch);
    
    //}
    
    void usart_init(int32_t bound)
    {
      rcu_periph_clock_enable( RCU_GPIOD);
    
      /* enable USART clock */
      rcu_periph_clock_enable(RCU_USART1);
    
      /* connect port to USARTx_Tx */
      gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_5);
    
      /* connect port to USARTx_Rx */
      gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_6);
    
      /* configure USART Tx as alternate function push-pull */
      gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_5);
      gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_5);
    
      /* configure USART Rx as alternate function push-pull */
      gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_6);
      gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6);
    
      /* USART configure */
      usart_deinit(USART1);
      usart_baudrate_set(USART1,bound);
      usart_receive_config(USART1, USART_RECEIVE_ENABLE);
      usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);
      
    //    nvic_irq_enable(USART1_IRQn, 2, 0);//设置串口中断的优先级
    //    //开启串口接收中断
    //    usart_interrupt_enable(USART1, USART_INT_RBNE);
      usart_enable(USART1);
    }
    
    
    //void USART1_IRQHandler(void)
    //{
    //    uint8_t rx_data = 0;
    //    //当接收中断发生
    //    if((RESET != usart_interrupt_flag_get(USART1, USART_INT_FLAG_RBNE)) && 
    //       (RESET != usart_flag_get(USART1, USART_FLAG_RBNE))){
    //        /* Read one byte from the receive data register */
    //        rx_data = (uint8_t)usart_data_receive(USART1);//获取接收到的数据
    ////           rt_kprintf("rx_data is %d",rx_data);
    //    }
    //    
    //     //当发送中断发生
    //    if((RESET != usart_flag_get(USART1, USART_FLAG_TBE)) && 
    //       (RESET != usart_interrupt_flag_get(USART1, USART_INT_FLAG_TBE))){
    //        /* Write one byte to the transmit data register */
    //    }
    //}
    
    
  • 添加Finsh源码
    Fiinsh.jpg
  • 在rtconfig.h中打开finsh_config.h
    对对对6.jpg
  • board.c中初始化串口

    /*
     * Copyright (c) 2006-2019, RT-Thread Development Team
     *
     * SPDX-License-Identifier: Apache-2.0
     *
     * Change Logs:
     * Date           Author       Notes
     * 2021-05-24                  the first version
     */
    
    #include <rthw.h>
    #include <rtthread.h>
    #include "systick.h"
    #include "gd32f4xx.h"
    #include "usart.h"
    
    #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
    /*
     * Please modify RT_HEAP_SIZE if you enable RT_USING_HEAP
     * the RT_HEAP_SIZE max value = (sram size - ZI size), 1024 means 1024 bytes
     */
    #define RT_HEAP_SIZE (20*1024)
    static rt_uint8_t rt_heap[RT_HEAP_SIZE];
    
    RT_WEAK void *rt_heap_begin_get(void)
    {
      return rt_heap;
    }
    
    RT_WEAK void *rt_heap_end_get(void)
    {
      return rt_heap + RT_HEAP_SIZE;
    }
    #endif
    
    void rt_os_tick_callback(void)
    {
      rt_interrupt_enter();
      
      rt_tick_increase();
    
      rt_interrupt_leave();
    }
    
    
    /* cortex-m 架构使用 SysTick_Handler() */
    void SysTick_Handler()
    {
      rt_os_tick_callback();
    
    }
    
    /**
     * This function will initial your board.
     */
    void rt_hw_board_init(void)
    {
    //#error "TODO 1: OS Tick Configuration."
      /* 
       * 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. 
       */
    
       systick_config();
       SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
       usart_init(115200);
    
      /* 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
    }
    
    #ifdef RT_USING_CONSOLE
    
    //static int uart_init(void)
    //{
    //#error "TODO 2: Enable the hardware uart and config baudrate."
    //    return 0;
    //}
    //INIT_BOARD_EXPORT(uart_init);
    
    void uart_send_byte(rt_uint8_t data)
    {
       while( usart_flag_get(USART1,USART_FLAG_TC)!= SET);   
        usart_data_transmit(USART1, (unsigned char) data);
      
    }
    
    void rt_hw_console_output(const char *str)
    {
    //#error "TODO 3: Output the string 'str' through the uart."
      
      rt_size_t i = 0, size = 0;
      char a = '\r';
    
    //    __HAL_UNLOCK(&UartHandle);
    
      size = rt_strlen(str);
      for (i = 0; i < size; i++)
      {
          if (*(str + i) == '\n')
          {
             uart_send_byte(a);
          }
           uart_send_byte( *(str + i) );
      }
    }
    
    #endif
    
    
  • 在finsh_port.c中添加接收代码

    /*
     * Copyright (c) 2006-2021, RT-Thread Development Team
     *
     * SPDX-License-Identifier: Apache-2.0
     *
     * Change Logs:
     * Date           Author       Notes
     */
    
    #include <rthw.h>
    #include <rtconfig.h>
    #include "usart.h"
    
    
    #ifndef RT_USING_FINSH
    #error Please uncomment the line <#include "finsh_config.h"> in the rtconfig.h 
    #endif
    
    #ifdef RT_USING_FINSH
    
    RT_WEAK char rt_hw_console_getchar(void)
    {
      /* Note: the initial value of ch must < 0 */
      int ch = -1;
    
    //#error "TODO 4: Read a char from the uart and assign it to 'ch'."
      
      if( usart_flag_get(USART1,USART_FLAG_RBNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
      {
          ch = (uint8_t)usart_data_receive(USART1) & 0xff;
    //        rt_kprintf("ch is %d",ch);
      }
      else 
      {
          if( usart_flag_get(USART1, USART_FLAG_ORERR) != RESET)  //
          {
               usart_flag_clear(USART1, USART_FLAG_RBNE);
          }
          rt_thread_mdelay(10);
      }
    
      return ch;
    }
    
    #endif /* RT_USING_FINSH */
    
    

    运行结果

  • 下载程序,打开终端
    结果.jpg
  • 输入一个命令list_thread
    命令.jpg
推荐阅读
关注数
10708
内容数
187
中国高性能通用微控制器领域的领跑者兆易创新GD系列芯片技术专栏。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息