應用層去呼叫一些介面函式時,會進入核心,驅動也是核心的一部分。以c庫函式中的open函式為例,open函式的實現繪製行一條swi val指令,執行之後會引發異常:
核心的第一層:核心的系統呼叫介面。系統呼叫介面會根據發生異常的原因呼叫不同的異常處理函式,比如sys_open函式;
核心的第二層:虛擬檔案系統。比如sys_open函式
核心的第三層:驅動。具體操作硬體的函式。sys_open函式會呼叫具體的硬體函式實現操作。
具體的框架:
①首先需要定義乙個file_operations結構體變數,為了告訴核心有這個驅動
static struct file_operations first_drv_fops = ;
②然後把這個結構體變數告訴核心,即註冊驅動程式,使用register_chrdev函式
register_chrdev(major, const char *name, const struct file_operation *fops); // 註冊, 告訴核心
major是主裝置號,是為了方便呼叫file_operations裡面的相關成員函式。注:在虛擬機器上使用ls -l命令檢視時開頭的:c表示字元裝置驅動d表示目錄(資料夾)
-表示常規檔案
第乙個數字代表主裝置號
③然後決定誰來呼叫,即設定驅動的入口
int major;
static int first_drv_init(void)
有first_init,就有second_init,各有不同,因此需要乙個函式指標方便呼叫④使用巨集module_init(first_drv_init):設定乙個函式指標
module_init(first_drv_init);
⑤定義出口函式,用於解除安裝驅動,也一樣需要使用巨集來修飾
static void first_drv_exit(void)
module_exit(first_drv_exit);
乙個應用程式,比如是/dev/***下的open,read,write,屬性為c,主裝置號是111,
開啟之後:
①經過c庫進入核心
②核心在字元裝置的結構體陣列裡根據主裝置號找到file_operations結構體並執行對應的功能函式
③在驅動程式裡實現,先寫完功能函式,在定義該結構體變數,在入口函式裡用register_chrdev函式將結構體放到該陣列裡。
掛接nfs檔案系統之後,虛擬機器應該使用命令cd /mnt才能開始操作
註冊驅動使用命令insmod ***.ko
解除安裝驅動使用命令rmmod ***.ko
之後使用命令mknod 目錄 裝置型別 主裝置號 次裝置號
檢視哪些主裝置號有空閒使用命令cat /proc/devices
執行測試程式時應該先使用命令chmod 主裝置號+檔名,之後再使用命令./檔名
也可以選擇自動建立目錄/dev/xyz ,即在**裡面加入:
static struct class *firstdrv_class;
static struct class_device *firstdrv_class_dev;
firstdrv_class = class_create(this_module, "firstdrv"); /* 註冊的是當前驅動 */
firstdrv_class_dev = class_device_create(firstdrv_class, null, mkdev(major, 0), null, "xyz"); /* /dev/xyz */
這個是因為之前建立根檔案系統時在rcs命令下使用了:
echo /sbin/mdev > /proc/sys/kernel/hotplug就是熱插拔的意思,一有驅動被註冊或解除安裝時系統就會自動建立目錄/* /dev/xyz */
struct file_operations ;
int register_chrdev(unsigned int, const char *,
const struct file_operations *);
struct class_device *class_device_create(struct class *cls,
struct class_device *parent,
dev_t devt,
struct device *device,
const char *fmt, ...)
__attribute__((format(printf,5,6)));
int unregister_chrdev(unsigned int, const char *);
static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
寫微控制器程式時直接對實體地址操作,但是寫驅動是對虛擬位址操作,因此需要這個函式來實現位址對映。
#define ioremap(cookie,size) __arm_ioremap(cookie, size, mt_device)
extern void __iomem * __arm_ioremap(unsigned long, size_t, unsigned int);
#define module_init(x) __initcall(x);
#define module_exit(x) __exitcall(x);
LED字元裝置驅動
一 實驗環境 開發機環境 作業系統 ubuntu 10.10 交叉編譯環境 arm linux gcc 4.4.1,安裝位置 usr local arm 4.4.1 6410板子核心原始碼路徑 work linux 2.6.36.2 v1.05 目標板環境 ok6410 a linux2.6.36 ...
字元裝置驅動 Led
驅動檔案 使用linux3.2.81核心 include include include include include include include include include include include static struct class ledsdrv class 類結構體 st...
字元裝置驅動 LED型
字元驅動程式 對於led型別的字元裝置驅動函式編寫 1 建立乙個file operation結構體,裡面會有點燈操作的各個硬體操作函式 2 編寫乙個drv init 函式 3 要對drv init函式進行修飾為入口函式,告訴核心,載入驅動時進行掛接 4 有init函式,那麼也會有出口函式exit m...