嵌入式Linux驅動開發之helloword心得

2021-07-12 06:16:22 字數 3855 閱讀 4978

自從選擇了物聯網這個專業,智慧型xx的字樣牽動著每乙個學習這個專業的孩子。

大家興致勃勃的來到了學校,結果一切想象和自己的設想並不一樣。想象中的各種智慧型般夢幻的場景變成了真實的高數/電路/模電等等諸如此類!不知道這個世界什麼時候變得如此的浮躁,當大家的一段時間的努力看不到結果的時候就往往會不太感興趣,模電大家都沒聽懂,於是大家自我安慰***學這玩意到底幹什麼?本人當初也是這樣,可是到了後來接觸了微控制器,接觸了應用電路的設計才知道那些課程那個沒用啊!當初還是too young,too ******呀!

這個學期也將要過去了,明年就開始去實習啦!趁著現在就實現自己的物聯網夢想吧!沒錯,就是比較惡俗的智慧型家具系統。

考慮到微控制器侷限比較大,遂向同學借了一塊友善之臂的板子,本人第一次接觸arm,微控制器系自學,文中又搞笑的地方大家笑笑就行了,如果能給予指正,那就更好了。先來實現乙個比較簡單的功能,即通過web遠端控制燈光的亮滅。要實現這個功能,我們需要在嵌入式linux的平台上寫led的驅動,要學習驅動我們直接寫led的驅動可能難度比較大,而且不易成功,所以我們先用著名的helloworld來熟悉環境。

現在,越來越覺得和計算機打交道,要有兩條準則:1 思路要清晰  2 實現過程要一步一步。因為計算機是機器,0和1的世界,程式過程中稍不注意就會錯誤百出。所以寫程式過程中一定要步步為營,一點一點測試,一點一點推進,這樣看似很慢,卻非常有效也容易成功。好了,不為我寫hellow辯護了。其實我在寫helloworld的時候也是做準備了,那就是在pc端上已經成功的測試過了。

在補充一點,我們寫的驅動程式最終都是要載入進核心的,我們有兩種方法新增到核心中。第一種是直接編進核心裡,第二種是動態編進核心裡。動態加入核心就是我們把自己的驅動程式看成乙個模組,然後把這個模組載入到核心內。直接編譯進核心就是這個模組和核心一起編譯,如果有什麼這個驅動有什麼問題的話,我們還需要除錯編譯整個核心,因此剛開始學習的時候我採用了模組化的動態載入核心。

下面就開發過程中的一些地方做一些記錄:

1 在pc機上為目標機編寫驅動程式的.c檔案應該放在**比較好?

這個應該放在目標機核心的目錄。比如我的是友善之臂的板子,因為helloworld是字元裝置,因此hello.c就建在了/opt/friendlyarm/mini2440/linux-2.6.32.2/drivers/char的目錄內。為什麼要建在這裡,因為這樣我們可以借助與char內的makefile來編譯出模組,也就是說我們不必自己單獨寫makefile,有點抱大腿的趕腳。

2 最簡單的helloworld模組是什麼樣的?

1 #include 2 #include 3

static

int __init mini2440_hello_module_init(void)4

8static

void __exit mini2440_hello_module_cleanup(void)9

12module_init(mini2440_hello_module_init);

13module_exit(mini2440_hello_module_cleanup);

14 module_license("

gpl");

第一行和第二行就不說了,因為我們用到了核心的相關函式以及模組的一些東西,因此必須要宣告。

最後一行是核心2.6以上版本建議大家把模組的lincense帶上。

在我們動態載入和解除安裝模組的時候,我們需要init_module和exit_module這兩個函式來載入,而上面的**中並沒有。原因在**呢?

原來是module_init和module_exit在作怪。以module_init為例,這個函式有兩個功能,乙個是驗證傳入的引數是否為正確的模組格式,另乙個是將引數改名字為init_module。這樣模組就能被成功的載入了。

雖然上面的module是個空架子,但是也可以讓我們對模組有個感官的認識。

3 編譯這個模組前需要做那些準備?

第一步,將模組新增到核心選單,這樣在我們啟動核心選單的時候才能對我們新新增的模組進行配置。

1

config hello_module

2 tristate "

hello module"3

depends on mach_mini2440

4default m if

mach_mini2440

5help

6 hello module

這個模組就是比照著周圍的模組寫的,當然了,使用者手冊上也是詳細步驟的。

簡單看下這段**,tristate就是這個模組在核心選單中顯示的名字。

depends on 是依靠的平台,下面是說如果依靠這個平台預設的是動態載入到核心。

新增完以上的**,回到linux核心目錄下,make menuconfig調出核心編譯選單。在字元裝置的地方可以找到新新增的hello模組。

第二步,新增完**後,還需要將編譯檔案makefile和原始碼聯絡起來,這樣執行makefile的時候才能找到原始碼進行編譯。因為我們是在核心下抱大腿寫的makefile,所以我們不必重新寫makefile,只需要在字元裝置的makefile檔案中新增這個關係就可以了。

1 obj-$(config_hello_module)      += hello.o
這樣一來,make的時候就能找到hello模組的原始檔啦!

4  編譯模組和檢驗模組

在2.6以後版本的核心中,我們只需要在核心目錄下執行make modules便可以編譯模組。

在編譯模組後一定要做最重要的檢驗工作,可以用modinfo命令檢視生成的.ko檔案的資訊。最重要的是核對.ko檔案的vermagic:   所顯示的核心資訊和你目標板的核心資訊是否一致,這點灰常重要,否則即便你移植到了目標板,也不能載入成功。

5 載入測試

好了,現在我們該檢驗結果啦,雞凍啊!在模組當前目錄,用insmod來載入我們的hello.ko模組。

什麼居然神馬也木有,心頓時涼了半截。。。。。。

還好不是神馬大問題,上面文章已經說過啦!printk是核心級別的函式,檢視需要輸出:dmesg | tail

另外,也可以採用lsmod指令來驗證模組是否載入成功。

最後刻意驗證了這個模組的生命週期,退出終端重新進入,檢視模組還在。重新啟動後發現模組不見鳥。

至此,所有的工作都完成鳥。第乙個在嵌入式裝置上開發的第乙個雞肋驅動就完成了。在整個過程中覺得,只要一步一步來問題都是可以解決的,機器是非常認真的,只要我們按照機器一樣的思維認真的去一步一步解決問題的時候,發現你就可以hold住機器,md,以後會不會變成了乙個和機器一樣的人。。。。

發現了為什麼大傢伙都說嵌入式入門灰常難,其實就是灰常繁,大家可以看上面那麼多東西基本上沒有涉及到和智商有關的東西,全部都是步驟程式化的,當自己沒有走完乙個流程的時候發現這玩意太難了,當走完乙個流程後會覺得,nima,什麼玩意。。。。。

問題解決前前後後大概一兩天吧!發現越是糾結的時候長的問題,當結果出來那一刻會更興奮,越是容易的問題,解決後沒有一點興奮的趕腳!

又扯遠啦!馬上進入真槍實彈的驅動-led驅動啦!   加油!md,我是誰,這麼帥氣的男淫!

最後覺得linux裡面的makefile和kconfig真強大,linux核心是乙個大工程啦,通過kconfig一層一層的去建立選單,通過makefile檔案來批量的去編譯,真是太強大了。這樣以來覺得linux雖然做個什麼東西都特別麻煩,但是更能讓我們清楚的去了解系統的工作原理,linux和微控制器真不愧是學習作業系統和計算機組成原理的法寶啊!

當然,過程中還會有很多的錯誤,這裡沒有一一列出。下面推薦一些這個過程中可能幫助我們的一些網友 的部落格:

如果你的核心選單沒有出現你新增的模組,請參考

inti_module/exit_module的詳細分析,請參考

最後想藉此認識一些嵌入式linux的同夥,因為大家一走才能走的更歡樂,才能走的更遠!

如果那個大牛有什麼好的建議和方法,那這篇文章就賺大發啦!

嵌入式linux之NOR FLASH驅動

flash 儲存器介面還有兩個標準 cfi和jedec。cfi為公共flash介面 common flash inte ce 用來幫助程式從flash晶元中獲取操作方式資訊,而不用在程式中硬編碼flash的id。jedec用來幫助程式讀取flash的製造商id和裝置id,以確定flash的大小和演算...

Linux嵌入式系統開發之Led開發 驅動篇

linux嵌入式系統開發之led開發 驅動篇 小濤哥,你給我說說昨天那個led驅動吧,我知道咋用程式點亮它了,可是呼叫的是驅動,我就是乙個命令,感覺不知道究竟怎麼弄的.小王央求道。這樣啊,那也行,要不咱們這樣以後,就講一次應用,然後就講與之相關的驅動開發,趁著應用的熱度,順便把驅動學了 我想想說。好...

嵌入式Linux驅動開發 簡要備忘

一 搭建編譯環境 1.從天嵌盤拷出 linux 2.6.30.4 20100531.tar.bz2 到 opt下,並解壓到當前目錄 2.shell到目錄 embedsky linux 2.6.30.4 3.cp config embedsky w43 config 4.make menuconfig...