目錄
- 背景
- 系統版本
- vs code的安裝和使用
-
- 1.安裝
- 2.建立工程
- 3.設定vs code工程的頭檔案查找路徑及編譯器路徑
- 4.Intelli Sense Engine Fallback設定為ENABLE
- 編輯驅動檔案和Makefile
背景
早期的ubuntu版本上沒有好的可用的IDE,那個時候嵌入式linux驅動開發人員多使用vim進行編碼;而對于沒有圖像界面的linux伺服器,開發人員更是隻能選擇vim這一編輯工具。但是,接觸過IDE的人會感覺到vim的不友善:需要記一些指令,而且沒有代碼自動補全,沒有代碼提示,沒有括号自動補全,沒有回車後自動縮進等等。
後來ubuntu上有了gedit這個好了許多的編輯工具,使開發人員有了在windows上編輯文本文檔的感覺,但它仍然缺乏IDE擁有的代碼自動補全等功能。
雖然真正的linux開發大神們都是号稱使用vim或者gedit加上插件(如代碼自動補全插件,關鍵詞高亮插件,括号自動補全插件)的方式來程式設計的,但在選擇更為豐富的現在,選擇一款界面漂亮、支援各種友好操作(如代碼自動補全)的IDE也是一個不錯的選擇,它能大大提升嵌入式linux驅動人員的編碼體驗。而對于沒有圖像界面的linux伺服器,我們也可以選擇先在本地用IDE交叉編譯好了,然後再上傳到伺服器上。
本文主要介紹visual studio code(vs code)這款IDE在嵌入式linux驅動開發中的使用。其他可能也能用于嵌入式linux驅動開發的IDE,還有eclipse。
本文所有操作是建立在你的開發環境已經搭建好了的前提下的。如果你的開發環境沒有搭建好,可以參考我另一篇部落格《ubuntu20.04.1 64位搭建嵌入式linux開發環境》。
下面總結下VS CODE能幫我們做什麼:
- 提供函數名的自動補全以及參數的提示
- 提供已存在變量名的自動補全
- 換行自動對齊
- 輸入左括号時自動補齊右括号
- 可以用于閱讀linux源碼,因為他有很友善的查找功能:菜單欄中Edit->Find以及Edit->Find in Files;Ctrl+左鍵也可以嘗試查找函數和變量定義的位置(列出來很多地方讓你自己看,準确率挺高)。
- 可以自定義快捷鍵,比如我不想用鍵盤上的上下左右來進行光标移動,可以将他們用更友善的快捷鍵替代(如Alt+w,a,s,d)。
目前發現的VS CODE不能做的事情:
暫時沒有,我需要的功能他都有提供。
原本以為VS CODE無法自動補全結構體名和結構體變量名,也無法自動補全結構體的成員名。後來發現是沒有正确設定
"compilerPath"
導緻的。見“設定vs code工程的頭檔案查找路徑及編譯器路徑”一節中最後部分。
另外IDE本身也有點問題:當定義一個結構體變量時,輸入
struct xxx aaa;
時,結構體名xxx不會自動補全;但是當你不輸入struct,而是直接輸入xxx時又會自動補全。
我猜測這是IDE認為你輸入struct後可能會定義一個結構體,此時确實是不需要代碼補全的。代碼補全隻有在定義結構體變量的時候才需要。不過我們也不用擔心,我們可以通過按鍵
Ctrl+Space
強制彈出代碼提示。在一些自動補全突然不好使的情況下,這種強制的方法挺好用的。
系統版本
我是通過在win10系統上安裝vmware workstation pro 15,然後在上面安裝ubuntu20.04.1 64位虛拟機來建立開發環境的。
之是以選擇20.04.1這麼高的版本,是因為我平時還會做opencv的開發,較高版本的opencv需要較高版本的ubuntu來支援,否則會有各種麻煩的問題。選擇這種高版本的ubuntu的話,我就不用建立各種版本的虛拟機,隻需要一個虛拟機就能搞定所有開發。arm linux開發闆廠商的提供給我們的開發環境總是低版本的vmware加低版本的ubuntu(雖然也是64位),高版本的開發環境的搭建需要我們自己去探索。我的這番嘗試也證明了高版本的ubuntu也是能勝任開發環境的。
vs code的安裝和使用
1.安裝
Visual Studio Code是微軟開發的一款可以用于Linux平台的免費IDE。我們可以在vs code的官網上下載下傳,也可以在ubuntu software軟體中心下載下傳。我是從後者下載下傳的。安裝完之後,點選ubuntu界面的左上角的activity,在搜尋框中輸入visual studio code,打開vs code并将其添加到favorite中,友善以後使用。
2.建立工程
vs code是基于檔案夾進行工程管理的。
如果你隻需要用到一個檔案夾,那麼直接在你的目錄中(比如Home)建立一個新檔案夾,然後點選vs code菜單欄的File->Open Folder,打開你剛剛建立的檔案夾就完成了工程的建立,接下來你就可以往裡面添加檔案了:如下圖,點選左側工程欄,建立的檔案夾(我這裡是HELLODRIVER)的右側的紅圈部分。這裡我添加了helloWorld.c檔案和Makefile檔案,用于編寫之後的驅動程式。注意第一次使用vs code時,此時它會要求你安裝C/C++ for Visual Studio Code。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNyZuBnLzEjN3IDMxcTMzEDOwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
如果你需要同時管理多個檔案夾,vs code的workspace機制會幫助到你。此時,除了要建立一個檔案夾外,還需要點選菜單欄File->Add Folder to Workspace添加你要管理的第二個檔案夾到你的workspace中。接着儲存你的workspace并為其命名:File->Save Workspace As。這樣,你就得到如下圖所示的界面(我的workspace名為HELLODRIVER,下面有兩個檔案夾:helloDriver和iTop4412_Kernel_3.0)。
以後使用的時候,你就隻需要打開這個工作空間了。
3.設定vs code工程的頭檔案查找路徑及編譯器路徑
我們使用vs code,是希望能使用“代碼自動補全”這一功能。要想實作這一點,IDE自然要知道包含那些函數、變量聲明的頭檔案所在的路徑。
vs code的每一個工程都需要我們自己設定頭檔案的查找路徑,我們也可以儲存一份配置檔案,建立工程時把它複制過來再改改。
vs code配置頭檔案查找路徑以及宏定義的檔案叫做c_cpp_properties.json,打開它的方法如下:在菜單欄View->Command Palette,然後在出現的搜尋框中輸入“edit”,注意搜尋框中本身有一個“>”,這樣搜尋框裡的内容就是“>edit”,之後在搜尋提示清單中選擇 c/c++:Edit Configurations(JSON),這樣就打開了c_cpp_properties.json這個配置檔案。
c_cpp_properties.json檔案内容如下:
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/home/liyu/iTop4412_Kernel_3.0/include",
"/home/liyu/iTop4412_Kernel_3.0/arch/arm/include",
"/home/liyu/iTop4412_Kernel_3.0/arch/arm/mach-exynos/include"
],
"defines": [],
"compilerPath": "/usr/local/arm/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-none-linux-gnueabi-gcc",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "gcc-x64"
}
],
"version": 4
}
如上面代碼塊所示,我們需要在“includePath”中填寫需要包含的頭檔案路徑,用于讓IDE知道如何補全代碼。"${workspaceFolder}/**"這一條是預設就有的。我們還需要添加linux源碼的通用頭檔案包含路徑:
"/home/liyu/iTop4412_Kernel_3.0/include"
以及具體平台的頭檔案包含路徑:
"/home/liyu/iTop4412_Kernel_3.0/arch/arm/include"和 "/home/liyu/iTop4412_Kernel_3.0/arch/arm/mach-exynos/include"
。
除此之外,我們還需要在 "compilerPath"中填寫我們使用的交叉編譯工具中的具體編譯器的路徑,如
"compilerPath": "/usr/local/arm/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-none-linux-gnueabi-gcc"
。把滑鼠放在 "compilerPath"上,會提示:Full path of the compiler being used, e.g. /usr/bin/gcc, to enable more accurate IntelliSense. 可見雖然我們直接用他進行編譯工作,但是他直接影響到我們的代碼補全(IntelliSense),實測具體表現為:結構體名不會自動補全,成員名也不會自動補全。另外,如果不設定正确的編譯器路徑,當需要使用一些标準庫時,如stdlib.h,IDE定位到的标準庫就不是你的交叉編譯工具中的标準庫,而是你的PC上自帶的标準庫了,這會帶來一些錯誤。
至于宏定義“defines”,我目前還沒用到,以後可能會用到。
4.Intelli Sense Engine Fallback設定為ENABLE
有時候IDE的自動補全功能會失效(包括函數名和變量名等),我猜測這種情況會在找不到頭檔案時出現。
為了解決這個問題,選擇菜單欄File->Preferences->Settings,在彈出的視窗中選擇User->Extensions->C/C++,然後再上方的搜尋欄中輸入“Intelli Sense Engine Fallback”,将其設定為ENABLE即可。
他的英文描述我不是太懂,感覺意思是當包含頭檔案出現錯誤時,IDE仍能正常智能解析和提示(自動補全)。
編輯驅動檔案和Makefile
“建立工程”一節中提到的helloWorld.c和Makefile内容如下:
//helloWorld.c
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("DUAL BSD/GPL");
MODULE_AUTHOR("LIYU");
static int hello_init(void)
{
printk(KERN_EMERG "hello world enter!");
return 0;
}
static int hello_exit(void)
{
printk(KERN_EMERG "hello world exit!");
return 0;
}
module_init(hello_init);
module_exit(hello_exit);
//Makefile
obj-m += helloWorld.o
KDIR := /home/liyu/iTop4412_Kernel_3.0
PWD ?= $(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -rf *.o
rm -rf *.ko
rm -rf *.mod.c
rm -rf *.symvers
rm -rf *.order
在敲上述代碼的時候,頭檔案名是自動補全的,
MODULE_LICENSE
這些也是可以自動補全的,還能看到函數允許填寫的參數;括号自動補全、回車自動縮進也都是有的,可謂友好極了。這裡就不解釋代碼了,畢竟我們的重心不在這裡,隻要證明可行就行了。
需要注意的是,
helloWorld.c
檔案裡會有報錯,比如包含頭檔案時,說找不到一些頭檔案裡面包含的頭檔案:
cannot open source file "asm/rwsem.h" (dependency of "linux/module.h")C/C++(1696)
。這是正常的,并且不影響我們使用Makefile建構驅動子產品。因為我們僅僅使用IDE進行編輯工作,并不用它來進行編譯。
最後,我們點選vs code下方的terminal或者菜單欄Terminal->New Terminal來使用内置的終端,在裡面輸入make,出現下面的結果表示編譯成功。此時你的目錄下也會多出來很多檔案,當然也包含你的.ko檔案。
将該.ko檔案拷貝到開發闆,運作
insmod helloWorld.ko
,系統列印出
hello world enter!
,證明驅動子產品編譯成功。