一:    ioctl函数的作用

ioctl用于向设备发控制和配置命令 ,有些命令也需要读写一些数据,但这些数据是不能用read/write读写的,称为Out-of-band数据。也就是说,read/write读写的数据是in-band数据,是I/O操作的主体,而ioctl命令传送的是控制信息 ,其中的数据是辅助的数据。

ioctl是设备驱动程序中对设备的I/O通道进行管理的函数,所谓对I/O通道进行管理,就是对设备的一些特性进行控制 ,例如,在串口线上收发数据通过read/write操作,而串口的波特率、校验位、停止位通过ioctl设置,A/D转换的结果通过read读取,而A/D转换的精度和工作频率通过ioctl设置。
    ioctl函数是文件结构中的一个属性分量,就是说如果你的驱动程序提供了对ioctl的支持,用户就可以在用户程序中使用ioctl函数控制设备的I/O通道。
    如果不用ioctl的话,也可以实现对设备I/O通道的控制,但那就是蛮拧了。例如,我们可以在驱动程序中实现write的时候检查一下是否有特殊约定的数据流通过,如果有的话,那么后面就跟着控制命令(一般在socket编程中常常这样做)。但是如果这样做的话,会导致代码分工不明,程序结构混乱,程序员自己也会头昏眼花的。
  
  所以,我们就使用ioctl来实现控制的功能 。要记住,用户程序所作的只是通过命令码告诉驱动程序它想做什么,至于怎么解释这些命令和怎么实现这些命令,这都是驱动程序要做的事情。

二: ioctl()用法 
    int ioctl(int fd, ind cmd, …);

其中fd就是用户程序打开设备时使用open函数返回的文件标示符,cmd就是用户程序对设备的控制命令,至于后面的省略号,那是一些补充参数,一般最多一个,有或没有是和cmd的意义相关的。下面是一个关于V4L视频采集中用到的用ioctl来配置视频采集设备(USB摄像头)的一些特性参数的例子:

1.   定义设备结构体

struct vdIn {
    int fd ; //设备描述符
    char *videodevice ; //设备节点,在linux下,通用的视频采集设备节点为/dev/video0
    struct video_mmap vmmap;
    struct video_capability videocap;
    int mmapsize;
    struct video_mbuf videombuf;
    struct video_picture videopict;
    struct video_window videowin;
    struct video_channel videochan;    
    int cameratype ;
    char *cameraname;
    char bridge[9];
    int sizenative; // available size in jpeg
    int sizeothers;    // others palette 
    int palette; // available palette
    int norme ; // set spca506 usb video grabber
    int channel ; // set spca506 usb video grabber
    int grabMethod ; 
    unsigned char *pFramebuffer;
    unsigned char *ptframe[4];
    int framelock[4];
    pthread_mutex_t grabmutex;
    int framesizeIn ;
    volatile int frame_cour;
    int bppIn;
    int  hdrwidth;
    int  hdrheight; 
    int  formatIn;
    int signalquit;    
    };

2.   设备节点赋值, "/dev/video0"是真实的物理摄像头设备在linux中的表示

if (videodevice == NULL || *videodevice == 0)
    {
      videodevice = "/dev/video0";
    }

3.  调用 设备 初始化函数

struct vdIn videoIn;  //在spcav4l.h中定义
   videodevice = "/dev/video0"; //节点
   int width = 352;  //宽
   int height = 288;   //高
   int format = VIDEO_PALETTE_JPEG; //格式
   int grabmethod = 1;

memset (&videoIn, 0, sizeof (struct vdIn));
  if (init_videoIn(&videoIn, videodevice, width, height, format,grabmethod) != 0)
     
    if(debug) printf (" damned encore rate !!\n");

4.   设备初始化函数传值

int init_videoIn (struct vdIn *vd, char *device, int width, int height,
          int format, int grabmethod)
{
  int err = -1;
  int i;
  if (vd == NULL || device == NULL)
    return -1;
  if (width == 0 || height == 0)
    return -1;
  if(grabmethod < 0 || grabmethod > 1)
      grabmethod = 1; //read by default;
    // check format 
  vd->videodevice = NULL;
  vd->cameraname = NULL;
  vd->videodevice = NULL;
  vd->videodevice = (char *) realloc (vd->videodevice, 16);
  vd->cameraname = (char *) realloc (vd->cameraname, 32);

snprintf (vd->videodevice, 12, "%s", device);
  if(debug) printf("video %s \n",vd->videodevice);

memset (vd->cameraname, 0, sizeof (vd->cameraname));
  memset(vd->bridge, 0, sizeof(vd->bridge));
  vd->signalquit = 1;//信号设置
  vd->hdrwidth = width;
  vd->hdrheight = height;
  /*          compute the max frame size   */
  vd->formatIn = format; //传进来的 format = VIDEO_PALETTE_JPEG;
  vd->bppIn = GetDepth (vd->formatIn);

vd->grabMethod = grabmethod;        //mmap or read 
  vd->pFramebuffer = NULL;
  /* init and check all setting */

err = init_v4l (vd); // V4L初始化函数 
  ....................................................
}

5.     V4L初始化函数

static int init_v4l (struct vdIn *vd)
{
  int f;
  int erreur = 0;
  int err;
  if ((vd->fd = open (vd->videodevice, O_RDWR)) == -1)//打开 
    exit_fatal ("ERROR opening V4L interface");

if (ioctl (vd->fd, VIDIOCGCAP, &(vd->videocap) ) == -1)
    exit_fatal ("Couldn't get videodevice capability");

....................................

    在视频采集之前,先要对Video4Linux进行初始化
初始化阶段用ioctl(int fd, ind cmd, …) 函数和设备进行“对话”。Fd是设备的文件描述符,cmd是用户程序对设备的控制命令 ,省略号一般是一个表示类型长度的参数,也可以没有。初始化步骤如下:
1.打开视频:
open (vd->videodevice, O_RDWR))
2. 读video_capability 中信息包括设备名称,支持最大最小分辨率,信号源信息等。
  调用函数ioctl (vd->fd, VIDIOCGCAP, &(vd->videocap))成功后可读取vd->capability各分量 
   video_capability是Video4linux支持的数据结构, video_capability 包含设备的基本信息(设备名称、支持的最大最小分辨率、信号源信息等),包含的分量:
•name[32]   //设备名称
•maxwidth ,maxheight,minwidth,minheight
•Channels //信号源个数
•type    //是否能capture,彩色还是黑白,是否能裁剪等等。值如VID_TYPE_CAPTURE等

 
struct video_capability
{
        char name[32];
        int type;
        int channels;        /* Num channels */
        int audios;        /* Num audio devices */
        int maxwidth;        /* Supported width */
        int maxheight;        /* And height */
        int minwidth;        /* Supported width */
        int minheight;        /* And height */
};
3.对采集图象的各种属性进行设置 ,分为两步 首先获取摄象头缓冲区中video_picture中信息调用函数ioctl(vd->fd, VIDIOCGPICT, &(vd->picture));然后改变video_picture中分量的值,为vd->videopict分量赋新值,调用 ioctl (vd->fd, VIDIOCSPICT, &vd->videopict)即可实现

  

转载于:https://blog.51cto.com/decimal/447630

Linux中与驱动相关的ioctl函数相关推荐

  1. Linux绘图函数与驱动,Linux中与驱动相关的ioctl函数

    一:    ioctl函数的作用 ioctl用于向设备发控制和配置命令 ,有些命令也需要读写一些数据,但这些数据是不能用read/write读写的,称为Out-of-band数据.也就是说,read/ ...

  2. Linux 中的驱动开发的初学者体会

    Linux 中的驱动开发的初学者体会 很多年前,心里就存下这样一个愿望.就是把Linux 的驱动开发搞清楚. 但是一开始上上这样的开发难度天大了,对着一堆的寄存器发愁. 于是就从简单的STM8,PIC ...

  3. linux中spi驱动框架

    原 linux中spi驱动框架 2016年09月14日 15:57:06 andylauren 阅读数:403 <span class="tags-box artic-tag-box& ...

  4. The driver has not received any packets from the server.(linux中关于mysql相关命令)

    原因: 1.呃呃.重启服务器,没有重新启动mysql; 2.如果还不能连接可能是3306是不允许进行远程连接的,所以在防火墙中设置3306开启远程服务: /sbin/iptables -I INPUT ...

  5. Linux中nvme驱动详解

    NVMe离不开PCIe,NVMe SSD是PCIe的endpoint.PCIe是x86平台上一种流行的bus总线,由于其Plug and Play的特性,目前很多外设都通过PCI Bus与Host通信 ...

  6. SCSI PRs命令研究总结3 - Linux中的SCSI相关实现

    Linux下的SCSI驱动的实现,驱动与用户层交互接口规范的制定,以及用户态的配置管理工具主要由"The Linux SCSI Generic (sg) Driver"项目负责. ...

  7. Linux中逻辑卷相关知识简介

    一.在redhat系列Linux中逻辑卷的相关介绍 LVM(Logical Volume Manager),是逻辑卷管理器,是一个软件,可以实现磁盘的高效管理,如磁盘扩展和缩减等. 它包括物理卷(Ph ...

  8. Linux中dlfcn库相关学习

    博客搬家,原地址:https://langzi989.github.io/2017/10/16/Unix中dl库学习/ 在linux中静态链接库和动态链接库是进程之间代码共享的两种方式.Linux在& ...

  9. linux驱动相关的一些函数

    1)驱动加载函数 module_init(initialization_function); 2)驱动卸载函数 module_exit(cleanup_function); 3)模块参数 module ...

  10. Linux对显卡驱动相关操作后,重启进不去图形界面,左上角一个横杠在闪

    问题描述: NVIDA显卡驱动随着linux内核的更新而失效,nvida-smi没有出现显卡的相关信息.于是尝试之间在软件和更新这里选择驱动.结果是在重启进不去图形界面,左上角一个横杠在闪. 原因分析 ...

最新文章

  1. css元素居中方法归纳
  2. from server sql 拼接统计两个子查询_[SQL SERVER系列]之嵌套子查询和相关子查询
  3. 性能计时器监测服务器性能瓶颈
  4. java reducebykey_Spark入门(五)--Spark的reduce和reduceByKey
  5. Object Relational Tool Comparison Dot Net
  6. Java中的异常处理机制的简单原理和应用
  7. Tomcat8中URI不支持{}|等特殊字符解决方案
  8. 《UNIX网络编程 卷1:套接字联网API》学习笔记——基本UDP套接字编程
  9. 全国勘察设计注册暖通空调工程师专业基础考试大纲(送审稿)
  10. 电路城 电路方案 51单片机开发板(原理图+PCB+学习程序源文件)
  11. source insight同步的时候崩溃_“我在国外,崩溃了一整年。”
  12. c语言实验步骤与过程,实验一 C语言的运行环境和运行过程
  13. js打开新窗口并且不被拦截
  14. 【USACO1.3.3】最棒的回文
  15. 在移动硬盘中,安装CentOS 7双系统
  16. ipv6无状态自动分配地址,是如何进行工作的。
  17. Django2.0+小程序技术打造微信小程序助手百度云
  18. 串的定长顺序存储结构|C++实现
  19. AutoML- NNI
  20. MXNet预训练模型下载 ResNet 50 101

热门文章

  1. Yum Audio Everything Bundle for Mac - Yum Audio音频插件套装
  2. 黑苹果OC配置工具 OpenCore Configurator 2.25中文版
  3. TeamViewer会议功能有什么用?
  4. 考研政治思维导图之马克思主义基本原理
  5. A Tour of the Dart Language(译文):五控制流语句
  6. Mybaits 3.2.6设计的一个缺陷,欢迎拍砖交流
  7. ASP.NET输入文本框自动提示功能
  8. spring源码bean的加载过程
  9. gvim配置文件参考
  10. Shell 工作原理