ioctl

一、IOCTL函数的原型

1.应用程序的ioctl()—>linux的系统IO函数

#include <sys/ioctl.h>
int ioctl(int fd, unsigned long request, ...);

// 经常使用的函数原型:
int ioctl(int fd, unsigned int cmd, unsigned long args);
int ioctl(int fd, unsigned int cmd);

应用程序的ioctl()会系统调用驱动程序的ioctl()

2. 驱动程序的ioctl()—>file_operations

#include<include\linux\fs.h>
long (*unlocked_ioctl) (struct file *filp, unsigned int cmd, unsigned long args);

3. 应用的方法

1)应用程序向驱动程序发送命令cmd,但是不发送参数

int ioctl(int fd, unsigned int cmd);  // 应用程序下发
long (*unlocked_ioctl) (struct file *filp, unsigned int cmd, unsigned long args); // 驱动对应接口收到

unsigned long args—>应用没有args,驱动则忽略args

2)应用程序向驱动程序发送命令,并发送参数

int ioctl(int fd, unsigned int cmd, unsigned long args); // 应用程序
long (*unlocked_ioctl) (struct file *filp, unsigned int cmd, unsigned long args); // 驱动程序

unsigned int cmd —>应用程序发下来的命令
unsigned long args —>应用程序发下来的参数

例子:

#include <linux/videodev2.h>
struct v4l2_format fmt;  //保存或设置摄像头输出的视频格式

fmt.fmt.pix.width       = 640;//设置视频输出宽为640
fmt.fmt.pix.height      = 480;//输出高位480
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;//设置输出格式为YUYV格式(必须要摄像头支持YUYV格式设置才有效)
fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;
ret = ioctl(fd, VIDIOC_S_FMT, &fmt); //把格式数据设置到驱动中
if (ret < 0)
{
    printf("VIDIOC_S_FMT failed (%d)\n", ret);
       return ret;
}

应用程序向驱动程序发送命令VIDIOC_S_FMT,并发送参数fmt。

3)应用程序向驱动程序发送命令,并获取参数

int ioctl(int fd, unsigned int cmd, unsigned long args);
long (*unlocked_ioctl) (struct file *filp, unsigned int cmd, unsigned long args);
unsigned int cmd --->应用程序发下来的命令
unsigned long args  --->发送给应用程序的参数

例子:

#include <linux/videodev2.h>
struct v4l2_format fmt;  //保存或设置摄像头输出的视频格式
memset(&fmt, 0, sizeof(struct v4l2_format));

ret = ioctl(fd, VIDIOC_G_FMT, &fmt);//从驱动中获取信息
if (ret < 0) {
    printf("***********************************\nVIDIOC_G_FMT failed (%d)\n", ret);
    return ret;
}
printf("Stream Format Informations:\n");
printf(" type: %d\n", fmt.type);
printf(" width: %d", fmt.fmt.pix.width);
printf(" height: %d\n", fmt.fmt.pix.height);

应用程序向驱动程序发送命令VIDIOC_G_FMT,获取驱动的数据fmt

二、IOCTL的命令

IOCTL的命令需要预先定义好,应用程序和驱动程序要使用相同的命令。命令是一个32位无符号的整型值,该整型值是有固定格式要求的。
我们要使用固定的格式标准,定义自己的cmd。

#include<include\asm-generic\ioctl.h>
// 定义一个命令,但是不需要参数参数
#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0) 

// 定义一个命令,应用程序从驱动程序读参数
#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size))) 

// 定义一个命令,应用程序向驱动程序写参数
#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) 

// 定义一个命令,参数是双向传递的。
#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) 

函数的参数说明:
type ----> 命令的类型,一般为一个ASCII码,一般一个驱动程序使用一个type
nr —> 该命令下序号。一个驱动有多个命令,一般他们的type一样,序号不同
size —> args的类型
例子:
应用程序定义的cmd:/usr/include/linux/videodev2.h
#define VIDIOC_S_FMT _IOWR(‘V’, 5, struct v4l2_format)

驱动程序定义的cmd:内核源码/include/linux/videodev2.h
#define VIDIOC_S_FMT _IOWR(‘V’, 5, struct v4l2_format)

例如:

// 定义LED灯驱动的命令:
// 应用程序发命令:灯亮和灯灭
// 应用程序发参数:灯号:8/9/10/11

#define S5P6818_LED_ON			_IOW('L',  1, unsigned long)
#define S5P6818_LED_OFF			_IOW('L',  2, unsigned long)
// 应用程序发参数:每个Byte表示一个灯的状态:8/9/10/11
#define S5P6818_LED_READ_STATE	_IOR('L',  3, unsigned long) 

// 定义BEEP灯驱动的命令:
#define GEC6818_BEEP_ON	_IO('B',  1)
#define GEC6818_BEEP_OFF	_IO('B',  2)

三、例程

例程源码:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值