linux系統将設備分為3類:字符設備、塊設備、網絡設備。可以把一個系統劃分為應用、文件系統、設備驅動結構示意圖如下:
設備分層示意圖
字符設備:是指隻能一個字節一個字節讀寫的設備,不能随機讀取設備内存中的某一數據,讀取數據需要按照先後數據。字符設備是面向流的設備,常見的字符設備有鼠标、鍵盤、串口、控制台和LED設備等。
塊設備:是指可以從設備的任意位置讀取一定長度數據的設備。塊設備包括硬盤、磁盤、U盤和SD卡等。
每一個字符設備或塊設備都在/dev目錄下對應一個設備文件。linux用戶程序通過設備文件(或稱設備節點)來使用驅動程序操作字符設備和塊設備
字符設備驅動模型
int register_chrdev_region(dev_t from, unsigned count, const char *name);
功能:申請使用從from開始的count 個設備号(主設備号不變,次設備号增加)
靜态申請相對較簡單,但是一旦驅動被廣泛使用,這個随機選定的主設備号可能會導緻設備号沖突,而使驅動程序無法注冊。
動态方法如下
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,const char *name); 功能:請求内核動态分配count個設備号,且次設備号從baseminor開始。 動态申請簡單,易于驅動推廣,但是無法在安裝驅動前創建設備文件(因為安裝前還沒有分配到主設備号)。 靜态申請是已知起始設備号的情況,如先使用cat /proc/devices 命令查得哪個設備号未事先使用(不推薦使用靜态申請);動态申請是由系統自動分配,隻需設置major = 0即可 2 初始化cdev void cdev_init(struct cdev *, const struct file_operations *); 該函數用于初始化 cdev 的成員,并建立 cdev 和 file_operations 之間的連接。 struct cdev *cdev_alloc(void); 用于動态分配一個cdev結構 int cdev_add(struct cdev *, dev_t, unsigned); 向内核注冊一個cdev結構 void cdev_del(struct cdev *); 向内核注銷一個cdev結構 3 注冊cdev int cdev_add(struct cdev *, dev_t, unsigned); 用于向系統添加一個 cdev,完成字符設備的注冊。 (二)設備實現操作 用戶空間的程序以訪問文件的形式訪問字符設備,通常進行open、read、write、close等系統調用。而這些系統調用的最終落實則是file_operations結構體中成員函數,它們是字符設備驅動與内核的接口 這個結構體是字符設備當中最重要的結構體之一,file_operations 結構體中的成員函數指針是字符設備驅動程序設計的主體内容。 static struct file_operations globalmem_fops = { .owner = THIS_MODULE, .open = globalmem_open, .release = globalmem_close, .read = globalmem_read }; 代碼中的globalmem_open、globalmem_close、globalmem_read是要在具體的驅動中自己實現的。 (三)驅動注銷 1 删除 cdev 在字符設備驅動模塊卸載函數中通過cdev_del()函數向系統删除一個cdev,完成字符設備的注銷。 void cdev_del(struct cdev *); 2 釋放設備号 在調用cdev_del()函數從系統注銷字符設備之後,unregister_chrdev_region()應該被調用以釋放原先申請的設備号 void unregister_chrdev_region(dev_t from, unsigned count); |
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!