1. 程式人生 > >嵌入式核心及驅動開發之學習筆記(一) 認識與使用驅動模組

嵌入式核心及驅動開發之學習筆記(一) 認識與使用驅動模組

應用層的程序是通過核心層驅動來訪問硬體的,Linux核心原始碼在每次編譯之後生成一個總的映象,將映象載入記憶體中執行並使用(核心在系統執行時會移植佔用核心空間)。驅動屬於核心原始碼的一部分,如果每次修改驅動都要重新編譯載入核心的話,這態麻煩了,所以我們通過模組,使驅動可以獨立於核心映象之外,並能動態的載入和解除安裝。

在搭建好開發環境之後,通過source insight我們可以方便的檢視和編輯核心原始碼,並結合交叉編譯工具鏈實現編輯--編譯--燒錄--執行 的完整開發流程。

  • 物理機(Win7)     程式編輯環境
  • 虛擬機器(Ubuntu14.04) 程式的編譯環境
  • 開發板(FS4412)  程式的除錯執行環境

編寫驅動

建立驅動檔案hello.c,編輯原始碼

#include <linux/init.h>
#include <linux/module.h>
#include <linux/stat.h>


static int __init hello_drv_init(void)
{
	printk("-------%s-------------\n", __FUNCTION__);	
	return 0;
}

static void __exit hello_drv_exit(void)
{
	printk("-------%s-------------\n", __FUNCTION__);
}


module_init(hello_drv_init);
module_exit(hello_drv_exit);

MODULE_LICENSE("GPL");

這個簡單的驅動模組程式碼,沒有涉及到任何硬體,它的功能是可以在載入和解除安裝該模組時列印輸出資訊,僅此。要建立這個框架,分成4個步驟:

1.載入標頭檔案  #include <linux/init.h>                 包含模組裝解除安裝函式原型宣告 #include <linux/module.h>               這裡沒有用到其實 #include <linux/stat.h>                  包含printk函式的原型宣告

2.驅動模組裝載/解除安裝函式宣告 module_init(hello_drv_init);                          裝載 hello_drv_init為回撥函式 module_exit(hello_drv_exit);                          解除安裝 hello_drv_exit為回撥函式

3.實現函式入口(回撥函式實現) static int __init hello_drv_init(void) {     return 0; }

static void __exit hello_drv_exit(void) {      return ; }

4.GPL宣告 MODULE_LICENSE("GPL");       一種開源宣告  

編輯Makefile的規則

用來負責驅動檔案的編譯和管理。這裡make -C引數,借用了核心原始碼根目錄中的Makefile檔案的規則來編譯驅動程式碼生成成.ko模組。

ROOTFS_DIR = /nfs/rootfs

ifeq ($(KERNELRELEASE), )

KERNEL_DIR = /mnt/hgfs/sharefolder/kernel/linux-3.14-fs4412
CUR_DIR = $(shell pwd)

all :
	make -C  $(KERNEL_DIR) M=$(CUR_DIR) modules

clean :
	make -C  $(KERNEL_DIR) M=$(CUR_DIR) clean
	
install:
	cp -raf *.ko   $(ROOTFS_DIR)/drv_module


else

obj-m += hello.o


endif

ROOTFS_DIR變數指定 nfs共享跟目錄 KERNEL_DIR變數指定 核心原始碼的根目錄(絕對路徑) obj-m += hello.o 表示將hello.o這個目標檔案編譯成模組

編譯動作

Ubuntu系統中進入Makefile所在目錄

[email protected]:/mnt/hgfs/sharefolder/kernel/linux-3.14-fs4412/drivers/mydrivers/hello_drv$ make

[email protected]:/mnt/hgfs/sharefolder/kernel/linux-3.14-fs4412/drivers/mydrivers/hello_drv$ make install

載入/解除安裝模組的指令

在核心執行時

  • insmod xxx.ko   裝載
  • rmmod xxx       解除安裝
  • modinfo         檢視

其他

對模組的傳參

有時候對原廠開發,一些程式碼叫做韌體,我們不能進入函式的內部去修改引數的預設指定。通過命令列傳參

  • 手動傳遞

insmod hello.ko myname="george" myvalue=33

  • 函式接收

 module_param(name, type, perm)

符號表

使用 EXPORT_SYMBOL 可以將一個函式以符號的方式匯出給其他模組使用。原理類似於應用層的動態庫。 這樣就使模組與模組之間形成依賴關係(使用方依賴於匯出符號的模組),例如

EXPORT_SYMBOL(my_add);   my_add是匯出的函式名

//math.c
#include <linux/module.h>
#include <linux/init.h>

int my_add(int a, int b)
{
	return a+b;
}

EXPORT_SYMBOL(my_add);


MODULE_LICENSE("GPL");