1,概述linux
linux設備驅動分爲三種:字符驅動設備、塊驅動設備、網絡設備網絡
架構:架構
1,字符設備驅動函數
是指只能一個字節一個字節讀寫的設備,不能隨機讀取設備內存中的某一數據,讀取數據須要按照前後數據。字符設備是面向流的設備,常見的字符設備有鼠標、鍵盤、串口、控制檯和LED設備等。優化
2.塊設備驅動ui
是指能夠從設備的任意位置讀取必定長度數據的設備。塊設備包括硬盤、磁盤、U盤和SD卡等。spa
3網絡設備驅動3d
網卡驅動,CAN驅動等調試
2,驅動的靜態加載和動態加載code
區別:
1,編譯選擇不同。選擇 * 就是編入內核鏡像 ,選擇 M 是單獨編爲一個驅動模塊,獨立存在於文件系統上;
2,靜態加載,在內核中加載時間靠前;動態加載,在文件系統中爲 .ko的文件,須要等到系統跑起來以後,手動用insmod 命令加載,時間相對靠後 。
動態加載的優點:
1,支持熱插拔
2,有利於驅動調試
3,開機優化。界面啓動快
——————————————————————————————————————————————————————————————————————————
字符設備驅動:
1,概念
(1)設備號
內核中經過類型 dev_t 來描述設備號,其實質是 unsigned int 32位整數,其中高12位爲主設備號(用來區分不一樣類別的設備),低20位爲次設備號(用來區分同一類別的不一樣設備)
註冊函數:
1. 靜態申請:
int register_chrdev_region (dev_t from, unsigned count, const char *name)
/** * register_chrdev_region() - register a range of device numbers * @from: the first in the desired range of device numbers; must include * the major number. * @count: the number of consecutive device numbers required * @name: the name of the device or driver. * * Return value is zero on success, a negative error code on failure. */
2.動態分配:
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name);
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name); /** * alloc_chrdev_region() - register a range of char device numbers * @dev: output parameter for first assigned number * @baseminor: first of the requested range of minor numbers * @count: the number of minor numbers required * @name: the name of the associated device or driver * * Allocates a range of char device numbers. The major number will be * chosen dynamically, and returned (along with the first minor number) * in @dev. Returns zero or a negative error code. */
3.註銷設備號:
void unregister_chrdev_region(dev_t from, unsigned count);
獲取設備號 :
#define MINORBITS 20 #define MINORMASK ((1U << MINORBITS) - 1) #define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS)) #define MINOR(dev) ((unsigned int) ((dev) & MINORMASK)) #define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))
(2)設備信息的描述
struct cdev { struct kebject kobj; //由內核中設備管理模型來操做 struct module *owner; //爲了加載驅動實現的,都會給它賦值 const struct file_operations *ops; //函數集 struct list_head list; //鏈表 dev_t dev; //設備號 unsignde int count; //支持的設備 };
(3)設備行爲的描述
/include/linux/fs.h struct file_openrations { struct module *owner; ………… ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); ssize_t (*read_iter) (struct kiocb *, struct iov_iter *); ssize_t (*write_iter) (struct kiocb *, struct iov_iter *); ………… }
從下一節開始,咱們手動編寫一個字符驅動。