前言
最近调试一块 GD32F407VET6(168Mhz,8Mhz晶振) 板子时,踩了一些"启动失败"的坑。本以为是时钟配置有误,最后发现是链接脚本(.ld 文件)没有配置好,导致程序根本没能正常执行 main() 函数。
顺着这个调试过程,我认真梳理了一遍裸机开发中几个关键文件的作用,也对兆易官方的工程模板、工具链支持以及主流开发方式有了更深理解。
这篇文章记录下踩坑的点:
-
GD32F407 是什么
-
.ld、启动文件 .s、gd32f4xx.h、system_gd32f4xx.c 各自做什么
-
为什么 Keil 用户往往感知不到这些文件
-
用 VS Code + GCC 为什么必须掌握这些底层配置
-
顺带了解 RT-Thread 软件包在裸机开发中的角色
具体的构建烧录可以参考我前阵写的关于STM32板子的文章:
真.从"零"搞 VSCode+STM32CubeMx+C <1>构建
真.从"零"搞 VSCode+STM32CubeMx+C <2>调试+烧录
GD32F407 是什么?
GD32F407 是 兆易创新(GigaDevice) 出品的一款高性能、Cortex-M4F 内核的国产 MCU,很多方面与 STM32F407 十分接近,甚至寄存器定义、引脚排列都保持高度兼容。
它的核心特性包括:
-
Cortex-M4 @168MHz,支持 FPU、DSP
-
Flash:最多 1MB,SRAM:最多 192KB(我这个Flash512k,Ram192k)
-
丰富外设:ADC、DAC、CAN、USB OTG、ETH、FSMC、USART、SPI、I2C 等
-
多种封装:LQFP100、LQFP144、BGA 等
-
支持 SWD/JTAG 在线调试
兆易推出 GD32 系列,就是想打破 STM32 在中高端 MCU 的垄断,性价比很高,受到不少国产项目的青睐。许多资料表示是可以完全平替的,但是经试用,还是有一些门槛的,尤其是在迁移上。
程序是如何启动的?
我们以"点亮一个 LED 灯"为例,要让一个空白的 GD32F407 板子成功运行 main() 函数,中间需要经历一系列复杂的初始化:
涉及的关键文件:
文件 | 作用 |
---|---|
startup_gd32f407xx.s | 启动汇编文件,设置栈、跳转到 main() |
system_gd32f4xx.c | 初始化系统时钟、PLL 等 |
gd32f4xx.h | 寄存器定义头文件 |
.ld 文件 | GCC 链接脚本,决定各段如何映射到内存 |
这些文件具体做了什么?
1. 启动文件 .s(startup_gd32f407xx.s)
启动汇编是程序真正的起点。其主要工作包括:
-
设置 MSP(主栈指针)初始值
-
定义中断向量表(.isr_vector 段)
-
运行 C 程序前的初始化(拷贝 .data 段、清零 .bss 段)
-
调用 SystemInit() 初始化系统时钟
-
最后跳转到 main()
注意:官方只提供了Keil版,一般例程都是Keil版的,是没有.s和.ld文件的,github上的例程大多是带两种版本的:
- ARMCC/Keil 版(语法更偏汇编,.asm)
- GCC 版(.s,符合 GNU 汇编语法)
- 如果你用的是 GCC,需要选对文件,否则编译会报错。
2. system_gd32f4xx.c
这是一个用 C 语言写的底层初始化文件,主要负责:
-
启用外部晶振 HSE
-
配置 PLL、AHB/APB 分频
-
设置 FLASH 加速参数
-
更新全局变量 SystemCoreClock
SystemInit() 是由启动文件在最开始调用的,它决定了你的程序到底是跑在 16MHz(HSI)还是 168MHz(PLL)上,如下图,我选择的是168Mhz和8M晶振

3. gd32f4xx.h
这个头文件包含了所有外设的寄存器定义和映射,宏非常多,比如:
#define GPIOA_BASE (0x40020000UL)
#define GPIOA ((gpio_reg_struct *) GPIOA_BASE)
你能像下面这样控制 GPIO 灯,就是因为这些定义:
GPIOA->ODCTL |= GPIO_PIN_0;
也就是说,这个文件相当于裸机程序的"控制面板"。注意这里也有个配晶振的地方。

4. .ld链接脚本文件(GCC 专属)
.ld 是 GCC 编译时才需要的文件,决定了:
-
哪些代码段放在 Flash,哪些放在 RAM
-
main() 的入口在哪(通常由 .isr_vector 决定)
-
栈、堆、全局变量的布局是否合理
-
.data 是否正确从 Flash 拷贝到 RAM
MEMORY {
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
}
没有正确的 .ld 文件,哪怕你 main() 写得再好,程序也跑不起来。
Keil 用户为何"感觉不到"这些文件?
GD32 官方对 Keil 的支持非常完善,可以说是"官方首选工具链":
-
提供完整的 Keil 工程模板
-
不需要 .ld 文件,Keil 使用内部 scatter 文件自动配置
-
启动文件、系统文件全都配置好,一键编译运行
-
集成调试、仿真、烧录工具链非常成熟
也正因为如此,很多初学者用 Keil 上手时,往往不需要关注 .s 和 .ld 这些底层配置文件。
这也导致了一种错觉:"只要写代码就能跑",一旦换到 GCC 环境就懵了。
VS Code + GCC
如果你像我一样用的是:
-
VS Code + GCC + CMake 或 Makefile
-
OpenOCD 进行烧录调试
那么你必须亲自处理:
任务 | 所需文件 |
---|---|
指定入口地址 | .ld 脚本 |
启动中断向量表 | 启动汇编 .s |
系统时钟配置 | system_gd32f4xx.c |
外设控制宏定义 | gd32f4xx.h |
这是一条"裸机开发 + 自定义构建系统"的路线,更接近真实嵌入式底层工程师的工作方式。
RT-Thread 软件包的角色
很多 GD32 工程也会用到 RT-Thread 软件包。它的作用:
-
提供轻量级的实时操作系统内核(调度器、线程、定时器、信号量等)
-
统一驱动框架(设备树、HAL 层)
-
配合 BSP 提供板级初始化、外设驱动
在裸机开发中,也常常只用它的 BSP 初始化和驱动部分,比如:
rt_hw_board_init(); // 初始化引脚、时钟、串口等
你可以只用它的初始化和驱动部分,不一定用内核调度。我也下载安装了,本以为会向资料表示的可以像STM32CubeMx那样生成代码,再和VSCode联动,没想到连BSP都没下载成功,就放弃了。
总结
工具链 | 是否需要关注 .ld / .s |
---|---|
Keil / MDK | 否,自动配置,官方模板支持 |
VS Code + GCC | 是,必须手动配置 |
理解 .ld 和 .s 是裸机开发的必经之路。
如果你:
-
用 GCC 编译工具链
-
用 OpenOCD 烧录
那么早点掌握这些启动流程、链接布局、外设定义,绝对会让你少踩很多坑。
附1:VSCode EIED配置图

附2:.s、.ld代码
/*
* linker script for GD32F4xx with GNU ld
* BruceOu 2021-12-14
*/
/* Program Entry, set to mark it as "used" and avoid gc */
MEMORY
{
CODE (rx) : ORIGIN = 0x08000000, LENGTH = 512k /* 512KB flash */
DATA (rw) : ORIGIN = 0x20000000, LENGTH = 128k /* 128KB sram ,0x1000 0000 - 0x1000 FFFF TCMSRAM(64KB)*/
}
ENTRY(Reset_Handler)
_system_stack_size = 0x200;
SECTIONS
{
.text :
{
. = ALIGN(4);
_stext = .;
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
*(.text) /* remaining code */
*(.text.*) /* remaining code */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.gnu.linkonce.t*)
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(4);
/* section information for initial. */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(4);
. = ALIGN(4);
_etext = .;
} > CODE = 0
/* .ARM.exidx is sorted, so has to go in its own output section. */
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
/* This is used by the startup in order to initialize the .data secion */
_sidata = .;
} > CODE
__exidx_end = .;
/* .data section which is used for initialized data */
.data : AT (_sidata)
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_sdata = . ;
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_edata = . ;
} >DATA
.stack :
{
. = . + _system_stack_size;
. = ALIGN(4);
_estack = .;
} >DATA
__bss_start = .;
.bss :
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_ebss = . ;
*(.bss.init)
} > DATA
__bss_end = .;
_end = .;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
* Symbols in the DWARF debugging sections are relative to the beginning
* of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}
.syntax unified
.cpu cortex-m4
.fpu softvfp
.thumb
.global g_pfnVectors
.global Default_Handler
/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
/* start address for the .bss section. defined in linker script */
.word _sbss
/* end address for the .bss section. defined in linker script */
.word _ebss
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit
CopyDataInit:
ldr r3, =_sidata
ldr r3, [r3, r1]
str r3, [r0, r1]
adds r1, r1, #4
LoopCopyDataInit:
ldr r0, =_sdata
ldr r3, =_edata
adds r2, r0, r1
cmp r2, r3
bcc CopyDataInit
ldr r2, =_sbss
b LoopFillZerobss
/* Zero fill the bss segment. */
FillZerobss:
movs r3, #0
str r3, [r2]
adds r2, r2, #4
LoopFillZerobss:
ldr r3, = _ebss
cmp r2, r3
bcc FillZerobss
/* Call the clock system initialization function.*/
bl SystemInit
/* Call into static constructors (C++) */
bl __libc_init_array
/* Call the application's entry point.*/
bl main
bx lr
.size Reset_Handler, .-Reset_Handler
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
* @param None
* @retval None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex M4. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
*******************************************************************************/
.section .isr_vector,"a",%progbits
.type g_pfnVectors, %object
.size g_pfnVectors, .-g_pfnVectors
g_pfnVectors:
.word _estack /* Top of Stack */
.word Reset_Handler /* Reset Handler */
.word NMI_Handler /* NMI Handler */
.word HardFault_Handler /* Hard Fault Handler */
.word MemManage_Handler /* MPU Fault Handler */
.word BusFault_Handler /* Bus Fault Handler */
.word UsageFault_Handler /* Usage Fault Handler */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word SVC_Handler /* SVCall Handler */
.word DebugMon_Handler /* Debug Monitor Handler */
.word 0 /* Reserved */
.word PendSV_Handler /* PendSV Handler */
.word SysTick_Handler /* SysTick Handler */
.word WWDGT_IRQHandler /* 16:Window Watchdog Timer */
.word LVD_IRQHandler /* 17:LVD through EXTI Line detect */
.word TAMPER_STAMP_IRQHandler /* 18:Tamper and TimeStamp through EXTI Line detect */
.word RTC_WKUP_IRQHandler /* 19:RTC Wakeup through EXTI Line */
.word FMC_IRQHandler /* 20:FMC */
.word RCU_CTC_IRQHandler /* 21:RCU and CTC */
.word EXTI0_IRQHandler /* 22:EXTI Line 0 */
.word EXTI1_IRQHandler /* 23:EXTI Line 1 */
.word EXTI2_IRQHandler /* 24:EXTI Line 2 */
.word EXTI3_IRQHandler /* 25:EXTI Line 3 */
.word EXTI4_IRQHandler /* 26:EXTI Line 4 */
.word DMA0_Channel0_IRQHandler /* 27:DMA0 Channel0 */
.word DMA0_Channel1_IRQHandler /* 28:DMA0 Channel1 */
.word DMA0_Channel2_IRQHandler /* 29:DMA0 Channel2 */
.word DMA0_Channel3_IRQHandler /* 30:DMA0 Channel3 */
.word DMA0_Channel4_IRQHandler /* 31:DMA0 Channel4 */
.word DMA0_Channel5_IRQHandler /* 32:DMA0 Channel5 */
.word DMA0_Channel6_IRQHandler /* 33:DMA0 Channel6 */
.word ADC_IRQHandler /* 34:ADC */
.word CAN0_TX_IRQHandler /* 35:CAN0 TX */
.word CAN0_RX0_IRQHandler /* 36:CAN0 RX0 */
.word CAN0_RX1_IRQHandler /* 37:CAN0 RX1 */
.word CAN0_EWMC_IRQHandler /* 38:CAN0 EWMC */
.word EXTI5_9_IRQHandler /* 39:EXTI5 to EXTI9 */
.word TIMER0_BRK_TIMER8_IRQHandler /* 40:TIMER0 Break and TIMER8 */
.word TIMER0_UP_TIMER9_IRQHandler /* 41:TIMER0 Update and TIMER9 */
.word TIMER0_TRG_CMT_TIMER10_IRQHandler /* 42:TIMER0 Trigger and Commutation and TIMER10 */
.word TIMER0_Channel_IRQHandler /* 43:TIMER0 Channel Capture Compare */
.word TIMER1_IRQHandler /* 44:TIMER1 */
.word TIMER2_IRQHandler /* 45:TIMER2 */
.word TIMER3_IRQHandler /* 46:TIMER3 */
.word I2C0_EV_IRQHandler /* 47:I2C0 Event */
.word I2C0_ER_IRQHandler /* 48:I2C0 Error */
.word I2C1_EV_IRQHandler /* 49:I2C1 Event */
.word I2C1_ER_IRQHandler /* 50:I2C1 Error */
.word SPI0_IRQHandler /* 51:SPI0 */
.word SPI1_IRQHandler /* 52:SPI1 */
.word USART0_IRQHandler /* 53:USART0 */
.word USART1_IRQHandler /* 54:USART1 */
.word USART2_IRQHandler /* 55:USART2 */
.word EXTI10_15_IRQHandler /* 56:EXTI10 to EXTI15 */
.word RTC_Alarm_IRQHandler /* 57:RTC Alarm */
.word USBFS_WKUP_IRQHandler /* 58:USBFS Wakeup */
.word TIMER7_BRK_TIMER11_IRQHandler /* 59:TIMER7 Break and TIMER11 */
.word TIMER7_UP_TIMER12_IRQHandler /* 60:TIMER7 Update and TIMER12 */
.word TIMER7_TRG_CMT_TIMER13_IRQHandler /* 61:TIMER7 Trigger and Commutation and TIMER13 */
.word TIMER7_Channel_IRQHandler /* 62:TIMER7 Capture Compare */
.word DMA0_Channel7_IRQHandler /* 63:DMA0 Channel7 */
.word EXMC_IRQHandler /* 64:EXMC */
.word SDIO_IRQHandler /* 65:SDIO */
.word TIMER4_IRQHandler /* 66:TIMER4 */
.word SPI2_IRQHandler /* 67:SPI2 */
.word UART3_IRQHandler /* 68:UART3 */
.word UART4_IRQHandler /* 69:UART4 */
.word TIMER5_DAC_IRQHandler /* 70:TIMER5 and DAC0 DAC1 Underrun error */
.word TIMER6_IRQHandler /* 71:TIMER6 */
.word DMA1_Channel0_IRQHandler /* 72:DMA1 Channel0 */
.word DMA1_Channel1_IRQHandler /* 73:DMA1 Channel1 */
.word DMA1_Channel2_IRQHandler /* 74:DMA1 Channel2 */
.word DMA1_Channel3_IRQHandler /* 75:DMA1 Channel3 */
.word DMA1_Channel4_IRQHandler /* 76:DMA1 Channel4 */
.word ENET_IRQHandler /* 77:Ethernet */
.word ENET_WKUP_IRQHandler /* 78:Ethernet Wakeup through EXTI Line */
.word CAN1_TX_IRQHandler /* 79:CAN1 TX */
.word CAN1_RX0_IRQHandler /* 80:CAN1 RX0 */
.word CAN1_RX1_IRQHandler /* 81:CAN1 RX1 */
.word CAN1_EWMC_IRQHandler /* 82:CAN1 EWMC */
.word USBFS_IRQHandler /* 83:USBFS */
.word DMA1_Channel5_IRQHandler /* 84:DMA1 Channel5 */
.word DMA1_Channel6_IRQHandler /* 85:DMA1 Channel6 */
.word DMA1_Channel7_IRQHandler /* 86:DMA1 Channel7 */
.word USART5_IRQHandler /* 87:USART5 */
.word I2C2_EV_IRQHandler /* 88:I2C2 Event */
.word I2C2_ER_IRQHandler /* 89:I2C2 Error */
.word USBHS_EP1_Out_IRQHandler /* 90:USBHS Endpoint 1 Out */
.word USBHS_EP1_In_IRQHandler /* 91:USBHS Endpoint 1 in */
.word USBHS_WKUP_IRQHandler /* 92:USBHS Wakeup through EXTI Line */
.word USBHS_IRQHandler /* 93:USBHS */
.word DCI_IRQHandler /* 94:DCI */
.word 0 /* 95:Reserved */
.word TRNG_IRQHandler /* 96:TRNG */
.word FPU_IRQHandler /* 97:FPU */
/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler
.weak HardFault_Handler
.thumb_set HardFault_Handler,Default_Handler
.weak MemManage_Handler
.thumb_set MemManage_Handler,Default_Handler
.weak BusFault_Handler
.thumb_set BusFault_Handler,Default_Handler
.weak UsageFault_Handler
.thumb_set UsageFault_Handler,Default_Handler
.weak SVC_Handler
.thumb_set SVC_Handler,Default_Handler
.weak DebugMon_Handler
.thumb_set DebugMon_Handler,Default_Handler
.weak PendSV_Handler
.thumb_set PendSV_Handler,Default_Handler
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
.weak WWDGT_IRQHandler
.thumb_set WWDGT_IRQHandler,Default_Handler
.weak LVD_IRQHandler
.thumb_set LVD_IRQHandler,Default_Handler
.weak TAMPER_STAMP_IRQHandler
.thumb_set TAMPER_STAMP_IRQHandler,Default_Handler
.weak RTC_WKUP_IRQHandler
.thumb_set RTC_WKUP_IRQHandler,Default_Handler
.weak FMC_IRQHandler
.thumb_set FMC_IRQHandler,Default_Handler
.weak RCU_CTC_IRQHandler
.thumb_set RCU_CTC_IRQHandler,Default_Handler
.weak EXTI0_IRQHandler
.thumb_set EXTI0_IRQHandler,Default_Handler
.weak EXTI1_IRQHandler
.thumb_set EXTI1_IRQHandler,Default_Handler
.weak EXTI2_IRQHandler
.thumb_set EXTI2_IRQHandler,Default_Handler
.weak EXTI3_IRQHandler
.thumb_set EXTI3_IRQHandler,Default_Handler
.weak EXTI4_IRQHandler
.thumb_set EXTI4_IRQHandler,Default_Handler
.weak DMA0_Channel0_IRQHandler
.thumb_set DMA0_Channel0_IRQHandler,Default_Handler
.weak DMA0_Channel1_IRQHandler
.thumb_set DMA0_Channel1_IRQHandler,Default_Handler
.weak DMA0_Channel2_IRQHandler
.thumb_set DMA0_Channel2_IRQHandler,Default_Handler
.weak DMA0_Channel3_IRQHandler
.thumb_set DMA0_Channel3_IRQHandler,Default_Handler
.weak DMA0_Channel4_IRQHandler
.thumb_set DMA0_Channel4_IRQHandler,Default_Handler
.weak DMA0_Channel5_IRQHandler
.thumb_set DMA0_Channel5_IRQHandler,Default_Handler
.weak DMA0_Channel6_IRQHandler
.thumb_set DMA0_Channel6_IRQHandler,Default_Handler
.weak ADC_IRQHandler
.thumb_set ADC_IRQHandler,Default_Handler
.weak CAN0_TX_IRQHandler
.thumb_set CAN0_TX_IRQHandler,Default_Handler
.weak CAN0_RX0_IRQHandler
.thumb_set CAN0_RX0_IRQHandler,Default_Handler
.weak CAN0_RX1_IRQHandler
.thumb_set CAN0_RX1_IRQHandler,Default_Handler
.weak CAN0_EWMC_IRQHandler
.thumb_set CAN0_EWMC_IRQHandler,Default_Handler
.weak EXTI5_9_IRQHandler
.thumb_set EXTI5_9_IRQHandler,Default_Handler
.weak TIMER0_BRK_TIMER8_IRQHandler
.thumb_set TIMER0_BRK_TIMER8_IRQHandler,Default_Handler
.weak TIMER0_UP_TIMER9_IRQHandler
.thumb_set TIMER0_UP_TIMER9_IRQHandler,Default_Handler
.weak TIMER0_TRG_CMT_TIMER10_IRQHandler
.thumb_set TIMER0_TRG_CMT_TIMER10_IRQHandler,Default_Handler
.weak TIMER0_Channel_IRQHandler
.thumb_set TIMER0_Channel_IRQHandler,Default_Handler
.weak TIMER1_IRQHandler
.thumb_set TIMER1_IRQHandler,Default_Handler
.weak TIMER2_IRQHandler
.thumb_set TIMER2_IRQHandler,Default_Handler
.weak TIMER3_IRQHandler
.thumb_set TIMER3_IRQHandler,Default_Handler
.weak I2C0_EV_IRQHandler
.thumb_set I2C0_EV_IRQHandler,Default_Handler
.weak I2C0_ER_IRQHandler
.thumb_set I2C0_ER_IRQHandler,Default_Handler
.weak I2C1_EV_IRQHandler
.thumb_set I2C1_EV_IRQHandler,Default_Handler
.weak I2C1_ER_IRQHandler
.thumb_set I2C1_ER_IRQHandler,Default_Handler
.weak SPI0_IRQHandler
.thumb_set SPI0_IRQHandler,Default_Handler
.weak SPI1_IRQHandler
.thumb_set SPI1_IRQHandler,Default_Handler
.weak USART0_IRQHandler
.thumb_set USART0_IRQHandler,Default_Handler
.weak USART1_IRQHandler
.thumb_set USART1_IRQHandler,Default_Handler
.weak USART2_IRQHandler
.thumb_set USART2_IRQHandler,Default_Handler
.weak EXTI10_15_IRQHandler
.thumb_set EXTI10_15_IRQHandler,Default_Handler
.weak RTC_Alarm_IRQHandler
.thumb_set RTC_Alarm_IRQHandler,Default_Handler
.weak USBFS_WKUP_IRQHandler
.thumb_set USBFS_WKUP_IRQHandler,Default_Handler
.weak TIMER7_BRK_TIMER11_IRQHandler
.thumb_set TIMER7_BRK_TIMER11_IRQHandler,Default_Handler
.weak TIMER7_UP_TIMER12_IRQHandler
.thumb_set TIMER7_UP_TIMER12_IRQHandler,Default_Handler
.weak TIMER7_TRG_CMT_TIMER13_IRQHandler
.thumb_set TIMER7_TRG_CMT_TIMER13_IRQHandler,Default_Handler
.weak TIMER7_Channel_IRQHandler
.thumb_set TIMER7_Channel_IRQHandler,Default_Handler
.weak DMA0_Channel7_IRQHandler
.thumb_set DMA0_Channel7_IRQHandler,Default_Handler
.weak EXMC_IRQHandler
.thumb_set EXMC_IRQHandler,Default_Handler
.weak SDIO_IRQHandler
.thumb_set SDIO_IRQHandler,Default_Handler
.weak TIMER4_IRQHandler
.thumb_set TIMER4_IRQHandler,Default_Handler
.weak SPI2_IRQHandler
.thumb_set SPI2_IRQHandler,Default_Handler
.weak UART3_IRQHandler
.thumb_set UART3_IRQHandler,Default_Handler
.weak UART4_IRQHandler
.thumb_set UART4_IRQHandler,Default_Handler
.weak TIMER5_DAC_IRQHandler
.thumb_set TIMER5_DAC_IRQHandler,Default_Handler
.weak TIMER6_IRQHandler
.thumb_set TIMER6_IRQHandler,Default_Handler
.weak DMA1_Channel0_IRQHandler
.thumb_set DMA1_Channel0_IRQHandler,Default_Handler
.weak DMA1_Channel1_IRQHandler
.thumb_set DMA1_Channel1_IRQHandler,Default_Handler
.weak DMA1_Channel2_IRQHandler
.thumb_set DMA1_Channel2_IRQHandler,Default_Handler
.weak DMA1_Channel3_IRQHandler
.thumb_set DMA1_Channel3_IRQHandler,Default_Handler
.weak DMA1_Channel4_IRQHandler
.thumb_set DMA1_Channel4_IRQHandler,Default_Handler
.weak ENET_IRQHandler
.thumb_set ENET_IRQHandler,Default_Handler
.weak ENET_WKUP_IRQHandler
.thumb_set ENET_WKUP_IRQHandler,Default_Handler
.weak CAN1_TX_IRQHandler
.thumb_set CAN1_TX_IRQHandler,Default_Handler
.weak CAN1_RX0_IRQHandler
.thumb_set CAN1_RX0_IRQHandler,Default_Handler
.weak CAN1_RX1_IRQHandler
.thumb_set CAN1_RX1_IRQHandler,Default_Handler
.weak CAN1_EWMC_IRQHandler
.thumb_set CAN1_EWMC_IRQHandler,Default_Handler
.weak USBFS_IRQHandler
.thumb_set USBFS_IRQHandler,Default_Handler
.weak DMA1_Channel5_IRQHandler
.thumb_set DMA1_Channel5_IRQHandler,Default_Handler
.weak DMA1_Channel6_IRQHandler
.thumb_set DMA1_Channel6_IRQHandler,Default_Handler
.weak DMA1_Channel7_IRQHandler
.thumb_set DMA1_Channel7_IRQHandler,Default_Handler
.weak USART5_IRQHandler
.thumb_set USART5_IRQHandler,Default_Handler
.weak I2C2_EV_IRQHandler
.thumb_set I2C2_EV_IRQHandler,Default_Handler
.weak I2C2_ER_IRQHandler
.thumb_set I2C2_ER_IRQHandler,Default_Handler
.weak USBHS_EP1_Out_IRQHandler
.thumb_set USBHS_EP1_Out_IRQHandler,Default_Handler
.weak USBHS_EP1_In_IRQHandler
.thumb_set USBHS_EP1_In_IRQHandler,Default_Handler
.weak USBHS_WKUP_IRQHandler
.thumb_set USBHS_WKUP_IRQHandler,Default_Handler
.weak USBHS_IRQHandler
.thumb_set USBHS_IRQHandler,Default_Handler
.weak DCI_IRQHandler
.thumb_set DCI_IRQHandler,Default_Handler
.weak TRNG_IRQHandler
.thumb_set TRNG_IRQHandler,Default_Handler
.weak FPU_IRQHandler
.thumb_set FPU_IRQHandler,Default_Handler