在linux中,一開始bus下的device有乙個device鍊錶,driver也有乙個鍊錶,當註冊platform_device的時候,會把新的platform_device結構體放入device鍊錶,然後從driver的鍊錶中把已有的driver乙個乙個地取出來跟platform_device結構體中的name進行比較,如果匹配的話,就會呼叫platform_driver結構體中的probe函式,此時才會成功建立裝置節點。反之先註冊driver也一樣,所以先註冊platform_device還是先註冊platform_driver都可以,最終如果匹配,都會去呼叫platform_driver中的probe函式。
在platform_device.h檔案中定義了platform_device與platform_driver結構體:
struct platform_device ;
struct platform_driver ;
在platform_driver結構體中,成員platform_device_id結構體中有成員name:
struct platform_device_id ;
成員struct device_driver中也有成員name:
struct device_driver ;
platform_device與platform_driver通過platform.c檔案中的platform_match函式進行匹配,優先比較id_table,如果沒有id_table,則比較pdev->name與pdrv->name:
static int platform_match(struct device *dev, struct device_driver *drv)
在match函式中通過platform_match_id函式進行兩者的比較:
static const struct platform_device_id *platform_match_id(const struct platform_device_id *id, struct platform_device *pdev)
id++;
} return null;
}
傳統的字元裝置驅動程式寫法思路是這樣的:
分配、設定乙個file_operations結構體,通過file_operations結構體中的成員函式完成對led的驅動,完善led_open函式,led_write函式和led_release函式。
static int led_open(struct inode *node, struct file *filp)
static ssize_t led_write(struct file *filp, const char __user *buf, size_t size, loff_t *off)
static int led_release(struct inode *node, struct file *filp)
static struct file_operations myled_oprs = ;
通過init函式與exit函式完成字元裝置的註冊或解除安裝,類與裝置節點的建立和登出:
static int myled_init(void)
static void myled_exit(void)
以上是傳統字元裝置驅動程式的框架結構。
而在匯流排裝置驅動模型中,乙個字元裝置驅動程式的框架是這樣的,需要有device.c和driver.c兩個檔案,device檔案中通過platform_device結構體中的成員指定硬體資源:
static struce resource led_resource = ,
};static void led_release(struct device * dev)
/* 分配/設定乙個platform_device */
static struct platform_device led_dev = ;
/* 註冊platform_device */
static int led_dev_init(void)
/* 解除安裝platform_device */
static void led_dev_exit(void)
module_init(led_dev_init);
module_exit(led_dev_exit);
module_license("gpl");
在driver檔案中是分配、設定乙個platform_driver結構體,包含probe函式與remove函式:
struct platform_driver led_drv =
};
傳統字元裝置驅動程式的init函式中對字元裝置的註冊、類的建立與裝置節點的建立現在在probe函式中完成:
static int led_probe(struct platform_device * pdev)
在probe函式中會呼叫file_operations結構體中的open函式、write函式等,但該open函式中不再進行字元裝置的註冊等操作,release函式中不再進行字元裝置的解除安裝等操作:
static int led_open(struct inode *node, struct file *filp)
static ssize_t led_write(struct file *filp, const char __user *buf, size_t size, loff_t *off)
else
return 1; /* 已寫入1個資料 */
}static int led_release(struct inode *node, struct file *filp)
static struct file_operations myled_oprs = ;
對字元裝置的解除安裝、類與裝置節點的登出在remove函式中完成:
static int led_remove(struct platform_device * pdev)
現在的init函式中只是註冊platform_driver,在exit函式中解除安裝platform_driver:
static int myled_init(void)
static void myled_exit(void)
匯流排 裝置 驅動模型
裝置元素 匯流排,驅動,裝置 匯流排 處理器和裝置之間的通道,在裝置模型中,所有的裝置都通過匯流排相連,甚至是內部的虛擬 platform 匯流排 定時器,看門狗並沒有直接相連 在linux裝置模型中,匯流排由bus type結構表示,定義在 匯流排的註冊使用 bus register struct...
匯流排裝置驅動模型
匯流排裝置驅動模型 匯流排是主機和裝置之間的通道,由bus type 結構描述。int bus register struct bus type bus 匯流排的註冊,若成功,新的匯流排將被新增進系統,並可在 sysfs 的 sys bus 下看到。void bus unregister struc...
匯流排裝置驅動模型
匯流排 乙個匯流排是處理器和乙個或多個裝置之間的通道。為裝置模型的目的,所有的裝置都通過乙個匯流排連線,甚至當它是乙個內部的虛擬的 平台 匯流排。裝置 裝置就是連線在匯流排上的物理實體。裝置是有功能之分的。具有相同功能的裝置被歸到乙個類 class 中。在linux 系統中,每個裝置由乙個 stru...