教你动手移植RT-Thread到国产MCU

2023-11-07

摘要

  • 现在芯片价格不断上涨,国内很多厂商也在不断的找替换方案。以ST为例,一个芯片涨了十几倍。蛋疼。。。。

  • 最近刚好有机会拿到国产芯片MCU--兆易创新的评估板(GD32350R)。板载资源如下:

硬件 描述
芯片型号 GD32F350R8T6
CPU ARM Cortex M4
主频 108M
片内SRAM 16K
片内FLASH 64K
下载器 GD-Link

  • 拿到这个板子,首先肯定是去看看RT-THREAD是否已经包含这个BSP了,答案:没有这个GD32F350系列的BSP。那必须把他移植个RTT,然后PR一个BSP上去才行。

  • 移植M系列的BSP还是比较简单的,我主要分为六个步骤:

  1. 环境搭建

  2. BSP基础工程

  3. 系统时钟

  4. 串口驱动

  5. 验证工程

  6. 完成BSP总结。

环境搭建

  • GD-Link编程器:

    • 板载有GD-Link适配器。

    • GD-Link编程器软件(GD Link Programmer),官网下载链接:http://www.gd32mcu.com/cn/download/7

    • 因为GD-Link,其实就是一个CMSIS DAP Debugger,所以我在移植过程中直接使用KEIL IDE进行调试,没有GD Link Programmer。

  • 安装KEIL5。

  • 安装GD32350的pack:GigaDevice.GD32F30x_DFP.2.1.0.pack,官网下载链接:http://www.gd32mcu.com/cn/download/7

  • 串口助手 - XShell。

BSP基础工程

  • 其实移植RT-THREAD到一些比较通用的内核还是比较方便的,因为可以投机取巧。那接下来告诉你怎么投机取巧移植RT-Thread到国产MCU。

  • 本文只适配KEIL5的环境,GCC、KEIL4和IAR环境不做讲解。

  1. 基础模板:首先看看RT-Thread代码仓库中已有的BSP已存在GD的多款芯片,Cortex-M3内核,Cortex-M4内核,RISC-V内核。而我要移植的是Cortex-M4内核。在原有的BSP中,gd32450z-eval就是一个Cortex-M4内核,所以只需要把它复制一份,并修改文件名为:gd32350r-eval。这样就有一个基础的工程。然后就开始增删改查,完成最终的BSP。

  1. 配置Kconfig:修改根目录的Kconfig文件,修改内容如下图。①修改成对应的SOC名字,②因为GD32350R不包含SDRAM和只有两路串口,所以去除不相关的配置。

  1. 链接脚本:修改KEIL5的连接脚本,因为GD32F350R8T6的flash大小为64K,SRAM大小为16K。所以要进行修改。其实这一步不修改也是可以的,可以在KEIL中设置,修改内容如下图:

  1. 修改库:

  • 下载官方的库文件,下载链接:http://www.gd32mcu.com/cn/download/7?kw=GD32F3

  • 删除BSP的Libraries目录下除了SConscript文件的其他内容

  • 然后解压复制目录(GD32F3x0_Firmware_Library_V2.0.2\SDK v2.0.2\GD32F3x0_Firmware_Library\Firmware)下的所有内容到BSP中Libraries目录的文件。

  1. 修改Libraries中SConscript文件。修改内容如下:

  1. 修改KEIL的模板工程。双击:template.uvprojx,如下图:

  • 修改工程名:

  • 修改FLASH和RAM的配置:

  • 修改为对应芯片设备:

  • 修改可执行文件名字:

  • 修改优化等级为O3:

  • 修改默认调试工具:CMSIS-DAP Debugger。

  • 修改编程算法:GD32F3x0 FMC。

  1. 修改驱动文件夹,在drivers目录中除了board.c,board.h和SConscript文件保留,其他的全部删除。然后添加两个文件:drv_usart.c和drv_usart.h。

  1. 修改驱动文件夹下的脚本SConscript。

  1. 添加gd32f3x0_libopt.h文件到BSP的drivers目录中,gd32f3x0_libopt.h存在固件库路径:\GD32F3x0_Firmware_Library_V2.0.2\SDK v2.0.2\GD32F3x0_Firmware_Library\Template。

  1. menuconfig配置。

  • 关闭套接字抽象层。

-> RT-Thread Components
    -> Network
        -> Socket abstraction layer
            [ ] Enable socket abstraction layer
  • 关闭网络设备接口

-> RT-Thread Components
    -> Network
        -> Network interface device
            [ ] Enable network interface device
  • 关闭LWIP协议栈

-> RT-Thread Components
    -> Network
        -> light weight TCP/IP stack
            [ ] Enable lwIP stack
  • 关闭libc接口

-> RT-Thread Components
    -> POSIX layer and C standard library
        [ ] Enable libc APIs from toolchain
  • 关闭虚拟文件系统

-> RT-Thread Components
    -> Device virtual file system
        [ ] Using device virtual file system
  1. 重新生成MDK5的工程,在env中执行:scons --target=mdk5.

> scons --target=mdk5
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: building associated VariantDir targets: build
CC build\applications\main.o
CC build\drivers\board.o
CC build\drivers\drv_usart.o
CC build\kernel\components\drivers\misc\pin.o
CC build\kernel\components\drivers\serial\serial.o
CC build\kernel\components\drivers\src\completion.o
CC build\kernel\components\drivers\src\dataqueue.o
....
....
AS Libraries\CMSIS\GD\GD32F3x0\Source\ARM\startup_gd32f3x0.o
CC Libraries\CMSIS\GD\GD32F3x0\Source\system_gd32f3x0.o
LINK rtthread-gd32f3x0.elf
fromelf --bin rtthread-gd32f3x0.elf --output rtthread.bin
fromelf -z rtthread-gd32f3x0.elf
scons: done building targets.
  1. 修改board.h中ram的大小配置。将128修改为16即可。

  1. 编译测试。双击:project.uvprojx文件

  • 如果编译报如下错误,将所有的#include <gd32f4xx.h>修改为#include <gd32f3x0.h>。

  • 然后就可以正常编译通过:

系统时钟

  • 提供给系统的是采用GD32的SysTick,代码如下,然后再rt_hw_board_init()函数初始化SystemClock_Config()。

void SystemClock_Config(void)
{
    SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
    NVIC_SetPriority(SysTick_IRQn, 0);
}

void SysTick_Handler(void)
{
    /* enter interrupt */
    rt_interrupt_enter();

    rt_tick_increase();

    /* leave interrupt */
    rt_interrupt_leave();
}
  • 通过keil进行在线调试,看看是否可以跑到main.c中。在main函数加个断点。然后全速执行,可以看到执行到我们设置的断点停住了,移植基本完成。

串口驱动

  • 一个基本的BSP中,串口是必不可少的,所以还需要编写串口驱动

  • 在GD32F350中有两组驱动:UART0和UART1。

  • 在RTT中只需要对接好串口框架中的(struct rt_uart_ops)即可。

static struct rt_uart_ops usart_ops =
{
    gd32_usart_configure,
    gd32_usart_control,
    gd32_usart_putc,
    gd32_usart_getc,
    gd32_usart_dma_transmit,
};
  • 具体的代码就不过多描述,后面作者再出一篇串口驱动框架的文件。

  • 配置完串口,如果串口输出如下log,说明BSP已经制作完毕。

 \ | /
- RT -     Thread Operating System
 / | \     4.0.4 build Jun 22 2021
 2006 - 2021 Copyright by rt-thread team
msh >

验证工程

  • 输入如下命令。查看是否有输出。

完成BSP总结

  • 关于RT-THREAD的移植还是比较方便的,主要是复杂地方官方都已经做好了,如调度器。

  • 而作者移植的Cortex M4是一个比较通用的内核,rtt提供的libcpu已经包含了相关的内容,所以无需造轮子。

  • 关于GD这款芯片的评价,我觉得官方提供的库中,API太不优雅了。这个是指的改进的,就好比一个GPIO的API就多达15个。

  • 在上述中内容,除了适配了串口驱动,我还是适配了GPIO驱动,由于资源的问题,其他驱动我就没在适配了。

  • 关于兆易创新的GD32350R评估板的BSP目前我也已经提交到了RT-THREAD,应该过几天就可以merge到主仓库中。

1.机器学习的未来在何方?

2.Cadence“系统动力双剑”,这么霸气的工具得用起来!

3.干货 | 分享一个实用的、可应用于单片机的内存管理模块

4.MCU、RTOS和物联网之间有什么关系?

5.香港突发:500万芯片抢劫案!全程搜捕!

6.肝 | 一种串口高效收发思路及方案

免责声明:本文系网络转载,版权归原作者所有。如涉及作品版权问题,请与我们联系,我们将根据您提供的版权证明材料确认版权并支付稿酬或者删除内容。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

教你动手移植RT-Thread到国产MCU 的相关文章

  • 用于 RHEL 的 gdb-multiarch

    我正在尝试寻找方法来运行gdb 多架构RHEL 中的命令 我已经安装了用于 ARM 处理的 QEMU 模拟器 我想安装GDB进行调试 我能够安装GDB 多体系结构在 Ubuntu 中运行命令成功 sudo apt get GDB multi
  • 哪些变量类型/大小在 STM32 微控制器上是原子的?

    以下是 STM32 微控制器上的数据类型 http www keil com support man docs armcc armcc chr1359125009502 htm http www keil com support man d
  • 来自task_struct的完整进程名称

    我想从中获取完整的进程名称struct task struct The comm字段仅存储 16 个字符 而进程名称可以更长 有没有办法获得完整的进程名称 这可以通过获取来完成struct vm area struct from task
  • Linux malloc() 在 ARM 和 x86 上的行为是否不同?

    这个网站上有很多关于内存分配的问题 但是我 找不到专门解决我的问题的人 这 问题 https stackoverflow com questions 19148296 linux memory overcommit details似乎最接近
  • 可以使用Visual Studio 2012构建ARM桌面程序吗?

    我正在使用 Visual Studio 2012 beta 我的桌面 win32 程序在 ARM 架构中编译得很好 升级到 Visual Studio 2012 RC 后 编译器无法工作并出现以下错误 不支持为 ARM 平台编译桌面应用程序
  • 对内核模块代码进行单元测试是否可行?

    如果是这样我应该使用什么技术 我正在考虑使用 hippomock 因为它们可以用来模拟 C 方法 还有更好的方法吗 如果是这样 任何人都可以提供建议 或者您认为内核的单元测试是否太过分了 从 Linux 内核版本 5 5 开始KUnit可用
  • 当端点和 PMA 地址均更改时,CubeMX 生成的 USB HID 设备发送错误数据

    我正在调试我正在创建的复合设备的问题 并在新生成的仅 CubeMX 代码中重新创建了该问题 以使其更容易解决 我添加了少量代码main 让我发送 USB HID 鼠标点击 并在按下蓝色按钮时使 LED 闪烁 uint8 t click re
  • 在 Mac OS X 中创建虚拟 USB 设备

    我尝试以编程方式在 Mac OS 中添加带有驱动程序的虚拟 USB 设备 IOKit 文档说 传统上 虚拟设备的驱动程序在 IOResources 上匹配 因为虚拟设备不发布自己的 nub 此类驱动程序的另一个示例是 HelloIOKit
  • 分析 Cortex-M7 (stm32f7) 上的 memcpy 性能

    简洁版本 从 GNU ARM 工具链中提取的 memcpy 的性能指标在 ARM Cortex M7 上对于不同的副本大小似乎差异很大 即使复制数据的代码始终保持不变 这可能是什么原因造成的 长版 我是使用 GNU Arm 工具链 11 2
  • 如何使用 Neon SIMD 将无符号字符转换为有符号整数

    如何转换变量的数据类型uint8 t to int32 t使用霓虹灯 我找不到执行此操作的任何内在因素 假设您想要将 16 x 8 位整数的向量转换为 4 个 4 x 32 位整数的向量 您可以通过首先解压缩为 16 位 然后再次解压缩为
  • Linux 中 NDIS 过滤器的类似物是什么?

    我正在研究一个as close to real time我在linux中尽可能地使用系统 并且需要在收到特定数据包后立即发送大约600 800字节的TCP数据包 为了获得最佳的延迟 我希望这个数据包直接从内核发送 而不是将接收到的数据包一直
  • 从 Linux 内核模块的文件描述符获取文件名/路径?

    在Linux内核模块中 有没有一种方法可以从文件名 路径中获取文件名 路径 unsigned int fd 我知道这个答案 如何从内核模块内的文件描述符获取文件名 https stackoverflow com questions 8250
  • 每个进程是否都存在内核堆栈?

    每个用户空间进程是否都存在一个内核堆栈和一个用户空间堆栈 如果两个堆栈都存在 那么每个用户空间进程应该有 2 个堆栈指针 对吗 在 Linux 中 每个任务 用户空间或内核线程 都有一个 8kb 或 4kb 的内核堆栈 具体取决于内核配置
  • Alsa 带有来自调制解调器的 PCM 接口

    我有一个基于 imx28 CPU 的定制板 CPU 的串行端口连接到调制解调器的 PCM 输出 我必须为调制解调器的 PCM 接口开发一个驱动程序 使其成为 ALSA SoC 的一部分 您能指出内核树 中与我的设置重新组合的一些驱动程序吗
  • 尝试映射大页面 (1GB) 时 mmap 失败

    我做了什么 使用 root 启用大页 我的系统支持 1MB 大页 echo 20 gt proc sys vm nr hugepages 将大页文件系统挂载到 mnt hugepages mount t hugetlbfs nodev mn
  • Windows 内存映射文件

    我正在尝试研究 Windows 内核在内存映射文件 虚拟内存方面的行为 具体来说 我感兴趣的是确定内存映射文件的内容 由 Windows 刷新到磁盘的频率以及 Windows 使用什么标准来决定是时候这样做 我在网上做了一些研究 除了 MS
  • 在 Intel 机器上构建 Apple Silicon 二进制文件

    如何在 macOS 11 Intel 上编译 C 项目以在 Silicon 上运行 我当前的构建脚本很简单 configure make sudo make install 我尝试过使用 host and target标志与aarch64
  • 没有设备的设备驱动程序?

    我正在创建一个需要使用一些内核级模块的应用程序 为此我将应用程序分为 2 个 一个用户级程序和一个内核级程序 在阅读了有关设备驱动程序并浏览一些教程后 我有点困惑 是否可以存在没有任何特定设备与之关联的设备驱动程序 除了设备驱动程序 内核代
  • 如何模拟ARM处理器运行环境并加载Linux内核模块?

    我尝试加载我的vmlinux into gdb并使用 ARM 内核模拟器 但我不明白为什么我会得到Undefined target command sim 这是外壳输出 arm eabi gdb vmlinux GNU gdb GDB 7
  • iPhone 3GS 上的 ARM 与 Thumb 性能比较,非浮点代码

    我想知道是否有人有关于 iPhone 3GS 上 ARM 与 Thumb 代码性能的硬性数据 特别是对于非浮点 VFP 或 NEON 代码 我知道 Thumb 模式下的浮点性能问题 更大的 ARM 指令的额外代码大小是否会在某个时刻成为性能

随机推荐

  • RFID系统在物流仓储中的应用

    RFID系统是一种无线识别技术 最近成为物流仓储行业的热门话题 本文将介绍RFID系统在物流仓储中的应用 包括如何使用RFID标签进行物流管理 如何使用RFID技术提高仓库的安全性 并细述RFID技术在物流仓储中的优势 除此之外 本文还会探
  • 华为od机考真题-报数游戏

    while 1 try m int input if 1 gt m or m gt 100 print ERROR else 模拟1 100的圈 nums
  • keil使用指南

    keil使用指南 1 项目的创建 头文件 1 项目的创建 1 首先创建文件夹 2 打开keil软件而后 创建新项目 并定位到1创建的文件夹 3 创建文件 并将文件添加到项目中 4 勾选hex文件生成 5 项目demo编写与编译 编译当前所在
  • 实战wxPython:051- 自定义控件

    前面系列文章中 我们介绍了wxPython提供各种的各种控件 在一般情况下可以满足我们开发应用的各种需求 但是在一些情况下 比如对按钮的美化 一个可以显示CPU占用率的控件等等 这首就需要自定义的控件 才能满足要求 自定义控件可以通过两种方
  • Postgresql 学习记录,模式,分区表,触发器,事务,窗口函数,视图,建表,约束等

    Postgresql 学习记录 模式 分区表 触发器 事务 窗口函数 视图 建表 约束等 PostgreSQL使用一种客户端 服务器的模型 一次PostgreSQL会话由下列相关的进程 程序 组成 一个服务器进程 它管理数据库文件 接受来自
  • 将word文档转换为图片格式的PDF

    0x00 前言 编写一篇文档后 往往会通过转为pdf版本后发布来避免在不同环境下格式出现混乱的情况 但这样操作转出pdf文档可以通过普通的pdf阅读器进行文本的抓取 不能达到我们想要保护知识产权的想法 因此在这里推出一篇如何将word文档转
  • 设计模式之(二)---代理模式Proxy Pattern

    什么是代理模式呢 我很忙 忙的没空理你 那你要找我呢就先找我的代理人吧 那代理人总要知道 被代理人能做哪些事情不能做哪些事情吧 那就是两个人具备同一个接口 代理人虽然不能干活 但是被 代理的人能干活呀 比如西门庆找潘金莲 那潘金莲不好意思答
  • 前端优化-WEB综合

    开启 gzip 压缩 gzip 是 GNUzip 的缩写 最早用于 UNIX 系统的文件压缩 HTTP 协议上的 gzip 编码是一种用来改进 web 应用程序性能的技术 web 服务器和客户端 浏览器 必须共同支持 gzip 目前主流的浏
  • object...args参数

    Java object args参数 Java反射中用到方法public Object newInstance String className Object args 该方法中使用了object args参数 也可以写成object ar
  • 认清现实重新理解游戏的本质

    认清现实重新理解游戏的本质 OVERVIEW 认清现实重新理解游戏的本质 现实 两条小路的启发 四个动机 1 当前的学习任务或工作任务太艰巨 2 完美主义 3 对未来太过于自信 无知 4 大脑小看未来的收益 四个方法 1 让未来的收益足够巨
  • R语言 时间序列ARIMA模型方法

    原理什么的百度一搜一堆 看不明白 先学会用这个工具吧 ARIMA 全称为自回归积分滑动平均模型 Autoregressive Integrated Moving Average Model 简记ARIMA 是由博克思 Box 和詹金斯 Je
  • 使用git提交代码到gerrit

    系统 Linux 需要安装 git 第一步 cd mkdir learn git cd learn git 注意 下面的用户名和邮箱和gerrit网站的账号一定要相同 git config global user name 用户名 git
  • python爬取百度使用kw关键字爬取时出现,百度安全验证,解决方法

    python爬取百度使用kw关键字爬取时出现 百度安全验证 解决方法 之前爬取百度用kw时的代码 没有任何问题 import requests url http www baidu com s headers User Agent Mozi
  • 工具类用于ajax使用json请求时返回一个json

    package com noe utils import java util HashMap 工具类 封装响应内容 会被转成json响应 MyStatus ok gt new MyStatus 0 gt code 0 new MyStatu
  • Jenkins部署及代码静态检查工具Checkstyle集成

    CheckStyle是SourceForge下的一个项目 提供了一个帮助JAVA开发人员遵守某些编码规范的工具 接下来给大家讲下如何在jenkins 我是在tomcat下安装的jenkins 集成checkstyle 构建项目并发送邮件 一
  • Face Alignment / Human Pose Estimation [CVPR‘23, ECCV‘22, NeurIPS‘22]

    CVPR 23 accepted paper list Facial Landmark Face Alignment 论文较少 CVPR 23 3篇 值得关注的子领域 Synthetic Data STAR Loss Reducing Se
  • Service层有多个查询,若依(ruoyi)分页失灵?如何解决呢?

    Service层有多个查询 若依分页失灵 教你如何解决 情景一 当Service层只有一个查询时 若需要分页 只需要在Controller层做以下操作 添加继承BaseController中的startPage 和getDataTable
  • Linux共享内存的查看和删除

    使用的总结 1 共享内存查看 命令 ipcs m Shared Memory Segments key shmid owner perms bytes nattch status 0x00000000 1867776 root 600 39
  • linux ikev1切换到ikev2,IKEv2与IKEv1的差异.doc

    IKEv2与IKEv1的差异 IKEv2与IKEv1的差异IKEv2与IKEv1的差异 摘自RFC4306 附录 A 1 To define the entire IKE protocol in a single document repl
  • 教你动手移植RT-Thread到国产MCU

    摘要 现在芯片价格不断上涨 国内很多厂商也在不断的找替换方案 以ST为例 一个芯片涨了十几倍 蛋疼 最近刚好有机会拿到国产芯片MCU 兆易创新的评估板 GD32350R 板载资源如下 硬件 描述 芯片型号 GD32F350R8T6 CPU