/*
* 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) |