VSCode + GD32F407 構建燒錄

前言

? ? ? 最近調試一塊?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 = 1024KRAM   (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, #0b  LoopCopyDataInitCopyDataInit:ldr  r3, =_sidataldr  r3, [r3, r1]str  r3, [r0, r1]adds  r1, r1, #4LoopCopyDataInit:ldr  r0, =_sdataldr  r3, =_edataadds  r2, r0, r1cmp  r2, r3bcc  CopyDataInitldr  r2, =_sbssb  LoopFillZerobss
    /* Zero fill the bss segment. */  
    FillZerobss:movs  r3, #0str  r3, [r2]adds r2, r2, #4LoopFillZerobss:ldr  r3, = _ebsscmp  r2, r3bcc  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  mainbx  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_pfnVectorsg_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

    本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
    如若轉載,請注明出處:http://www.pswp.cn/pingmian/82886.shtml
    繁體地址,請注明出處:http://hk.pswp.cn/pingmian/82886.shtml
    英文地址,請注明出處:http://en.pswp.cn/pingmian/82886.shtml

    如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

    相關文章

    AI繪畫提示詞:從零開始掌握Prompt Engineering的藝術

    文章目錄 什么是AI繪畫提示詞?提示詞的基本結構主體描述場景/背景風格指定技術參數負面提示人物肖像模板風景模板 高級技巧權重調整混合風格顏色控制情緒氛圍 常見問題與解決方法手部變形問題構圖不理想風格不夠突出 提示詞示例庫科幻場景奇幻人物靜物畫 結語 在當今…

    在 Linux 上安裝 Minikube:輕松搭建本地 Kubernetes 單節點集群

    🔥「炎碼工坊」技術彈藥已裝填! 點擊關注 → 解鎖工業級干貨【工具實測|項目避坑|源碼燃燒指南】 一、Minikube 是什么? Minikube 是 Kubernetes 官方推出的輕量級工具,專為開發者設計,用于在本地快速搭建單節點 Kube…

    day41 python圖像識別任務

    目錄 一、數據預處理:為模型打下堅實基礎 二、模型構建:多層感知機的實現 三、訓練過程:迭代優化與性能評估 四、測試結果:模型性能的最終檢驗 五、總結與展望 在深度學習的旅程中,多層感知機(MLP&…

    JS數組 concat() 與擴展運算符的深度解析與最佳實踐

    文章目錄 前言一、語法對比1. Array.prototype.concat()2. 擴展運算符(解構賦值) 二、性能差異(大規模數組)關鍵差異原因 三、適用場景建議總結 前言 最近工作中遇到了一個大規模數組合并相關的問題,在數據合并時有些…

    一套qt c++的串口通信

    實現了創建線程使用串口的功能 具備功能: 1.線程使用串口 2.定時發送隊列內容,防止粘包 3.沒處理接收粘包,根據你的需求來,handleReadyRead函數中,可以通過m_receiveBuffer來緩存接收,然后拆分數據來處理 源碼 seri…

    設計模式-發布訂閱

    文章目錄 發布訂閱概念發布訂閱 vs 監聽者例子代碼 發布訂閱概念 發布/訂閱者模式最大的特點就是實現了松耦合,也就是說你可以讓發布者發布消息、訂閱者接受消息,而不是尋找一種方式把兩個分離 的系統連接在一起。當然這種松耦合也是發布/訂閱者模式最大…

    windows-cmd 如何查詢cpu、內存、磁盤的使用情況

    在 Windows 中,您可以使用命令提示符(CMD)通過一些命令來查詢 CPU、內存和磁盤的使用情況。以下是常用的命令和方法: 1. 查詢 CPU 使用情況 使用 wmic 命令 wmic cpu get loadpercentage 這個命令會顯示當前 CPU 的使用百分比…

    allWebPlugin中間件VLC專用版之截圖功能介紹

    背景 VLC控件原有接口具有視頻截圖方法,即video對象的takeSnapshot方法,但是該方法返回的是一個IPicture對象,不適合在谷歌等現代瀏覽器上使用。因此,本人增加一個新的視頻截圖方法takeSnapshot2B64方法,直接將視頻截圖…

    第Y5周:yolo.py文件解讀

    🍨 本文為🔗365天深度學習訓練營 中的學習記錄博客🍖 原作者:K同學啊 本次任務:將YOLOv5s網絡模型中的C3模塊按照下圖方式修改形成C2模塊,并將C2模塊插入第2層與第3層之間,且跑通YOLOv5s。 任務…

    寶塔安裝ssh證書報錯:/usr/bin/curl: symbol lookup error: curl_easy_header

    原因: 你當前的 curl 命令版本是 7.70.0(不是系統默認版本,應該是你手動安裝的)。它鏈接的是 /usr/local/lib/libcurl.so.4,而不是 CentOS 系統默認的 /usr/lib64/libcurl.so.4。/usr/local/lib/libcurl.so.4 很可能是…

    Apache SeaTunnel 引擎深度解析:原理、技術與高效實踐

    Apache SeaTunnel 作為新一代高性能分布式數據集成平臺,其核心引擎設計融合了現代大數據處理架構的精髓。 Apache SeaTunnel引擎通過分布式架構革新、精細化資源控制及企業級可靠性設計,顯著提升了數據集成管道的執行效率與運維體驗。其模塊化設計允許用…

    測試用例及黑盒測試方法

    一、測試用例 1.1 基本要素 測試用例(Test Case)是為了實施測試而向被測試的系統提供的一組集合,這組集合包含:測試環境、操作步驟、測試數據、預期結果等4個主要要素。 1.1.1 測試環境 定義:測試執行所需的軟硬件…

    硬件工程師筆記——運算放大電路Multisim電路仿真實驗匯總

    目錄 1 運算放大電路基礎 1.1 概述 1.1.1 基本結構 1.1.2 理想特性 1.2 運算放大分析方法 1.2.1 虛短 1.2.2虛斷 1.2.3 疊加定理 2 同向比例運算放大電路 2.1 概述 2.1.1 基本電路結構 2.1.2 電路原理 2.2 仿真分析 2.2.1 電壓增益 2.2.2 相位分析 3 反向比例運…

    板凳-------Mysql cookbook學習 (九)

    第4章:表管理 4.0 引言 MySQL :: 員工樣例數據庫 :: 3 安裝 https://dev.mysql.com/doc/employee/en/employees-installation.html Employees 數據庫與幾種不同的 存儲引擎,默認情況下啟用 InnoDB 引擎。編…

    MySQL省市區數據表

    數據結構簡單展示一下 具體的可以點擊文章最后的鏈接地址下載 連接地址中有兩個文件一個是詳細的另一個是簡潔的 SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS 0;-- ---------------------------- -- Table structure for ln_new_region -- ---------------------------- DROP…

    無人機報警器探測模塊技術解析!

    一、運行方式 1. 頻譜監測與信號識別 全頻段掃描:模塊實時掃描900MHz、1.5GHz、2.4GHz、5.8GHz等無人機常用頻段,覆蓋遙控、圖傳及GPS導航信號。 多路分集技術:采用多傳感器陣列,通過信號加權合并提升信噪比,…

    Oracle 導入導出 dmp 數據文件實戰

    一、DMP文件基礎知識?? 1. ??DMP文件定義?? DMP(Data Pump Dump File)是Oracle數據庫專用的二進制格式文件,由expdp/impdp或舊版exp/imp工具生成。它包含數據庫對象的元數據(表結構、索引等)和實際數據&#x…

    Coursier:安裝sbt

    命令 ./cs launch sbt -- --version 的含義是??通過 Coursier(cs)工具啟動 SBT(Scala 構建工具),并查詢其版本信息??。具體解析如下: ??1. 命令結構解析?? ??./cs??: 這是 Coursie…

    【深度學習】12. VIT與GPT 模型與語言生成:從 GPT-1 到 GPT4

    VIT與GPT 模型與語言生成:從 GPT-1 到 GPT4 本教程將介紹 GPT 系列模型的發展歷程、結構原理、訓練方式以及人類反饋強化學習(RLHF)對生成對齊的改進。內容涵蓋 GPT-1、GPT-2、GPT-3、GPT-3.5(InstructGPT)、ChatGPT …

    項目更改權限后都被git標記為改變,怎么去除

    ?問題描述: 當你修改了項目中的文件權限(如使用 chmod 改了可執行權限),Git 會把這些文件標記為“已更改”,即使內容并沒有發生任何改變。 ? 解決方法: ? 方法一:告訴 Git 忽略權限變化&am…