Linux下面一個簡單的虛擬platform驅動

來源:互聯網
上載者:User

/*
 * Yao.GUET
 * http://blog.csdn.net/Yao_GUET
 * Linux下面一個簡單的虛擬platform驅動
 */

在Linux之中,約定如果裝置不屬於任何的匯流排,則可以把它註冊為虛擬platform裝置。

下面就簡單來學習一下一個簡單的platform裝置是怎麼建立出來的。

一般註冊platform驅動的步驟是:

1,platform_device_create註冊一個裝置

2,platform_driver_create註冊一個驅動。

static struct platform_driver chrdev_platform_driver = {
    .probe  =   chrdev_probe,
    .remove =   chrdev_remove,
    .driver =   {
        .name   =   CHRDEV_NAME,
        .owner  =   THIS_MODULE,
    },
};

static struct platform_device chrdev_platform_device = {
    .name   =   CHRDEV_NAME,
    .id     =   0,
    .dev    =   {
    }
};

platform_device和platform_driver的名字必須一致

然後在chrdev_probe中完成註冊一個字元裝置。一般註冊字元裝置的流程如下:

1,alloc_chrdev_region分配一個未使用的裝置號

2,cdev_init和cdev_add使用(1)分配到的裝置號添加一個字元裝置

如果到這裡就結束了,我們就需要使用分配到的裝置號手動去建立/dev下面的裝置節點,,,

在這裡可以使用class_create和device_create讓udev deamon自動為我們建立裝置節點

3,class_create(THIS_MODULE, "chrdev");

4,device_create(chrdev_class, NULL, chrdev_devno, NULL, "chrdev");

當使用insmod把模組載入到系統之後,就會在/dev下面自動建立名為"chrdev"的裝置節點,模組名字應該盡量跟註冊驅動的名字一致,不然可能會遇到不可測的問題。

源檔案:chrdev.c

#include <linux/module.h>#include <linux/init.h>#include <linux/platform_device.h>#include <linux/cdev.h>#include <linux/fs.h>/////////////////////////////////////////////////////////////////////////////////*  * Yao.GUET * http://blog.csdn.net/Yao_GUET * a simple platform character driver */////////////////////////////////////////////////////////////////////////////////MODULE_LICENSE("Dual BSD/GPL");////////////////////////////////////////////////////////////////////////////////static int chrdev_open(struct inode *inode, struct file *file) {    printk(KERN_ALERT "chrdev open!\n");    return 0;}static int chrdev_release(struct inode *inode, struct file *file) {    printk(KERN_ALERT "chrdev release!\n");    return 0;}static int chrdev_ioctl(struct inode *inode, struct file *file,    unsigned int cmd, unsigned long arg) {    printk(KERN_ALERT "chrdev release!\n");    return 0;}// Kernel interfacestatic struct file_operations chrdev_fops = {    .owner      =   THIS_MODULE,    .ioctl      =   chrdev_ioctl,    .open       =   chrdev_open,    .release    =   chrdev_release,};#define CHRDEV_NAME "chrdev"// driver interfacestatic struct class *chrdev_class = NULL;static struct device *chrdev_device = NULL;static dev_t chrdev_devno;static struct cdev chrdev_cdev;static int chrdev_probe(struct platform_device *dev) {    int ret = 0, err = 0;        printk(KERN_ALERT "chrdev probe!\n");        // alloc character device number    ret = alloc_chrdev_region(&chrdev_devno, 0, 1, CHRDEV_NAME);    if (ret) {        printk(KERN_ALERT " alloc_chrdev_region failed!\n");        goto PROBE_ERR;    }    printk(KERN_ALERT " major:%d minor:%d\n", MAJOR(chrdev_devno), MINOR(chrdev_devno));        cdev_init(&chrdev_cdev, &chrdev_fops);    chrdev_cdev.owner = THIS_MODULE;    // add a character device    err = cdev_add(&chrdev_cdev, chrdev_devno, 1);    if (err) {        printk(KERN_ALERT " cdev_add failed!\n");        goto PROBE_ERR;    }        // create the device class    chrdev_class = class_create(THIS_MODULE, CHRDEV_NAME);    if (IS_ERR(chrdev_class)) {        printk(KERN_ALERT " class_create failed!\n");        goto PROBE_ERR;    }        // create the device node in /dev    chrdev_device = device_create(chrdev_class, NULL, chrdev_devno,        NULL, CHRDEV_NAME);    if (NULL == chrdev_device) {        printk(KERN_ALERT " device_create failed!\n");        goto PROBE_ERR;    }        printk(KERN_ALERT " chrdev probe ok!\n");    return 0;    PROBE_ERR:    if (err)        cdev_del(&chrdev_cdev);    if (ret)         unregister_chrdev_region(chrdev_devno, 1);    return -1;}static int chrdev_remove (struct platform_device *dev) {    printk(KERN_ALERT " chrdev remove!\n");        cdev_del(&chrdev_cdev);    unregister_chrdev_region(chrdev_devno, 1);        device_destroy(chrdev_class, chrdev_devno);    class_destroy(chrdev_class);    return 0;}// platform_device and platform_driver must has a same name!// or it will not work normallystatic struct platform_driver chrdev_platform_driver = {    .probe  =   chrdev_probe,    .remove =   chrdev_remove,    .driver =   {        .name   =   CHRDEV_NAME,        .owner  =   THIS_MODULE,    },};static struct platform_device chrdev_platform_device = {    .name   =   CHRDEV_NAME,    .id     =   0,    .dev    =   {    }};static __init int chrdev_init(void) {    int ret = 0;    printk(KERN_ALERT "chrdev init!\n");        ret = platform_device_register(&chrdev_platform_device);    if (ret) {        printk(KERN_ALERT " platform_device_register failed!\n");        return ret;    }        ret = platform_driver_register(&chrdev_platform_driver);    if (ret) {        printk(KERN_ALERT " platform_driver_register failed!\n");        return ret;    }    printk(KERN_ALERT " chrdev_init ok!\n");    return ret;}static __exit void chrdev_exit(void) {    printk(KERN_ALERT "chrdev exit!\n");    platform_driver_unregister(&chrdev_platform_driver);}module_init(chrdev_init);module_exit(chrdev_exit);

Makefile:

### Makefileobj-m := chrdev.oKERNEL_DIR := /lib/modules/$(shell uname -r)/buildPWD := $(shell pwd)default:$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modulesclean:$(MAKE) -C $(KERNEL_DIR) M=$(PWD) clean

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.