Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2676134
  • 博文数量: 877
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 5921
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-05 12:25
个人简介

技术的乐趣在于分享,欢迎多多交流,多多沟通。

文章分类

全部博文(877)

文章存档

2021年(2)

2016年(20)

2015年(471)

2014年(358)

2013年(26)

分类: LINUX

2014-03-28 13:53:34

/*
 * Filename:scull.c
 * Function:test character device driver
 * Author:dengwei
 * From:<>
 * Time:2010-4-19
 */
#include
#include
#include
#include
#include
#include
#include
#include    /*字符设备注册*/

#include "scull.h"

struct scull_qset{
    void **data;
    struct scull_qset *next;
};

struct scull_dev{
    struct scull_qset *data;
    int quantum;
    int qset;
    unsigned long size;
    unsigned int access_key;
    struct cdev cdev;  //如果已经将struct cdev 嵌入到自己的设备的特定结构体中
};

static struct file_operations scull_fops =
{
        .owner = THIS_MODULE
};

static dev_t dev;
static int scull_major = SCULL_MAJOR;
static int scull_minor = SCULL_MINOR;
static int scull_nr_devs = SCULL_NR_DEVS;
static int result = -1;
static char __initdata info[]= "This is my first charater device driver!\n";
static struct class *scull_class;

/*scull 设备注册函数*/
static int scull_setup_cdev(struct scull_dev *scull_dev, dev_t devt)
{
    int err;
//    int devno = MKDEV(scull_major, scull_minor + index);

    cdev_init(&scull_dev->cdev, &scull_fops);   /*cdev 的初始化*/
    scull_dev->cdev.owner = THIS_MODULE;
    scull_dev->cdev.ops = &scull_fops;
    err = cdev_add(&scull_dev->cdev, devt, 2);
    if (err)
    {
        printk(KERN_NOTICE "Error %d adding scull!", err);
        return err;
    }
    return 0;
}  

static int __init scull_init(void)
{
    int ret;
    struct cdev *sdev = cdev_alloc();   /*分配一个独立得cdev结构*/
    printk(info);
    /* 动态分配设备号*/
    if (scull_major)
    {
        dev = MKDEV(scull_major,scull_minor );
        result = register_chrdev_region(dev, scull_nr_devs, "scull");
    }
    else
    {
        result = alloc_chrdev_region(&dev, scull_major,scull_nr_devs,"scull");
        scull_major = MAJOR(dev);
    }
    if (result < 0)
    {
        printk(KERN_WARNING  "scull: can't get major %d\n",scull_major);
        return result;
    }
    else{
        printk(DEVICE_NAME "major = %d\n",scull_major);
    }

    /*注册设备*/
    ret = scull_setup_cdev(sdev,dev);
    if (ret < 0)
    {
        printk(DEVICE_NAME "can't register major module!\n");
        return ret;
    }
    /*注册一个类,使得mdev能在/dev下创建设备节点*/
    scull_class = class_create(THIS_MODULE,DEVICE_NAME);
    if(IS_ERR(scull_class))
    {
        printk(KERN_ALERT "Err:faile in scull_class!\n");
        return -1;
    }
    /*创建设备节点,名字为DEVICE_NAME ,主设备号用上面动态生成的dev*/
    device_create(scull_class, NULL, dev, NULL, DEVICE_NAME);
    printk(DEVICE_NAME"initializa\n");
    return 0;

}

static void __exit scull_exit(void)
{
       printk(KERN_ALERT "Moudle exit! Charater Device Driver End!\n");
       unregister_chrdev_region(dev,scull_nr_devs);
       device_destroy(scull_class,dev);
       class_destroy(scull_class);
}
module_init(scull_init);
module_exit(scull_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("CHARACTER DEVICE DRVER");
MODULE_AUTHOR("dengwei");
==========================================================
#define SCULL_MAJOR         0
#define SCULL_MINOR         0
#define SCULL_NR_DEVS         4
#define DEVICE_NAME      "scull"
==========================================================
字符设备驱动步骤:
1、最好动态申请主设备号。
2、在内核中注册设备。
     <1>
分配一个独立得struct cdev结构struct cdev *my_cdev = cdev_alloc();
     <2> cdev的初始化。cdev_init(&scull_dev->cdev, &scull_fops);
                      cdev.owner = THIS_MODULE;
3、在文件系统中生成设备节点。
  
下面来说明如何生策划那个设备节点:
   static struct class *scull_class;//先定义一个设备类,该结构在#include 中定义
/*注册一个类,使mdev可以在/dev下创建设备节点*/
   scull_class = class_create(THIS_MODULE, DEVICE_NAME);
      if(IS_ERR(scull_class))
      {
           printk(KERN_ALERT”Err:faile in scull_class!\n”);
           return -1;
      }
/*创建设备节点,名字为DEVICE_NAME ,主设备号用上面动态生成的dev*/
  device_create(scull_class, NULL, dev, NULL, DEVICE_NAME);   ///2.6.31
                 ///////class_device_create(scull_class, NULL, dev, NULL, DEVICE_NAME);
4、释放设备节点
  
unregister_chrdev_region(dev,scull_nr_devs);
   device_destroy(scull_class,dev);
   class_destroy(scull_class);

参考:http://blog.chinaunix.net/u2/70288/showart.php?id=2188027
==================================================
实验结果:
root@dw:/home/dengwei/eclipse_workspace/scull_dw# ls -al /dev/scull
crw-rw---- 1 root root 251, 0 2010-04-19 16:54 /dev/scull
root@dw:/home/dengwei/eclipse_workspace/scull_dw# cat /var/log/syslog |grep de
Apr 19 16:54:03 dw kernel: [13872.263843] This is my first charater device driver!
root@dw:/home/dengwei/eclipse_workspace/scull_dw# cat /var/log/syslog |grep Th
Apr 19 16:54:03 dw kernel: [13872.263843] This is my first charater device driver!
root@dw:/home/dengwei/eclipse_workspace/scull_dw# cat /var/log/syslog |grep sc
Apr 19 16:54:03 dw kernel: [13872.263848] scullmajor = 251
Apr 19 16:54:03 dw kernel: [13872.263915] scullinitializa

=====================================================
错误调试:
 error: implicit declaration of function ‘class_device_create’
由于:版本问题引起的。class_device_create 改为 device_create.






阅读(888) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~