[ARM-Linux開發] 主裝置號--驅動模組與裝置節點聯絡的紐帶__Linux

來源:互聯網
上載者:User
一、如何對裝置操作
linux中對裝置進行操作是通過檔案的方式進行的,包括open、read、write。
對於裝置檔案,一般稱其為裝置節點,
節點有一個屬性是裝置號(主裝置號、次裝置號),其中主裝置號將裝置檔案與驅動模組對應起來


當我們open一個裝置節點時,告訴了kernel要操作的是是主裝置號為XX的節點,然後kernel會通過過XX來尋找合適的記憶體模組,進而調用記憶體模組中定義的open函數

由於動作節點之前kernel就需要有主裝置號的資訊,因此主裝置號的申請、具有該主裝置號的字元裝置的添加都需要在驅動模組的初始化函數中執行

二、主裝置號的申請 建議採用動態申請的主裝置號的方式,linux中有很多裝置,每一個裝置對應著一個主裝置號,動態申請是由核心分配一個沒用的主

裝置號,
動態申請函數為alloc_chrdev_region,相對應的釋放函數為unregister_chrdev_region。
申請完後,可以從/proc/devices中讀到分配的主裝置號,後面建立裝置節點時還需要用到

三、向kernle添加字元裝置 上一步向核心申請了主裝置號,就可以向kernel中添加字元裝置了
kennel中一個字元裝置對應了一個結構體cdev,這個結構體中定義了對字元裝置的操作方式file_operations(包括open、read、write),這些操作方式也需要在驅動模組中事先定義好。


字元裝置結構體cdev的添加步驟:
cdev初始化:cdev_init,該函數將file_operations與cdev對應起來
向kernel添加:cdev_add,該函數將主裝置號與cdev結構體對應起來

當對open裝置節點時,首先通過節點找到主裝置號,然後再kernel中搜尋與主裝置號相對應的字元裝置cdev,然後動過cdev中file_operations結構體定義的open方法(這個open是需要自己實現的)


四、3個重要的結構體 一個是file_operations,這裡面主要包含了驅動的主要實現方法
一個是inode,這個是節點的資訊,包含了主裝置號和cdev結構體
一個是file,當節點首次被開啟時,就會在核心中建立一個file結構體,file結構其充當了file_operations中方法的紐帶,要不然read和wirte方法怎麼知道操作的是那個裝置的資料。

file中的自訂內容(驅動需要的資料)一般是在open中定義,然後read和write就可以操作自訂的資料了。



下面是一個簡單的執行個體,可以看到驅動是怎樣把自訂的open方法和主裝置號對應起來的


#include <linux/module.h>  /*它定義了模組的 API、類型和宏(MODULE_LICENSE、MODULE_AUTHOR等等),所有的核心模組都必須包含這個標頭檔。*/   
#include <linux/init.h>  
#include <linux/fs.h> //裝置號相關函數  
#include <linux/slab.h> //記憶體配置相關函數  
#include <linux/types.h>  
#include <linux/kdev_t.h>//裝置號相關函數  
#include <linux/cdev.h>//字元裝置標頭檔  
#include <linux/module.h>  
  
struct char_dev  
{  
    int size;  
    char *data;  
    struct cdev cdev;//核心中的字元裝置  
};  
  
int major = 0;  
int minor = 0;  
struct char_dev char_devices;  
  
int char_open(struct inode *inode, struct file *filep)  
{  
    int Major = 0;  
    Major = MAJOR(inode->i_rdev);  
    printk("open my_char_dev major: %d\n", Major);  
      
    return 0;  
}  
  
struct file_operations char_fops = {  
    .owner = THIS_MODULE,  
    .open = char_open,  
};  
  
  
  
  
static void char_exit(void) //如果init函數中調用了該函數,則不應有 __exit  
{  
    dev_t dev;  
    printk("char device driver exit \n");  
    //釋放裝置號  
    dev = MKDEV(major, minor);  
    unregister_chrdev_region(dev, 1);  
    printk("release major %d\n", major);  
      
    //釋放記憶體  
    if(char_devices.data){  
        kfree(char_devices.data);  
    }  
      
    //從核心中刪除字元裝置  
    cdev_del(&(char_devices.cdev));  
}  
  
static int __init char_init(void)//__init一個標記,表明是初始化函數  
{  
    //初始化的代碼  
    dev_t dev;  
    int result;   
    printk("char device driver init \n");  
      
    //動態向核心申請裝置號      
    result = alloc_chrdev_region(&dev, 0, 1, "my_char_dev");  
    major = MAJOR(dev);  
    minor = MINOR(dev);  
    printk("alloc major %d\n", major);  
    if (result < 0) {  
        printk(KERN_WARNING "my_char_dev: can't get major %d\n", major);  
        return result;  
    }  
      
    //為裝置分配一塊記憶體  
    char_devices.size = 100;  
    char_devices.data = (char*)kmalloc(char_devices.size, GFP_KERNEL);  
    if (!char_devices.data) {  
        result = -ENOMEM;  
        goto fail;  //不能直接退出函數,需要釋放裝置號  
    }  
      
    //向核心中添加字元裝置cdev  
    cdev_init(&(char_devices.cdev), &char_fops);  
    char_devices.cdev.owner = THIS_MODULE;  
    char_devices.cdev.ops = &char_fops;  
    result = cdev_add(&(char_devices.cdev), dev, 1);  
    if((result < 0)) {  
        printk(KERN_WARNING "Error %d adding my_char_dev\n", result);  
        goto fail;  
    }  
  
    return 0; //成功  
fail:  
    char_exit();  
    return result;  
}  
  
MODULE_LICENSE("Dual BSD/GPL");  
//當模組被載入時,執行moudle_init函數,該函數會調用初始化函數  
module_init(char_init);  
//模組卸載時,調用,釋放資源  
module_exit(char_exit);   


KDIR=/usr/src/linux-headers-$(shell uname -r)


PWD=$(shell pwd)


obj-m = CharDevice.o


all:
$(MAKE) -C $(KDIR) M=$(PWD)


註:驅動insmod後,通過/proc/devices查看主裝置號,然後通過mknod在/dev下建立裝置節點,注意保持主裝置好的一致,當前的節點只支援open方法,可以在demsg中進行驗證。







聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.