×
单片机 > 单片机程序设计 > 详情

ARM驱动开发之ioctl函数的使用

发布时间:2020-08-21 发布时间:
|

0. linux 版本对 ioct l的影响


kernel 2.6.36 中已经完全删除了fs.h中的struct file_operations 中的ioctl 函数指针,取而代之的是unlocked_ioctl 


我们这里还是用 ioctl指针介绍吧,但实际使用的时候要注意自己的linux版本,如果是2.6.36以上的,在其fs.h中的


struct file_operations 也会有 unlock_ioctl函数指针的。


1.ioctl应用程序(用户空间)向驱动程序(内核空间)发送命令(当然也可以反过来内核空间向用户空间发命令),内核程序也有一个ioctl对应的函数用来接收命令,然后通过一个switch语句判断命令然后执行相应的操作。(不止可以发命令,也可以发参数过去)


2.内核空间的 ioct l函数和 应用空间的 ioctl 函数


内核空间:(在linux内核 fs.h中的结构体 file_operation 可以找到)


int (*ioctl)(struct inode *i, struct file *f, unsigned int cmd, unsigned long args)  //这里只是函数指针,把(*ioctl)任意改个名字就可以往下编写这个函数了


其中 cmd 表示发送的命令,args表示附带的参数,不写也行


用户空间:int ioctl(int fd, int cmd,int args)


      fd 表示文件描述符


      cmd 表示命令


      args表示附带的参数,不写也行



当用户空间调用 ioctl后,对应内核空间的 ioctl 函数也会被调用


3.ioctl 命令的定义:


例如:



#define COMMAND1 _IOWR('I',0,unsigned long)

#define COMMAND2 _IOWR('I',1,unsigned long)

其中的 _IOWR是构造命令的,表示可读写的,类型为I,分别为类型 I 的0号命令和1号命令。 类型为 I 也是为了区分命令,就如一个人性陈,叫陈一,陈二

后面的 usigned long 是这个命令附带的参数的类型


还有几种构造命令的宏:


#define _IO(type,n)     ------构造无参数命令


#define _IOR(type,n,size) -------构造从驱动中读取数据的命令,size为命令附带参数的类型


#define _IOW(type,n,size) ------构造向驱动写入数据的命令,size为命令附带参数的类型


#define _IOWR(type,n,size) -------构造驱动程序和应用程序双向传输数据的命令,size为命令附带参数的类型


4.代码:


应用程序:


#include

#include

#include

#include

#include

#include

#include

 

#define COMMAND1 _IOWR('I',0,unsigned long)

#define COMMAND2 _IOWR('I',1,unsigned long)

 

int main()

{

int fd;

fd = open("/dev/ioctlt",O_RDWR);

if(fd<0)

{

perror("failed to open");

return -1;

}

 

while(1)

{

ioctl(fd,COMMAND1,100);//向驱动程序发COMMAND1命令,并附带参数100

sleep(1);

ioctl(fd,COMMAND2);//向驱动程序发COMMAND1命令,不附带参数

sleep(1);

}

return 0;

}


驱动程序:

#include

#include

#include

#include

#include

#include

#include

#include

#include

 

#define COMMAND1 _IOWR('I',0,unsigned long)

#define COMMAND2 _IOWR('I',1,unsigned long)

 

int ioctl_open(struct inode *i, struct file *f)

{

printk("open!\n");

return 0;

}

 

int ioctl_ioctl(struct inode *i, struct file *f, 

unsigned int cmd, unsigned long args)

{

switch(cmd)

{

case COMMAND1:

printk("enter COMMAND1 program!,arg=%ld\n",args);break;//收到命令1后,并打印附带的参数

case COMMAND2:

printk("enter COMMAND2 program!\n");break;

}

return 0;

}

 

static struct file_operations fops ={

.owner = THIS_MODULE,

.open = ioctl_open,

.ioctl = ioctl_ioctl,

};

 

static struct miscdevice misc={

.minor = MISC_DYNAMIC_MINOR,

.name = "ioctlt",

.fops = &fops,

};

 

 

 

static int __init io_init(void)

{

int ret;

printk("init!\n");

ret = misc_register(&misc);

if(ret<0)

{

printk("failed to register misc\n");

return -1;

}

return 0;

}

 

static void __exit io_exit(void)

{

printk("rmmod mod!\n");

misc_deregister(&misc);

return ;

}

 

module_init(io_init);

module_exit(io_exit);

MODULE_LICENSE("GPL");





『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
可升级和可配置的PSoC62系列MCU平台架构