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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用cdev_add注册字符设备

發布時間:2024/9/21 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用cdev_add注册字符设备 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在前面已經提到設備號有主設備號和次設備號,其中主設備號表示設備類?型,對應于確定的驅動程序,具備相同主設備號的設備之間共用同一個驅動程?序,而用次設備號來標識具體物理設備。因此在創建字符設備之前,必須先獲?得設備的編號(可能需要分配多個設備號)。

在?Linux?2.6?的版本中,用?dev_t?類型來描述設備號(dev_t?是?32?位數值類型,其?中高?12?位表示主設備號,低?20?位表示次設備號)。用兩個宏?MAJOR?和?MINOR?分別?獲得?dev_t?設備號的主設備號和次設備號,而且用?MKDEV?宏來實現逆過程,即組合?主設備號和次設備號而獲得?dev_t?類型設備號。

分配設備號有靜態和動態的兩種方法。靜態分配(register_chrdev_region()函數)是?指在事先知道設備主設備號的情況下,通過參數函數指定第一個設備號(它的次設備?號通常為?0)而向系統申請分配一定數目的設備號。動態分配(alloc_chrdev_region())?是指通過參數僅設置第一個次設備號(通常為?0,事先不會知道主設備號)和要分配?的設備數目而系統動態分配所需的設備號。通過?unregister_chrdev_region()函數釋放已分配的(無論是靜態的還是動態的)設?備號。

在Linux 2.6內核中的字符設備用cdev結構來描述,其定義如下:

struct?cdev? ? { ? ????struct?kobject?kobj; ? ????struct?module?*owner;?//所屬模塊 ? ????const?struct?file_operations?*ops;?//文件操作結構 ? ????struct?list_head?list; ? ????dev_t?dev;?//設備號,int?類型,高12位為主設備號,低20位為次設備號 ? ????unsigned?int?count; ? }; ?

下面一組函數用來對cdev結構進行操作: struct?cdev?*cdev_alloc(void);//分配一個cdev ? void?cdev_init(struct?cdev?*,?const?struct?file_operations?*);//初始化cdev的file_operation ? void?cdev_put(struct?cdev?*p);//?//減少使用計數 ? //注冊設備,通常發生在驅動模塊的加載函數中 ? int?cdev_add(struct?cdev?*,?dev_t,?unsigned);? ? //注銷設備,通常發生在驅動模塊的卸載函數中 ? void?cdev_del(struct?cdev?*);??

使用cdev_add注冊字符設備前應該先調用register_chrdev_region或alloc_chrdev_region分配設備號。register_chrdev_region函數用于指定設備號的情況,alloc_chrdev_region函數用于動態申請設備號,系統自動返回沒有占用的設備號。

int?register_chrdev_region(dev_t?from,?unsigned?count,?const?char?*name)?; ? int?alloc_chrdev_region(dev_t?*dev,unsigned?baseminor,unsigned?count,const?char?*name);?

函數傳入值

first:要分配的設備號的初始值

?count:要分配(釋放)的設備號數目

?name:要申請設備號的設備名稱(在/proc/devices?和?sysfs?中顯示)?

dev:動態分配的第一個設備號

函數返回值

??????????????? 成功:0(只限于兩種注冊函數)

??????????????? 出錯:?1(只限于兩種注冊函數)

alloc_chrdev_region申請一個動態主設備號,并申請一系列次設備號。baseminor為起始次設備號,count為次設備號的數量。注銷設備號(cdev_del)后使用unregister_chrdev_region:
  • void?unregister_chrdev_region(dev_t?from,unsigned?count)?;?
  • 這里講解?2.6?內核中的字符設備的注冊和注銷過程。

    在?Linux?內核中使用?struct?cdev?結構來描述字符設備,我們在驅動程序中必?須將已分配到的設備號以及設備操作接口(即為?struct?file_operations?結構)賦予?struct?cdev?結構變量。首先使用?cdev_alloc()函數向系統申請分配?struct?cdev?結構,?再用?cdev_init()函數初始化已分配到的結構并與?file_operations?結構關聯起來。最?后調用?cdev_add()函數將設備號與?struct??cdev?結構進行關聯并向內核正式報告新?設備的注冊,這樣新設備可以被用起來了。

    如果要從系統中刪除一個設備,則要調用?cdev_del()函數。

    例1.4? cdev_add注冊字符設備實例

    代碼見光盤\src\1drivermodel\1-4cdev。核心代碼如下所示:

  • struct?file_operations?simple_fops?=?{ ?
  • ????.owner?=????THIS_MODULE, ?
  • ????.read?=?????simple_read, ?
  • ????.write?=????simple_write, ?
  • ????.open?=?????simple_open, ?
  • ????.release?=??simple_release, ?
  • }; ?
  • /******************************************************* ?
  • ????????????????MODULE?ROUTINE ?
  • *******************************************************/ ?
  • void?simple_cleanup_module(void) ?
  • { ?
  • ????dev_t?devno?=?MKDEV(simple_MAJOR,?simple_MINOR); ?
  • ????if?(simple_devices)? ?
  • ????{ ?
  • ????????cdev_del(&simple_devices->cdev); ?
  • ????????kfree(simple_devices); ?
  • ????} ?
  • ????unregister_chrdev_region(devno,1); ?
  • } ?
  • //模塊初始化 ?
  • int?simple_init_module(void) ?
  • { ?
  • ????int?result; ?
  • ????dev_t?dev?=?0; ?
  • ????dev?=?MKDEV(simple_MAJOR,?simple_MINOR); ?
  • ????result?=?register_chrdev_region(dev,?1,?"DEMO");//申請設備號 ?
  • ????if?(result?<?0)? ?
  • ????{ ?
  • ????????printk(KERN_WARNING?"DEMO:?can't?get?major?%d\n",?simple_MAJOR); ?
  • ????????return?result; ?
  • ????} ?
  • ????simple_devices?=?kmalloc(sizeof(struct?simple_dev),?GFP_KERNEL); ?
  • ????if?(!simple_devices) ?
  • ????{ ?
  • ????????result?=?-ENOMEM; ?
  • ????????goto?fail; ?
  • ????} ?
  • ????memset(simple_devices,?0,?sizeof(struct?simple_dev)); ?
  • ????//初始化設備結構 ?
  • ????cdev_init(&simple_devices->cdev,?&simple_fops); ?
  • ????simple_devices->cdev.owner?=?THIS_MODULE; ?
  • ????simple_devices->cdev.ops?=?&simple_fops; ?
  • ????result?=?cdev_add?(&simple_devices->cdev,?dev,?1);//添加字符設備 ?
  • ????if(result) ?
  • ????{ ?
  • ????????printk(KERN_NOTICE?"Error?%d?adding?DEMO\n",?result); ?
  • ????????goto?fail; ?
  • ????} ?
  • ????return?0; ?
  • fail: ?
  • ????simple_cleanup_module(); ?
  • ????return?result; ?
  • } ?
  • module_init(simple_init_module); ?
  • module_exit(simple_cleanup_module); ?
  • 本例的應用層代碼與運行結果同上例。 與50位技術專家面對面20年技術見證,附贈技術全景圖

    總結

    以上是生活随笔為你收集整理的使用cdev_add注册字符设备的全部內容,希望文章能夠幫你解決所遇到的問題。

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