红联Linux门户
Linux帮助

写Linux字符设备驱动模板--测试通过

发布时间:2016-04-03 02:58:07来源:linux网站作者:工程人在路上

1,首先,建立文件夹driver,在该文件夹下面新建globalvar.c和Makefile文件,然后编写驱动程序,保存到globalvar.c中

/* 
*  Simple Char_device Driver Test-- globalvar.c 
*  Date2016/04/01 
*  Author  Jerryz 
*/ 

#include <linux/init.h> 
#include <linux/module.h> 
#include <linux/cdev.h> 
#include <linux/fs.h> 
#include <asm/uaccess.h> 

MODULE_LICENSE("GPL"); 
MODULE_AUTHOR("Jerryz"); 

#define MINIOR_NUM 0 
#define DEVICE_SUM 1 
#define MAJOR_NUM 100   /* major device number */ 
#define MINOR_NUM 0 /* minor device number */ 

static int globalvar_open(struct inode *inode, struct file *filp); 
static int globalvar_release(struct inode *, struct file *filp); 
static ssize_t globalvar_read(struct file*, char*, size_t, loff_t*); 
static ssize_t globalvar_write(struct file*, const char*, size_t, loff_t*); 

/* the major device number */ 
static int globalvar_major = MAJOR_NUM; 
static int globalvar_minor = MINOR_NUM; 

/* init the file_operations structure */ 
struct file_operations globalvar_fops = 

.owner = THIS_MODULE, 
.open = globalvar_open, 
.release = globalvar_release, 
.read = globalvar_read, 
.write = globalvar_write, 
}; 

/* define a cdev device */ 
struct cdev *cdev; 

static int global_var = 0; /* global var */ 

/* module init */ 
static int __init globalvar_init(void) 

int ret = 0; 
dev_t devno = MKDEV(MAJOR_NUM, MINOR_NUM); 
cdev = cdev_alloc(); 
/* register the device driver */ 
/*ret = alloc_chrdev_region(MAJOR_NUM, "globalvar", &globalvar_fops);*/ 
if(register_chrdev_region(devno, DEVICE_SUM, "globalvar")) 

/* register fail, so use automatic allocate */ 
if(alloc_chrdev_region(&devno, globalvar_minor, DEVICE_SUM, "globalvar")) 
printk("globalvar register failure.\n"); 
globalvar_major = MAJOR(devno); 

else 

/* 
* cdev_init should be use if use the way of static statement. 
* struct cdev cdev; 
* cdev_init(&cdev, &globalvar_fops); 
* cdev.owner = THIS_MODULE; 

* if using dymatic allocation. 
* struct cdev *cdev; 
* cdev = cdev_alloc(); 
* cdev->owner = THIS_MODULE; 
* cdev->ops = &globalvar_fops; 
*/ 
cdev->owner = THIS_MODULE; 
cdev->ops = &globalvar_fops; 
if ((ret = cdev_add(cdev, devno, 1))) 
printk(KERN_NOTICE "Error %d adding globalvar.\n", ret); 
else 
printk("globalvar register success.\n"); 

return ret; 

/* module exit */ 
static void __exit globalvar_exit(void) 

dev_t devno = MKDEV(globalvar_major, 0); 
/* remove cdev from kernel */ 
cdev_del(cdev); 
/* unregister the device driver */ 
unregister_chrdev_region(devno, 1); 
/* free the dev structure */ 
if(cdev) 
kfree(cdev); 
cdev = NULL; 

/* open device */ 
static int globalvar_open(struct inode *inode, struct file *filp) 

int ret = 0; 
printk("open success.\n"); 
return ret; 

/* release device */ 
static int globalvar_release(struct inode *inode, struct file *filp) 

printk("release success.\n"); 
return 0; 

/* read device */ 
static ssize_t globalvar_read(struct file *filp, char *buf, size_t len, loff_t *off) 

printk("reading...\n"); 
if(copy_to_user(buf, &global_var, sizeof(int))) 

return -EFAULT; 

return sizeof(int); 

/* write device */ 
static ssize_t globalvar_write(struct file *filp, const char *buf, size_t len, loff_t *off) 

printk("writing...\n"); 
if(copy_from_user(&global_var, buf, sizeof(int))) 

return -EFAULT; 

return sizeof(int); 

 
/* module register */ 
module_init(globalvar_init); 
module_exit(globalvar_exit); 


2,编写驱动程序的Makefile,保存到driver文件夹下的Makefile中


# Makefile -- for driver  

module=globalvar 

ifneq ($(KERNELRELEASE),) 
obj-m := ${module}.o 
else 
KERNELDIR ?= /lib/modules/$(shell uname -r)/build 
PWD := $(shell pwd) 
default: 
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules 
clean: 
rm -f *.o *.ko *.mod.c *~ 
insmod: 
sudo insmod ${module}.ko 
dmesg | tail 
rmmod: 
sudo rmmod ${module} 
dmesg | tail 
endif 


3,新建文件夹AppTest,然后在该文件夹下新建test.c和Makefile文件,然后编写应用程序,保存到test.c中

/* 
* test.c -- a test file for globalvar reading and writing 
*/ 

#include <stdio.h> 
#include <stdlib.h> 
#include <fcntl.h> 
#include <sys/stat.h> 

int main(void) 

int fd, num; 
/*打开"/dev/globalvar"*/ 
fd = open("/dev/globalvar", O_RDWR, S_IRUSR | S_IWUSR); 
if (fd != -1 ) 

/*初次读globalvar*/ 
read(fd, &num, sizeof(int)); 
printf("The globalvar is %d\n", num); 

/*写globalvar*/ 
printf("Please input the num written to globalvar\n"); 
scanf("%d", &num); 
write(fd, &num, sizeof(int)); 

/*再次读globalvar*/ 
read(fd, &num, sizeof(int)); 
printf("The globalvar is %d\n", num); 

/*关闭"/dev/globalvar"*/ 
close(fd); 

else 

/* if not sudo, maybe come here */ 
printf("Device open failure\n"); 


4,编写应用程序Makefile,保存到AppTest文件夹下的Makefile中

CROSS= 

all: test 

test:test.c 
$(CROSS)gcc -o test test.c 
$(CROSS)strip test 
clean: 
@rm -vf test *.o *~ 


5,进入终端,分别进入目录driver和AppTest中,敲入make命令,编译完成后,我们要用到的是globalvar.ko文件,下面的操作把驱动程序加载到内核,然后创建设备节点:

一、insmod -f globalvar.ko

二、mknod /dev/globalvar c 100 0

其中c表示字符设备,100是主设备号,0是从设备号。


6,测试程序。进入AppTest目录中,执行以下命令测试

./test


本文永久更新地址:http://www.linuxdiyf.com/linux/19488.html