歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> Linux技術

Linux設備驅動(2)字符設備

設備號

設備號由主設備號和次設備號組成。linux下,一切設備皆文件,所有的設備都能在/dev目錄下找到相應的文件。這些文件除了名字不一樣以外,還每個設備文件都有不一樣的設備號; 一般地,主設備號對應一個類型的驅動設備,之所以有次設備號,它是用來驅動同類型的設備。如串口,所有的串口共用一個主設備號,每個串口有不同的次設備號。

dev_t類型用來保存設備編號(包含主設備號和次設備號),實際上是一個32位整數,12位用來表示主設備號,後20位表示次設備號。

[code]#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))

設備號的分配和釋放

靜態分配

[code]/**
 * 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.
 */
int register_chrdev_region(dev_t from, unsigned count, const char *name)
指定從設備號from開始,申請count個設備號,在/proc/devices中的名字為name

動態分配

[code]int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)
動態申請從次設備號baseminor開始的count個設備號,在/proc/devices中的名字為name,並通過dev指針把分配到的設備號返回給調用函數者。

釋放

[code]void unregister_chrdev_region(dev_t from, unsigned count)

設備注冊

字符設備struct cdev

[code]struct cdev {
    struct kobject kobj;
    struct module *owner;//一般初始化為THIS_MODULE
    const struct file_operations *ops;//文件操作結構體
    struct list_head list;
    dev_t dev;//設備號
    unsigned int count;//添加的設備個數
};
注冊的三個步驟:

1)分配cdev;

2)初始化cdev;

3)添加cdev;

分配

直接定義struct cdev test_cdev;或者動態分配

truct cdev* test_cdev;

test_cdev = cdev_alloc();

初始化

[code]/**
 * cdev_init() - initialize a cdev structure
 * @cdev: the structure to initialize
 * @fops: the file_operations for this device
 *
 * Initializes @cdev, remembering @fops, making it ready to add to the
 * system with cdev_add().
 */
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
這個函數干了兩件事情:

1)內核自己填充了結構體中list和kobj的內容

2)把傳入的文件操作結構體也填充進去

一般的,還要手工定義結構體成員owner。

添加

將cdev結構體與設備號關聯起來:
[code]int cdev_add(struct cdev *cdev, dev_t dev, unsigned count)

參數:

cdev:指定要被添加的cdev結構體;

dev:對應的設備號

count:從設備號dev開始添加count個設備.

函數干了也兩件事:

1)把cdev結構體中還沒填充的兩個成員dev和count按照傳入參數賦值。

2)把cdev結構體中傳入內核,這樣內核就知道對應設備號和具體的文件操作結構體了。

刪除

[code]void cdev_del(struct cdev *p)

Copyright © Linux教程網 All Rights Reserved