日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux驱动编程 step-by-step (四) 字符设备的注册与设备节点的自动创建

發布時間:2024/9/21 linux 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux驱动编程 step-by-step (四) 字符设备的注册与设备节点的自动创建 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

字符設備的注冊與設備節點的自動創建

cdev 結構

內核內部使用struct cdev<linux/cdev.h>來表示一個字符設備

struct?cdev?{
????struct?kobject?kobj;?//kobj設備模型以后介紹
????struct?module?*owner;
????const?struct?file_operations?*ops;//文件操作
????struct?list_head?list;
????dev_t?dev;//設備號
????unsigned?int?count;?//設備個數
};

注冊字符設備

動態初始化:

struct?cdev?*my_cdev?=?cdev_alloc();
my_cdev->ops?=?&my_ops;

靜態初始化:

struct?cdev?my_cdev;
cdev_init(&my_dev,?&my_ops);

向內核注冊(添加設備):

int?cdev_add(struct?cdev?*dev,?dev_t?num,?unsigned?count); dev:? 指向以初始化的字符設備結構
num: 設備號
count: 所要添加的設備個數
返回值:
成功返回0 失敗返回錯誤碼,設備被注冊時候可能立即會唄調用,所以在驅動程序還沒有準備好處理設備操作時候不要先調用cdev_add

注銷字符設備:

在不需要用西設備時候需要注銷設備
void?cdev_del(struct?cdev?*);

早期的方法

在2.6的內核之前注冊字符設備有一個簡單易用的方法,現在也可以使用但是不建議使用,因為到最后這個方法會從內核消失

注冊字符設備:

static?inline?int?register_chrdev(unsigned?int?major,?
????const?char?*name,?const?struct?file_operations?*fops);
major: 主設備號 (當major為0時表示有內核分配一個可用的主設備號并返回)
name: 驅動名
fops: 文件操作
缺點: 不能同時注冊多個設備, 他是用一種默認的方式去建立一個cdev結構,而這樣的話它不能使用大于255的主次設備號

注銷設備:

static?inline?void?unregister_chrdev(unsigned?int?major,?const?char?*name)

設備節點的自動創建

在上一個程序中,雖然能夠爭取的得到一個設備號,但是并不會在/dev/目錄下生成一個設備節點。

使用手動創建

mknod?/dev/device_name?c?major?minor
device_name: 指設備名,
c: 表述創建字符設備節點(同理b 表示創建塊設備文件節點)
major: 主設備號
minor: 次設備號
在做測試時候這樣做事可以理解的,而在作為一個模塊要發行時候,這樣就太不方面了,①要先查看設備是否成功創建,②查看注冊設備的主設備號,③輸入命令創建文件節點
當然可以寫一個shell腳本來完成這些事情。?

自動創建設備節點

需要的纖體內核空間支持udev,在內核配置,及busybox配置時候需要指定
內核中定義了struct class 與 struct devic結構<linux/device.h>
創建一個class結構
#define?class_create(owner,?name)????\
({????????????\
????static?struct?lock_class_key?__key;???\
????__class_create(owner,?name,?&__key);?\
})
owner表示擁有這個模塊的指針
name 表示設備名
調用此函數后 創建了一個struct class結構放在sysfs下邊,而后調用
struct?device?*device_create(struct?class?*cls,?
?? ?struct?device?*parent,
????????????????????dev_t?devt,?void?*drvdata,
????????????????????const?char?*fmt,?...)
在/dev目錄下創建設備節點
cls : 是上邊函數的創建的struct class結構指針
parent: 指向設備的父節點設備(如果沒有填NULL
devt: 被添加設備的設備號
drvdata: 回調函數參數
fmt ,args:一個或者多個設備名
至此我們就自動創建了一個設備節點

刪除設備節點

在設備不需要使用時候我們需要刪除設備節點:
void?device_destroy(struct?class?*class,?dev_t?devt);//刪除設備節點
void?class_destroy(struct?class?*cls);//刪除sysfs下得struct?class結構
至于深層的一些實現機制,沒有細細研究,大家干興趣可以參考相關資料

實例:

初始化 添加設備到內核

  • ????simple_cdev?=?cdev_alloc();?//動態初始化字符設備??
  • ????if(simple_cdev?!=?NULL) ??
  • ????{ ??
  • ????????simple_cdev->ops???=?&simple_fops;?//文件操作??
  • ????????simple_cdev->owner?=?THIS_MODULE; ??
  • ????} ??
  • ????else??
  • ????{ ??
  • ????????printk(KERN_ERR?"alloc?cdev?err?no?memory"); ??
  • ????????unregister_chrdev_region(dev,?DEV_COUNT);?//如果分配資源出錯則釋放設備號??
  • ????????return?-ENOMEM; ??
  • ????} ??
  • ??
  • ????err?=?cdev_add(simple_cdev,?dev,?DEV_COUNT);?//向內核添加設備??
  • ????if(err?<?0) ??
  • ????{ ??
  • ????????printk(KERN_ERR?"add?cdev?err?\n"); ??
  • ????????goto?error1; ??
  • ????} ??
  • ????else??
  • ????{ ??
  • #if?SIMPLE_DEBUG???
  • ????????printk(KERN_INFO?"add?char?dev?OK!\n"); ??
  • #endif???
  • ????} ??
  • 自動創建設備節點

  • ????simple_class?=?class_create(THIS_MODULE,?SIMPLE_NAME); ??
  • ????if(simple_class?==?NULL) ??
  • ????{ ??
  • ????????printk(KERN_ERR?"create?simple?class?error\n"); ??
  • ????????goto?error2; ??
  • ????} ??
  • ????else??
  • ????{ ??
  • #if?SIMPLE_DEBUG???
  • ????????printk(KERN_INFO?"create?simple?class??OK!\n"); ??
  • #endif???
  • ????} ??
  • ??
  • ????simple_dev?=?device_create(simple_class,?NULL,?dev,?NULL,?SIMPLE_NAME); ??
  • ????if(simple_dev?==?NULL) ??
  • ????{ ??
  • ????????printk(KERN_ERR?"create?device?error"); ??
  • ????????goto?error3; ??
  • ????} ??
  • ????else??
  • ????{ ??
  • #if?SIMPLE_DEBUG???
  • ????????printk(KERN_INFO?"create?simple?device??OK!\n"); ??
  • #endif???
  • ????}??
  • 刪除設備節點,注銷字符設備

  • dev?=?MKDEV(simple_major,?simple_minor);?//計算出設備號??
  • device_destroy(simple_class,?dev);?//刪除設備節點??
  • class_destroy(simple_class);//刪除并釋放class結構??
  • cdev_del(simple_cdev);//注銷設備???
  • cdev_put(simple_cdev);//對動態的設備需要使用cdev_put‘來釋放資源??
  • 總結

    以上是生活随笔為你收集整理的Linux驱动编程 step-by-step (四) 字符设备的注册与设备节点的自动创建的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。