前言
基於linux的驅動開發學習筆記,本篇是描述了一個字符驅動的基礎開發流程,以便做嵌入式開發多年的應用或者系統學習驅動開發。
筆者擁有硬件基礎,單片機軟硬基礎,linux系統基礎等各種,就是沒有linux驅動框架基礎,未做過linux系統移植和驅動移植開發了。所以補完linux系統移植和驅動開發就基本可以打通嵌入式整套流程了,作爲技術leader不一定親自動手做,但是一定要對產品構架中的每一塊業務和技術要基本清楚。
建議參考xun爲的視頻教程,教程整個過程非常清晰,直接給擁有很多知識基礎的資深研發,可以不陷入某山的固有思維誤區,也不用imx6的太過龐從彙報理解大而冗餘,它能直接以最終實現目標爲目的,不用從什麼裸機開始做開發學習,怎麼做也告訴你爲什麼都交代清楚,再結合多年相關從業工作經驗,說實在的,一通百通可以融會貫通。從業多年,第一次推薦,因爲確實真的是好東西。
- 頭文件:宏定義等等
- 驅動模塊的入口和出口宏:linux驅動框架
- 聲明信息:linux內核模塊的必要聲明
- 功能實現:真正實現驅動的實體代碼
包含宏定義的頭文件init.h,是一些初始化和宏頭文件,一些module_init,module_exit等。
#include <linux/init.h>
包含了初始化加載模塊的頭文件
#include <linux/module.h>
module_init()和module_exit()入口和出口宏。(PS:這裏括號內實際上需要填入入口出口函數,後續再填入)
module_init();
module_exit();
告訴內核,本模塊驅動有開源許可證。
MODULE_LICENSE(“GPL”);
入口函數
static int hello_init(void)
{
// 在內核裏面無法使用基礎c庫printf,需要使用內核庫printk
printk(“Hello, I’m hongPangZi\n”);
return 0;
}
出口函數
static void hello_exit(void)
{
printk(“bye-bye!!!\n”);
}
此時可以修改,步驟二的出口入口宏了
module_init(hello_init);
module_exit(hello_exit);
總結,按部就班四步法,搭建了基礎的驅動代碼框架。
#include <linux/init.h>
#include <linux/module.h>
static int hello_init(void)
{
// 在內核裏面無法使用基礎c庫printf,需要使用內核庫printk
printk(“Hello, I’m hongPangZi\n”);
return 0;
}
static void hello_exit(void)
{
printk(“bye-bye!!!\n”);
}
MODULE_LICENSE(“GPL”);
module_init(hello_init);
module_exit(hello_exit);
把驅動編譯城模塊,然後加載到內核裏面。
把驅動直接編譯到內核,運行內核則會直接加載驅動。
obj-m += helloworld.o
內核在哪,實際路徑在哪
KDIR:=
PWD?=$(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
make進去KDIR路徑,當前路徑編譯成模塊。
obj-m = helloworld.o
KDIR:=
PWD?=$(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
編譯驅動之前有幾點要注意:
與驅動編譯成的目標系統,獲取對應的內核且需要編譯通過。
開發板或者系統跑的內核版本需要與編譯內核驅動的內核源碼版本一致。
注意3:編譯目標環境要確認是否是需要的構架,在內核目錄下:
make menu configure
export ARCH=arm
修改構架後,可使用menu configure查看標題欄的內核構架
找到使用的arm編譯器(實際爲arm-linux-gnueabihf-gcc,取gcc前綴)
export CROSS_COMPILE=arm-linux-gnueabihf-
直接輸入make,編譯驅動,會生成hellowold.ko文件,ko文件就是編譯好的驅動模塊。
將驅動拷貝到開發板或者目標系統,然後使用加載指令:
insmod helloworld.ko
會打印入口加載的printk輸出。
lsmod
可以查看到加載的驅動模塊
rmmod helloworld
可以移除指定驅動模塊(PS:卸載驅動不需要.ko後綴),卸載成功會打印之前的printk輸出。
學習了驅動的基礎框架,那麼爲了方便很好的測試,讓大家都有基礎環境,下一篇,將使用ubuntu18.04,編譯ubuntu18.04的驅動,然後做好本篇文章的相關實戰測試。