linux驅動模型 - 設備

TheBasic Device Structure

~~~~~~~~~~~~~~~~~~~~~~~~~~

See the kerneldoc for the struct device.

 

 

ProgrammingInterface

~~~~~~~~~~~~~~~~~~~~~

檢測到設備的總線驅動使用如下函數將設備註冊到內核:

int device_register(struct device * dev);

 

總線負責初始化device結構的下列域:

    - parent

    - name

    - bus_id

    - bus

 

當設備的reference count變爲0時,會從內核中移除. 使用下列函數調整reference count

struct device * get_device(struct device * dev);

void put_device(struct device * dev);

 

如果reference count還不是0(如果正好處於移除的過程中),get_device()會返回指向傳遞給它的struct device的指針.

 

驅動可以使用下列函數訪問device結構中的lock:

void lock_device(struct device * dev);

void unlock_device(struct device * dev);

 

 

Attributes

~~~~~~~~~~

struct device_attribute {

         structattribute        attr;

         ssize_t(*show)(struct device *dev, struct device_attribute *attr, char *buf);

         ssize_t (*store)(struct device *dev,struct device_attribute *attr,        const char *buf, size_t count);

};

 

驅動可以使用一個類似於procfs(sysfs)的接口來導出設備的屬性。有關sysfs如何工作的內容,請參考Documentation/filesystems/sysfs.txt.

 

設備屬性可以通過宏DEVICE_ATTR聲明:

#define DEVICE_ATTR(name,mode,show,store)

 

Example:

DEVICE_ATTR(power,0644,show_power,store_power);

 

這個宏聲明瞭一個名爲'dev_attr_power'的device_attribute結構. 通過下列函數可以將屬性添加/移除到設備在/sysfs的目錄:

int device_create_file(struct device *device, structdevice_attribute * entry);

void device_remove_file(struct device * dev, structdevice_attribute * attr);

 

Example:

device_create_file(dev,&dev_attr_power);

device_remove_file(dev,&dev_attr_power);

 

該文件的名字是'power' ,訪問權限爲0644 (-rw-r--r--).

 

警告:  無論何時,當內核允許對一個設備調用device_create_file()和

device_remove_file(), 用戶空間對設備屬性何時被創建有嚴格的期望. 當一個新設備註冊到內核,會產生一個uevent以提示用戶空間(比如udev)有新設備可用. 如果屬性在設備註冊之後才添加,用戶空間則無從瞭解這個屬性.

 

對於設備驅動而言,在探測(probe)設備時要做的一項重要工作是爲設備發佈額外的屬性. 如果設備驅動只是簡單地對傳遞給它的device結構調用device_create_file(), 那麼用戶空間永遠無法獲得新屬性的通知. 相反地,設備驅動或許應當在模塊入口函數modules_init()中使用class_create() 和 class->dev_attrs創建一個屬性列表,而後在

.probe()中使用device_create()創建一個設備,作爲被探測到的設備的子設備. 這個新的設備會產生uevent並將新的屬性發布到用戶空間.

 

舉例來說,如果一個驅動想要增添如下屬性:

struct device_attribute mydriver_attribs[] = {

         __ATTR(port_count,0444, port_count_show),

         __ATTR(serial_number,0444, serial_number_show),

         NULL

};

 

在模塊入口函數中應該做:

         mydriver_class= class_create(THIS_MODULE, "my_attrs");

         mydriver_class.dev_attr= mydriver_attribs;

 

假設'dev' 是傳遞到probe()的參數,設備驅動的probe函數則要做:

         device_create(&mydriver_class,dev, chrdev, &private_data, "my_name");

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章