当前位置: 首页 > news >正文

基于GD32的RT-Thread移植(邪修版)

准备源码,配置工程

仅供有移植RTOS基础的人参考借鉴。

添加源码

直接用CubeMX生成的RT-Thread_Nano源码,复制到自己的GD32F303工程内里。

GD32有的芯片是M4架构,注意替换libcpu中的文件。

把RTT源码添加进keil工程

添加头文件

修改部分.c/.h

注释掉几个中断

注释掉GD32的SVC_Handler、PendSV_Handler(void)、SysTick_Handler(void)、HardFault_Handler(void),因为这些函数RT-Thread已经帮我们实现好了。

如:SysTick_Handler

void SysTick_Handler(void)
{rt_interrupt_enter();rt_tick_increase();rt_interrupt_leave();
}

根据板子重新实现特定函数

修改board.c中的rt_hw_board_init。如果需要使用RT-Thread的shell命令行调试工具,还需要修改uart_init(void)、rt_hw_console_output、rt_hw_console_getchar这几个函数

rt_hw_board_init:

这个作用主要就是初始化时钟,关键是要开启SysTick中断。

/*** This function will initial your board.*/
void rt_hw_board_init(void)
{/* * 1: OS Tick Configuration* Enable the hardware timer and call the rt_os_tick_callback function* periodically with the frequency RT_TICK_PER_SECOND. */delay_init(120); /* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INITrt_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
}

uart_init(void)、rt_hw_console_output

// 定义使用的USART端口和引脚
#define CONSOLE_USART USART0static int uart_init(void)
{/* TODO: Please modify the UART port number according to your needs */usart_init(115200); return 0;
}
INIT_BOARD_EXPORT(uart_init);void rt_hw_console_output(const char *str)
{rt_size_t i = 0;rt_size_t size = rt_strlen(str);char a = '\r';  // 换行前添加回车for (i = 0; i < size; i++){// 遇到换行符时先发送回车if (*(str + i) == '\n'){// 等待发送缓冲区为空while (usart_flag_get(CONSOLE_USART, USART_FLAG_TBE) == RESET);usart_data_transmit(CONSOLE_USART, a);}// 发送当前字符while (usart_flag_get(CONSOLE_USART, USART_FLAG_TBE) == RESET);usart_data_transmit(CONSOLE_USART, *(str + i));}// 等待最后一个字符发送完成while (usart_flag_get(CONSOLE_USART, USART_FLAG_TC) == RESET);
}

同时增加一个USART0_IRQHandler

// 接收缓存:-1表示无数据(int类型避免符号警告)
static volatile int usart_rx_buf = -1;        
static volatile rt_bool_t usart_rx_ready = RT_FALSE;/*** 串口中断处理函数:接收数据并缓存*/
void USART0_IRQHandler(void)
{rt_interrupt_enter();// 处理接收非空状态(使用状态标志宏USART_FLAG_RBNE)if (usart_flag_get(CONSOLE_USART, USART_FLAG_RBNE) == SET){// 读取接收数据并缓存usart_rx_buf = (int)(usart_data_receive(CONSOLE_USART) & 0xFF);usart_rx_ready = RT_TRUE;// 清除状态标志(读取数据后硬件自动清除,保险起见)usart_flag_clear(CONSOLE_USART, USART_FLAG_RBNE);}rt_interrupt_leave();
}/*** 控制台输入函数:供FinSH调用*/
char rt_hw_console_getchar(void)
{int ch = -1;// 等待中断接收数据while (usart_rx_ready != RT_TRUE){rt_thread_mdelay(1);}// 读取缓存数据ch = usart_rx_buf;usart_rx_ready = RT_FALSE;usart_rx_buf = -1;return (char)ch;
}

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 "main.h"
#include "delay.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 (15*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;
}
#endifvoid SysTick_Handler(void)
{rt_interrupt_enter();rt_tick_increase();rt_interrupt_leave();
}#ifdef RT_USING_FINSH
#include <finsh.h>
static void reboot(uint8_t argc, char **argv)
{rt_hw_cpu_reset();
}
MSH_CMD_EXPORT(reboot, Reboot System);
#endif /* RT_USING_FINSH *//*** This function will initial your board.*/
void rt_hw_board_init(void)
{/* * 1: OS Tick Configuration* Enable the hardware timer and call the rt_os_tick_callback function* periodically with the frequency RT_TICK_PER_SECOND. */delay_init(120); /* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INITrt_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// 定义使用的USART端口和引脚
#define CONSOLE_USART USART0static int uart_init(void)
{/* TODO: Please modify the UART port number according to your needs */usart_init(115200); return 0;
}
INIT_BOARD_EXPORT(uart_init);void rt_hw_console_output(const char *str)
{rt_size_t i = 0;rt_size_t size = rt_strlen(str);char a = '\r';  // 换行前添加回车for (i = 0; i < size; i++){// 遇到换行符时先发送回车if (*(str + i) == '\n'){// 等待发送缓冲区为空while (usart_flag_get(CONSOLE_USART, USART_FLAG_TBE) == RESET);usart_data_transmit(CONSOLE_USART, a);}// 发送当前字符while (usart_flag_get(CONSOLE_USART, USART_FLAG_TBE) == RESET);usart_data_transmit(CONSOLE_USART, *(str + i));}// 等待最后一个字符发送完成while (usart_flag_get(CONSOLE_USART, USART_FLAG_TC) == RESET);
}
#endif#ifdef RT_USING_FINSH// 接收缓存:-1表示无数据(int类型避免符号警告)
static volatile int usart_rx_buf = -1;        
static volatile rt_bool_t usart_rx_ready = RT_FALSE;/*** 串口中断处理函数:接收数据并缓存*/
void USART0_IRQHandler(void)
{rt_interrupt_enter();// 处理接收非空状态(使用状态标志宏USART_FLAG_RBNE)if (usart_flag_get(CONSOLE_USART, USART_FLAG_RBNE) == SET){// 读取接收数据并缓存usart_rx_buf = (int)(usart_data_receive(CONSOLE_USART) & 0xFF);usart_rx_ready = RT_TRUE;// 清除状态标志(读取数据后硬件自动清除,保险起见)usart_flag_clear(CONSOLE_USART, USART_FLAG_RBNE);}rt_interrupt_leave();
}/*** 控制台输入函数:供FinSH调用*/
char rt_hw_console_getchar(void)
{int ch = -1;// 等待中断接收数据while (usart_rx_ready != RT_TRUE){rt_thread_mdelay(1);}// 读取缓存数据ch = usart_rx_buf;usart_rx_ready = RT_FALSE;usart_rx_buf = -1;return (char)ch;
}#endif

main示例代码

/************************************************
* WKS Mini GD32开发板
* 串口通信 实验
************************************************/#include "sys.h"
#include "usart.h"		
#include "delay.h"	
#include "led.h"#include <rthw.h>
#include "rtthread.h"
#include <stdio.h>/* 定义线程控制块 */
static rt_thread_t led1_thread = RT_NULL;static void led1_thread_entry(void *parameter)
{while (1){gpio_togglepin(GPIOA, GPIO_PIN_8);rt_thread_delay(500); /* 延时500个tick */
//    printf("hello \r\n");}
}int main(void)
{ delay_init(120);                          //初始化延时函数 usart_init(115200);                       //初始化串口LED_Init();							                  //初始化LEDled1_thread =                           /* 线程控制块指针 */rt_thread_create("led1",            /* 线程名字 */led1_thread_entry, /* 线程入口函数 */RT_NULL,           /* 线程入口函数参数 */128,               /* 线程栈大小 */20,                /* 线程的优先级 */20);               /* 线程时间片 *//* 启动线程,开启调度 */rt_thread_startup(led1_thread);while(1){rt_thread_delay(100);}
}

shell命令行启动成功,led按预期点亮。

http://www.dtcms.com/a/457419.html

相关文章:

  • 如何让百度口碑收录自己的网站怎么用vs2015做网站
  • 2017优秀网站设计案例个人域名备案有什么风险
  • [论文阅读] AI+软件工程(需求工程)| 告别需求混乱!AI-native时代,需求工程的5大痛点与3大破局方向
  • WPF基本布局容器与控件
  • 临时需电子印章?无需下载注册生成高清印章
  • Qt基础之五十:Qt设置样式的几种方式
  • 理解Roo Code的速率限制与成本优化
  • 农村建设集团有限公司网站重庆南川网站制作价格
  • 爬虫调试技巧:常用工具与日志分析,快速定位问题
  • 反向代理和负载均衡
  • 水果网站设计论文网页传奇游戏中心
  • 兰州网站建设lst0931wordpress调用函数大全
  • JavaScript核心构成与基础语法详解1
  • Redission分布式锁、WatchDog续约、布隆过滤器
  • 《jQuery 捕获》
  • 【开题答辩全过程】以 阿歹果园养鸡场管理系统为例,包含答辩的问题和答案
  • 【数据结构】考研数据结构核心考点:二叉排序树(BST)全方位详解与代码实现
  • 河北做网站哪家公司好广州市网站建设公
  • AI学习日记——卷积神经网络(CNN):卷积层与池化层的概念
  • JavaScript中的axios
  • 我们提供的网站建设响应式网站 尺寸
  • Robotframework 并发执行
  • 兰州拼团网站建设网站建设知识点的总结
  • 做门窗的建网站怎么赚钱网页设计图片怎么变小
  • 第十六篇: 算法复杂度分析:大O表示法实战指南
  • 网站倍攻击wordpress 换行符
  • 【PyTorch】神经风格迁移
  • LabVIEW运行时快捷菜单创建
  • 用rp怎么做网站原型网站开发包括后台 前台
  • asp.net网站运行助手wordpress哪个php版本好