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

自從選擇了物聯網這個專業,智能XX的字樣牽動着每個學習這個專業的孩子。html

你們興致勃勃的來到了學校,結果一切想象和本身的設想並不同。想象中的各類智能般夢幻的場景變成了真實的高數/電路/模電等等諸如此類!不知道這個世界何時變得如此的浮躁,當你們的一段時間的努力看不到結果的時候就每每會不太感興趣,模電你們都沒聽懂,因而你們自我安慰tmd學這玩意到底幹什麼?本人當初也是這樣,但是到了後來接觸了單片機,接觸了應用電路的設計才知道那些課程那個沒用啊!當初仍是too young,too simple呀!linux

這個學期也將要過去了,明年就開始去實習啦!趁着如今就實現本身的物聯網夢想吧!沒錯,就是比較惡俗的智能傢俱系統。
web

考慮到單片機侷限比較大,遂向同窗借了一塊友善之臂的板子,本人第一次接觸arm,單片機系自學,文中又搞笑的地方你們笑笑就好了,若是能給予指正,那就更好了。先來實現一個比較簡單的功能,即經過web遠程控制燈光的亮滅。要實現這個功能,咱們須要在嵌入式linux的平臺上寫led的驅動,要學習驅動咱們直接寫led的驅動可能難度比較大,並且不易成功,因此咱們先用著名的helloworld來熟悉環境。模塊化

如今,愈來愈以爲和計算機打交道,要有兩條準則:1 思路要清晰  2 實現過程要一步一步。由於計算機是機器,0和1的世界,程序過程當中稍不注意就會錯誤百出。因此寫程序過程當中必定要步步爲營,一點一點測試,一點一點推動,這樣看似很慢,卻很是有效也容易成功。好了,不爲我寫hellow辯護了。其實我在寫helloworld的時候也是作準備了,那就是在pc端上已經成功的測試過了。函數

在補充一點,咱們寫的驅動程序最終都是要加載進內核的,咱們有兩種方法添加到內核中。第一種是直接編進內核裏,第二種是動態編進內核裏。動態加入內核就是咱們把本身的驅動程序當作一個模塊,而後把這個模塊加載到內核內。直接編譯進內核就是這個模塊和內核一塊兒編譯,若是有什麼這個驅動有什麼問題的話,咱們還須要調試編譯整個內核,所以剛開始學習的時候我採用了模塊化的動態加載內核。學習

下面就開發過程當中的一些地方作一些記錄:測試

1 在pc機上爲目標機編寫驅動程序的.c文件應該放在哪裏比較好? spa

這個應該放在目標機內核的目錄。好比個人是友善之臂的板子,由於helloworld是字符設備,所以hello.c就建在了/opt/FriendlyARM/mini2440/linux-2.6.32.2/drivers/char的目錄內。爲何要建在這裏,由於這樣咱們能夠藉助與char內的makefile來編譯出模塊,也就是說咱們沒必要本身單獨寫makefile,有點抱大腿的趕腳。操作系統

2 最簡單的helloworld模塊是什麼樣的?.net

 

 1 #include <linux/kernel.h>
 2 #include <linux/module.h>
 3 static int __init mini2440_hello_module_init(void)
 4 {
 5 printk("Hello, world !\n");
 6 return 0;
 7 }
 8 static void __exit mini2440_hello_module_cleanup(void)
 9 {
10 printk("Good-bye!\n");
11 }
12 module_init(mini2440_hello_module_init);
13 module_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
4         default m if MACH_MINI2440
5         help
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和單片機真不愧是學習操做系統和計算機組成原理的法寶啊!

固然,過程當中還會有不少的錯誤,這裏沒有一一列出。下面推薦一些這個過程當中可能幫助咱們的一些網友 的博客:

若是你的內核菜單沒有出現你添加的模塊,請參考

http://blog.csdn.net/hadise/article/details/6222538

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

http://www.embedu.org/Column/Column517.htm

建議第一次接觸的朋友能夠如今pc機上的系統去實現一下,這樣過渡一下效果會更好一點,下面是pc機上實現helloworld驅動的連接:

http://www.cnblogs.com/heat-man/articles/4174899.html

最後想借此認識一些嵌入式linux的同夥,由於你們一走才能走的更歡樂,才能走的更遠!

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

相關文章
相關標籤/搜索