前情提要
上一篇文章记录了一下如何创建GD32E503的BSP。但由于时间关系只实现了MDK版本的工程模板,后面如果需要提交BSP时再去补全IAR版本的。但对于我个人而言,IAR只在读书时玩蓝牙开发的时候用过,而MDK虽然用的比较多但最近几年也很少用了。感觉还是VSCode等编辑器用起来更舒服一些,而对于RTT系统的开发,我个人还是更倾向于使用官方的RTThreadStudioIDE进行开发。于是今天想想办法怎么移到RTTStudio上去。
面临的问题
上篇文章已经发现,目前官方的固件库竟然没有GCC版本的启动文件,所以要想办法弄个启动文件
RTTStudio自带的GCC编译器版本太老,不支持编译M33内核,所以要升级GCC
计划用开源的DAP调试器进行调试,但同样RTTStudio自带的pyocd调试工具版本太老,需要升级
添加GCC版本的启动文件
拷贝启动文件模板
从GD32F4xx固件包内把GCC文件夹拷贝到新添加的GDE50x固件包的对应位置,并把汇编文件名称修改为gd32e50x的,注意,GD32E50x分了高密度版(hd)和互联版(cl),我这里暂且只修改了一份我用到的高密度版本的。cl版本的也类似修改即可。
修改启动文件
众所周知,汇编的启动文件要干的事情就是做一些芯片启动的前期初始化工作,搭建C代码的运行环境。所以这里也并不需要对照汇编指令,把每条语句的功能都搞明白,只需大致了解一下即可。一眼望去,感觉这个汇编文件主要做了三大事情。
第一,定义中断向量;
第二,定义启动入口;
第三,声明中断函数。
而启动入口相关的不用修改,都是先调用SystemInit函数做一些时钟等基础初始化,然后再调用entry或者main函数执行后续的代码。
所以这里主要修改的就是中断向量的定义和中断函数的声明,按照armcc版本的进行修改即可:
1; * Copyright (c) 2006-2021, RT-Thread Development Team
2; *
3; * SPDX-License-Identifier: Apache-2.0
4; *
5; * Change Logs:
6; * Date Author Notes
7; * 2018-05-22 tanek first implementation
8; */
9.syntax unified
10.cpu cortex-m33
11.fpu softvfp
12.thumb
13.global g_pfnVectors
14.global Default_Handler
15 .section .isr_vector,"a",%progbits
16 .type g_pfnVectors, %object
17g_pfnVectors:
18 .word _estack // Top of Stack
19 .word Reset_Handler // Reset Handler
20 .word NMI_Handler // NMI Handler
21 .word HardFault_Handler // Hard Fault Handler
22 .word MemManage_Handler // MPU Fault Handler
23 .word BusFault_Handler // Bus Fault Handler
24 .word UsageFault_Handler // Usage Fault Handler
25 .word 0 // Reserved
26 .word 0 // Reserved
27 .word 0 // Reserved
28 .word 0 // Reserved
29 .word SVC_Handler // SVCall Handler
30 .word DebugMon_Handler // Debug Monitor Handler
31 .word 0 // Reserved
32 .word PendSV_Handler // PendSV Handler
33 .word SysTick_Handler // SysTick Handler
34 // external interrupts handler
35 .word WWDGT_IRQHandler // 16:Window Watchdog Timer
36 .word LVD_IRQHandler // 17:LVD through EXTI Line detect
37 .word TAMPER_IRQHandler // 18:Tamper through EXTI Line detect
38 .word RTC_IRQHandler // 19:RTC through EXTI Line
39 .word FMC_IRQHandler // 20:FMC
40 .word RCU_CTC_IRQHandler // 21:RCU and CTC
41 .word EXTI0_IRQHandler // 22:EXTI Line 0
42 .word EXTI1_IRQHandler // 23:EXTI Line 1
43 .word EXTI2_IRQHandler // 24:EXTI Line 2
44 .word EXTI3_IRQHandler // 25:EXTI Line 3
45 .word EXTI4_IRQHandler // 26:EXTI Line 4
46 .word DMA0_Channel0_IRQHandler // 27:DMA0 Channel0
47 .word DMA0_Channel1_IRQHandler // 28:DMA0 Channel1
48 .word DMA0_Channel2_IRQHandler // 29:DMA0 Channel2
49 .word DMA0_Channel3_IRQHandler // 30:DMA0 Channel3
50 .word DMA0_Channel4_IRQHandler // 31:DMA0 Channel4
51 .word DMA0_Channel5_IRQHandler // 32:DMA0 Channel5
52 .word DMA0_Channel6_IRQHandler // 33:DMA0 Channel6
53 .word ADC0_1_IRQHandler // 34:ADC0 and ADC1
54 .word USBD_HP_CAN0_TX_IRQHandler // 35:USBD HP or CAN0 TX
55 .word USBD_LP_CAN0_RX0_IRQHandler // 36:USBD LP or CAN0 RX0
56 .word CAN0_RX1_IRQHandler // 37:CAN0 RX1
57 .word CAN0_EWMC_IRQHandler // 38:CAN0 EWMC
58 .word EXTI5_9_IRQHandler // 39:EXTI5 to EXTI9
59 .word TIMER0_BRK_TIMER8_IRQHandler // 40:TIMER0 Break and TIMER8
60 .word TIMER0_UP_TIMER9_IRQHandler // 41:TIMER0 Update and TIMER9
61 .word TIMER0_TRG_CMT_TIMER10_IRQHandler // 42:TIMER0 Trigger and Commutation and TIMER10
62 .word TIMER0_Channel_IRQHandler // 43:TIMER0 Channel Capture Compare
63 .word TIMER1_IRQHandler // 44:TIMER1
64 .word TIMER2_IRQHandler // 45:TIMER2
65 .word TIMER3_IRQHandler // 46:TIMER3
66 .word I2C0_EV_IRQHandler // 47:I2C0 Event
67 .word I2C0_ER_IRQHandler // 48:I2C0 Error
68 .word I2C1_EV_IRQHandler // 49:I2C1 Event
69 .word I2C1_ER_IRQHandler // 50:I2C1 Error
70 .word SPI0_IRQHandler // 51:SPI0
71 .word SPI1_I2S1ADD_IRQHandler // 52:SPI1 or I2S1ADD
72 .word USART0_IRQHandler // 53:USART0
73 .word USART1_IRQHandler // 54:USART1
74 .word USART2_IRQHandler // 55:USART2
75 .word EXTI10_15_IRQHandler // 56:EXTI10 to EXTI15
76 .word RTC_Alarm_IRQHandler // 57:RTC Alarm
77 .word USBD_WKUP_IRQHandler // 58:USBD Wakeup
78 .word TIMER7_BRK_TIMER11_IRQHandler // 59:TIMER7 Break and TIMER11
79 .word TIMER7_UP_TIMER12_IRQHandler // 60:TIMER7 Update and TIMER12
80 .word TIMER7_TRG_CMT_TIMER13_IRQHandler // 61:TIMER7 Trigger and Commutation and TIMER13
81 .word TIMER7_Channel_IRQHandler // 62:TIMER7 Channel Compare
82 .word ADC2_IRQHandler // 63:ADC2
83 .word EXMC_IRQHandler // 64:EXMC
84 .word SDIO_IRQHandler // 65:SDIO
85 .word TIMER4_IRQHandler // 66:TIMER4
86 .word SPI2_I2S2ADD_IRQHandler // 67:SPI2 or I2S2ADD
87 .word UART3_IRQHandler // 68:UART3
88 .word UART4_IRQHandler // 69:UART4
89 .word TIMER5_DAC_IRQHandler // 70:TIMER5 and DAC0 DAC1 Underrun error
90 .word TIMER6_IRQHandler // 71:TIMER6
91 .word DMA1_Channel0_IRQHandler // 72:DMA1 Channel0
92 .word DMA1_Channel1_IRQHandler // 73:DMA1 Channel1
93 .word DMA1_Channel2_IRQHandler // 74:DMA1 Channel2
94 .word DMA1_Channel3_4_IRQHandler // 75:DMA1 Channel3 and Channel4
95 .word 0 // 76:Reserved
96 .word 0 // 77:Reserved
97 .word 0 // 78:Reserved
98 .word CAN1_TX_IRQHandler // 79:CAN1 TX
99 .word CAN1_RX0_IRQHandler // 80:CAN1 RX0
100 .word CAN1_RX1_IRQHandler // 81:CAN1 RX1
101 .word CAN1_EWMC_IRQHandler // 82:CAN1 EWMC
102 .word 0 // 83:Reserved
103 .word 0 // 84:Reserved
104 .word SHRTIMER_IRQ2_IRQHandler // 85:SHRTIMER IRQ2
105 .word SHRTIMER_IRQ3_IRQHandler // 86:SHRTIMER IRQ3
106 .word SHRTIMER_IRQ4_IRQHandler // 87:SHRTIMER IRQ4
107 .word SHRTIMER_IRQ5_IRQHandler // 88:SHRTIMER IRQ5
108 .word SHRTIMER_IRQ6_IRQHandler // 89:SHRTIMER IRQ6
109 .word 0 // 90:Reserved
110 .word 0 // 91:Reserved
111 .word SHRTIMER_IRQ0_IRQHandler // 92:SHRTIMER IRQ0
112 .word SHRTIMER_IRQ1_IRQHandler // 93:SHRTIMER IRQ1
113 .word 0 // 94:Reserved
114 .word 0 // 95:Reserved
115 .word 0 // 96:Reserved
116 .word 0 // 97:Reserved
117 .word I2C2_EV_IRQHandler // 98:I2C2 Event
118 .word I2C2_ER_IRQHandler // 99:I2C2 Error
119 .word USART5_IRQHandler // 100:USART5
120 .word I2C2_WKUP_IRQHandler // 101:I2C2 Wakeup
121 .word USART5_WKUP_IRQHandler // 102:USART5 Wakeup
122 .word 0 // 103:Reserved
123 .size g_pfnVectors, .-g_pfnVectors
124 .section .text.Reset_Handler
125 .weak Reset_Handler
126 .type Reset_Handler, %function
127Reset_Handler:
128 ldr r1, =_sidata
129 ldr r2, =_sdata
130 ldr r3, =_edata
131 subs r3, r2
132 ble fill_bss_start
133loop_copy_data:
134 subs r3, #4
135 ldr r0, [r1,r3]
136 str r0, [r2,r3]
137 bgt loop_copy_data
138fill_bss_start:
139 ldr r1, =__bss_start
140 ldr r2, =__bss_end
141 movs r0, 0
142 subs r2, r1
143 ble startup_enter
144loop_fill_bss:
145 subs r2, #4
146 str r0, [r1, r2]
147 bgt loop_fill_bss
148startup_enter:
149 bl SystemInit
150 bl entry
151 /* Exception Handlers */
152 .weak NMI_Handler
153 .type NMI_Handler, %function
154NMI_Handler:
155 b .
156 .size NMI_Handler, . - NMI_Handler
157 .weak MemManage_Handler
158 .type MemManage_Handler, %function
159MemManage_Handler:
160 b .
161 .size MemManage_Handler, . - MemManage_Handler
162 .weak BusFault_Handler
163 .type BusFault_Handler, %function
164BusFault_Handler:
165 b .
166 .size BusFault_Handler, . - BusFault_Handler
167 .weak UsageFault_Handler
168 .type UsageFault_Handler, %function
169UsageFault_Handler:
170 b .
171 .size UsageFault_Handler, . - UsageFault_Handler
172 .weak SVC_Handler
173 .type SVC_Handler, %function
174SVC_Handler:
175 b .
176 .size SVC_Handler, . - SVC_Handler
177 .weak DebugMon_Handler
178 .type DebugMon_Handler, %function
179DebugMon_Handler:
180 b .
181 .size DebugMon_Handler, . - DebugMon_Handler
182 .weak PendSV_Handler
183 .type PendSV_Handler, %function
184PendSV_Handler:
185 b .
186 .size PendSV_Handler, . - PendSV_Handler
187 .weak SysTick_Handler
188 .type SysTick_Handler, %function
189SysTick_Handler:
190 b .
191 .size SysTick_Handler, . - SysTick_Handler
192 /* IQR Handler */
193 .section .text.Default_Handler,"ax",%progbits
194 .type Default_Handler, %function
195Default_Handler:
196 b .
197 .size Default_Handler, . - Default_Handler
198 .macro IRQ handler
199 .weak \handler
200 .set \handler, Default_Handler
201 .endm
202 IRQ WWDGT_IRQHandler
203 IRQ LVD_IRQHandler
204 IRQ TAMPER_IRQHandler
205 IRQ RTC_IRQHandler
206 IRQ FMC_IRQHandler
207 IRQ RCU_CTC_IRQHandler
208 IRQ EXTI0_IRQHandler
209 IRQ EXTI1_IRQHandler
210 IRQ EXTI2_IRQHandler
211 IRQ EXTI3_IRQHandler
212 IRQ EXTI4_IRQHandler
213 IRQ DMA0_Channel0_IRQHandler
214 IRQ DMA0_Channel1_IRQHandler
215 IRQ DMA0_Channel2_IRQHandler
216 IRQ DMA0_Channel3_IRQHandler
217 IRQ DMA0_Channel4_IRQHandler
218 IRQ DMA0_Channel5_IRQHandler
219 IRQ DMA0_Channel6_IRQHandler
220 IRQ ADC0_1_IRQHandler
221 IRQ USBD_HP_CAN0_TX_IRQHandler
222 IRQ USBD_LP_CAN0_RX0_IRQHandler
223 IRQ CAN0_RX1_IRQHandler
224 IRQ CAN0_EWMC_IRQHandler
225 IRQ EXTI5_9_IRQHandler
226 IRQ TIMER0_BRK_TIMER8_IRQHandler
227 IRQ TIMER0_UP_TIMER9_IRQHandler
228 IRQ TIMER0_TRG_CMT_TIMER10_IRQHandler
229 IRQ TIMER0_Channel_IRQHandler
230 IRQ TIMER1_IRQHandler
231 IRQ TIMER2_IRQHandler
232 IRQ TIMER3_IRQHandler
233 IRQ I2C0_EV_IRQHandler
234 IRQ I2C0_ER_IRQHandler
235 IRQ I2C1_EV_IRQHandler
236 IRQ I2C1_ER_IRQHandler
237 IRQ SPI0_IRQHandler
238 IRQ SPI1_I2S1ADD_IRQHandler
239 IRQ USART0_IRQHandler
240 IRQ USART1_IRQHandler
241 IRQ USART2_IRQHandler
242 IRQ EXTI10_15_IRQHandler
243 IRQ RTC_Alarm_IRQHandler
244 IRQ USBD_WKUP_IRQHandler
245 IRQ TIMER7_BRK_TIMER11_IRQHandler
246 IRQ TIMER7_UP_TIMER12_IRQHandler
247 IRQ TIMER7_TRG_CMT_TIMER13_IRQHandler
248 IRQ TIMER7_Channel_IRQHandler
249 IRQ ADC2_IRQHandler
250 IRQ EXMC_IRQHandler
251 IRQ SDIO_IRQHandler
252 IRQ TIMER4_IRQHandler
253 IRQ SPI2_I2S2ADD_IRQHandler
254 IRQ UART3_IRQHandler
255 IRQ UART4_IRQHandler
256 IRQ TIMER5_DAC_IRQHandler
257 IRQ TIMER6_IRQHandler
258 IRQ DMA1_Channel0_IRQHandler
259 IRQ DMA1_Channel1_IRQHandler
260 IRQ DMA1_Channel2_IRQHandler
261 IRQ DMA1_Channel3_4_IRQHandler
262 IRQ CAN1_TX_IRQHandler
263 IRQ CAN1_RX0_IRQHandler
264 IRQ CAN1_RX1_IRQHandler
265 IRQ CAN1_EWMC_IRQHandler
266 IRQ SHRTIMER_IRQ2_IRQHandler
267 IRQ SHRTIMER_IRQ3_IRQHandler
268 IRQ SHRTIMER_IRQ4_IRQHandler
269 IRQ SHRTIMER_IRQ5_IRQHandler
270 IRQ SHRTIMER_IRQ6_IRQHandler
271 IRQ SHRTIMER_IRQ0_IRQHandler
272 IRQ SHRTIMER_IRQ1_IRQHandler
273 IRQ I2C2_EV_IRQHandler
274 IRQ I2C2_ER_IRQHandler
275 IRQ USART5_IRQHandler
276 IRQ I2C2_WKUP_IRQHandler
277 IRQ USART5_WKUP_IRQHandler
导入RTTStudioIDE
导入工程
有了GCC版本的启动文件,那不妨先用RTTStudio导入一下工程,然后再根据错误想办法解决。点击“文件”菜单内的“导入”图标,打开导入对话框:
选择“RT-Thread Bsp到工作空间中”,然后点击下一步按钮:
根据自己的实际情况填写内容,然后点击“完成按钮”进行导入:
如下是我导入后的项目资源列表,会把所需的内容都拷贝到工程内部:
编译根据错误解决问题
不妨先编译一下工程,发现报了一些错误,这是必然的,因为还有很多操作没做呢。那首当其冲的错误就是如下的GCC不支持m33内核的问题。
1arm-none-eabi-gcc: error: unrecognized argument in option '-mcpu=cortex-m33+nodsp'
2arm-none-eabi-gcc: note: valid arguments to '-mcpu=' are: arm1020e arm1020t arm1022e arm1026ej-s arm10e arm10tdmi arm1136j-s arm1136jf-s arm1156t2-s arm1156t2f-s arm1176jz-s arm1176jzf-s arm2 arm250 arm3 arm6 arm60 arm600 arm610 arm620 arm7 arm70 arm700 arm700i arm710 arm7100 arm710c arm710t arm720 arm720t arm740t arm7500 arm7500fe arm7d arm7di arm7dm arm7dmi arm7m arm7tdmi arm7tdmi-s arm8 arm810 arm9 arm920 arm920t arm922t arm926ej-s arm940t arm946e-s arm966e-s arm968e-s arm9e arm9tdmi cortex-a12 cortex-a15 cortex-a15.cortex-a7 cortex-a17 cortex-a17.cortex-a7 cortex-a5 cortex-a53 cortex-a57 cortex-a57.cortex-a53 cortex-a7 cortex-a72 cortex-a72.cortex-a53 cortex-a8 cortex-a9 cortex-m0 cortex-m0.small-multiply cortex-m0plus cortex-m0plus.small-multiply cortex-m1 cortex-m1.small-multiply cortex-m3 cortex-m4 cortex-m7 cortex-r4 cortex-r4f cortex-r5 cortex-r7 cortex-r8 ep9312 exynos-m1 fa526 fa606te fa626 fa626te fa726te fmp626 generic-armv7-a iwmmxt iwmmxt2 marvell-pj4 mpcore mpcorenovfp native strongarm strongarm110 strongarm1100 strongarm1110 xgene1 xscale
3make: *** [rt-thread/src/subdir.mk:54: rt-thread/src/clock.o] Error 1
更新GCC
去arm官网,下载最新版本的gcc-arm-none-eabi:
GCC下载地址: https://developer.arm.com/downloads/-/gnu-rm
把解压后的GCC文件夹拷贝到RTTStudio的GCC工具路径内,为了减小点路径长度,可以把文件夹名字重命名为”10.3”:
点击“构建配置”工具图标,打开配置对话框,在“设置”栏的“Toolchains”图页内就可以配置GCC相关信息了。GCC应该是向下兼容的,这里不妨选择”global”进行全局设置:
点击“浏览”按钮,选择刚加入的GCC工具路径,要选择到里面的bin级目录:
添加“cmsis_gcc.h”头文件
点击“应用并关闭”按钮,完成修改,再次编译,发现之前不支持M33内核的错误不见了。不过错误反而变多了😅,也很正常,因为之前就没进行到GCC编译这一步,很多错误自然出现不了,不用着急,先看第一个错误:
1D:\RT-ThreadStudio\workspace\FOC_MiniCar\libraries\GD32E50x_Firmware_Library\CMSIS/cmsis_compiler.h:54:12: fatal error: cmsis_gcc.h: No such file or directory
2 54 | #include "cmsis_gcc.h"
报的是固件库缺少“cmsis_gcc.h”文件。也对,官方固件并没有做GCC的支持,怎么会有这个头文件呢。那继续从其它固件那里拷贝一份到当前工程内即可,当然为了之前做的BSP的完整性,也可以同时往其对应位置拷贝一份:
再次编译,呕吼!错误更多了,依然不急,先看第一个错误:
1D:\RT-ThreadStudio\workspace\FOC_MiniCar\libraries\GD32E50x_Firmware_Library\CMSIS/core_cm33.h:2668:10: fatal error: mpu_armv8.h: No such file or directory
2 2668 | #include "mpu_armv8.h"
提示找不到”mpu_armv8.h”头文件。这里比较奇怪,m33内核确实属于armv8架构,但官方固件库内却找不到此头文件,倒是在其它的BSP内搜到了此头文件,于是随便拷贝一个到工程内即可,比如我是从瑞萨的一个BSP内拷贝的。当然,这里也可以关掉mpu的配置宏,不用mpu。
于是再次进行编译,就会发现编译通过了:
更新pyocd
那不妨下载一下试试,不出意外自然会出现意外,果真不能正常下载。原因就是最开始提到的自带的pyocd版本太老了,不支持GD32E503RC的器件。需要更新pyocd:
打开CMD命令窗口,运行如下命令,安装新的pyocd:
等待安装完毕,就可以在python的安装路径下找到新的”pyocd.exe”
在终端输入“pyocd -V”命令,可查看到新安装pyocd的版本。还可以输入“pyocd list —targets”命令查看目前pyocd支持的器件。
最后会发现,默认并不支持兆易创新的器件,所以,还需要自己添加支持包:
安装完后,再查看安装包和支持的器件,就能找到GD32了:
最后再修改一些RTTStudio的工程配置,选择先安装的pyocd.exe和pyocd-gdbserver.exe:
然后再尝试一些烧写,就可以正常下载甚至调试程序了:
相关链接
本系列首篇文章链接:
https://club.rt-thread.org/ask/article/5c0c4ba7eb4ab1ad.html
———————End———————