Linux裝置驅動-platform虛擬匯流排dya02
阿新 • • 發佈:2018-12-20
參考書:<linux裝置驅動開發詳解>宋寶華
上一篇介紹了platform的基本構成與原始碼,本篇用例項來說明platform的實現.
參考書中介紹了一個名為globalfifo的驅動,以他為例,來說明作為platfrom裝置如何實現驅動和裝置的匹配. 將globalfifo驅動掛接到platform總線上,要完成兩部分工作: (1)將globalfifo移植為platform驅動 (2)在板檔案中新增globalfifo這個platform裝置
1.移植 為完成globalfifo移植到platform驅動的工作,需要在原始的字元裝置globalfifo驅動中套一層platfrom_driver外殼. 這一步驟並沒有改變globalfifo字元裝置的本質,只是將其掛接到了platform總線上.
static int globalfifo_probe(struct platform_device *pdev) { int ret; dev_t devno = MKDEV(globalfifo_major,0); //定義裝置號,資料型別dev_t,32位數 if (globalfifo_major) //靜態申請 ret = register_chrdev_region(devno,1,"globalfifo");//申請字元裝置驅動,1表示申請的連續裝置編號的個數,globalfifo是裝置名稱 else{ //靜態申請失敗 ret = alloc_chrdev_region(&devno,0,1,"globalfifo"); //0表示請求的第一個次裝置號,1表示個數 globalfifo_major = MAJOR(devno); } if (ret < 0) return ret; globalfifo_devp = devm_kzalloc(&pdev->dev,sizeof(*globalfifo_devp),GFP_KERNEL); if (!globalfifo_devp) { ret = -ENOMEM; goto fail_malloc; } globalfifo_setup_cdev(globalfifo_devp,0); //cdev初始化和新增 mutex_init( &globalfifo_devp->mutex); init_waitqueue_head(&globalfifo_devp->r_wait); //初始化佇列頭 init_waitqueue_head(&globalfifo_devp->w_wait); return 0; fail_malloc: unregister_chrdev_region(devno,1); return ret; } static int globalfifo_remove(struct platform_device *pdev) { cdev_del(&globalfifo_devp->cdev);//刪除cdev結構體 unregister_chrdev_region(MKDEV(globalfifo_major,0),1);//登出裝置區域 return 0; } static struct platform_driver globalfifo_driver = { .driver = { .name = "globalfifo", .owner = THIS_MODULE, }, .probe = globalfifo_probe, .remove = globalfifo_remove, }; module_platform_driver(globalfifo_driver);
註冊完globalfifo對應的platform_driver後,會發現/sys/bus/platform/drivers目錄下多出一個名叫globalfifo的子目錄. 板檔案arch/arm/mach-<soc名>/mach-<板名>.c中新增如下程式碼:
static struct platform_device globalfifo_device = {
.name = "globalfifo",
.id = -1,
};
如果一切順利,會在/sys/devices/platform目錄下看到一個名為globalfifo的子目錄 /sys/devices/platfrom/globalfifo中會有一個driver檔案,指向/sys/bus/platform/drivers/globalfifo的符號連結, 證明驅動和裝置匹配上了.