
先說個場景你用 STM32CubeIDE 2.2.0 配 Segger JLink程序編譯零報錯點下燒錄控制臺提示 Download 成功然后板子一點反應都沒有。沒有 LED 閃爍沒有外設動作萬用表量一下電源也是正常的。按一下板子上的復位鍵程序才開始跑。第一次遇到這種情況很多人會懷疑代碼有問題但代碼明明在 Keil 或者 IAR 下是正常的。這個現象就是典型的 “no reset/start after flashing”——燒錄完成后目標芯片沒有自動復位也沒有自動啟動執行程序。這個問題在 STM32CubeIDE 2.2.0 和 JLink 組合下非常常見尤其是從 Keil 轉過來的用戶特別容易踩中。Keil 的默認行為是燒錄完成后自動復位并運行但 CubeIDE 的調試啟動機制不一樣它默認把芯片停在復位向量入口等 GDB 指令如果啟動配置里沒勾選自動運行程序就一直停在原地看起來就像燒錄完沒啟動。這篇文章就把這個問題的底層機制、五種解法、排查套路一次講清楚。1. 問題現象與影響范圍不只是“沒跑起來”這么簡單1.1 三種典型表現燒錄后整個系統像“死”了我把這類問題按現象分一下方便你對號入座第一種是完全不動。燒錄成功芯片沒有任何反應按復位鍵才執行程序。這種情況通常說明復位序列根本沒執行或者 JLink 發出的復位信號被芯片忽略了。第二種是調試模式下停在某行代碼。比如燒錄完停在了main()入口或某個斷點處看起來像卡死其實只是 GDB 設置了斷點程序還沒運行。你如果點一下 Resume 或者按 F8程序就正常跑了。第三種比較隱蔽燒錄完程序在跑但跑一會兒就掛了。這種不完全是復位問題有可能是復位時序不正確導致外設初始化時序錯亂或者時鐘配置里用到了復位引腳對應的復用功能。這里要明確一個概念燒錄成功不等于程序運行。燒錄器只負責把固件寫進 Flash寫完之后要不要復位、要不要啟動完全取決于調試器配置和調試協議。JLink 在燒錄完成后會執行一個復位序列但如果配置的復位方式不適用于當前目標芯片或者當前接線方式復位就會失敗。1.2 為什么偏偏在 CubeIDE 2.2.0 上容易出問題STM32CubeIDE 2.2.0 是 2021 年左右的版本它內置的 JLink 調試插件和配套的 GDB Server 版本不算太老但如果你用的是新型號的 STM32U5、H7 甚至 G0 系列固件版本和調試插件之間就可能存在兼容性空白。更核心的原因是CubeIDE 的調試配置默認值偏向“停在入口等待調試”這和很多人習慣的“燒完就跑”完全不同。它在 Debug Configuration 里把“Behavior on connection”默認為 Reset 并停在 main同時 Startup 頁簽里的 Resume 選項默認不勾選。結果就是你燒完程序后芯片被復位并停在復位向量或 main 入口就是不肯自動運行。另外很多人使用的是 ST-Link 轉接后接 JLink 的 SWD 接線方式或者干脆沒有接 JLink 的 NRST 信號線。JLink 的 SWD 協議理論上只需要 SWDIO、SWCLK、GND 三根線就能燒錄但沒有 NRST 線時自動選擇復位類型會受到很大限制這一點我會在后面展開。2. 核心原因拆解JLink 復位到底是怎么工作的2.1 JLink 復位目標芯片的兩種途徑硬件復位與軟件復位要理解為什么會出現燒錄后不復位得先搞清楚 JLink 復位 MCU 的原理。JLink 復位目標芯片主要有兩條路第一條是硬件復位。JLink 通過其接口的 NRST 引腳Pin 15輸出一個低電平脈沖到目標芯片的 NRST 引腳強制芯片復位。這是最直接的復位方式和手按復位鍵一個道理。它的前提條件是 JLink 的 NRST 引腳和目標板的 NRST 引腳必須有一根實線連接而且目標芯片的 NRST 復位電路不能有異常比如接了大電容導致電平拉不下去。第二條是軟件復位。JLink 通過 SWD 協議向目標芯片的調試接口發送復位命令讓芯片內核執行復位操作。這種方式不需要 NRST 連線但對芯片的調試接口狀態有要求如果芯片已經進入低功耗模式或者調試接口被禁用軟件復位就發不進去需要配合“Connect under Reset”先把調試接口搶回來。IDE 在燒錄完成后的復位動作通常默認先嘗試硬件復位如果硬件復位失敗或者檢測不到目標芯片再切換軟件復位。這就是為什么有時候你能看到日志里有 “Reset: Failed” 或者 “Cannot reset target” 的報錯但燒錄本身卻是成功的。2.2 Debug Configuration 里的 Reset Type 四擋選項Normal、Type A、Type B、Type C在 STM32CubeIDE 的 Debug Configuration 中Debugger 頁簽下面有個Reset Type下拉框包含 Normal、Type A、Type B、Type C 四個選項。這個選項直接影響 JLink 與目標芯片連接和復位時的時序策略。它是 STM32CubeIDE 內置的 JLink 調試插件對外暴露的復位類型配置不同選項對應 JLink 內部不同的復位序列。Normal默認選項。JLink 按標準流程連接后復位目標。適用于絕大多數正常設計的板子但如果你沒接 NRST 線或者芯片的 NRST 引腳被配置成普通 GPIONormal 模式會失效。Type AJLink 在連接目標芯片期間拉低 NRST 引腳保持復位狀態然后通過 SWD 連接成功后釋放。這種方式適用于 NRST 引腳被復用為 GPIO、但 SWD 引腳仍然可用的場景很多 H7 和 F4 系列項目會用到。Type B類似 Type A但在復位釋放后會發送一個額外的復位脈沖常用于短復位脈沖需求的目標芯片比如某些對外部復位脈寬有最小時間要求的設計。Type CJLink 會先連接調試接口然后讓內核在異步復位狀態下停止常用于內核已經跑飛、需要強行拉回到調試狀態的場景。我實測下來如果是 STM32F1、F4 這類常規芯片優先推薦 Type A。Type A 對 NRST 接線缺失的情況兼容性最好不會因為復位失敗卡死啟動流程。Type C 雖然看起來最強大但它的啟動時序會讓部分外設初始化出現紊亂不適合作為常規默認項。2.3 容易被忽略的 Options BytesNRST 引腳被重新配置了除了 IDE 里的配置芯片本身的Option Bytes也會影響復位行為。STM32 的 Option Bytes 里有一組位叫nRST_MODE它決定 NRST 引腳的工作模式具體有四種組合nRST_MODENRST 功能BOR掉電復位0b00輸入 輸出默認使能0b01輸入 輸出關閉0b10僅輸入使能0b11僅輸入關閉如果芯片的 Option Bytes 被配置成 0b10 或 0b11NRST 引腳就變成了僅輸入模式JLink 通過 NRST 引腳發出去的低電平復位信號就無效了。這種情況往往不是用戶主動設置的而是某些燒錄工具在配置 Option Bytes 時順手改掉的。用 CubeProgrammer 燒錄時如果勾選了“Reset after programming”只影響燒錄后行為但如果在 Option Bytes 頁面誤改了 nRST_MODE那燒錄后不復位的現象就會出現。所以遇到不復位問題時不要只盯著 Debug Configuration 看還要用 STM32CubeProgrammer 讀一下 Option Bytes確認 nRST_MODE 是否被改成了“僅輸入”模式。如果是改回 0b00 再燒一次問題大概率就解決了。3. 實操解決讓程序燒錄后自動復位并啟動的六步方案3.1 第一步先檢查 Debug Configuration 的連線與復位配置打開 STM32CubeIDE選 Run Debug Configurations找到你當前工程的調試配置。在左側列表里選中你的配置右側切到Debugger頁簽。先確認Debug Probe是否選中了 Segger JLink而不是默認的 ST-LINK。有些項目從其他 IDE 導入后Debug Probe 會停留在 ST-LINK導致 JLink 根本沒參與復位。如果這里選錯了JLink 壓根不會啟動。然后看Reset Type按我前面說的建議改成Type A。如果你的板子 NRST 連了線、復位電路正常那 Normal 也能用如果沒接 NRST 線Type A 的成功率更高。Debug Probe 可能需要填設備名稱或序列號但一般情況下 CubeIDE 會自動掃描。如果掃描不到檢查 JLink 驅動是否安裝、USB 連接是否正常。3.2 第二步Startup 頁簽里勾上 Resume讓程序跑起來切到Startup頁簽這是“燒完不啟動”最直接的開關。你會看到啟動序列的列表包括 Load Image、Reset、Breakpoint 等步驟。在列表下方的Startup Options中有兩個關鍵選項Set breakpoint at: main默認勾選表示在 main 函數入口打斷點。這個斷點不是你手動設的是 GDB 自動設置的啟動斷點目的是一進 main 就暫停。要讓它不停取消勾選或者把斷點地址改成main之外的空閑地址不太推薦沒必要。Resume默認不勾選。這個選項的意思是“在啟動序列完成后繼續運行”。你需要手動勾上它程序才能在燒錄完成后自動運行否則芯片會一直停在復位向量或 main 入口看起來就是沒啟動。這一步是 90% 場景下解決“燒完不跑”的關鍵。很多人不知道 Startup 頁簽里有這個選項從頭到尾都只調 DFU、Flash Download 那邊的參數結果一直找不到原因。3.3 第三步Flash Download 里確保燒寫到內部 Flash 且加載了算法切到Flash Download頁簽確認勾選了Download to Flash并且Flash algorithm列表中已經為你的目標芯片添加了正確的編程算法。比如 F103 系列一般需要 STM32F10x Flash 算法如果這里空白或者只加載了外部 Flash 算法固件會燒到別處或者干脆沒燒進去程序自然啟動不了。如果算法列表為空點 Add 按鈕在彈出的窗口中選擇和你 MCU 系列匹配的 Flash 算法。注意單片機內部 Flash 的起始地址一般是 0x08000000Startup 頁簽里 Load Image 的地址也要對應別改成 0x8000000 這種漏一位的地址我見過有人把地址寫錯導致燒錄后每次都要重新上電才能跑。3.4 第四步遇到硬件復位失敗用 GDB 手動復位驗證如果做完前三步現象依舊那就要看是不是硬件復位鏈路本身有問題。最快的驗證方法是打開調試會話在 GDB Console 里輸入復位命令手動復位一次。從 Run Debug 啟動調試如果 IDE 停在某行代碼就在 GDB Console 里輸入monitor reset continue如果monitor reset執行后程序能跑起來說明 JLink 和目標芯片的復位鏈路沒問題是啟動配置里的自動復位參數不對。如果monitor reset直接報錯說明 JLink 根本沒法復位目標優先查硬件接線和 Option Bytes。GDB Console 默認可能沒顯示可以在 Window Show View Console 里打開然后從下拉列表里切到 GDB 調試控制臺。3.5 第五步檢查 JLink 固件和驅動版本STM32CubeIDE 2.2.0 內置的 JLink 驅動大概對應 Segger 的 6.80 左右。如果你用的是 JLink V9、V10、V11 等不同硬件版本或者目標芯片比較新舊驅動對復位時序的支持會有偏差。更新 JLink 驅動有兩種方式第一種是從 Segger 官網下載最新版的 J-Link Software and Documentation Pack安裝完成后在 CubeIDE 的 Window Preferences MCU 里找到 J-Link 相關的設置把安裝路徑指向新版的 JLink 安裝目錄。第二種是直接升級 JLink 固件。連接 JLink 到電腦然后啟動 Segger 的 J-Link Configurator或 JLink.exe它會提示固件版本太舊按提示升級即可。JLink 設備固件升級后對復位時序的兼容性會大幅改善尤其是老一點的 V8、V9 版本。這個步驟很多資料里沒強調但我實測下來JLink 固件太舊確實會導致 Type A/Type B 復位模式失效更新固件后異常消失。建議你把 JLink 固件升級到新版再配合前面幾步的配置基本不會出現燒錄后不復位的問題。3.6 第六步極端情況用外部工具輔助驗證如果 CubeIDE 里怎么調都不行別在 IDE 里死磕用 Segger 自帶的 JLink Commander 做獨立驗證。打開命令行進入 JLink 安裝目錄執行JLink.exe -device STM32F103C8 -if SWD -speed 4000 -autoconnect 1連接成功后會進入 JLink 命令行交互界面依次輸入r gr是復位目標芯片g是讓程序全速運行。如果這兩條命令執行后板子開始跑了說明問題一定在 CubeIDE 的調試配置層面。如果r命令本身就報錯那就回到硬件層面排查。注意 JLink 的命令行參數里-device要填你的具體型號-if填 SWD 或者 JTAG-speed不要一開始就拉太高4000 kHz 是個比較穩的起步值。速度太高尤其在飛線連接時容易造成時序不穩復位命令誤發或不生效。4. 排查實錄與常見問題速查4.1 從 GDB 日志判斷復位失敗的真正階段調試過程中GDB Console 會輸出大量日志很多人不看但其實里面藏著定位問題的關鍵。我舉兩個典型的日志示例情況一燒錄后日志里出現類似Resetting target... Reset: Failed Cannot reset target這說明 JLink 連接本身成功但復位動作失敗。優先檢查 NRST 接線、Options Bytes 的 nRST_MODE、以及 Reset Type 是否選對。此時把 Reset Type 從 Normal 改成 Type A大概率能過。情況二日志里出現Downloading 8192 bytes to 0x08000000 Load complete Breakpoint set at main沒有 Reset 相關報錯但程序不跑。這說明復位已經執行只是啟動序列停在了 main 斷點。這種情況到 Startup 頁簽勾上 Resume 或者取消 main 斷點就行。還有一種常見日志The firmware on the J-Link is too old. Please update直接按我前面第 3.5 節的方法升級 JLink 固件。4.2 常見問題速查表現象可能原因推薦排查方向燒錄成功但完全不動Reset Type 不匹配 / Startup 未勾 Resume / NRST 未接線改 Reset Type 為 Type A勾上 Startup 的 Resume檢查 NRST 連線燒錄停在 main 函數Startup 頁簽默認勾選了 main 斷點取消 main 斷點或勾選 Resume燒錄后需要手動按復位鍵才運行JLink 復位序列失效檢查 nRST_MODE Option Bytes用 JLink Commander 驗證復位GDB 日志報 Reset FailedNRST 接線異常 / nRST_MODE 僅輸入 / 固件太舊檢查接線恢復默認 Option Bytes升級 JLink 固件上電后程序在跑但燒錄后不跑Flash 地址不對 / Boot 引腳配置問題確認 Load Image 地址為 0x08000000檢查 BOOT0/BOOT1 電平調試模式下程序停住但按 Resume 能跑GDB 斷點停住檢查 Startup 頁簽的 Breakpoint 設置和 Resume 選項復位后程序啟動了但外設初始化異常復位時序不規范外設寄存器處于異常狀態改為軟件復位Monitor PC或徹底斷電重新上電這個表格基本覆蓋了我這些年遇到的大部分復位相關問題。你對照著找自己的現象一般五分鐘內能定位到問題。4.3 補充幾個容易踩的硬件層的坑配置全對的情況下問題可能出在硬件連接上。以下幾個是實際調試中經常遇到的坑一NRST 引腳虛焊或者被復用。很多用戶用的是核心板NRST 引腳上接了復位電容和上拉電阻但 JLink 的 NRST 線沒接只接了 SWDIO 和 SWCLK。這種接線方式下你選 Normal 復位模式基本是無效的因為 JLink 沒有通路把低電平送到 NRST 引腳。坑二SWDIO 被模擬復用功能占用。如果程序里把 SWDIOPA13或 SWCLKPA14配置成了普通 GPIO 輸出燒錄完成并復位后SWD 引腳立刻變成 GPIO調試器失去控制。這種情況下如果你選的復位類型依賴后續 SWD 通信就會失敗。解法是使用 Type A 或 Type B讓 JLink 在復位期間搶先連接調試接口。坑三目標板供電異常。JLink 的 VCCPin 1引腳是電壓檢測參考不是供電引腳。如果目標板沒有獨立供電或者 JLink 的 VCC 檢測線沒接JLink 會誤判目標電壓導致復位電平邏輯異常。確保目標板單獨供電且 JLink 的 VCC 引腳和目標板電源連接正常。坑四外部復位電容太大。有些板子為了讓復位穩定在 NRST 上接了 1uF 以上的電容。JLink 輸出的低電平脈寬不夠長電容沒放完電就恢復了復位根本沒生效。這種情況要么調長 JLink 的復位脈寬JLink Commander 里可以設置exec SetResetPulseWidth要么換小一點的電容。不過一般小板子都是 100nF這個坑在自制大電容復位電路上比較常見。4.4 為什么換了 Keil 就沒問題換 CubeIDE 就復現這是被問得最多的問題“Keil 燒完就能跑CubeIDE 燒完不跑是不是 CubeIDE 的 Bug”不是 Bug是兩套工具的默認行為不同。Keil 的 Flash Download 頁面里有個默認勾選的 “Reset and Run”燒錄完成后自動復位并全速運行。CubeIDE 的調試哲學是“燒錄和調試一體”它默認你在調試器里需要停在斷點等待你操作。所以 CubeIDE 不會默認執行“燒完就跑”而是停在 main 等 GDB 命令。如果你用 CubeIDE 只是想燒錄程序、不想調試那你要做的不是點 Debug 按鈕而是配置好 Debug Configuration 后把 Startup 頁簽的 main 斷點取消、Resume 勾上這樣行為就接近 Keil 的 “Reset and Run” 了。或者干脆用 STM32CubeProgrammer 進行燒錄它默認在燒錄完成后會有一個復位運行的選項和 Keil 行為一致。搞清楚這個設計邏輯之后你就不容易再被類似問題困住了。5. 一些實際操作中的個人體會寫到最后分享一下我做嵌入式開發這幾年在復位問題上的經驗。我現在的調試配置模板是這樣的Reset Type 選 Type ABehavior on connection 選 ResetStartup 頁簽取消 main 斷點并勾選 ResumeFlash Download 勾選 Download to FlashFlash algorithm 選擇與 MCU 匹配的型號。這套組合在我手上的 F1、F4、G0、H7 都驗證過燒錄后的自動復位和自動啟動基本沒出過問題。還有一點心得排查復位問題時要學會用 Segger 的 JLink Commander 做隔離測試。IDE 里配置項太多變量太多直接在 JLink 命令行里敲r、g能一步判斷問題到底出在 CubeIDE 配置還是出在硬件接線。我遇到過好幾次IDE 里折騰兩小時沒搞定切到 JLink 命令行發現是 NRST 線接觸不良重新拔插一下就恢復正常。工具越底層排錯越高效。另外如果你現在用的是 STM32CubeIDE 2.2.0建議升級到 2.15.0 或者更新版本。新版內置的 JLink 插件對各類 MCU 的復位時序處理得更完善UI 也順手很多。當然如果因故只能用 2.2.0按本文第 3 節的方法一樣能解決。