android 字符设备驱动模块及在 /dev 下自动创建设备节点问题

本文详细介绍了在Android系统中如何编写字符设备驱动,并实现设备节点在/dev目录下的自动创建。主要涉及cdev、struct、class及相关内核函数的使用,包括mry_open和mry_ioctl等关键函数的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

转载时请注明出处和作者文章出处:http://blog.youkuaiyun.com/lbmygf/archive/2011/06/16/6547946.aspx

作者:曼云-->孤峰

 

 

#include <linux/input.h>

#include <linux/types.h>

#include <linux/errno.h>

#include <linux/mm.h>

#include <linux/sched.h>

#include <linux/init.h>

#include <linux/cdev.h>

#include <asm/io.h>

#include <asm/system.h>

#include <asm/uaccess.h>

#include <linux/security.h>

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/fs.h>

#include <linux/device.h>

 

#define MRY_MAJOR 99

#define uint unsigned int 

#define ulong unsigned long 

 

static int mry_major=MRY_MAJOR;

 

typedef struct 

{

    struct cdev dev;

    //add private data

 

}mry_dev;

 

mry_dev *_pdev;

 

static int mry_open(struct inode *pinode,struct file *pfile)

{

    printk("in open now--------------------------------------------------------/n");

    return 0;

}

 

static int mry_ioctl(struct inode *pinode,struct file *pfile,uint cmd,ulong arg)

{

printk("cmd == %d arg == %ld --------------------------------------------------------/n", cmd, arg);

 

    switch(cmd)

    {

  case 1:

break;

        default:

             return -1;

    }

    return 0;

}

 

static const struct file_operations _fops=

{

.owner=THIS_MODULE,

.ioctl=mry_ioctl,

.open=mry_open,

};

 

static void mry_setup_cdev(mry_dev *pdev,int index)

{

    int err,devno=MKDEV(mry_major,index);

     cdev_init(&pdev->dev,&_fops);

     pdev->dev.owner=THIS_MODULE;

     pdev->dev.ops=&_fops;

     err=cdev_add(&pdev->dev,devno,1);

    if(err)

         printk(KERN_NOTICE "Error %d adding LED %d",err,index);

}

 

struct class *my_class;

 

int mry_init(void)

{

    int rs;

     dev_t devno=MKDEV(mry_major,0);   //获取设备节点号

 

    if(mry_major)

         rs=register_chrdev_region(devno,1,"gps_sleep"); // 注册gps_sleep 设备

    else

    {

         rs=alloc_chrdev_region(&devno,0,1,"gps_sleep"); //动态注册gps_sleep设备,也就是自动获取设备号

         mry_major=MAJOR(devno);  //获取主设备号

    }

 

    if(rs<0){

        return rs;

    }

     _pdev=kmalloc(sizeof(mry_dev),GFP_KERNEL); //为 _pdev分配空间

 

    if(!_pdev)

    {

         rs=-ENOMEM;

        goto fail_malloc;

    }

    memset(_pdev,0,sizeof(mry_dev));  //初始化_pdev

    mry_setup_cdev(_pdev,0);

 

     my_class = class_create(THIS_MODULE, "gps_sleep");

//class_create和device_create  自动在/dev目录下创建设备节点gps_sleep

 

   if(IS_ERR(my_class)) 

     {

          printk("Err: failed in creating class.--------------------------------------------/n");

          return -1; 

      }

 

 

device_create(my_class, NULL, MKDEV(mry_major, 0),  NULL, "gps_sleep");

//在这里需要注意了,由于内核版本不同,导致device_create的参数可能有变化,

//我就遇到了,在网上找了一个,一用就出问题了,系统会跑死,现在这个的内核是2.6.35的

 

    printk(KERN_INFO "mry driver ok----------------------------------------------------------------");

    return 0;

fail_malloc:

     printk(KERN_INFO "failed");

     unregister_chrdev_region(devno,1);

    return rs;

}

 

void mry_exit(void)

{

dev_t devno = MKDEV (mry_major, 0);

 

     cdev_del(&_pdev->dev);

 

     device_destroy(my_class, MKDEV(mry_major, 0));         //delete device node under /dev

     class_destroy(my_class);                               //delete class created by us

 

     kfree(_pdev);

 

     unregister_chrdev_region(MKDEV(mry_major,0),1);

}

 

module_init(mry_init);

module_exit(mry_exit);

 

MODULE_AUTHOR("liu");

MODULE_DESCRIPTION("gps sleep wake  driver");

MODULE_LICENSE("GPL");

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值