欢迎进入Linux社区论坛,与200万技术人员互动交流 >>进入
先介绍下我的环境,用的ubuntu发行版,kernel版本是3.8.0,《Linux设备驱动程序》一书是针对2.6.0的kernel,在这个例子中会看到一些差异。这个例子要实现的目标是,编译装载该module后,通过udev动态的生成设备节点star0,读取设备节点cat /dev/star0可以打印出星号,星号的数量可以由模块参数动态的指定。以下为源代码:
star.h
#ifndef STAR_H_H_H
#define STAR_H_H_H
#define AUTHOR “Tao Yang”
#define DESCRIPTION “A CHAR DEVICE DIRVERS SAMPLE USING UDEV”
#define VERSION “0.1”
#endif
star.c
//module_init module_exit
#include
#include
//module_param
#include
//printk container_of
#include
//dev_t MAJOR MINOR MKDEV
#include
//file_operations file register/unregister_chrdev_region alloc_chrdev_region register/unregister_chrdev(old)
#include
//cdev cdev_init/add/del
#include
//copy_from_user copy_to_user
#include
#include
#include “star.h”
//define device number
#define STAR_MAJOR 0
#define STAR_MINOR 0
#define STAR_DEVS 1
#define DEVICE_NAME “star0”
#define CLASS_NAME “star”
static int howmany=5;
module_param(howmany,int,S_IRUGO);
//module info
MODULE_AUTHOR(AUTHOR);
MODULE_DESCRIPTION(DESCRIPTION);
MODULE_VERSION(VERSION);
MODULE_LICENSE(“GPL”);
//device variables
static struct class* star_class=NULL;
static struct device* star_sysdevice=NULL;
int star_major=STAR_MAJOR;
int star_minor=STAR_MINOR;
int star_nr_devs=STAR_DEVS;
//device struct
static struct star_dev {
char *data;
struct cdev cdev;
};
static struct star_dev star_device;
static ssize_t star_read(struct file * filp,char * buf,size_t count,loff_t *ppos)
{
int i;
char star_str[10000];
struct star_dev *dev=filp->private_data;
for (i=0;i
star_str[i]=’*’;
}
star_str[howmany]=’\n’;
int len=strlen(star_str);
if(count
return -EINVAL;
if(*ppos!=0)
return 0;
if(copy_to_user(buf,star_str,len))
return -EINVAL;
*ppos=len;
return len;
}
int star_open(struct inode *inode,struct file *filp)
{
struct star_dev *dev;
dev=container_of(inode->i_cdev,struct star_dev,cdev);
filp->private_data=dev;
//……
return 0;
}
//file operations
static const struct file_operations star_fops = {
.owner = THIS_MODULE,
.read = star_read,
.open = star_open,
};
static void star_setup_cdev(struct star_dev *dev,int index)
{
int err,devno=MKDEV(star_major,star_minor+index);
printk(KERN_ALERT “setup cdev…\n”);
cdev_init(&dev->cdev,&star_fops);
dev->cdev.owner=THIS_MODULE;
dev->cdev.ops=&star_fops;
err=cdev_add(&dev->cdev,devno,1);
if(err)
printk(KERN_ALERT “Error %d adding star%d”,err,index);
}
static int __init star_init(void)
{
int ret;
dev_t dev;
[1][2]
对困难的回答是胜利,对胜利的回答是谦逊。