環(huán)境搭建與配置實戰(zhàn)指南)
1. 嵌入式開發(fā)環(huán)境搭建的起點(diǎn)搞嵌入式開發(fā)繞不開的第一個坎就是裝工具鏈。不管你后面是要點(diǎn)燈、調(diào)串口、跑RTOS還是搞USB協(xié)議棧第一步永遠(yuǎn)是讓編譯器和調(diào)試器在電腦上跑起來。MDK-ARM 5大家更習(xí)慣叫它Keil 5就是ARM Cortex-M系列MCU開發(fā)里用得最廣的一個集成開發(fā)環(huán)境沒有之一。它把編輯器、編譯器、鏈接器、調(diào)試器、燒錄工具全部打包在一起裝完之后基本可以做到“開箱即用”不需要你再去手動拼湊GCC、OpenOCD、GDB那一套。這篇內(nèi)容適合誰看如果你是剛?cè)胄械那度胧叫率质掷锬弥粔KSTM32或者GD32的開發(fā)板完全不知道從哪下手那這篇就是寫給你的。如果你是從IAR或者老版本Keil 4遷移過來的老手也可以看看里面關(guān)于Pack Installer和器件支持包的細(xì)節(jié)能幫你少走彎路。我會從下載、安裝、激活、器件包管理、工程創(chuàng)建、編譯配置、調(diào)試器設(shè)置這幾個環(huán)節(jié)一步步拆開講把每個步驟背后的原因也一并說清楚讓你不只是“照著點(diǎn)”而是真正理解這套工具鏈?zhǔn)窃趺催\(yùn)轉(zhuǎn)的。需要提前說明的是Keil 5和Keil 4最大的區(qū)別在于器件支持包Device Family Pack簡稱DFP的引入。Keil 4時代你裝一個版本就固定支持那幾家的芯片想換芯片型號往往要重裝或者打補(bǔ)丁。Keil 5把內(nèi)核、編譯器、器件支持徹底解耦了IDE本體只負(fù)責(zé)框架具體芯片的支持通過Pack Installer在線下載。這個設(shè)計思路很像現(xiàn)代瀏覽器的插件機(jī)制好處是靈活壞處是新手第一次裝完之后發(fā)現(xiàn)“怎么找不到我的芯片”其實只是包沒裝而已。2. 安裝前的準(zhǔn)備工作與版本選擇2.1 安裝包從哪里獲取Keil MDK-ARM 5的官方安裝包只有一個來源就是Keil官網(wǎng)現(xiàn)在歸屬Arm旗下。搜索“MDK-ARM”就能找到下載頁面填寫一個簡單的表單姓名、郵箱、公司、國家之后就能拿到下載鏈接。安裝包是一個大概800MB到1GB左右的exe文件版本號格式類似MDK537.exe這種前面的5代表Keil 5后面的數(shù)字是具體版本。這里有個經(jīng)驗不建議盲目追最新版本。我踩過的坑是某些新版本剛發(fā)布時對老器件的支持包兼容性會有問題尤其是那些已經(jīng)停產(chǎn)的Cortex-M0/M3老芯片。如果你做的是新項目用最新版沒問題如果是維護(hù)老項目建議用比項目立項時間晚半年到一年的版本穩(wěn)定性最好。比如項目是2020年做的用MDK 5.30到5.33這個區(qū)間通常比較穩(wěn)。另外要注意官網(wǎng)下載的是MDK-ARM完整版不是那個免費(fèi)的MDK-Lite。完整版安裝后如果不激活會以Lite模式運(yùn)行代碼大小限制在32KB。對于學(xué)習(xí)點(diǎn)燈、串口收發(fā)這種小工程完全夠用但一旦你的工程超過32KB編譯就會報錯。所以后面激活這一步是必須做的。2.2 系統(tǒng)環(huán)境要求Keil 5對系統(tǒng)要求不算高但也有幾個硬性條件項目最低要求推薦配置操作系統(tǒng)Windows 7 SP1Windows 10/11 64位處理器1GHz2GHz以上多核內(nèi)存2GB8GB以上硬盤空間2GB可用10GB以上Pack包很占地方顯示器1024x7681920x1080特別提醒兩點(diǎn)。第一安裝路徑絕對不要帶中文和空格。默認(rèn)路徑是C:\Keil_v5這個就很好別手賤改成D:\我的軟件\Keil 5后面編譯時各種莫名其妙的路徑錯誤能把你逼瘋。第二如果你電腦上已經(jīng)裝了Keil 4或者更早的版本建議先卸載干凈再裝Keil 5兩個版本共存雖然理論上可以但注冊表里的編譯器路徑會打架導(dǎo)致編譯時調(diào)用了錯誤的armcc。2.3 安裝過程中的關(guān)鍵選項雙擊安裝包之后前面幾步都是常規(guī)的下一步到了選擇組件的界面要留意一下。安裝程序會列出幾個可選項Core核心組件必裝包含IDE本體和ARM編譯器。Device Specific器件相關(guān)的示例和庫可以不裝后面用Pack Installer按需下載。Pack Installer器件包管理器必裝這是Keil 5的靈魂。CMSISARM官方的一套軟件接口標(biāo)準(zhǔn)建議裝很多庫依賴它。我的建議是Core、Pack Installer、CMSIS三個勾上Device Specific不勾。原因很簡單Device Specific里預(yù)置的那些示例工程往往版本很老你后面從Pack Installer下載的才是最新的裝了反而占地方還容易混淆。安裝過程大概需要5到10分鐘取決于硬盤速度。裝完之后第一次啟動IDE會提示你安裝Pack這時候先別急著裝把激活搞定再說。3. 激活與License管理3.1 為什么必須激活前面說了不激活就是Lite模式32KB代碼限制。這個限制在什么概念呢一個簡單的HAL庫點(diǎn)燈工程編譯出來大概6到8KB加上串口打印、定時器、中斷可能到15KB一旦你上了RTOS或者USB協(xié)議棧輕松突破32KB。所以只要你不是純粹玩玩激活是必須的。激活需要申請一個License。Keil提供幾種License類型個人學(xué)習(xí)可以申請免費(fèi)的社區(qū)版Community Edition商業(yè)用途需要購買。社區(qū)版的申請流程很簡單在Keil官網(wǎng)注冊賬號填寫用途說明一般幾個工作日內(nèi)會收到License文件。3.2 激活操作步驟拿到License之后打開Keil 5點(diǎn)擊菜單欄的File-License Management會彈出一個對話框。對話框里有一個CIDCustomer ID字段這是一串基于你電腦硬件生成的唯一標(biāo)識。把CID復(fù)制出來粘貼到Keil官網(wǎng)的License申請頁面提交后會生成一個License字符串再把它粘貼回對話框的New License ID Code輸入框點(diǎn)擊Add LIC就完成了。注意CID是和電腦硬件綁定的換主板或者重裝系統(tǒng)后CID會變需要重新申請License。所以建議把License文件備份好換系統(tǒng)后直接重新添加即可。激活成功后對話框上方會顯示License的過期日期和代碼大小限制看到Unlimited就說明搞定了。3.3 常見激活問題有時候添加License會提示“Invalid License”大概率是CID復(fù)制時帶了空格或者換行。解決方法是把CID粘貼到記事本里確認(rèn)是一串連續(xù)的字符再復(fù)制過去。還有一種情況是License已經(jīng)綁定到其他電腦了社區(qū)版一般允許綁定兩臺設(shè)備如果超了需要先在官網(wǎng)解綁舊設(shè)備。4. Pack Installer與器件支持包管理4.1 Pack Installer是什么Pack Installer是Keil 5區(qū)別于Keil 4的核心組件。你可以把它理解成一個應(yīng)用商店里面按芯片廠商分類列出了各家MCU的支持包。每個支持包DFP里包含該系列芯片的啟動文件startup_xxx.s外設(shè)寄存器定義頭文件系統(tǒng)初始化代碼system_xxx.cFlash燒錄算法調(diào)試配置文件示例工程沒有裝對應(yīng)的DFP你在新建工程時就找不到那顆芯片編譯也會報錯說找不到器件。4.2 如何安裝器件包打開Pack Installer工具欄上那個綠色小盒子圖標(biāo)左側(cè)是廠商列表右側(cè)是包列表。找到你用的芯片廠商比如STMicroelectronics展開后找到對應(yīng)的系列比如STM32F1 Series再找到具體型號的DFP點(diǎn)擊Install。這里有個坑Pack Installer的下載服務(wù)器在國外國內(nèi)下載速度可能很慢甚至超時。解決辦法是使用離線包。各家廠商的DFP也可以從官網(wǎng)單獨(dú)下載下載下來是一個.pack文件雙擊就能安裝不需要通過Pack Installer在線下載。我一般會提前把常用的幾個系列的pack文件都下載好放在本地?fù)Q電腦時直接雙擊安裝比在線等快得多。4.3 器件包版本選擇同一個系列可能有多個版本的DFP比如STM32F1系列有2.3.0、2.4.0等。選哪個原則是選新不選舊但別選太新。新版本通常修復(fù)了bug、增加了新器件支持但偶爾會引入兼容性問題。如果你用的是比較成熟的芯片型號用比最新版早一兩個小版本的DFP通常最穩(wěn)。安裝完DFP之后新建工程時在Device選擇框里就能搜到你的芯片了。如果搜不到檢查一下是不是Pack Installer里沒裝對應(yīng)的包或者裝完之后沒有重啟IDE。5. 新建工程與編譯配置5.1 從零創(chuàng)建一個工程點(diǎn)擊Project-New uVision Project選擇一個空文件夾作為工程目錄。注意工程路徑同樣不能有中文和空格。然后會彈出器件選擇窗口搜索你的芯片型號選中后點(diǎn)擊OK。接下來會彈出一個“Manage Run-Time Environment”窗口這是Keil 5的另一個特色功能叫RTERun-Time Environment。它允許你直接勾選需要的軟件組件比如CMSIS Core、Device Startup、HAL庫等IDE會自動把對應(yīng)的源文件和頭文件路徑添加到工程里。對于新手來說這個功能非常方便省去了手動添加文件的過程。不過我的習(xí)慣是不用RTE手動管理文件。原因有兩個一是RTE自動添加的文件路徑很深工程遷移時容易出問題二是手動添加能讓你清楚知道每個文件是干什么的對理解工程結(jié)構(gòu)有幫助。當(dāng)然如果你只是想快速跑個Demo用RTE也沒問題。5.2 手動添加啟動文件和庫文件一個最簡的STM32工程需要哪些文件啟動文件startup_stm32f103xb.s根據(jù)具體型號選系統(tǒng)文件system_stm32f1xx.c鏈接腳本STM32F103xB_FLASH.ldKeil用的是.sct分散加載文件在Options里配置庫文件標(biāo)準(zhǔn)外設(shè)庫或者HAL庫的.c文件主文件main.c把這些文件添加到工程的不同Group里比如Startup、CMSIS、Library、User結(jié)構(gòu)清晰后面維護(hù)方便。5.3 編譯選項配置點(diǎn)擊Options for Target魔術(shù)棒圖標(biāo)有幾個關(guān)鍵配置Target標(biāo)簽頁設(shè)置晶振頻率Xtal這個值影響調(diào)試時的時序計算填你板子上的實際晶振頻率比如8MHz或者12MHz。Output標(biāo)簽頁勾選Create HEX File這樣編譯后會生成hex文件方便用其他工具燒錄。Debug Information也勾上調(diào)試時需要。C/C標(biāo)簽頁在Define里填入宏定義比如STM32F103xB, USE_HAL_DRIVER。在Include Paths里添加所有頭文件所在目錄。這里有個技巧頭文件路徑要加到最底層的公共目錄而不是每個子目錄都加否則路徑列表會非常長。Debug標(biāo)簽頁選擇調(diào)試器比如ST-Link Debugger或者J-LINK。旁邊的Settings里可以配置燒錄算法和調(diào)試接口SWD還是JTAG。5.4 編譯與常見報錯配置好之后按F7編譯。常見的報錯和解決方法報錯信息原因解決方法cannot open source input file xxx.h頭文件路徑?jīng)]加在Include Paths里添加對應(yīng)目錄undefined symbol xxx源文件沒加到工程把對應(yīng)的.c文件添加進(jìn)來region RAM overflowed內(nèi)存不夠優(yōu)化代碼或換更大內(nèi)存的芯片L6218E: Undefined symbol函數(shù)聲明了但沒實現(xiàn)檢查是否漏了.c文件Error: Flash Download failed燒錄算法沒選對在Debug Settings里選正確的Flash算法編譯通過后Output窗口會顯示0 Error(s), 0 Warning(s)并給出代碼大小信息。如果Warning很多別忽視很多運(yùn)行時的問題都是Warning積累出來的。6. 調(diào)試器配置與程序燒錄6.1 調(diào)試器選型常見的調(diào)試器有ST-Link、J-Link、DAPLink等。ST-Link是ST官方出的便宜好用支持SWD接口配合STM32芯片很穩(wěn)。J-Link性能更強(qiáng)支持更多芯片但價格貴。DAPLink是開源的性價比高適合DIY。在Keil里配置調(diào)試器Options for Target-Debug下拉框里選對應(yīng)的調(diào)試器。然后點(diǎn)Settings在Debug標(biāo)簽頁里確認(rèn)能識別到芯片ID。如果識別不到檢查接線SWD需要接SWCLK、SWDIO、GND、VCC四根線有時候還需要接RESET。6.2 Flash燒錄算法配置在Settings的Flash Download標(biāo)簽頁里需要添加對應(yīng)的Flash算法。比如STM32F103xB的算法是STM32F10x High-density Flash。如果列表里沒有說明DFP沒裝好或者版本不對。選好算法后下面的地址范圍會自動填充確認(rèn)起始地址是0x08000000STM32的Flash起始地址。提示如果燒錄時提示“Flash Download failed - Target DLL has been cancelled”大概率是Flash算法選錯了或者芯片處于讀保護(hù)狀態(tài)。前者換算法后者需要用工具解除讀保護(hù)。6.3 在線調(diào)試技巧配置好調(diào)試器后按CtrlF5進(jìn)入調(diào)試模式。常用的調(diào)試操作斷點(diǎn)在代碼行號旁邊點(diǎn)擊出現(xiàn)紅點(diǎn)就是斷點(diǎn)。程序運(yùn)行到斷點(diǎn)會暫停。單步執(zhí)行F11是Step Into進(jìn)入函數(shù)F10是Step Over跳過函數(shù)。查看變量把鼠標(biāo)懸停在變量上或者把變量拖到Watch窗口。查看寄存器在View菜單里打開Registers窗口可以看R0-R15、SP、PC等。查看內(nèi)存View - Memory Windows輸入地址可以查看內(nèi)存內(nèi)容。我個人的經(jīng)驗是調(diào)試時優(yōu)先看外設(shè)寄存器的值比看變量更直接。比如串口沒輸出先看USART的CR1寄存器里UE位和TE位有沒有置1再看BRR寄存器的分頻值對不對基本就能定位問題。7. 實操心得與避坑指南7.1 工程目錄結(jié)構(gòu)規(guī)范我見過太多新手把所有的.c和.h文件堆在一個文件夾里工程大了之后根本沒法維護(hù)。建議的目錄結(jié)構(gòu)Project/ ├── CMSIS/ # 內(nèi)核相關(guān)文件 ├── Drivers/ │ ├── STM32F1xx_HAL_Driver/ # HAL庫 │ └── CMSIS/ # 器件頭文件 ├── Inc/ # 用戶頭文件 ├── Src/ # 用戶源文件 ├── Startup/ # 啟動文件 └── MDK-ARM/ # Keil工程文件這樣分的好處是換IDE或者遷移工程時只需要改MDK-ARM目錄其他源碼目錄可以原封不動。7.2 編譯速度優(yōu)化Keil默認(rèn)是單線程編譯工程大了之后編譯一次要幾分鐘??梢栽贠ptions for Target-Output里勾選Browse Information關(guān)掉能省不少時間。另外C/C標(biāo)簽頁里的Optimization級別調(diào)試階段用Level 0不優(yōu)化方便單步跟蹤發(fā)布階段用Level 3最高優(yōu)化代碼體積和速度都更好。7.3 常見問題速查問題一編譯提示“cannot open source input file core_cm3.h”這是CMSIS核心頭文件找不到。解決方法是確認(rèn)DFP裝好了并且在Include Paths里添加了CMSIS/Include目錄。問題二燒錄后程序不運(yùn)行先檢查啟動文件里的堆棧大小是否夠用再檢查中斷向量表是否偏移正確。如果是BootloaderApp的結(jié)構(gòu)App的向量表需要重映射。問題三調(diào)試時進(jìn)不了main函數(shù)大概率是啟動文件里的Reset_Handler有問題或者時鐘初始化卡住了??梢栽赟ystemInit函數(shù)里加個斷點(diǎn)看能不能走到。問題四Pack Installer下載速度極慢用離線pack文件前面說過了。另外Pack Installer的緩存目錄在C:\Users\用戶名\AppData\Local\Arm\Packs可以把下載好的pack文件直接拷進(jìn)去重啟IDE就能識別。7.4 版本遷移注意事項從Keil 4遷移到Keil 5最大的變化是器件包管理方式。Keil 4的工程文件.uvproj不能直接在Keil 5里打開需要先轉(zhuǎn)換成.uvprojx格式。轉(zhuǎn)換過程中器件選擇、頭文件路徑、庫文件引用都可能需要手動調(diào)整。我的建議是不要直接轉(zhuǎn)換而是新建工程把源碼文件重新添加一遍這樣能順便清理掉一些歷史遺留的冗余配置。從標(biāo)準(zhǔn)外設(shè)庫遷移到HAL庫也是類似的情況。HAL庫的API和標(biāo)準(zhǔn)庫完全不同函數(shù)名、參數(shù)、返回值都不一樣直接替換文件是編譯不過的。需要逐個外設(shè)重寫初始化代碼。這個過程很痛苦但HAL庫的跨系列兼容性更好長期來看是值得的。8. 工具鏈的延伸與擴(kuò)展Keil 5裝好之后其實還有很多可以折騰的地方。比如可以配置外部編輯器VS Code、Sublime Text來寫代碼Keil只負(fù)責(zé)編譯和調(diào)試。方法是在Options for Target-Output里勾選Browse Information然后在VS Code里裝Keil Assistant插件就能在VS Code里直接調(diào)用Keil的編譯命令。還可以配置版本控制把工程里的.uvprojx、.uvoptx、源碼文件納入Git管理但Objects、Listings、DebugConfig這些編譯產(chǎn)物目錄要加到.gitignore里。這樣多人協(xié)作時每個人拉下來代碼就能直接編譯不會因為路徑問題打架。另外Keil 5支持命令行編譯用UV4.exe -b project.uvprojx -o build.log就能在CI流水線里自動編譯。這個對于需要持續(xù)集成的項目很有用每次提交代碼后自動編譯一遍能及早發(fā)現(xiàn)編譯錯誤。最后分享一個我個人的習(xí)慣每裝好一個環(huán)境先跑一個最小系統(tǒng)驗證。不要急著上復(fù)雜功能先寫一個空的main函數(shù)編譯燒錄確認(rèn)能進(jìn)調(diào)試、能看變量、能單步執(zhí)行。這個最小系統(tǒng)跑通了說明工具鏈沒問題后面再出問題就是代碼問題排查范圍小很多。這個習(xí)慣幫我省了無數(shù)次“到底是環(huán)境問題還是代碼問題”的糾結(jié)。