手把手帶你使用 VSCode 搭建 STM32 開發環境
對於單片機開發,使用比較多的就是 Keil,但它是一個收費軟件,雖然可以 Po 解,但是很多公司也害怕收到 ** 函,如果公司準備上市,那就更不能使用 Keil 開發了。
一直都比較喜歡 VSCode 的這種黑色主題,還能安裝各種插件,免費又好用,於是決定搭建一個用 VSCode + 開源 arm 工具鏈 + OpenOCD 開發 STM32 的環境。
一、需要的軟件和工具
1. 下載最新版 VS Code : 安裝好插件,具有良好的代碼補全與調試功能。
VS Code 下載地址:https://code.visualstudio.com/
2. 下載 LLVM :用於代碼補全,其實可以理解爲 Clang。因爲 VS Code 中 “C/C++” 插件的自動補全功能不太好用。STM32 中好多庫函數都補全不出來。記得按照好之後,將路徑添加到環境變量裏。
Git 下載地址:https://gitforwindows.org/
3. 下載安裝 **Git for Windows:**提供 Git 支持和 MINGW64 指令終端。
Git 下載地址:https://gitforwindows.org/
4. 下載安裝 arm-none-eabi-gcc:選擇 "gcc-arm-none-eabi-5_4-2016q3-20160926-win32.exe (md5)" 這裏是一個 2016 年的,我目前也是用的這個,好像還有其他的新版的下載,GNU Arm Embedded Toolchain 。
正常安裝後,記得需要將軟件的安裝目錄下的 bin 文件夾設置進入環境變量 PATH 中。
arm-none-eabi-gcc 下載地址:https://launchpad.net/gcc-arm-embedded/+download
5. 下載 OpenOCD for Windows :
一個開源的片上調試器 (Open On-Chip Debugger)。
在 Windows 下自己編譯可能有問題 。所以,我們選擇編譯好的。
下載後的文件不是安裝包,把程序文件夾放入自己的軟件安裝目錄下,將軟件的 bin 文件夾路徑加入用戶環境變量 PATH 中
OpenOCD 下載地址:http://gnutoolchains.com/arm-eabi/openocd/
6. STM32CubeMX:用於生成帶 makefile 的工程。
這樣我們就可以不用自己寫 MakeFile 了。套用他的模板,然後修改爲自己的目錄就可以。
STM32CubeMX 鏈接:http://www.stm32cube.com/
二、搭建編譯環境
1. 用 STM32Cube 創建工程
STM32CubeMX 生成的是用 HAL 庫開發的項目,具體怎麼配置這裏就不介紹了,只介紹與主題有關的部分。
(1). STM32CubeMx 芯片包(固件庫)下載,注意事項:
需要選擇 “help -> updater settings ->Connection Parameters" 設置好網絡後,才能下載固件包。
(2). 生成工程。選擇 MakeFile 選項。
注意:4.18.0 以下的版本是沒有 Makefile 這個選項的。最後下載一箇中間版本,因爲 5.0 以上的版本界面很亂。我選擇的是 4.27.0.
2. 配置 VS Code
(1). 打開工程所在的文件夾。再右鍵 “用 VS Code 打開工程文件夾”
你將會看到這樣的目錄結構
.ioc 文件是 STM32Cube 的工程文件,Inc 和 Src 是供用戶修改的源碼,Driver 裏是 STM32 和 ARM CMSIS 的庫,最好不要修改。
不過,如果你要採用標準庫開發的話,就修改爲標準庫的 Driver.
(2). 安裝 VS Code 插件,需要這幾樣:
(3). 配置 VS Code 內置終端
這裏將我們上面安裝的 Git for Windows 設置爲 VScode 的內置終端。
文件–首選項–設置,搜索 terminal,設置內置終端的 Shell 爲 Bash(安裝 VS Code 的時候它會推薦你安裝 Git,裏面有這個 Bash)。
或者打開 Settings.json 添加下面兩句。
/* 終端在Windows上使用的shell的路徑 */
"terminal.integrated.shell.windows": "D:\\Program Files\\Git\\bin\\bash.exe",
"terminal.external.windowsExec": "D:\\Program Files\\Git\\bin\\bash.exe"
然後按 Ctrl+` 就可以打開終端,看到 Bash 了
(4). 配置智能補全、智能感知插件
前面我們安裝了 LLVM 用它來實現智能補全,與糾錯,自然就需要一個路徑去尋找這些文件。因此我們需要一個。c_cpp_properties.json 文件的配置文件。
我們在當前目錄的. vscode 文件夾下創建 c_cpp_properties.json 配置文件,用來告訴 VS Code 我們定義的宏與文件的路徑。
{
"configurations": [
{
"name": "Win32",
"browse": {
"path": [
"${workspaceFolder}/",
"${workspaceFolder}/Drivers/CMSIS",
"${workspaceFolder}/Drivers/FWlib/inc",
"${workspaceFolder}/Drivers/CMSIS/startup",
"${workspaceFolder}/User/inc",
"${workspaceFolder}/User",
"${workspaceFolder}/ThirdParty/crclib/include"
],
"limitSymbolsToIncludedHeaders": true
},
"includePath": [
"${workspaceFolder}/",
"${workspaceFolder}/",
"${workspaceFolder}/Drivers/CMSIS",
"${workspaceFolder}/Drivers/FWlib/inc",
"${workspaceFolder}/Drivers/CMSIS/startup",
"${workspaceFolder}/User/inc",
"${workspaceFolder}/User",
"${workspaceFolder}/ThirdParty/crclib/include"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE",
"__CC_ARM",
"USE_STDPERIPH_DRIVER",
"STM32F10X_HD"
],
"compilerPath": "C:\\Program Files\\LLVM\\bin\\clang-format.exe",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
}
注意:如果提示 variable “uint32_t” is not a type name 不是一個 type 類型。
則需要 添加宏定義__CC_ARM,如果沒有該宏定義,則 uint32_t 類型會報錯。並且結構體中使用了 uint32_t 定義的成員,也會補全不了。
(5). 編譯程序
gcc 下編譯過程如下圖所示:
-
.c 文件 經過 arm-none-eabi-gcc 編譯成 .o 文件
-
**.s **文件 經過 arm-none-eabi-as 編譯成 .o 文件
-
**.o **文件 和 .a 文件 經過 arm-none-eabi-ld 鏈接成 .elf 文件
-
**.elf **文件 經過 arm-none-eabi-objcopy 和 arm-none-eabi-objdump 轉換成 hex 文件 / dis 文件
-
arm-none-eabi-gdb 使用 .elf 文件 進行 debug
在 Terminal 下輸入 make 指令,即會開始 build 程序
編譯完成後,生成的所有文件都會放在 Build 文件夾下.
注意:由於我安裝了 Qt. Qt 中自帶了 mingw32-make.exe。我把這個文件複製了一份,重命名爲 make.exe。並且添加進了環境變量中。因此我可以直接使用 make。
如果你沒有 make 的環境。可以下載一個 choco 包管理器,它類似於 linux 下的 apt,只不過是 windows 下使用的。然後用 choco 安裝 make 即可:
如果改了 source code,需要重新編譯程序,那就得先執行 make clean 指令去刪除之前 build 好的所有東西。然後重新執行 make 指令即可。
三、搭建調試環境
1. 配置 openocd
要運行 openocd 這個 gdb server,需要配置如下幾個參數:
-
用什麼仿真器?(J-link, ST-link…)
-
用什麼接口?(JTAG, SWD…)
-
目標芯片是什麼?(STM32F4x, tm4c123g…)
首先我們打開 openocd 的安裝目錄,打開 share/openocd/scripts,裏面有很多提前寫好的配置文件。
target 裏存放目標芯片的配置文件,例如 stm32f4.cfg
interface 裏存放仿真器相關的配置文件,例如 jlink.cfg,stlink.cfg.
當我們啓動 openocd 時,可以用 - f 參數來指定一個配置文件。例如:
openocd –f interface/stlink.cfg –f target/stm32f4.cfg
【注】配置仿真器的參數必須在配置目標 MCU 的參數之前,否則將報錯。
如果我們不帶參數啓動,openocd 就會自動查找當前目錄下有沒有名爲 openocd.cfg 的文件,並把它作爲配置文件來啓動。因此,我們就在當前工程下創建一個名爲 openocd.cfg 的文件。
我們選擇使用 ST-link,SWD 接口,目標芯片爲 stm32f1x。
(PS:這裏註釋掉了 SWD 接口,如果採用 Jlink 則需要 SWD 接口)。
這樣,我們連好板子上好電,直接在終端裏敲 openocd,即可啓動。
openocd 運行時,這個 shell 終端就被佔用了,我們一會要新開一個終端。
2. 用 gdb 連接上 openocd
(1) 直接啓動 gdb,參數爲編譯好的調試文件 (.elf)
(2) 使 gdb 連接上 openocd
前面已經說過 openocd 留給 gdb 的 TCP/IP 端口是 3333,因此輸入:
target remote localhost:3333
注意,在連接 openocd 的時候,一定需要先運行 openocd 服務才能通信上,否則一直出現 taget remote 錯誤。
(3) 下載代碼
後面就和普通的 gdb 一樣操作了,加斷點,單步運行什麼的,網上可以搜到很多教程。
【注】最後記得輸入 q 來退出 gdb,以免影響後面的配置。
3. 配置 openocd 任務與 build 任務
爲了避免每次都在終端輸入 make 和 make clean ,與 openocd 。我們可以在 VSCode 中,建立一個 Task 來幫我們完成這個任務,
(1). 在當前目錄下創建 build.py 的文件。
(2). 在 VSCode 界面下,單擊 “任務”,選擇 “配置任務”
按 F1,選擇 "配置任務" .vscode 目錄下就會創建一個 tasks.json 配置文件.
打開 tasks.json,修改內容如下:
注意上面是兩個任務,一個是 openocd. 用於連接 st-link 調試。一個是 build 用於編譯。
它相當於是創建了一個名爲 build 的任務,任務的內容是在 shell 裏面執行 python build.py 這個命令。只是不用我們手動輸入而已。
4. 配置 VS Code 的調試功能
使用 VS Code,肯定是圖方便,圖好看。所以我肯定不會讓大家靠敲命令來調試,這樣豈不是開倒車,還不如用 keil。因此,這裏要配置 VS Code 的調試功能,相當於對 gdb 的一個圖形化吧。
在 VS Code 內選擇 debug(就是左邊那個蟲子圖標),選擇 “添加配置”,類型爲 GDB。就會在. vscode 文件夾下生成 launch.json 配置文件。
按照下面來配置:
{
// 使用 IntelliSense 瞭解相關屬性。
// 懸停以查看現有屬性的描述。
// 欲瞭解更多信息,請訪問: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "ARM Debug",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/Build/STM32F103RC_Template.elf",// 要調試的程序(在下面的參數中指定了,這裏的沒有意義)
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false, // 調試時是否顯示控制檯窗口
"MIMode": "gdb",
"miDebuggerPath": "C:\\Program Files (x86)\\GNU Tools ARM Embedded\\5.4 2016q3\\bin\\arm-none-eabi-gdb.exe",//調試工具原始路徑
"targetArchitecture": "arm", //目標架構,此參數必須要有
"setupCommands": [// 進入GDB以後,自動執行的一些配置
{
"description": "選擇調試文件(.elf)到gdb",
"text": "file E:/VScode/STM32_VSCode/stm32f103_temp/Build/STM32F103RC_Template.elf",
"ignoreFailures": false
},
{
"description": "連接GDB Server",
"text": "target remote localhost:3333",
"ignoreFailures": false
},
{
"description": "Reset MCU",
"text": "monitor reset",
"ignoreFailures": false
},
{
"description": "Halt",
"text": "monitor halt",
"ignoreFailures": false
},
{
"description":"下載代碼到MCU",
"text": "load" ,
"ignoreFailures": false
}
],
"preLaunchTask": "build", // 在調試前預先執行的任務,此處是tasks.json中的
}
]
}
可以看到,setupCommands 裏面就是我們之前試用 gdb 時操作過的流程:連接 GDB Server——reset——halt——下載代碼。
而 preLaunchTask 中是我們之前在 tasks.json 中配置的 build 任務。它可以讓我們每次調試時都先編譯一遍。
保存後,隨便打幾個斷點,按下 F5,就可以快樂調試了。可以看到功能還是很齊全的。
【注意】:在進行調試的時候,需要先 按 F1 --> 任務:運行任務裏選擇 openocd 任務運行。
因爲調試,需要連接 st-link 進行調試,而 openocd 任務是開啓 st-link 的服務。這樣客戶端才能連接上。
否則會一直出現 target remote localhost:3333 的錯誤。
【注】這裏有一個問題我一直沒有解決,就是 setupCommands 裏,用 file 選擇調試用的 elf 文件時,必須用文件的絕對路徑。我試過用 ${workspaceFolder}/build/xxx.elf 和./build/xxx.elf 都不行,都找不到文件,不知道是不是 windows 路徑分割符是”\” 導致的。具體的後續再完善。
原文:http://t.csdn.cn/89MOD
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/BrK9xEsSOpjH_V3aOx2J9g