很多朋友在開發(fā)嵌入式的時候,一般常用Keil MDK、IAR等IDE工具,不過這些都是收費的,而且非常笨重,跨平臺開發(fā)不方便,依次筆者將推薦使用VS Code開發(fā)嵌入式。
如果想要使用VS Code開發(fā)嵌入式,則需要以下工具:
(1) GNU Arm Embedded Toolchain:ARM用的GNU工具鏈,包括編譯器(gcc),調(diào)試器(gdb),鏈接器(ld)和其它工具,支持Windows、Linux、Mac。GCC(GNU Compiler Collection)。
(2) Git/make:代碼管理工具,但是我們這里要使用的是下載git附帶的git bash。這個bash是基于mingw的,非常輕量,甚至于make都沒有,但是可以安裝相應(yīng)的插件來支持make,wget等工具。當然啦,如果是在Linux平臺直接使用make工具就行。
(3) OpenOCD:一個開源的片上調(diào)試器(Open On-Chip Debugger)。OpenOCD負責把GDB的高級別命令轉(zhuǎn)換成JTAG命令,并通過特定下載器的要求進行打包,準備調(diào)用OS提供的USB驅(qū)動由USB發(fā)送出去。GDB和OpenOCD之間使用TCP協(xié)議進行連接,說的簡單點,OpenOCD就是一個協(xié)議轉(zhuǎn)換工具。
本文將分為兩個部分:工具安裝,固件開發(fā)。
1 軟件安裝
1.1 GCC編譯工具
編譯代碼需要編譯器,Linux系統(tǒng)的編譯器是GCC,而Windows的C/C++編譯器是Microsoft Visual C++,那么要想在Windows也能GCC等一系列編譯工具,就需要安裝MinGW。
MinGW 是用于進行 Windows 應(yīng)用開發(fā)的 GNU 工具鏈(開發(fā)環(huán)境),它的編譯產(chǎn)物一般是原生 Windows 應(yīng)用,雖然它本身不一定非要運行在 Windows 系統(tǒng)下(是的 MinGW 工具鏈也存在于 Linux、BSD 甚至 Cygwin 下)。說的通俗點,MinGW就是你在Windows下使用GNU工具鏈的一個編譯工具。
MinGW編譯的程序只能在X86上運行,不能運行在嵌入式的硬件平臺,因為嵌入式平臺大都是ARM體系結(jié)構(gòu),因此這就需要一個在Windows環(huán)境下能使用GNU編譯ARM體系結(jié)構(gòu)的編譯工具,這也就是交叉編譯工具。
所謂交叉編譯工具就是在一種平臺上編譯出能運行在體系結(jié)構(gòu)不同的另一種平臺上的程序,比如在PC平臺(X86 CPU)上編譯出能運行在以ARM為內(nèi)核的CPU平臺上的程序,編譯得到的程序在X86 CPU平臺上是不能運行的,必須放到ARM CPU平臺上才能運行。
做過嵌入式開發(fā)的朋友都知道,在嵌入式開發(fā)過程中有宿主機和目標機的角色之分:宿主機是執(zhí)行編譯、鏈接嵌入式軟件的計算機;目標機是運行嵌入式軟件的硬件平臺。
嵌入式開發(fā)流程大致就是在宿主機完成目標的開發(fā)工具,使用功能交叉編譯工具生成固件,將固件燒寫到目標機,在開發(fā)初期,還需要在線調(diào)試等工作,這就需要諸如J-link等調(diào)試工具。
gcc-arm-none-eabi就是一個基于ARM的交叉編譯工具鏈,而且還是開源的,適用于Arm Cortex-M和Coretex-A系列處理器,包括GNU編譯器(GCC),以及GDB,不僅適用于Windows,還適用于Linux,MacOS上的交叉編譯。
好了,直接看下載地址吧。
下載地址:https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
【注】這里要選擇GUN-RM下的工具,GUN-A是Cortex-A系列的交叉編譯工具。
下載后解壓,并把安裝目錄下的bin文件夾添加到環(huán)境變量:
然后在命令窗口中輸入下面的命令驗證安裝是否成功:
#arm-none-eabi-gcc -v
如果有信息輸出,那就是裝好了。
值得注意的是,如果不是ARM體系,就需要更換交叉編譯工具,比如RISC-V,就需要安裝RISC-V的交叉編譯工具鏈。
1.2 make工具安裝
如果使用gcc來編譯工程,一般需要使用功能Makefile來管理工程,那么就需要一個工具來識別Makefile文件,也就是make工具,在Linux中已經(jīng)自帶make了,在Windows就需要安裝make工具。
在安裝make工具之前,先來看看什么是makefile?Makefile 可以簡單的認為是一個工程文件的編譯規(guī)則,描述了整個工程的編譯和鏈接等規(guī)則。其中包含了那些文件需要編譯,那些文件不需要編譯,那些文件需要先編譯,那些文件需要后編譯,那些文件需要重建等等。編譯整個工程需要涉及到的,在 Makefile 中都可以進行描述。換句話說,Makefile 可以使得我們的項目工程的編譯變得自動化,不需要每次都手動輸入一堆源文件和參數(shù)。
本文的make工具是依賴Git工具的,我相信很多朋友都用過Git,但是很少使用Git的make等功能。
Git的bash實際上也就是一個mingw,是可以支持部分Linux指令的,但是只有少部分。在編譯代碼的時候經(jīng)常會使用make命令反而在bash下默認是不支持的。
Make工具下載地址:https://sourceforge.net/projects/ezwinports/files/
下載make-4.1-2-without-guile-w32-bin.zip 文件。
把該文件進行解壓,把解壓出來的文件全部拷貝的git的安裝目錄下:
C:\\Program Files\\Git\\mingw64
把文件夾進行合并,如果跳出來需要替換的文件要選擇不替換。
這樣在git bash窗口下就可以執(zhí)行make了。
沒有安裝Git先安裝Git工具。
Git下載地址:https://git-scm.com/download/win
1.3 OpenOCD安裝
OpenOCD是用于對MCU進行下載仿真的工具,是一個開源軟件包。
下載地址:https://gnutoolchains.com/arm-eabi/openocd/
下載后解壓即可。
打開share/openocd/scripts,里面有很多提前寫好的配置文件:
其中interface目錄下都是接口相關(guān)配置文件,例如jlink.cfg,stlink.cfg;target目錄下都是芯片相關(guān)的配置文件,例如stm32f1x.cfg。
然后配置下環(huán)境變量:
然后在命令窗口中輸入下面的命令驗證安裝是否成功:
表示安裝成功。
值得注意的是,想要在線下載調(diào)試就需要調(diào)試工具的驅(qū)動安裝。筆者首推J-link,幾乎所有的MCU都是可以用,當然如果是ST的MCU,也可以使用ST-Link。
2 固件開發(fā)
在開始之前,需要準備一個基于GCC的工程,筆者這里準備的是STM32的工程。
2.1 Visual Studio Code導入工程
選擇打開文件夾,選擇STM32CubeMX新建的工程.
最后創(chuàng)建的工程如下:
2.2 Visual Studio Code工程配置
接下來就是配置工程。
1. settings.json
點擊“在settings.json中編輯",修改為自己安裝git bash的路徑:
{
"terminal.integrated.profiles.windows": {
"my-bash": {
"source": "Git Bash",
"args": []
}
},
"terminal.integrated.defaultProfile.windows": "my-bash"
}
打開終端,就可以使用Bash了。當然了,這不是非必須的。
2. c_cpp_properties.json
VS Code只是一個編輯器,它檢查代碼的時候并不會去讀makefile,因此有些宏定義需要自行配置。c_cpp_properties.json的作用就是配置工程的頭文件、工具鏈、宏定義等參數(shù)。
打開c_cpp_properties.json配置文件,輸入以下內(nèi)容:
{
"configurations": [
{
"name": "Win32",
"includePath": [
"D:/gcc/gcc-arm-none-eabi-10.3-2021.07/arm-none-eabi/include",
"${workspaceFolder}/Core/Inc",
"${workspaceFolder}/Drivers/STM32F1xx_HAL_Driver/Inc",
"${workspaceFolder}/Drivers/STM32F1xx_HAL_Driver/Inc/Legacy",
"${workspaceFolder}/Drivers/CMSIS/Device/ST/STM32F1xx/Include",
"${workspaceFolder}/Drivers/CMSIS/Include"
],
"defines": [
"USE_HAL_DRIVER",
"STM32F103xE"
],
"compilerPath": "D:/gcc/gcc-arm-none-eabi-10.3-2021.07/bin/arm-none-eabi-gcc.exe",
"intelliSenseMode": "gcc-x64",
"browse": {
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": "",
"path": [
"${workspaceFolder}"
]
}
}
],
"version": 4
}
name :這是用于標記使用的平臺的標簽。除了win32還可以選Linux或Mac。也就是說,這個json里“configuration“下可以寫三組配置,只要每組配置前面寫上不同的平臺,即可在不同的操作系統(tǒng)上使用就會自動適配不同的配置。
includePath :頭文件路徑。第一個目錄是C語言標準庫的目錄, 剩下的幾個目錄直接從Makefile里復制然后稍微修改下即可。"${workspaceFolder}"表示項目文件夾;
defines :全局宏定義。
compilerPath :編譯器的路徑。
intelliSenseMode :因為我用的是gcc所以選gcc-x64。
browse :源文件搜索路徑。用來做代碼補全和查找定義的。這個路徑和includePath不同,browse.path是自動遞歸所有子目錄的。而include.path默認只看本目錄。
c_cpp_properties配置說明:
https://code.visualstudio.com/docs/cpp/c-cpp-properties-schema-reference
3.tasks.json
tasks.json的作用就是配置工程的編譯、下載等工作。如果沒有則需要創(chuàng)建tasks.json文件,內(nèi)容如下:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "make",
"args": [
"-j4"
]
},
{
"label": "download",
"type": "shell",
"command": "openocd",
"args": [
"-f",
"./interface/jlink.cfg",
"-f",
"./target/stm32f1x.cfg",
"-c",
"program build/STM32F103ZE.elf verify exit"
]
},
{
"label": "clean",
"type": "shell",
"command": "make",
"args": [
"clean"
]
}
]
}
這個文件創(chuàng)建了三個任務(wù),分別叫做build、download和clean,build任務(wù)就是在bash里執(zhí)行了make -j4,也就是使用多線程編譯,download也就是用于在線下載固件,clean任務(wù)就是在bash里執(zhí)行了make clean。
值得注意的是,這里需要拷貝OpenOCD中的interface和target中的相關(guān)配置,筆者是整個文件夾都拷貝過來了。
2.3 編譯
點擊‘終端->運行任務(wù)’,然后虛著呢‘build’。
等待編譯完成即可。
這里還可以直接使用終端編譯。
最后我們使用make編譯下前文新建的工程,編譯通過顯示如下:
2.4 固件下載
筆者這里使用功能OpenOCD下載。選擇“終端->運行任務(wù)…”
選擇task中配置的命令download。
復位設(shè)備,即可下載成功。
當然也可使用命令下載。
openocd -f ./interface/stlink.cfg -f ./target/stm32f1x.cfg -c 'program build/STM32F103ZE.elf verify exit‘
效果和使用界面是一樣的。
當然換成J-Link下載也是一樣的操作,只是需要修改命令。
openocd -f ./interface/jlink.cfg -f ./target/stm32f1x.cfg -c 'program build/STM32F103ZE.elf verify exit‘
另外,還需要注意的是如果J-Link的接口是swd,則需要在interface/jlink.cfg中添加如下語句。
transport select swd
當然還可以連接到OpenOCD守護程序燒寫。
$ openocd
值得注意的是,如果不加參數(shù),需要事先配置openocd.cfg,
如果不想配置,也可使用以下命令:
#openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg
效果都是一樣的。
打開另一個終端,輸入以下命令連接到OpenOCD守護程序。后面的所有命令都是在這個終端運行的。
telnet localhost 4444
成功通過ST-Link連接到STM32上之后,OpenOCD會監(jiān)聽本機的4444端口。通過telnet登錄上去,之后就可以控制OpenOCD干些什么了。
接下來就可以燒寫固件了。
program build/STM32F103ZE.elf verify reset exit
當然也可使用功能J-Link的J-Flash下載固件。
如果是ST的,還可使用ST-Link下載固件。
【注】OpenOCD使用J-link使用須知
在使用J-link之前,需要將J-link的驅(qū)動改為libusb,否則openocd無法連接到J-link。這里使用的工具是UsbDriverTool。
UsbDriverTool下載地址:https://visualgdb.com/UsbDriverTool/
使用功能方法如下:
如果使用J-link調(diào)試,則不修改修改。
2.5 ARM-GDB調(diào)試
直接使用GDB調(diào)試,
首先在終端輸入一下命令:
#openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg
【注】也可將命令配置成task任務(wù)。
【注】如果不帶參數(shù)啟動,openocd就會自動查找當前目錄下有沒有名為openocd.cfg的文件,并把它作為配置文件來啟動。
【注】openocd默認TCP/IP的3333端口作為gdb端口,4444作為telnet端口。在連接gdb之前,我們可以先用telnet連上試用一下。
如果你的電腦沒有開啟telnet功能,需要打開“啟用或關(guān)閉Windows功能”,然后在里面找到“telnet客戶端”,啟動即可。
openocd運行時,這個終端就被占用了因此還需要再開一個終端。
GDB也屬于GNU項目的一部分,跟在Linux上調(diào)試是一樣的,只是這里使用的是交叉編譯工具中的GDB。
arm-none-eabi-gdb build/STM32F103ZE.elf
GDB常用命令如表所示。
命令 描述
list(l) 查看代碼(默認一次顯示10行)
break(b) 設(shè)置斷點
clear(c) 清除斷點
ignore 忽略對應(yīng)斷點num次
info b 查看當前所設(shè)斷點
r(run) 運行程序
n(next) 單步調(diào)試,不進入函數(shù)調(diào)用
s(step) 單步調(diào)試,進入函數(shù)調(diào)用
p(print) 查看變量
display 每次自動顯示該變量值
c(continue) 繼續(xù)運行,直到結(jié)束或遇到新斷點
finish 運行程序,直到當前函數(shù)完成返回
q(quit) 退出
shell command 執(zhí)行shell命令
關(guān)于GDB的使用請看筆者文章:
https://bruceou.blog.csdn.net/article/details/88634967
接下來需要連接openocd服務(wù),openocd給GDB的TCP/IP端口是3333。
target remote localhost:3333
接下來和在Linux中調(diào)試一樣。
在 gdb 中鍵入"l"(list)就可以查看所載入的文件,如下所示。
自行參考筆者關(guān)于GDB的博文去調(diào)試吧。
如果覺得使用命令不方便,也可安裝VS Code的插件,但是這是基于Cortex-M系列的MCU,如果是其他系列的,還是使用GDB吧。
2.6 VS Code插件Cortex-Debug調(diào)試
如果沒有安裝Cortex-Debug調(diào)試插件,需要先安裝。
2.6.1 Cortex-Debug調(diào)試配置
1.GDB server路徑設(shè)置
設(shè)置J-Link和OpenOCD的路徑。
根據(jù)實際情況設(shè)置。
2.launch.json文件
在vscode文件夾中新建一個launch.json,該文件是調(diào)試的入口文件。內(nèi)容如下:
{
"version": "0.2.0",
"configurations": [
{
"cwd": "${workspaceRoot}",
"type": "cortex-debug",
"request": "launch",
"name": "OpenOCD",
"interface": "swd",
"servertype": "openocd",
"executable": "./build/STM32F103ZE.elf",
//"runToMain": true,
"device": "STM32F103ZE",
"svdFile": "./STM32F103xx.svd",
"configFiles": [
"${workspaceRoot}/openocd.cfg"
],
//"preLaunchTask": "build",
"armToolchainPath": "D:/gcc/gcc-arm-none-eabi-10.3-2021.07/bin/"
},
{
"cwd": "${workspaceRoot}",
"type": "cortex-debug",
"request": "launch",
"name": "J-Link",
"interface": "swd",
"servertype": "jlink",
"executable": "./build/STM32F103ZE.elf",
//"runToMain": true,
"device": "STM32F103ZE",
"svdFile": "./STM32F103xx.svd",
//"preLaunchTask": "build",
"armToolchainPath": "D:/gcc/gcc-arm-none-eabi-10.3-2021.07/bin/"
},
{
"cwd": "${workspaceRoot}",
"type": "cortex-debug",
"request": "launch",
"name": "ST-Link",
"interface": "swd",
"servertype": "stlink",
"executable": "./build/STM32F103ZE.elf",
//"runToMain": true,
"device": "STM32F103ZE",
"svdFile": "./STM32F103xx.svd",
//"preLaunchTask": "build",
"armToolchainPath": "D:/gcc/gcc-arm-none-eabi-10.3-2021.07/bin/"
}
]
}
executable :編譯出的二進制文件,也就是最終燒錄到單片機中的,這里是elf文件。根據(jù)芯片的不同,可能產(chǎn)生不同的名稱和后綴(例如TI的TM4C123芯片編譯出來的名稱是"main.axf")
request :可以選launch或attach。launch是指啟動調(diào)試時同時開始執(zhí)行程序;attcah是指程序已經(jīng)在運行了,然后開始調(diào)試。我沒測試過attach。
type :調(diào)試的類型,選cortex-debug,這是我們裝的插件。其實也可以填cppdbg之類的,但是那樣我們就得自己配置gdb了,配置起來將會非常麻煩。
device :目標芯片。如果你使用J-LINK GDB Server時必須要設(shè)置這個選項。
svdFile :svd文件的路徑,每個MCU的各不相同。
servertype :要選擇的gdb server。我這里用openocd。
configFiles :gdb的配置文件路徑。openocd會自動讀當前目錄下的openocd.cfg文件,這個選項不填也行。但是如果你想把openocd.cfg放在別處,就可以用這個選項指定配置文件的路徑。
preLaunchTask :在啟動調(diào)試前,預先執(zhí)行的任務(wù)。
armToolchainPath :工具鏈的路徑。
launch.json參考:https://code.visualstudio.com/docs/cpp/launch-json-reference
關(guān)于launch.json的更多配置請參看Cortex-Debug官網(wǎng)。
https://discuss.em-ide.com/blog/67-cortex-debug
3.openocd.cfg文件
在項目文件夾下新建一個openocd.cfg文件,用于配置調(diào)具體的調(diào)試器。內(nèi)容如下:
選擇調(diào)試器為jlink
#source [find interface/jlink.cfg]
source [find interface/stlink-v2.cfg]
選擇接口為SWD
transport select swd
選擇目標芯片
source [find target/stm32f1x.cfg]
我這里選擇使用ST-Link,SWD接口,目標芯片為stm32f1x。
【注】使用J-link調(diào)試也是一樣的,只需將openocd.cfg文件配置成J-link調(diào)試即可。
4.svd文件
用于尋找STM32F1的svd文件。CMSIS-SVD是CMSIS的一個組件,它包含完整微控制器系統(tǒng)(包括外設(shè))的程序員視圖的系統(tǒng)視圖描述 XML 文件。VS Code可以通過它來知道外設(shè)寄存器的地址分布,從而把寄存器內(nèi)容展示到窗口中。
svd文件地址:https://github.com/posborne/cmsis-svd
將下載好的STM32F103xx.svd文件放在項目文件夾根目錄即可。
2.6.2 Cortex-Debug調(diào)試
直接按F5,openocd啟動時,會自動在當前目錄下尋找名為openocd.cfg的文件作為配置文件。調(diào)試界面如下:
界面左邊可以看到變量窗口、調(diào)用堆棧等。窗口中間就是單步調(diào)試的各個按鈕。這個就沒啥好說的了,趕緊去玩起來吧。
這里可以在launch.json文件添加多個選項,就可使用多種調(diào)試手段了。
Cortex-Debug的本質(zhì)還是使用的OpenOCD。
本文介紹的開發(fā)方式不僅適用于ARM,還適用于RISC-V等系列的處理器。
-
嵌入式
+關(guān)注
關(guān)注
5082文章
19104瀏覽量
304791 -
調(diào)試器
+關(guān)注
關(guān)注
1文章
303瀏覽量
23716 -
RISC-V
+關(guān)注
關(guān)注
45文章
2270瀏覽量
46125 -
32MCU
+關(guān)注
關(guān)注
0文章
111瀏覽量
4714 -
vscode
+關(guān)注
關(guān)注
1文章
155瀏覽量
7696
發(fā)布評論請先 登錄
相關(guān)推薦
評論