Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread活动
RT-Thread移植
国产MCU移植
【国产MCU移植】移植RT-Thread到国产芯片HC32L196
发布于 2021-09-12 23:16:38 浏览:4607
订阅该版
[tocm] rt-thread国产MCU移植活动接近尾声,准确说是最后一天。我移植的平台是华大的HC32L196,在这周初已完成提交PR,不过由于无穷无近的加班,一直没时间写移植文章。rtt论坛中的国产MCU移植已是百花齐放,介绍了移植到各种平台的步骤。在这最后一天,我决定写点不一样的,介绍移植的原理与方法。如果大家想看一步步的移植步骤,可在rtt论坛搜索“国产MCU移植”。 # 移植原理 移植一款软件,无非是获取源码,修改其中与硬件相关的代码以适配目标硬件。移植rt-thread也是如此,首要任务是要明确要修改哪部分内容。带着这个问题,我们来分析rt-thread的源码结构。 ## rt-thread源码结构 rt-thread源码根目录结构如下: 目录 | 说明 ---|--- bsp | 板级支持包。存放各种硬件平台的驱动代码,初始化代码,工程文件。 components | 组件。如finsh控制台,抽象层驱动,文件系统,网络系统。 examples | 示例程序 include | 内核以及libc的头文件 libcpu | 与CPU架构相关的接口,为操作系统调度提供支持。 src | 内核代码,如线程、定时器、线程间通信(互斥锁,信号量)。 移植所涉及的目录有两个:**bsp**和**libcpu**,相应的移植分为**BSP移植**与**CPU架构移植**。其他的目录与具体的CPU无关,无须改动。 ## CPU架构移植 在嵌入式领域有多种不同 CPU 架构,例如 Cortex-M、ARM920T、MIPS32、RISC-V 等等。为了使 RT-Thread 能够在不同 CPU 架构的芯片上运行,RT-Thread 提供了一个 libcpu 抽象层来适配不同的 CPU 架构。向下提供了一套统一的 CPU 架构移植接口,这部分接口包含了全局中断开关函数、线程上下文切换函数、时钟节拍的配置和中断函数、Cache 等等内容。下表是 CPU 架构移植需要实现的接口和变量。 函数和变量 | 描述 ---|--- rt_base_t rt_hw_interrupt_disable(void); | 关闭全局中断 void rt_hw_interrupt_enable(rt_base_t level); | 打开全局中断 rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit); | 线程栈的初始化,内核在线程创建和线程初始化里面会调用这个函数 void rt_hw_context_switch_to(rt_uint32 to); | 没有来源线程的上下文切换,在调度器启动第一个线程的时候调用,以及在 signal 里面会调用 void rt_hw_context_switch(rt_uint32 from, rt_uint32 to); | 从 from 线程切换到 to 线程,用于线程和线程之间的切换 void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to); | 从 from 线程切换到 to 线程,用于中断里面进行切换的时候使用 rt_uint32_t rt_thread_switch_interrupt_flag; | 表示需要在中断里进行切换的标志 rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; | 在线程进行上下文切换时候,用来保存 from 和 to 线程 是不是看起来挺复杂的,其实rtt已经支持了非常多的CPU架构。下图的libcpu目录中已支持多种CPU架构。让我们看看对arm系列的支持情况,从低端的cortex-m0到高端的cortex-m7,甚至还有cortex-a和cortex-r系列的。大家熟知的stm32f103为cortex-m3内核,stm32f407为cortex-m4内核。如果要移植到的目录芯片内核出现在此目录之中,那就无需关注libcpu,只要在配置文件中指定正确的内核即可。 我移植的HC32L196使用cortex-m0+内核,可使用cortex-m0的代码,因此无须进行CPU构架移植。 ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/d4ff044e26ade4288e7f0a048367616de54f46ec.png) ## bsp结构 由于不需要进行CPU架构移植,所以本次移植相对简单,唯一的工作就是在rt-thread的bsp目录中创建自己硬件的bsp。 rt-thread当前支持了100多个bsp,可能大家用的最多的是stm32。不过我并不建议大家在移植时参考stm32,因为它是最复杂的一个bsp。 ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/25343e1730146651b9fa1c5c22fce2bced55b4b3.png) 早期rt-thread中关于stm32的bsp比较简单,各种型号如stm32f10x, stm32f40x都是独立的bsp。新手入门相对简单。不过弊病也很明显:随着支持的stm32系列的增加,bsp的子目录也就急剧增加,维护成本很高。 ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/bc8d6686ff2897e28a46f7856105899807f99c73.png) 可能得益于stm32的HAL库,可以相对较低的投入将它们合为一个bsp。它们共用一份驱动代码,其在HAL_Drivers中。 ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/4d2bff05a5e538f81822f049ed62d21802b39593.png) 可能以后国产MCU的bsp也会发展成这样,不过对于移植新手,最好是先易后难。我移植的HC32L196是华大单片机,以已经被rtt支持的hc32f4a0为模板进行移植。同时参考了swm320,以及stm32\stm32l053-st-nucleo。 大多数bsp目录结构: 目录 | 说明 ---|--- applications | 用户代码。纯净的bsp中只需要一个main.c文件,里面定义main函数。 board | 板级驱动代码(最主要的是board.c),链接脚本(gcc, keil, iar)。 drivers | 设备驱动代码,比如gpio和uart驱动。 figures | 电路板照片。 Libraries | 芯片厂商驱动库。 .config, rtconfig.h, Kconfig | Kconfig配置系统相关文件 rtconfig.py, SConscript, SConstruct | scons构建系统相关文件 template.uvprojx, template.uvoptx | keil模板工程 project.uvprojx, project.uvoptx | keil工程 template.eww, template.ewp | iar模板工程 project.eww, project.ewp | iar工程 可分为如下几类: 1. 代码文件:applications, board, drivers, Libraries中的.h和.c 2. Kconfig配置系统相关文件 3. scons构建系统相关文件 4. 工程模板 ## 代码结构 先来看看我移植后的keil工程,其打开的几个目录就是涉及移植的代码目录。 ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/6792f01d7e9ca0f06435e2637257884a7aa6f9b7.png) applications目录最为简单。drivers目录是移植的重点,不过它不是移植的首要任务。下面几节介绍移植前最迫切需要搞清楚的内容。 ## Kconfig rtt支持通过menuconfig命令来配置内核、组件及软件包。执行menuconfig命令时,其从Kconfig文件中解析菜单结构,由用户勾选、配置各个选项,最终将配置结果写入.config和rtconfig.h。 ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/ded28ae3cc342257dbfd5de3d51ce7abe92d2a20.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAd2VuYm9kb25n,size_20,color_FFFFFF,t_70,g_se,x_16) bsp中通常有两个Kconfig文件。一个位于根目录,另一个位于board。 ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/ff51ab3e8f2fc8165123112782cb6d44ab358dca.png) 根目录中的Kconfig仅仅是导入了别的目录的Kconfig,所有bsp的基本都一样,无须修改。 ```config mainmenu "RT-Thread Project Configuration" config BSP_DIR string option env="BSP_ROOT" default "." config RTT_DIR string option env="RTT_ROOT" default "../.." config PKGS_DIR string option env="PKGS_ROOT" default "packages" source "$RTT_DIR/Kconfig" source "$PKGS_DIR/Kconfig" source "board/Kconfig" ``` board/Kconfig ```config menu "Hardware Drivers Config" config MCU_HC32L196 bool select ARCH_ARM_CORTEX_M0 select RT_USING_COMPONENTS_INIT select RT_USING_USER_MAIN default y menu "Onboard Peripheral Drivers" endmenu menu "On-chip Peripheral Drivers" config BSP_USING_GPIO bool "Enable GPIO" select RT_USING_PIN default y menuconfig BSP_USING_UART bool "Enable UART" default y select RT_USING_SERIAL if BSP_USING_UART config BSP_USING_UART0 bool "Enable UART0" default y config BSP_USING_UART1 bool "Enable UART1" default n endif endmenu menu "Board extended module Drivers" endmenu endmenu ``` 其自动选择了几个必选的配置,比如RT_USING_USER_MAIN。另,定义了可配置的驱动选项,比如GPIO配置和串口配置。 上述文件对应的串口配置菜单如下: ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/e07bc77139959bbb30d453121c3c7c0c37013623.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAd2VuYm9kb25n,size_20,color_FFFFFF,t_70,g_se,x_16) rtt官方文档中有对Kconfig进行详细讲解:https://www.rt-thread.org/document/site/#/development-tools/kconfig/kconfig ## scons和工程模板文件 rt-thread使用scons作为构建系统,其用于编译源码,生成固件。不过呢,大家用的最多的,可能是用它生成keil工程,就是在使用menuconfig配置内核、组件和驱动之后,使用如下命令生成keil工程: ```bash scons --target=mdk5 ``` 其原理,以生成keil5工程为例,是scons根据rtconfig.h文件中的配置,在template.uvprojx上添加宏定义、头文件路径配置、文件链接,从而生成project.uvprojx。下图左侧为模板工程,右侧为生成的rtt工程。 ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/f5421433d9f3f7a4d7184839849b384f5ef183a1.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAd2VuYm9kb25n,size_20,color_FFFFFF,t_70,g_se,x_16) 再多说一句,rtt是如何能够读写keil工程文件呢?.uvprojx其实是xml文件,rtt通过模板工程创建新工程,就是在读写xml,有兴趣的话,可以阅读rt-thread源码根目录下的tools/keil.py。 rtconfig.h是在Kconfig系统中生成,只要修改好Kconfig相关文件后,无须操心rtconfig.h。要修改的是模板工程。不过也很简单,从其他bsp复制模板工程,修改设备类型,RAM和ROM配置就可以了。其他的配置,如下载接口等,可根据需要修改。 ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/47a4e29b69bf29998be9544cde82f89b14f40c24.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAd2VuYm9kb25n,size_20,color_FFFFFF,t_70,g_se,x_16) 稍复杂些的任务是修改下面三种文件: - SConstruct - rtconfig.py - SConscript 这三个文件都是python脚本,只不过它们里面调用了许多scons系统提供的函数。所以,如果熟悉python的话,修改起来会很轻松。 ### SConstruct SConstruct是scons的入口脚本,其通过rtconfig.py以导入各种编译配置,之后调用PrepareBuilding以获取编译对象(要编译哪些文件)。PrepareBuilding会调用各SConscript脚本以获取编译对象。这文件一般不用修改,除非参考的bsp有瑕疵。 ### rtconfig.py rtconfig.py中定义了各种与编译相关的选项和参数。 头部定义CPU架构与型号,还记得文首提到的架构移植吗?对于rtt已支持的CPU架构,只需要在这里指明即可,scons系统会根据这里的配置选择相应的架构代码以进行编译链接。 ```python ARCH='arm' CPU='cortex-m0' ``` 其他主要的是编译参数,比如armcc编译系列如下。 ```python elif PLATFORM == 'armcc': # toolchains CC = 'armcc' CXX = 'armcc' AS = 'armasm' AR = 'armar' LINK = 'armlink' TARGET_EXT = 'axf' DEVICE = ' --cpu Cortex-M0 ' CFLAGS = '-c ' + DEVICE + ' --apcs=interwork --c99' AFLAGS = DEVICE + ' --apcs=interwork ' LFLAGS = DEVICE + ' --scatter "board\linker_scripts\link.sct" --info sizes --info totals --info unused --info veneers --list rt-thread.map --strict' CFLAGS += ' -I' + EXEC_PATH + '/ARM/ARMCC/include' LFLAGS += ' --libpath=' + EXEC_PATH + '/ARM/ARMCC/lib' CFLAGS += ' -D__MICROLIB ' AFLAGS += ' --pd "__MICROLIB SETA 1" ' LFLAGS += ' --library_type=microlib ' EXEC_PATH += '/ARM/ARMCC/bin/' if BUILD == 'debug': CFLAGS += ' -g -O0' AFLAGS += ' -g' else: CFLAGS += ' -O2' CXXFLAGS = CFLAGS POST_ACTION = 'fromelf --bin $TARGET --output rtthread.bin \nfromelf -z $TARGET' ``` 这块与生成keil工程无关,而是在命令行下编译源码并生成固件。可能大家平时不会这么编译,都是用Keil。其实这种方法意义重大,其是持续集成的基础。 适配起来很也简单,直接把相同CPU的配置复制过来即可。我移植HC32L196,虽然主要参考HC32F4A0,然而HC32F4A0的构架是cortex-m4,显然不适合。所以在适配rtconfig.py时,我从stm32\stm32l053-st-nucleo获取cortex-m0的配置。 ### SConscript SConscript存在于各源码目录下,用于决定编译哪些文件。这些要编译的文件也会在创建keil工程中时被包含进去。 ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/02200c9a176b26b8a876e143285881927cd95896.png) bsp根目录下的SConscript用于扫描出子目录中的SConscript并调用之,一般不用修改。 子目录下的SConscript大致分为两种: 1. 将指定文件包含到编译目标之中,或者使用Glob('*.c')包含所有的C文件。 2. 根据rtconfig.h中的配置来包含被选中的文件。 application中的为第1种,drivers为第2种。修改时依葫芦画瓢即可。 更多细节,可参阅:https://www.rt-thread.org/document/site/#/development-tools/scons/scons ## board 终于进入代码讲解环节。board目录中通常会有一个board.c。 ```c void rt_hw_board_clock_init(void) { } void SysTick_Configuration(void) { } void SysTick_Handler(void) { /* enter interrupt */ rt_interrupt_enter(); rt_tick_increase(); /* leave interrupt */ rt_interrupt_leave(); } void rt_hw_board_init() { /* Configure the System clock */ rt_hw_board_clock_init(); /* Configure the SysTick */ SysTick_Configuration(); #ifdef RT_USING_HEAP rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END); #endif #ifdef RT_USING_COMPONENTS_INIT rt_components_board_init(); #endif #ifdef RT_USING_CONSOLE rt_console_set_device(RT_CONSOLE_DEVICE_NAME); #endif } ``` 其做了如下事情: - 初始化时钟 - 配置SysTick定时器 - 初始化rtt堆内存模块 - 初始化板级驱动,如gpio和uart - 设计控制台串口 所有bsp的board.c都差不多,上面代码中rt_hw_board_clock_init和SysTick_Configuration空着,这就是移植时需要修改的代码。其他部分,一般不用修改。 另,配置堆内存时用到的宏定义在board.h之中,需要根据硬件做修改。 ```c #define SRAM_BASE 0x20000000 #define SRAM_SIZE 0x8000 #define SRAM_END (SRAM_BASE + SRAM_SIZE) ``` board\linker_scripts目录中存放链接脚本,需要修改其中有关RAM和ROM的配置。 - link.sct:keil链接脚本 - link.lds:gcc链接脚本 - 没做iar支持,因为我不用iar,也没装iar:) ## Libraries Libraries存放芯片厂商提供的驱动代码。我移植的HC32L196基本结构如下: - HC32L196_StdPeriph_Driver:分inc和src,存放芯片驱动,如hc32l196_adc.h和hc32l196_adc.c。 - CMSIS\Include:存放CMSIS相关头文件,如core_cm0.h - CMSIS\Device\HDSC\HC32L196\Include:杂类驱动头文件。 - CMSIS\Device\HDSC\HC32L196\Source:杂类驱动源文件,比如system_hc32l19x.c,其内包含汇编启动文件会调用的SystemInit函数。 - CMSIS\Device\HDSC\HC32L196\Source\ARM:keil汇编启动文件startup_hc32l19x.s - CMSIS\Device\HDSC\HC32L196\Source\GCC:gcc汇编启动文件startup_hc32l19x.s - CMSIS\Device\HDSC\HC32L196\Source\IAR:iar汇编启动文件startup_hc32l19x.s - SConscript:包含本目录中的代码文件。在包含汇编启动文件时,根据rtconfig.CROSS_TOOL来包含相应编译平台的文件。 上述这些文件,除了SConscript,都来自芯片厂商的SDK,只不过其文件分布可能与上述不同。视具体情况做调整即可。 ## 汇编启动文件 关于Libraries中的汇编启动文件,需要补充说明一点。对于keil版本,一般无须修改。对于gcc版本,需要把跳转main函数的语句修改为跳转entry函数。 stm32的启动文件,其调用的是main函数。 ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/0a38f3ee512293eaa0ce7fb7b240eba93db94999.png) 需要改为: ``` bl entry ``` 之所以有如此差异,是因为armcc(keil编译器)与gcc的机制不同。 ### armcc armcc的汇编启动文件相对简单,职责如下: - 定义堆空间和栈空间,初始化栈指针 - 定义中断向量表 - 定义入口函数Reset_Handler,其先调用SystemInit,之后调用__main 初始化全局变量等工作放在了__main之中,__main完成初始化操作后会调用main函数。不过呢,armcc提供了一种函数补丁机制。如果定义了```$Sub$$main```函数的话,在main函数调用之前,会先调用```$Sub$$main```。rt-thread就是通过定义```$Sub$$main```函数,在其中进行操作系统的初始化,之后调用applications中的main函数以执行用户代码。 ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/55b9c47626a9d7ab7b484bb6982b5f14b462316e.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAd2VuYm9kb25n,size_19,color_FFFFFF,t_70,g_se,x_16) ### gcc gcc汇编启动文件职责如下: - 定义中断向量表 - 定义入口函数Reset_Handler,其负责初始化全局变量(data和bss),调用SystemInit,调用main函数 由于gcc没有armcc那样的函数补丁机制,所以要运行rt-thread的话,需要将调用main函数改为调用rt-thread入口函数,即entry。 rt-thread根据编译平台定义了不同的入口函数,armcc对应```$Sub$$main```,gcc对应```entry```。 ```c #ifdef __ARMCC_VERSION extern int $Super$$main(void); /* re-define main function */ int $Sub$$main(void) { rtthread_startup(); return 0; } #elif defined(__ICCARM__) extern int main(void); /* __low_level_init will auto called by IAR cstartup */ extern void __iar_data_init3(void); int __low_level_init(void) { // call IAR table copy function. __iar_data_init3(); rtthread_startup(); return 0; } #elif defined(__GNUC__) /* Add -eentry to arm-none-eabi-gcc argument */ int entry(void) { rtthread_startup(); return 0; } #endif ``` # 移植到HC32L196 如前所说,我不打算详细讲解每一步操作,仅提一些要点。 ## 移植步骤 可分为两步: - 创建可以运行的bsp,这是最关键的一步。 - 填充rtt设备驱动,如gpio和uart,这是相对费时的一步。 之所以分为两大步,是因为先完成关键的一步,运行成功,将给予移植者一个很大的激励,提高信心。如果第一步失败了,也好及时查找问题,而不是等经历了漫长的设备驱动移植后,在测试时发现rt-thread系统都还无法跑起来。 ### 创建可以运行的bsp 所谓可以运行,是指可以让rt-thread操作系统在芯片上跑起来,并不需要跑finsh控制台,甚至不需要点亮LED灯,不需要任何外设驱动,能运行如下代码就行。 main.c ```c int main(void) { for (uint32_t i = 0; ; i++) { rt_thread_delay(RT_TICK_PER_SECOND); }; } ``` 当然啦,没有任何外设驱动的话,只能在调试模式下运行才能观察效果。只要rt_thread_delay的功能正常,就说明rt-thread调度系统正常工作了。 在了解了移植原理后,创建可以运行的bsp应该能较快完成,具体步骤如下: 1. 复制一个bsp,将名称改为自己的平台。 2. 使用芯片原厂提供的SDK替换Libraries目录中的内容。对其中的汇编启动文件和链接脚本要稍加关注,尤其是gcc汇编。 3. 修改board目录源码,主要是board.c,完成初始化时钟和SysTick的工作。 4. 删除drivers中的文件,或者保留几个驱动文件的框架,删除硬件相关代码。 5. 修改模板工程。 6. 修改Kconfig相关文件。 7. 修改Scons相关文件。 8. 使用menuconfig更新rtconfig.h文件。 9. 使用scons生成rt-thread工程。 10.编译烧录调度。 ## RT-Thread Studio 创建可以运行的bsp之后,之后就是开发驱动程序了。此时其实是可以使用RT-Thread Studio开发的,其有一个非常好用的功能:导入Keil或者IAR项目到工作空间中。 ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/0e0111527dd990988fde432350af30c4e2b80b65.png) 我在之后的驱动开发环节一直使用RT-Thread Studio编写代码。 ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/806c65118de96b070a3f2c8d08afa80903c15748.png) ## gpio映射表 ```c struct rt_pin_ops { void (*pin_mode)(struct rt_device *device, rt_base_t pin, rt_base_t mode); void (*pin_write)(struct rt_device *device, rt_base_t pin, rt_base_t value); int (*pin_read)(struct rt_device *device, rt_base_t pin); rt_err_t (*pin_attach_irq)(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args); rt_err_t (*pin_detach_irq)(struct rt_device *device, rt_int32_t pin); rt_err_t (*pin_irq_enable)(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled); rt_base_t (*pin_get)(const char *name); }; ``` rt-thread gpio设备驱动接口使用引脚号(pin)来操作指定的引脚。早期的bsp会定义一个大数组来存储引脚列表,下图是swm320定义的列表。 ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/c3457a3f28e81e873922ede5a22d91e2c939a325.png) 这种方式比较繁琐。通常芯片的GPIO口有一定的规律,比如PA0-PA15,PB0-PB15,PC0-PC15,等等。这些GPIO对应的寄存器的地址是连续的,可以通过一个公式将寄存器地址转换为引脚序号,反之亦然。 因此出现了使用**GET_PIN**宏来计算指定GPIO引脚序号的方法,比如GET_PIN(A, 5)会计算出PA5引脚的序号。可能stm32 bsp最先使用这种方法,大家移植的时候可以参考一下。 ## 支持gcc ### 支持编译 HC32L196的原厂SDK中并不支持gcc。不过笔者是eclipse系列IDE的忠实用户,既然原厂不支持,那我就自己支持吧。 首先,要创建汇编启动文件:Libraries\CMSIS\Device\HDSC\HC32L196\Source\GCC\startup_hc32l19x.s。 怎么创建呢,当然不需要从零开始啦。从其他cortex-m0的bsp中复制一个来修改。比如stm32的, ``` bsp\stm32\libraries\STM32L0xx_HAL\CMSIS\Device\ST\STM32L0xx\Source\Templates\gcc\startup_stm32l053xx.s ``` 修改中断向量表和中断函数即可。 另外要关注下rtconfig.py和board\linker_scripts\link.lds,同样可以参考cortex-m0的bsp。 ### 支持烧录 添加了对gcc的支持后,使用RT-Thread Studio创建开发板支持包,就可以真正使用RT-Thread Studio来开发项目了。不过在这之前,需要先编译出固件并烧录验证。 使用scons命令编译。 ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/abc32f8b144c234b56ced24fe52bd097e096b89b.png) 编译后的固件位于bsp根目录: ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/1971e8956dad36db95cb1c2a8127fc4b4e5de375.png) 可使用J-Flash烧录: ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/44c12a0455185bf8460906f083766f81429d4d38.png) 成功运行: ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/5df7ca1036d72617373196232acfe9c5b4580cdd.png) 大家在使用J-Flash创建工程时,可能发现找不到自己的硬件配置。如下图,HC32系列只有我移植的HC32L196,而没有HC32F4A0等,这是我自己添加进去的。怎么添加呢,可参考我之前的一篇文章:https://mp.weixin.qq.com/s/ZPre7XZIKwIoS-s_8x_VTQ 。 ![在这里插入图片描述](https://oss-club.rt-thread.org/uploads/20220714/8848d704191e77c704e4d2de585a3b7772755532.png)
9
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
wenbodong
这家伙很懒,什么也没写!
文章
4
回答
44
被采纳
3
关注TA
发私信
相关文章
1
(苏州站)RT-Thread物联网开发者沙龙【已结束】
2
(成都站)RT-Thread物联网开发者沙龙
3
(深圳站)RT-Thread物联网开发者沙龙
4
(西安站)RT-Thread物联网开发者沙龙
5
成都站2018 RT-Thread开发者沙龙回顾及PPT下载
6
2018 RT-Thread物联网开发者沙龙(北京站)
7
2018 RT-Thread物联网开发者沙龙(南京站)
8
第十三届研电赛RT-Thread企业专项奖发布通知
9
RT-Thread应用作品征集大赛开始啦!
10
你的投票将决定RT-Thread官网应该优先准备的文档是哪些
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
ulog
C++_cpp
at_device
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
13
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
8
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
5
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部