資源描述:
《Linux驅(qū)動(dòng)程序開發(fā)-設(shè)備驅(qū)動(dòng)模型》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在行業(yè)資料-天天文庫(kù)。
1、Linux驅(qū)動(dòng)程序開發(fā)-設(shè)備驅(qū)動(dòng)模型初探序言從這一章開始,我們將詳細(xì)的介紹Linux的設(shè)備驅(qū)動(dòng)模型。Linux設(shè)備驅(qū)動(dòng)模型是一個(gè)相當(dāng)復(fù)雜的系統(tǒng),對(duì)于初學(xué)者來(lái)說真有些無(wú)從入手。而且更加困難的是,隨著新的LinuxKernel的release,Linux的設(shè)備驅(qū)動(dòng)模型總會(huì)有或大或小的變化,我們將盡量展現(xiàn)LinuxKernel的這種變化。早期的Linux內(nèi)核(版本2.4之前)并沒有實(shí)現(xiàn)一個(gè)統(tǒng)一的設(shè)備模型,設(shè)備節(jié)點(diǎn)的創(chuàng)建一般是mknod命令手動(dòng)創(chuàng)建或利用devfs文件系統(tǒng)創(chuàng)建。早期的Linux發(fā)行版一般會(huì)采用手動(dòng)創(chuàng)建的方式預(yù)先把通常用到的節(jié)點(diǎn)都創(chuàng)建出來(lái),而嵌入式系統(tǒng)則會(huì)采用devfs的方
2、式。起初Linux2.6內(nèi)核還支持devfs,但從2.6.18開始,內(nèi)核完全移除了devfs系統(tǒng)而采用的udev的方式動(dòng)態(tài)的創(chuàng)建設(shè)備節(jié)點(diǎn)。因此,新的Linux發(fā)行版都采用udev的方式管理設(shè)備節(jié)點(diǎn)文件。(關(guān)于udev的詳細(xì)信息,請(qǐng)參考:http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html)。Linux2.6設(shè)備驅(qū)動(dòng)模型的基本元素是Class、Bus、Device、Driver,下面我們分別介紹各個(gè)部分。Class和ClassDevice驅(qū)動(dòng)模型最基本的概念是設(shè)備及其類別,Linux中使用structclass
3、和structclass_device來(lái)管理不同類別的設(shè)備。由于設(shè)備驅(qū)動(dòng)模型是一個(gè)復(fù)雜的系統(tǒng),我們還是從一個(gè)簡(jiǎn)單的例子開始介紹,然后在逐步展開。其實(shí)實(shí)現(xiàn)設(shè)備節(jié)點(diǎn)的動(dòng)態(tài)創(chuàng)建是一個(gè)很簡(jiǎn)單的事情,并不需要太多的代碼。我們修改我們的驅(qū)動(dòng)初始化函數(shù)如下:#include#defineDEVNAME"hello"staticdev_tdev;staticstructclass*hello_class;staticstructcdev*hello_cdev;staticint__inithello_init(void){???interror;???error=
4、alloc_chrdev_region(&dev,0,2,"hello");???if(error)???{???????printk("hello:alloc_chardev_regionfailed!");???????gotoout;???}???hello_cdev=cdev_alloc();???if(hello_cdev==NULL)???{???????printk("hello:alloccdevfailed!");???????error=-ENOMEM;???????gotoout_chrdev;???}???hello_cdev->ops=&hell
5、o_fops;???hello_cdev->owner=THIS_MODULE;???error=cdev_add(hello_cdev,dev,1);???if(error)???{???????printk("hello:cdev_addfailed!");???????gotoout_cdev;???}???hello_class=class_create(THIS_MODULE,DEVNAME);???if(IS_ERR(hello_class))???{???????error=PTR_ERR(hello_class);???????gotoout_chrdev;?
6、??}???class_device_create(hello_class,NULL,dev,NULL,DEVNAME);???memset(hello_buf,0,sizeof(hello_buf));???memcpy(hello_buf,DEFAULT_MSG,sizeof(DEFAULT_MSG));???printk("hello:HelloWorld!");???return0;out_cdev:???cdev_del(hello_cdev);out_chrdev:???unregister_chrdev_region(hello_cdev->dev,2);out
7、:???returnerror;}staticvoid__exithello_exit(void){???class_device_destroy(hello_class,dev);???class_destroy(hello_class);???unregister_chrdev_region(hello_cdev->dev,2);???cdev_del(hello_cdev);???printk("hello:GoodbyeWorld");}重新編譯這個(gè)驅(qū)動(dòng)程序,當(dāng)加載這