
拿到一塊STM32MP235的核心板接上電源串口線連好波特率設(shè)置成115200打開終端上電——終端里一片空白。這就是“STM32MP235 fails to boot”最經(jīng)典的開場白。STM32MP235是ST第二代MPU產(chǎn)品線里的一員基于Arm Cortex-A35應(yīng)用處理器和Cortex-M33實時內(nèi)核的異構(gòu)架構(gòu)面向工業(yè)網(wǎng)關(guān)、智能顯示、物聯(lián)網(wǎng)邊緣設(shè)備這些場景。和第一代STM32MP1系列相比它在安全啟動、電源管理、外設(shè)隔離上做了不少強化但也正因為這些強化啟動鏈路變得更長排查啟動失敗的復(fù)雜度也跟著上來了。這篇文章圍繞我實際調(diào)試STM32MP235啟動失敗的過程把從硬件檢查到軟件配置的完整排查思路拆開講清楚給正在被這塊芯片折騰的工程師一點參考。1. 啟動失敗先別慌把STM32MP235的啟動鏈路拆開看STM32MP235這類MPU的啟動過程和單片機完全是兩碼事。玩過STM32單片機的朋友都知道上電之后從Flash的某個固定地址開始執(zhí)行指令搞個Bootloader也無非是IAP跳轉(zhuǎn)。但到了MPU這一級芯片內(nèi)部沒有大容量的可執(zhí)行Flash程序運行所依賴的外部DDR內(nèi)存顆粒在上電的瞬間也還沒有完成初始化CPU連代碼都沒地方放所以必須有一個分階段加載的過程。1.1 BootROM這一步到底干了什么芯片出廠時固化了一段不可修改的BootROM代碼上電后CPU的第一條指令就從BootROM開始執(zhí)行。BootROM的任務(wù)是先把最小系統(tǒng)跑起來——內(nèi)核時鐘、基礎(chǔ)電源域、啟動介質(zhì)對應(yīng)的接口控制器——然后根據(jù)BOOT引腳的組合電平或者OTP區(qū)域里燒寫的配置從SD卡、eMMC、NOR Flash、NAND Flash、USB、UART這些介質(zhì)中選擇一個啟動源把第一級引導(dǎo)程序FSBLFirst Stage Boot Loader加載到芯片內(nèi)部的SRAM里再跳轉(zhuǎn)過去執(zhí)行。這里有一個很多人第一次接觸時會踩的坑BootROM不像PC的BIOS那樣去理解分區(qū)表更不會去FAT32文件系統(tǒng)里尋找什么引導(dǎo)文件它是直接到固定偏移地址去讀取原始二進制鏡像的。你隨手拿一張SD卡格式化成FAT32把編譯好的TF-A鏡像文件復(fù)制進去插到板子上結(jié)果一定是什么反應(yīng)都沒有。BootROM要的是鏡像被燒寫到特定扇區(qū)偏移處的原始數(shù)據(jù)這個細節(jié)后面我會用一整章展開講。1.2 TF-A、OP-TEE、U-Boot、內(nèi)核誰接誰的班FSBL在ST的官方方案里通常就是Arm Trusted Firmware-ATF-A。TF-A運行后先初始化外部DDR內(nèi)存控制器配置電源管理把外設(shè)需要的時鐘補齊然后從同一個啟動介質(zhì)里加載FIPFirmware Image Package鏡像包。FIP里打包了OP-TEEBL32和U-BootBL33這兩個后續(xù)階段的鏡像。OP-TEE負責(zé)提供安全世界運行環(huán)境U-Boot作為第二級引導(dǎo)程序初始化設(shè)備樹、外設(shè)、網(wǎng)絡(luò)、顯示這些硬件功能設(shè)置bootargs最后把Linux內(nèi)核加載進內(nèi)存并跳轉(zhuǎn)執(zhí)行。你可以把這條鏈路理解成接力賽BootROM把第一棒交給TF-ATF-A把第二棒交給FIP里的OP-TEE和U-BootU-Boot再交給內(nèi)核。每一棒都有自己明確的職責(zé)邊界和日志輸出鏈條上任何一棒出了問題表現(xiàn)就是系統(tǒng)死在那個階段并打印對應(yīng)的錯誤日志——或者干脆連日志都沒有。1.3 用串口日志判斷“死在哪個環(huán)節(jié)”排查boot失敗的第一步永遠是先看日志停在哪個階段。我當(dāng)時調(diào)試這塊板卡串口終端上最后一行打到了TF-A的DDR初始化相關(guān)輸出之后就再無動靜那基本可以把問題鎖定在DDR配置或者后續(xù)FIP加載上。如果日志連TF-A的版本信息都沒打出來問題大概率在更前面要么BootROM沒找到有效的FSBL鏡像要么FSBL在加載階段就被硬件問題卡住了。我習(xí)慣把日志分成幾個區(qū)間來看完全靜默、只能看到BootROM早期輸出、TF-A開始打印、U-Boot開始打印、內(nèi)核早期打印。每個區(qū)間對應(yīng)不同的排查方向。用日志分段定位的方法比悶頭去翻原理圖高效得多也更容易向同事或者原廠FAE描述問題現(xiàn)狀。2. 上電后完全沒反應(yīng)硬件層面的排查順序如果遇到的是完全沒有任何串口輸出的情況不要急著懷疑軟件配置先老老實實回到硬件上查。嵌入式調(diào)試?yán)锵喈?dāng)大比例的“完全不啟動”都是由硬件層面的小問題引起的而且這些問題往往發(fā)生在你意想不到的地方。2.1 電源軌和時序先從萬用表量起STM32MP235這種MPU的電源軌數(shù)量遠超單片機核心供電、DDR供電、IO供電、模擬供電經(jīng)常是分開的獨立電源軌。上電之后第一件事拿萬用表逐路測量各路電壓是否正常特別是DDR供電和核心電壓。我遇到過一塊板子核心電壓紋波偏大常溫下一切正常溫度一上來就啟動失敗最后用示波器盯DDR電源的紋波才發(fā)現(xiàn)是濾波電容位置不對導(dǎo)致的。比電壓數(shù)值更隱蔽的是電源時序問題。MPU通常要求各路電源按特定順序上電比如先給VDD再給核心電壓如果電源管理芯片的配置不對就會出現(xiàn)上電順序顛倒。這種問題在廠商做好的核心板上很少見但在自己畫板子的時候是高發(fā)區(qū)。排查的時候拿示波器同時測幾路電源的上電波形和復(fù)位信號釋放點和參考手冊里的時序圖逐項對照基本能確認是不是時序問題。2.2 BOOT引腳撥碼開發(fā)板上的“啟動源選擇開關(guān)”很多開發(fā)板或者核心板上會有一組撥碼開關(guān)或者跳線用來選擇啟動源。STM32MP235和MP1系列類似通過BOOT引腳的組合電平來確定是從SD卡、eMMC、USB、UART還是其他介質(zhì)啟動。我犯過一個特別低級的錯誤為了用STM32CubeProgrammer燒錄鏡像把啟動模式切到了USB燒完之后忘了撥回SD卡啟動上電當(dāng)然起不來串口一點輸出都沒有。排查了半天最后發(fā)現(xiàn)只是撥碼開關(guān)沒撥回去。這個事聽起來蠢但實際工程中真的很容易發(fā)生因為你永遠不知道上一手調(diào)試的人把開關(guān)留在了什么位置。所以第一步應(yīng)該做的是對照板子原理圖確認當(dāng)前BOOT引腳電平對應(yīng)的實際啟動源同時明確測試目標(biāo)——我們到底想讓板子從哪個介質(zhì)啟動。調(diào)試排障期間每次上電之前都確認一下啟動模式撥碼的實際檔位這個習(xí)慣能替你省下大量的無效排查時間。2.3 時鐘與復(fù)位HSE晶振和NRST的隱蔽問題MPU啟動依賴外部高速時鐘HSEBootROM要起內(nèi)部PLL時鐘源如果沒起振后面全免談。我見過一個案例晶振虛焊示波器點上沒有波形BootROM把時鐘配置成錯誤狀態(tài)系統(tǒng)直接卡死。對于量產(chǎn)板貼片晶振的匹配電容值不對也會導(dǎo)致起振困難或者頻率偏差這些問題在低溫環(huán)境下表現(xiàn)更明顯。復(fù)位信號同樣值得關(guān)注。正常情況下上電時NRST引腳應(yīng)該有一次拉低再釋放的過程用示波器抓一下如果復(fù)位引腳一直被鉗在低電平說明外部復(fù)位電路異常或者有看門狗在反復(fù)復(fù)位芯片。反復(fù)復(fù)位這種情況很有迷惑性從日志上看像是“每次都啟動到同一個位置就死了”實際上是芯片被復(fù)位打斷又重新啟動形成了循環(huán)。遇到日志反復(fù)重演的情況記得先確認復(fù)位信號有沒有問題。2.4 調(diào)試串口型號與電平日志沒出來之前先確認通道串口是MPU調(diào)試最重要的通道但很多人栽在串口本身。首先確認調(diào)試串口用的是哪一組UARTSTM32MP235的官方開發(fā)板一般會把調(diào)試串口引到固定的引腳上但你自己設(shè)計的板子可能完全不同必須看原理圖確認。其次確認電平板上是否有USB轉(zhuǎn)串口芯片還是直接引出的TTL電平兩種情況接線方式完全不同。再有就是波特率常見的是115200 8N1但有些板子在引導(dǎo)階段可能用更低速率或者引導(dǎo)程序和內(nèi)核階段使用不同波特率遇到日志中斷可以試著換幾個波特率看看。我當(dāng)時調(diào)試的時候一度以為板子完全沒啟動后來發(fā)現(xiàn)是USB轉(zhuǎn)串口線壞了換了一根線馬上有日志輸出。排查的第一步永遠是把串口通道驗證好——可以把串口的TX和RX短接做自發(fā)自收測試確認通路沒問題再往下查設(shè)備。3. 有日志但卡在初始化FSBL與信任鏈的定位方法硬件排查是“外功”FSBL及后續(xù)階段的日志分析就是“內(nèi)功”。接下來專門講有日志輸出但系統(tǒng)初始化不通過的情況這種情況在啟動失敗里占比最高因為硬件問題往往比較直觀而啟動鏈路各階段的配置問題則需要結(jié)合日志逐層定位。3.1 日志卡在哪個函數(shù)問題就鎖定在哪個模塊TF-A啟動過程中會在串口輸出一系列NOTICE和ERROR信息。比如初始化DDR之前會有對應(yīng)的內(nèi)存檢測日志加載FIP之前會有介質(zhì)讀取的信息。如果你的日志停在了DDR初始化相關(guān)的位置那就應(yīng)該把目光集中在DDR這一塊而不是跑到U-Boot的配置里去找原因。我當(dāng)時調(diào)試手頭這塊STM32MP235板卡時日志停在了TF-A BL2階段的早期大概是在初始化DDR的地方。TF-A打印了DDR初始化相關(guān)的信息但后續(xù)沒有出現(xiàn)正常的FIP加載輸出。這說明TF-A認為DDR初始化失敗了或者初始化之后回讀校驗不過。這類問題多半和DDR顆粒型號、DDR初始化參數(shù)、PCB布線質(zhì)量有關(guān)。3.2 DDR初始化失敗的典型日志和排查DDR初始化是整個啟動鏈路中最容易出問題的環(huán)節(jié)之一。MPU的外部DRAM不是插上就能用的要根據(jù)顆粒型號、容量、位寬、時序參數(shù)做一整套寄存器配置。TF-A里編譯進去的DDR配置如果和實際顆粒不匹配輕則初始化失敗重則初始化流程能過但系統(tǒng)一跑就隨機死機。典型的日志長這樣NOTICE: BL2: v2.10-stm32mp2-r1 (stm32mp235) NOTICE: BL2: Built : 09:30:00, May 20 2025 NOTICE: BL2: DDR memory init... ERROR: DDR memory configuration failed排查DDR問題時先核對板子上實際使用的DDR顆粒和參考設(shè)計是否一致再核對TF-A里對應(yīng)DDR初始化文件中的參數(shù)容量、位寬、頻率、時序參數(shù)。STM32CubeMX在生成工程時會根據(jù)選擇的板卡自動帶入DDR配置但如果核心板是你自己設(shè)計的這部分必須認真手工核對尤其是PHY校準(zhǔn)相關(guān)的參數(shù)很容易因為PCB走線的細微差異導(dǎo)致失敗。3.3 簽名與OTPMP2新增的安全約束STM32MP2系列比MP1在安全啟動上強化了不少。如果OTP區(qū)域已經(jīng)燒寫了強制安全啟動的配置那么BootROM只會加載帶有效簽名的FSBL任何未簽名或者簽名校驗失敗的鏡像都會直接拒絕啟動。這類問題的特征很明顯BootROM可能有打印TF-A完全不出現(xiàn)或者TF-A打印了簽名校驗失敗的ERROR信息。排查時先確認當(dāng)前芯片的OTP配置狀態(tài)STM32CubeProgrammer可以讀取OTP。開發(fā)階段如果不是在聯(lián)調(diào)安全啟動我建議不要把OTP的安全啟動使能位提前燒進去。一旦燒進去之后每次調(diào)試都要面對鏡像簽名問題嚴(yán)重拖慢開發(fā)節(jié)奏。而且OTP是一次性可編程的燒錯了不能改回來這個教訓(xùn)在很多項目里都出現(xiàn)過。3.4 用STM32CubeMX重建FSBL和FIP當(dāng)FSBL相關(guān)配置可疑時重建一套干凈的FSBL和FIP通常比在舊配置上猜來猜去更高效。STM32CubeMX支持為STM32MP2系列生成TF-A、OP-TEE、U-Boot的整套工程模板生成之后編譯產(chǎn)出TF-A二進制、FIP鏡像再用ST官方工具燒進啟動介質(zhì)。這一步的關(guān)鍵是選對CubeMX版本和固件包版本。某些早期的MP2固件包存在已知的啟動問題升級到最新版可能就解決了。我遇到過一次情況用老版本固件包生成的TF-A在MP235上啟動時掛掉換成新版本固件包重新生成后一次通過。ST在MP2系列上的迭代很快保持工具鏈和固件包更新是降低啟動排障成本的重要一環(huán)。4. 啟動源和燒錄鏡像SD卡、eMMC的分區(qū)與偏移真相有日志、硬件也沒問題但系統(tǒng)就是起不來這時候十有八九是啟動介質(zhì)里的鏡像布局不對。這節(jié)專門講SD卡、eMMC這類啟動介質(zhì)的分區(qū)布局和燒錄細節(jié)也是STM32MP235啟動失敗里最容易忽略的一塊。4.1 BootROM找鏡像不看分區(qū)表只看偏移這是嵌入式MPU和PC最大的不同。PC的UEFI固件會去掃描GPT分區(qū)表里的ESP分區(qū)尋找bootloader文件而STM32MP235的BootROM不會解析任何復(fù)雜的文件系統(tǒng)它是直接尋址讀取SD卡或eMMC上某個固定偏移處的原始二進制數(shù)據(jù)。以STM32MP1系列為參考FSBL鏡像位于SD卡的某個固定扇區(qū)偏移隨后緊跟的是FIP鏡像位置。MP2系列的具體偏移以官方參考手冊為準(zhǔn)不同系列、不同版本之間可能有差異。很多人第一次接觸時把SD卡插到電腦上格式化成FAT32把TF-A和FIP文件拷貝進去再把SD卡插回板子然后發(fā)現(xiàn)啟動失敗——原因就是BootROM根本不認識FAT32文件系統(tǒng)里的文件它只去固定位置找原始數(shù)據(jù)。想驗證很簡單用十六進制工具直接查看SD卡對應(yīng)偏移區(qū)間的數(shù)據(jù)如果看到的不是二進制鏡像內(nèi)容而是一堆FAT文件系統(tǒng)標(biāo)記說明鏡像根本沒寫對地方。4.2 用STM32CubeProgrammer安全的燒錄流程STM32CubeProgrammer是ST官方的燒錄工具也是處理STM32MP235啟動失敗時繞不開的利器。它可以燒寫SD卡、eMMC、NOR等啟動介質(zhì)也可以操作OTP、讀取芯片信息。標(biāo)準(zhǔn)燒錄流程大致是準(zhǔn)備好一個包含flashlayout文件的工程目錄flashlayout里定義了FSBL、FIP等鏡像要寫到哪些偏移位置把目標(biāo)板BOOT撥碼切到USB啟動或UART/ST-LINK模式取決于開發(fā)板設(shè)計用USB線連接PC和目標(biāo)板在STM32CubeProgrammer里選擇對應(yīng)接口和配置文件執(zhí)行下載。燒錄完成后把撥碼切回正常啟動源復(fù)位板子。這里容易被忽略的細節(jié)是外部加載器External Loader的選擇。如果板子上用的是eMMC需要選擇對應(yīng)的eMMC加載器文件如果加載器選錯燒錄工具可能無法正確識別存儲介質(zhì)或者燒錄進去之后BootROM依然無法正常讀取。4.3 PC的“no boot device”和MPU的“啟動失敗”其實是一回事前面提到的“no boot device found.press any key to reboot the machine”這類PC啟動報錯在MPU世界里對應(yīng)的就是BootROM把可用的啟動源都嘗試了一遍但沒找到有效的FSBL鏡像。PC上會給出明確的英文提示而STM32MP235的BootROM通常不會輸出這么人性化的話往往就是安靜地失敗。理解這一點對調(diào)試很有幫助如果你把啟動介質(zhì)拔掉或者介質(zhì)里FSBL偏移處是空的板子就處于這種“找不到啟動設(shè)備”的狀態(tài)。所以當(dāng)板子完全靜默無日志時先假設(shè)它處于這種狀態(tài)然后檢查鏡像是否真的被寫進了正確的介質(zhì)偏移位置比反復(fù)懷疑硬件更有效。4.4 燒錄后第一次啟動失敗的常見原因燒錄流程本身顯示成功但啟動還是失敗這種情況也經(jīng)常遇到。我總結(jié)過幾個高頻原因第一燒錄時選擇了錯誤的flashlayout文件或加載器導(dǎo)致FSBL實際被寫到了錯誤偏移第二燒錄后啟動模式撥碼沒有切回正確的啟動源第三鏡像和芯片型號不匹配比如用了STM32MP1系列或者其他型號的FSBL去啟動MP235相互之間不兼容第四eMMC或SD卡的接口電壓配置與BootROM的默認配置不一致導(dǎo)致BootROM無法穩(wěn)定讀取介質(zhì)。這些問題的共同特征在于燒錄工具顯示編程完成但啟動日志完全靜默或者只有極少輸出。遇到這種情況先不要反復(fù)燒錄停下來核對三件事鏡像對不對、偏移對不對、啟動源對不對。5. 我總結(jié)的快速定位清單與避坑經(jīng)驗前面幾章把STM32MP235啟動失敗的主要排查方向都過了一遍最后這部分是我個人的總結(jié)整理成了一套可以直接照著做的排查清單以及一些容易踩的坑。5.1 五分鐘快速定位法確認調(diào)試串口通道本身是通的線纜、電平、波特率都檢查一遍確認啟動模式撥碼或OTP選中的啟動源和預(yù)期一致上電觀察是否有任何串口輸出完全沒有輸出就先測電源、時鐘、復(fù)位有早期輸出但卡住把日志定格對照TF-A各階段標(biāo)志信息確認卡點卡在鏡像加載相關(guān)階段用STM32CubeProgrammer重新燒錄正確偏移的鏡像燒錄后仍失敗換一套干凈的STM32CubeMX生成工程排除配置污染。這套順序基本覆蓋了從硬件到軟件的完整排查鏈路按序執(zhí)行能在短時間內(nèi)把問題范圍縮小到具體模塊。5.2 容易被忽略的細節(jié)有幾個細節(jié)是踩過坑之后才格外注意的列出來給大家提個醒開發(fā)板自帶的SD卡可能已經(jīng)燒錄過一套舊鏡像直接使用前先確認鏡像版本是否匹配當(dāng)前板卡某些核心板是通過電阻配置BOOT引腳而不是撥碼開關(guān)換板子時一定要重新看原理圖STM32MP2系列的電源域劃分比MP1更細如果軟件里配置了不支持的電源狀態(tài)啟動可能卡在電源管理初始化串口調(diào)試默認波特率各階段可能不同某些情況下需要嘗試多個波特率才能看到完整日志OTP配置是不可逆的開發(fā)階段不要隨意燒OTP尤其是安全相關(guān)選項。5.3 資料查找路線與參考手冊用法STM32MP235的資料查找我推薦優(yōu)先看ST官方的Reference Manual中的Boot章節(jié)、STM32CubeMP2固件包里的Docs目錄以及ST官方Wiki。很多啟動問題在官方Wiki上能找到對應(yīng)的說明或已知問題記錄。另外ST在Github上的tf-a、u-boot倉庫的commit記錄里也經(jīng)常能翻到針對特定啟動問題的修復(fù)值得花時間搜一搜。最后說一個我在實際調(diào)試中的體會遇到啟動失敗不要急著懷疑芯片壞了。STM32MP235這種復(fù)雜度遠超單片機的平臺啟動失敗幾乎總是由可復(fù)現(xiàn)的配置問題引起的。按照“串口通道 → 啟動源 → 電源時鐘復(fù)位 → 鏡像偏移 → 信任鏈 → DDR配置”這樣的順序來排查絕大多數(shù)問題都能在半小時內(nèi)定位到真正的根因。我當(dāng)時那塊板子最后查出來就是FIP鏡像里打包的U-Boot版本和TF-A版本不匹配導(dǎo)致啟動鏈在傳遞環(huán)節(jié)崩潰重新生成一套版本匹配的鏡像組合之后一切恢復(fù)正常。