struct device 結構
阿新 • • 發佈:2018-12-30
一、定義:
linux/include/linux/device.h
二、作用:
用於描述裝置相關的資訊裝置之間的層次關係,以及裝置與匯流排、驅動的關係。
三、詳解:
1、struct klist klist_children;
struct klist被定義在linux/include/linux/klist.h中,原型是:
可見它是對struct list_head的擴充套件,在此它的作用是連線裝置列表中的孩子列表。
2、struct klist_node knode_parent; /* node in sibling list */
struct klist_node被定義在linux/include/linux/klist.h,原型是:
在此它的作用是表示它的兄弟節點。
3、struct klist_node knode_driver;
表示它的驅動節點。
4、struct klist_node knode_bus;
表示匯流排節點。
5、struct device *parent;
指向其父裝置。
6、struct kobject kobj;
這裡http://blog.chinaunix.net/u1/55599/showart.php?id=1086478有對kobject的解釋,此處它是內嵌的一個kobject物件。
7、char bus_id[BUS_ID_SIZE];
bus_id表示其在父總線上的位置。BUS_ID_SIZE被定義為:
所以表示位置的字串長度不能超過20。
8、struct device_type *type;
被定義在/linux/include/linux/device.h中,原型是:
device_type結構表示裝置的型別。一個裝置類或者匯流排可以包含不同型別的裝置,例如“分割槽”和“磁碟” , “滑鼠”和“事件” 。device_type就可以標識某個裝置型別和該裝置的特有資訊,它就等同於kobject結構中的kobj_type一樣。如果name資料成員被指定,那麼uevent成員函式就會把它包含在DEVTYPE變數中。
9、unsigned is_registered:1;
標識該裝置是否已經被註冊過。is_registered:1這樣的形式表示is_registered這個變數只有一位。在32位linux系統下,unsigned是4位元組32位,而經過is_registered:1這樣的限制後,變數is_registered只有一位,其取值只能是1或者0,相當於聲明瞭一個boolean型別的變數。在此種用法中,後面指定資料寬度的值只能大於0且小於本身的資料寬度。
10、struct bus_type * bus;
指向所連線匯流排的指標。
11、struct device_driver *driver;
指向被分配到該裝置的裝置驅動。
12、u64 *dma_mask; /*指向裝置DMA遮蔽字。*/
u64 coherent_dma_mask;/*裝置一致性DMA的遮蔽字。*/
struct list_head dma_pools; /*聚集的DMA緩衝池。*/
struct dma_coherent_mem *dma_mem; /*指向裝置所使用的一致性DMA儲存器描述符的指標*/
13、spinlock_t devres_lock;
定義一個裝置自旋鎖,用於互斥訪問裝置。關於自旋鎖的詳細講解參考:
http://www.deansys.com/doc/ldd3/ch05s05.html
14、void (*release)(struct device * dev);
釋放裝置描述符的回撥函式。
四、操作:
linux核心系統了一系列完整的對device操作的函式。
1、其中device_register()函式用來將一個新的device物件插入裝置模型。它在linux/drivers/base/core.c中被實現:
該函式首先是呼叫device_initialize()初始化device結構,具體是初始化嵌入的kobject結構dev->kobj,初始化列表中的孩子列表kobj->klist_children,初始化DMA緩衝池dev->dma_pools,初始化自旋鎖dev->devres_lock等。接下來device_add()函式才真正將該device物件dev插入裝置模型中。device_add()函式首先是通過kboject_add()函式將它新增到kobject層次,再把它新增都全域性和兄弟連結串列中,最後新增到其他相關的子系統的驅動程式模型,完成device物件的註冊。
2、device_unregister()完成相反的過程:/linux/drivers/base/core.c
它會先以KERN_DEBUG級別列印登出裝置的資訊,然後才真正刪除裝置,減少裝置物件的引用計數。
3、get_device()和put_device()分別是增加和減少裝置物件的引用計數。這兩個函式都定義在:/linux/drivers/base/core.c中。具體是應用在註冊device物件時,device_add()函式會呼叫get_device()增加對該device物件的引用計數。在登出裝置物件時,device_unregister()函式直接呼叫put_device()函式減少對該device物件的引用計數。
linux/include/linux/device.h
407struct device { |
二、作用:
用於描述裝置相關的資訊裝置之間的層次關係,以及裝置與匯流排、驅動的關係。
三、詳解:
1、struct klist klist_children;
struct klist被定義在linux/include/linux/klist.h中,原型是:
可見它是對struct list_head的擴充套件,在此它的作用是連線裝置列表中的孩子列表。
2、struct klist_node knode_parent; /* node in sibling list */
struct klist_node被定義在linux/include/linux/klist.h,原型是:
在此它的作用是表示它的兄弟節點。
3、struct klist_node knode_driver;
表示它的驅動節點。
4、struct klist_node knode_bus;
表示匯流排節點。
5、struct device *parent;
指向其父裝置。
6、struct kobject kobj;
這裡http://blog.chinaunix.net/u1/55599/showart.php?id=1086478有對kobject的解釋,此處它是內嵌的一個kobject物件。
7、char bus_id[BUS_ID_SIZE];
bus_id表示其在父總線上的位置。BUS_ID_SIZE被定義為:
#define KOBJ_NAME_LEN 20 /*linux/include/linux/kobject.h*/ #define BUS_ID_SIZE KOBJ_NAME_LEN /*linux/include/linux/device.h*/ |
所以表示位置的字串長度不能超過20。
8、struct device_type *type;
被定義在/linux/include/linux/device.h中,原型是:
device_type結構表示裝置的型別。一個裝置類或者匯流排可以包含不同型別的裝置,例如“分割槽”和“磁碟” , “滑鼠”和“事件” 。device_type就可以標識某個裝置型別和該裝置的特有資訊,它就等同於kobject結構中的kobj_type一樣。如果name資料成員被指定,那麼uevent成員函式就會把它包含在DEVTYPE變數中。
9、unsigned is_registered:1;
標識該裝置是否已經被註冊過。is_registered:1這樣的形式表示is_registered這個變數只有一位。在32位linux系統下,unsigned是4位元組32位,而經過is_registered:1這樣的限制後,變數is_registered只有一位,其取值只能是1或者0,相當於聲明瞭一個boolean型別的變數。在此種用法中,後面指定資料寬度的值只能大於0且小於本身的資料寬度。
10、struct bus_type * bus;
指向所連線匯流排的指標。
11、struct device_driver *driver;
指向被分配到該裝置的裝置驅動。
12、u64 *dma_mask; /*指向裝置DMA遮蔽字。*/
u64 coherent_dma_mask;/*裝置一致性DMA的遮蔽字。*/
struct list_head dma_pools; /*聚集的DMA緩衝池。*/
struct dma_coherent_mem *dma_mem; /*指向裝置所使用的一致性DMA儲存器描述符的指標*/
13、spinlock_t devres_lock;
定義一個裝置自旋鎖,用於互斥訪問裝置。關於自旋鎖的詳細講解參考:
http://www.deansys.com/doc/ldd3/ch05s05.html
14、void (*release)(struct device * dev);
釋放裝置描述符的回撥函式。
四、操作:
linux核心系統了一系列完整的對device操作的函式。
1、其中device_register()函式用來將一個新的device物件插入裝置模型。它在linux/drivers/base/core.c中被實現:
該函式首先是呼叫device_initialize()初始化device結構,具體是初始化嵌入的kobject結構dev->kobj,初始化列表中的孩子列表kobj->klist_children,初始化DMA緩衝池dev->dma_pools,初始化自旋鎖dev->devres_lock等。接下來device_add()函式才真正將該device物件dev插入裝置模型中。device_add()函式首先是通過kboject_add()函式將它新增到kobject層次,再把它新增都全域性和兄弟連結串列中,最後新增到其他相關的子系統的驅動程式模型,完成device物件的註冊。
2、device_unregister()完成相反的過程:/linux/drivers/base/core.c
1044void device_unregister(struct device * dev) |
它會先以KERN_DEBUG級別列印登出裝置的資訊,然後才真正刪除裝置,減少裝置物件的引用計數。
3、get_device()和put_device()分別是增加和減少裝置物件的引用計數。這兩個函式都定義在:/linux/drivers/base/core.c中。具體是應用在註冊device物件時,device_add()函式會呼叫get_device()增加對該device物件的引用計數。在登出裝置物件時,device_unregister()函式直接呼叫put_device()函式減少對該device物件的引用計數。