一个简单的字符设备驱动
驱动层
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/cdev.h>
#include<linux/device.h>
#include<linux/init.h>
#include<asm/uaccess.h>
#include<linux/mm.h>
#include<linux/sched.h>
#include<linux/slab.h>
MODULE_LICENSE("GPL");
#define CDEV_MAJOR 255
struct demo_dev
{
struct cdev cdev;
};
struct demo_dev *demo_devp = NULL;
static ssize_t demo_read(struct file *filp, char __user *buf,size_t count,loff_t *ppos)
{
char buffer[6] = "hello";
copy_to_user(buf,&buffer,6);
return 1;
}
static struct file_operations fop={
.owner = THIS_MODULE,
.read = demo_read,
};
static void setup_cdev(struct demo_dev* dev,int index)
{
dev_t devno = MKDEV(CDEV_MAJOR,index);
cdev_init(&dev->cdev,&fop);
dev->cdev.owner = THIS_MODULE;
dev->cdev.ops = &fop;
cdev_add(&dev->cdev,devno,1);
}
int init_mymodule(void)
{
dev_t devno = MKDEV(CDEV_MAJOR,0);
int ret;
struct class *class;
ret = register_chrdev_region(devno,1,"demo");
demo_devp = kmalloc(sizeof(struct demo_dev),GFP_KERNEL);
memset(demo_devp,0,sizeof(struct demo_dev));
setup_cdev(demo_devp,0);
class = class_create(THIS_MODULE,"demo");
device_create(class,NULL,MKDEV(CDEV_MAJOR,0),NULL,"demo");
return 0;
}
void cleanup_mymodule(void)
{
printk("exit....\n");
cdev_del(&demo_devp->cdev);
kfree(demo_devp);
unregister_chrdev_region(MKDEV(CDEV_MAJOR,0),1);
}
module_init(init_mymodule);
module_exit(cleanup_mymodule);
应用层
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(){
int fd;
char buf[100];
fd = open("/dev/demo",O_CREAT);
read(fd,buf,100,0);
printf("%s\n",buf);
return 0;
}