編寫linux驅動先看一下驅動框架是什麼樣子的。
驅動編寫和應用層編寫有什麼區別呢?
(一)首先 入口函式的問題。應用層編寫我們的入口就是main函式,但在驅動編寫時不是這樣的,有兩種情況,
1、預設情況下
int __init init_module(void) 載入模組時的初始化函式,也就是驅動模組的入口函式
void __exit cleanup_module(void) 解除安裝模組時的函式,也就是解除安裝某個驅動時要執行的函式
2、static int __init ***x_init(void) 載入模組時的初始化函式,也就是驅動模組的入口函式
static void __exit ***x_exit(void) 解除安裝模組時的函式,也就是解除安裝某個驅動時要執行的函式
上述兩種情況相比,我們一般用第二種,因為第一種的名稱是固定的,我們不能做更改,第二種我們可以改寫***x為我們自己模組的名字。可以達到見文知義。
在用第二種模式時,我們要首先用固定格式宣告一下:
module_init(***x_init);
module_exit(***x_exit);
來表明載入初始化函式和解除安裝函式。
(二)c語言的標準函式庫不能使用
驅動屬於核心的一部分,我們此時還無法使用類似像printf這樣的c庫,但是核心會提供自己的c庫,在核心中我們用printk代替printf函式。
(三)新增license宣告
linux是開源的系統,那就要我們遵守一定的規範,我們一般用gpl規範,所以在驅動編寫時都要宣告一下
module_license(「gpl」);
基本的區別就是這些,我們來看乙個簡單的驅動框架
#include
#include
#include
module_license("gpl");
static int __init demo_init(void)
static void __exit demo_exit(void)
module_init(demo_init);
module_exit(demo_exit);
完成驅動編寫後,如何才能載入到核心呢?我們需要通過makefile生成.ko檔案,乙個簡單的makefile如下,這是在ubutnu下的makefile,如果換為arm平台下的linux需要更換源檔案目錄。具體解釋可以看核心模組編譯makefile入門。執行make即可生成模組.ko檔案
$(warning kernelrelease = $(kernelrelease))
ifeq ($(kernelrelease),)
#核心的原始碼路徑, ?= 條件賦值, uname -r 得到核心的版本號
kerneldir ?= /lib/modules/$(shell uname -r)/build
# := 立即賦值, 得到當前的絕對路徑
pwd := $(shell pwd)
# -c 切換工作路徑, make -c
modules:
$(make) -c $(kerneldir) m=$(pwd) modules
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions module* modules*
.phony: modules clean
else
# 生成模組
obj-m := used.o
endif
下面我們來看幾個驅動中常用的命令
1、載入驅動模組insmod
將生成驅動模組.ko檔案載入,
insmod ***.ko
載入後就會執行***x_init函式
2、解除安裝驅動模組rmmod
對應的解除安裝驅動的命令
rmmod ***x 注意不用帶.ko
3、檢視核心中的模組資訊
lsmod
4、檢視模組的描述資訊
modinfo ***x.ko
我們可以在驅動程式新增一些輔助資訊,例如作者 ,驅動描述等。
5、檢視模組列印資訊
dmesg
printk是核心列印函式,預設模式下在中斷下無法顯示(當然,可以設定成列印到終端),用dmesg可以檢視一下列印到核心的資訊。
上述幾個比較常用,有其他的我們可以以後再看。
我們把上述幾個熟悉一下
insmod /rmmod/dmesg
載入模組後執行初始化函式,列印函式名和行號
解除安裝模組後執行解除安裝函式,列印函式名和行號
列印模組資訊 modinfo
檢視核心中模組資訊lsmod
module為模組名稱 size為模組打下 usedby 表明有幾個其他檔案使用
實際上lsmod是讀取並分析「/proc/modules」檔案,我們來看一下這個檔案
核心已經載入的模組的資訊也存在於/sys/module目錄下,載入demo.ko後,核心中將包含/sys/moudle/demo目錄,demo的目錄樹結構如下
除了使用insmod載入模組以外,還可以用modprobe命令來載入模組,並且使用modprobe載入模組時,會同時載入模組所依賴的其他模組。insmod必須按順序乙個乙個載入模組。同樣在解除安裝時,modprobe -r filename的方式會同時解除安裝該模組所依賴的模組。
模組之間的依賴關係放在/lib/modules檔案中。實際上是在整體編譯核心的時候由depmod工具生成的,該檔案的格式很簡單:有依賴的直接在「:」後面加上。
linux驅動初步
主機環境 ubuntu 16.04 64bit 在虛擬機器中安裝完ubuntu 16.04後,預設的環境是可以直接進行驅動開發的,而無需重新編譯核心樹。下面以linux ubuntu 4.13.0 36 generic ubuntu 16.04 64bit為例,介紹簡單驅動程式的編寫和測試。1.he...
ThinkPHP框架初步掌握
為了幫老師用thinksns二次開發乙個微博系統,專門花了幾天學習thinkphp框架,現在將一些thinkphp入門知識作以記錄。首先宣告 本文不是完全教程,只是將開發中碰到的問題作以總結,如果需要學習thinkphp框架,請參考官網文件 官網首頁 thinkphp完全開發手冊 附 開源微博系統t...
Linux GPIO驅動 驅動框架概述
gpio是嵌入式開發中最常見的介面,之前自己就有寫過小的gpio驅動,提供ioctl介面給使用者空間操作。但直到最近才發現linux自身就有完善的gpio驅動框架,並且通過sysfs向使用者空間提供操作介面。linux的gpio驅動框架層次及資料結構如下 最上層是用來向向使用者空間提供介面,使用者可...