1、驱动头文件hello.h
#ifndef __HELLO_H
#define __HELLO_H
#define HELLO_MAGIC 'k' /*定义magic*/
/*定义命令*/
#define HELLO_ONE _IO(HELLO_MAGIC, 1) /*幻数,序号*/
#define HELLO_TWO _IO(HELLO_MAGIC, 2)
#endif
2、驱动源代码hello-ioctl.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/ioctl.h>
#include <asm/uaccess.h>
#include "hello.h"
static int hello_major = 250;//主设备号
static int hello_minor = 0;//次设备号
static int number_of_devices = 1;// 设备的数量
static char data[128] = "\0";
static struct cdev cdev;// 静态定义字符设备
static dev_t dev = 0;// 设备号
static int hello_open(struct inode *inode, struct file *file)
{
printk (KERN_INFO "Hey! device opened\n");
return 0;
}
static int hello_release(struct inode *inode, struct file *file)
{
printk (KERN_INFO "Hmmm! device closed\n");
return 0;
}
static int hello_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
int ret=0;
switch (cmd) {
case HELLO_ONE:
printk (KERN_INFO "HELLO_ONE called\n");
break;
case HELLO_TWO:
printk (KERN_INFO "HELLO_TWO called\n");
break;
default:
break;
}
return ret;
}
struct file_operations hello_fops = {
.owner = THIS_MODULE,
.open = hello_open,
.release = hello_release,
.ioctl = hello_ioctl,
};
static void char_reg_setup_cdev (void)
{
int error, devno = MKDEV(hello_major, hello_minor);//合并设备号
cdev_init(&cdev, &hello_fops);//初始化字符设备
cdev.owner = THIS_MODULE;
//cdev.ops = &hello_fops;
error = cdev_add(&cdev, devno, 1);// 注册字符设备
if (error)
printk (KERN_NOTICE "Error %d adding char_reg_setup_cdev", error);
}
static int __init hello_2_init (void)
{
int result;
dev = MKDEV(hello_major, hello_minor);//合并设备号
result = register_chrdev_region(dev, number_of_devices, "hello");// 静态申请设备号
if (result<0) {
printk (KERN_WARNING "hello: can't get major number %d\n", hello_major);
return result;
}
char_reg_setup_cdev();
printk (KERN_INFO "hello_ioctl driver done\n");
return 0;
}
static void __exit hello_2_exit (void)
{
dev_t devno = MKDEV(hello_major, hello_minor); //合并设备号
cdev_del (&cdev);// 注销字符设备
unregister_chrdev_region (devno, number_of_devices);// 注销设备号
printk (KERN_INFO "hello_ioctl cleaned up\n");
}
module_init(hello_2_init);
module_exit(hello_2_exit);
MODULE_LICENSE("GPL");
MODULE_VERSION("v1.0");
MODULE_AUTHOR("xz@vichip.com.cn");
MODULE_DESCRIPTION("Char Driver Module");
MODULE_ALIAS("char driver module");
3、Makefile
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
else
obj-m := hello-ioctl.o
endif
4、应用程序
#include <stdio.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include "hello.h"
int main (void)
{
int fd;
fd = open ("/dev/hello",O_RDWR);
if (fd < 0) {
printf ("fd open failed\n");
return -1;
}
printf ("/dev/hello opened, fd=%d\n",fd);
ioctl (fd, HELLO_ONE);
ioctl (fd, HELLO_TWO);
close (fd);
printf ("/dev/hello closed\n");
return 0;
}