在hellow.c中(将来编译成一个内核模块插入到内核中工作),为file_operations中加入成员函数hello_ioctl:
/* file operations for hello device */
static struct file_operations hello_ops = {
.owner = THIS_MODULE,
.unlocked_ioctl = hello_ioctl,
.open = hello_open,
.read = hello_read,
.write = hello_write,
.release = hello_release,
};
hello_ioctl()的定义如下:
static int hello_ioctl( struct file *file, unsigned int cmd, unsigned long arg)
{
int temp = 0;
switch(cmd)
{
case HELLO_CMD1:
{
temp = 1;
if(copy_to_user( (int *)arg, &temp, sizeof(int))) return -EFAULT;
break;
}
case HELLO_CMD2:
{
temp = 2;
if(copy_to_user( (int *)arg, &temp, sizeof(int))) return -EFAULT;
break;
}
}
printk( KERN_NOTICE"ioctl CMD%d done!\n",temp);
return 0;
}
在文件开头增加cmd的定义:
#define HELLO_MAGIC 'k'
#define HELLO_CMD1 _IO(HELLO_MAGIC,0x1a)
#define HELLO_CMD2 _IO(HELLO_MAGIC,0x1b)
其中'k'为幻数,要按照Linux内核的约定方法为驱动程序选择ioctl编号,应该首先看看include/asm/ioctl.h和Documentation/ioctl-number.txt这两个文件,下面是ioctl.h的部分内容,也是比较重要的:
注意对幻数的编号千万不能重复定义,如ioctl-number.txt已经说明‘k'的编号已经被占用的范围为:
'k' 00-0F linux/spi/spidev.h conflict!
'k' 00-05 video/kyro.h conflict!所以我们在这里分别编号为0x1a和0x1b,到这里,我们已经完成了对ioctl功能的编写,接下来就是在测试程序中利用系统调用来测试它。
=============================================================
ioctl测试程序
=============================================================
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/ioctl.h>
#define HELLO_MAGIC 'k' //当然我们也可以定义一个相应的头文件,把ioctl的cmd放进里面,然后再include进 来
#define HELLO_CMD1 _IO(HELLO_MAGIC,0x1a)
#define HELLO_CMD2 _IO(HELLO_MAGIC,0x1b)
int main(void)
{
int ioctl_rdata;
int fd, ret;
fd = open ( "/dev/hellow" , O_RDWR);
if ( fd == -1 )
{
perror("open");
exit(0);
}
ret = ioctl( fd, HELLO_CMD2,&ioctl_rdata);
if ( ret == -1)
{
perror("ioctl");
exit(0);
}
printf("ioctl_rdata= %d \n",ioctl_rdata);
close(fd);
return 0;
}
=============================================================
运行结果
=============================================================
root@Ubuntu:~/share/hellow# insmod hellow.ko
root@Ubuntu:~/share/hellow# mknod /dev/hellow c 251 0
root@Ubuntu:~/share/hellow# ./a.out
ioctl_rdata= 2
root@Ubuntu:~/share/hellow# dmesg | tail
[ 2431.126532] hello init. major:251, minor:0
[ 2453.326022] Hello device open!
[ 2453.326047] ioctl CMD2 done!
[ 2453.326487] Hello device close!