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