c语言ioctl函数_min函数用法

c语言ioctl函数_min函数用法ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用个数如下: intioctl(intfd,indcmd,…);    其中fd是用户程序打开设备时使用open函数返回的文件标示符,cmd是用户程序对设备的控制命令,至于后面的省略号,那是一些补充参数,一般最多一个,这个参数的…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用
ioctl是设备驱动程序中对设备的I/O通道进行管理的函数
所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的调用个数如下: 


int ioctl(int fd, ind cmd, …); 


    其中fd是用户程序打开设备时使用open函数返回的文件标示符,cmd是用户程序对设备的控制命令,至于后面的省略号,那是一些补充参数,一般最多一个,这个参数的有无和cmd的意义相关。 

    ioctl函数是文件结构中的一个属性分量,就是说如果你的驱动程序提供了对ioctl的支持,用户就可以在用户程序中使用ioctl函数来控制设备的I/O通道。


简单介绍一下函数:

int (*ioctl) (struct inode * node, struct file *filp, unsigned int cmd, unsigned long arg);

参数:

1)inodefileioctl的操作有可能是要修改文件的属性,或者访问硬件。要修改

文件属性的话,就要用到这两个结构体了,所以这里传来了它们的指针。

2)cmd:命令,接下来要长篇大论地说。

3)arg:参数,接下来也要长篇大论。

返回值:

1)如果传入的非法命令,ioctl返回错误号-EINVAL

2)内核中的驱动函数返回值都有一个默认的方法,只要是正数,内核就会傻乎乎的认为这是正确的返回,并把它传给应用层,如果是负值,内核就会认为它是错误号了。

Ioctl里面多个不同的命令,那就要看它函数的实现来决定返回值了。打个比方,如果ioctl里面有一个类似read的函数,那返回值也就可以像read一样返回。

当然,不返回也是可以的。

ioctl如何实现
    在驱动程序中实现的ioctl函数体内,实际上是有一个switch{case}结构,每一个case对应一个命令码,做出一些相应的操作。怎么实现这些操作,这是应用程序自己的事情。

在ioctl中命令码是唯一联系用户程序命令和驱动程序支持的途径
如果有两个不同的设备,但它们的ioctlcmd(命令码)却一样的,哪天有谁不小心打开错了,并且调用ioctl,这样就完蛋了。因为这个文件里面同样有cmd对应实现,故,我们可以自己生成未使用的命令码。
所以在Linux核心中是这样定义一个命令码的

一个cmd被分为了4个段,每一段都有各自的意义,cmd的定义在<linux/ioctl.h>。注:但实际上<linux/ioctl.h>中只是包含了<asm/ioctl.h>,这说明了这是跟平台相关的,ARM的定义在<arch/arm/include/asm/ioctl.h>,但这文件也是包含别的文件<asm-generic/ioctl.h>,千找万找,终于找到了。


<asm-generic/ioctl.h>中,cmd拆分如下:

全部都在
<asm-generic/ioctl.h>

ioctl-number.txt
这两个文档有说明


http:/…./linux/include/asm-generic/ioctl.h


 

#define _IOC(dir,type,nr,size) \



  
    
  
(((dir)  << _IOC_DIRSHIFT) | \



    
    
((type) << _IOC_TYPESHIFT) | \



   
    
 
((nr)   << _IOC_NRSHIFT) | \



   
    
 
((size) << _IOC_SIZESHIFT))




____________________________________


| 设备类型 | 序列号 | 方向 |数据尺寸|


|———-|——–|——|——–|


| 8 bit | 8 bit |2 bit |8~14 bit|


|———-|——–|——|——–|

c语言ioctl函数_min函数用法

这样一来,一个命令就变成了一个整数形式的命令码;但是命令码非常的不直观,所以Linux Kernel中提供了一些这些宏可根据便于理解的字符串生成命令码,或者是从命令码得到一些用户可以理解的字符串以标明这个命令对应的设备类型、设备序列号、数据传送方向和数据传输尺寸。

    幻数:说得再好听的名字也只不过是个0~0xff的数,占8bit(_IOC_TYPEBITS)。这个数是用来区分不同的驱动的,像设备号申请的时候一样,内核有一个文档给出一些推荐的或者已经被使用的幻数。在内核文件中定义如下
Ioctl-number.txt (f:\sourceproject\linux-kernel\linux-3.14.26-g2489c02\documentation\ioctl)

点击(此处)折叠或打开

  1. Code Seq#(hex)    Include File        Comments
  2. ========================================================
  3. 0x00    001F    linux/fs.h        
  4. 0x00    001F    scsi/scsi_ioctl.h    
  5. 0x00    001F    linux/fb.h        
  6. 0x00    001F    linux/wavefront.h    
  7. 0x02    all    linux/fd.h
  8. 0x03    all    linux/hdreg.h
  9. 0x04    D2DC    linux/umsdos_fs.h    Dead since 2.6.11, but dont reuse these.
  10. 0x06    all    linux/lp.h
  11. 0x09    all    linux/raid/md_u.h
  12. 0x10    000F    drivers/char/s390/vmcp.h
  13. 0x10    101F    arch/s390/include/uapi/sclp_ctl.h
  14. 0x10    202F    arch/s390/include/uapi/asm/hypfs.h
  15. 0x12    all    linux/fs.h
  16.         linux/blkpg.h
  17. 0x1b    all    InfiniBand Subsystem    <http://infiniband.sourceforge.net/>
  18. 0x20    all    drivers/cdrom/cm206.h
  19. 0x22    all    scsi/sg.h
  20. #    003F    IEEE 1394 Subsystem    Block for the entire subsystem
  21. $    000F    linux/perf_counter.h, linux/perf_event.h
  22. …………………
  23. ………………..


四、CMD参数如何得出



    cmd参数在用户程序端由一些宏根据设备类型、序列号、传送方向、数据尺寸等生成,这个整数通过系统调用传递到内核中的驱动程序,再由驱动程序使用解码宏从这个整数中得到设备的类型、序列号、传送方向、数据尺寸等信息,然后通过switch{case}结构进行相应的操作。

    Linux内核已经提供了相应的宏来自动生成ioctl命令码

_IO(type,nr)   //无数据传输
_IOR(type,nr,size)  //从设备读数据 
_IOW(type,nr,size)  //向设备写数据
_IOWR(type,nr,size)  //同时有读写数据

    
上面的命令已经定义了方向,我们要传的是幻数
(type)
序号
(nr)
大小
(size)
。在这里
szie
的参数只需要填参数的类型,如
int
,上面的命令就会帮你检测类型的正确然后赋值
sizeof(int)

  
  


    
相对的,Linux内核也提供了相应的宏来从ioctl命令号种
解码
相应的域值:

_IOC_DIR(nr)  //从命令中提取方向
_IOC_TYPE(nr) //从命令中提取幻数
_IOC_NR(nr)  //从命令中提取序数
_IOC_SIZE(nr)  //从命令中提取数据大小

例:
/*include_cmd.hpp*/

#define LED_IOC_MAGIC 0x13  //定义幻数

#define LED_MAX_NR    3          //定义命令的最大序数

#define 
LED_GPRS_MAGIC _IO(LED_IOC_MAGIC,0x00)  //0x00  
用”
宏+幻数来自动生成ioctl命令码


#define LED_WIFI
_MAGIC _IO(LED_IOC_MAGIC,0x01)  //0x00



#define LED_BT
_MAGIC _IO(LED_IOC_MAGIC,0x02)  //0x00

/*test.cpp*/
fd = open();
ioctl(fd,LED_GPRS_MAGIC,0);
ioctl(fd,LED_GPRS_MAGIC,1);
ioctl(fd,LED_WIFI_MAGIC ,0);
ioctl(fd,LED_WIFI_MAGIC ,1);

/*test_ioctl.c*/
int test_ioctl (struct inode *node, struct file *filp, unsigned int cmd, unsigned long arg)
{


    if(_IOC_TYPE(cmd) !=LED_IOC_MAGIC ) return -EINVAL;   //提取出幻数做检验
    if(_IOC_NR(cmd
) > LED_MAX_NR ) return -EINVAL;          //提取命令序数


    switch(cmd){

    case LED_GPRS_MAGIC:
     if(arg==0){

    //……….
    }else if(arg ==1){

    //……….
    }
    break;
    case LED_WIFI_MAGIC:
    //……….
    break;

    }

}

arg参数:

如果arg是一个整数,可以直接使用;
  如果是指针,我们必须确保这个用户地址是有效的,因此,使用之前需要进行正确检查。
  内部有检查的,

不需要检测的:

[cpp] 
view plain
 copy

 

  1. copy_from_user  
  2. copy_to_user  
  3. get_user  
  4. put_user  



需要检测
的:

[cpp] 
view plain
 copy

 

  1. __get_user  
  2. __put_user 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/180730.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • mysql自定义函数写法_mysql自定义函数返回多列值

    mysql自定义函数写法_mysql自定义函数返回多列值1、先查看函数功能是否开启:showvariableslike’%func%’;若是未开启则:SETGLOBALlog_bin_trust_function_creators=1;关闭则是:SETGLOBALlog_bin_trust_function_creators=0;2、自定义函数:delimiter$$;这个函数是合并两个字符串delimiter$$;DROPFUNC…

    2022年9月8日
    0
  • Java中重载与重写的特点和区别[通俗易懂]

    Java中重载与重写的特点和区别[通俗易懂]一、重载(overload)重载:发生在Java的同一个类里面,通过定义相同的方法,定义不同的参数列表来区分开这些相同的方法,参数列表的不同可以是参数的类型、参数的个数和参数的顺序。当我们调用这些方法的时候通过传入参数的不同,在运行时Java虚拟机会自行调用不同的方法来进行处理。由于Java的修饰符都可以访问同一个类里面的方法,所以方法的重载与方法的修饰符无关;Java的返回值不能区别这些方法,因为返回值是在运行后才体现出来的,而两个参数列表相同仅仅是返回值相同的方法在Java编译时就会报错,虚拟机在运行

    2022年7月8日
    22
  • NSGA2算法MATLAB

    NSGA2算法MATLABNSGA2算法MATLAB实现(能够自定义优化函数)以前写了一个简单的NSGA2的算法能够用在ZDT1函数上:http://www.omegaxyz.com/2017/05/04/nsga2matlabzdt1/那个NSGA2的算法不具有普遍性,下面参考课国外的课题小组的代码重新修改了内部冗余内容,使之能够自定义优化函数。更多内容访问omegaxyz.comNSGA2的过程为:

    2022年5月12日
    37
  • 简单理解冯诺依曼计算机模型[通俗易懂]

    引入计算机是如何工作的,冯诺依曼体系结构是最好的体现,如图1。冯诺依曼结构是由数学家冯·诺依曼提出,主要由运算器、控制器、存储器、输入设备、输出设备5部分组成。要点1.数据和指令一视同仁,都采用二进制存储。2.按照程序顺序执行,也就是按照顺序从内存中一条一条读取指令。组成1.运算器:顾名思义,主要进行计算,算术运算、逻辑运算等都由它来完成。2.存储器:这里存储器只是内存,不包括内存,用于存储数据、指令信息。3.控制器:控制器是是所有设备的调度中心,系统的正常运行都是有它来调配。4.输入设

    2022年4月7日
    97
  • Murmurhash 哈希算法 介绍与实现

    最近在项目代码中看到了一种hash算法,以前没有遇见过,在此记录下来。 一、介绍  MurmurHash是一种非加密型哈希函数,适用于一般的哈希检索操作。由AustinAppleby在2008年发明,并出现了多个变种,都已经发布到了公有领域(publicdomain)。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好。—摘自w…

    2022年4月5日
    64
  • Zookeeper-Zab协议

    Zookeeper-Zab协议Zookeeper消息广播模式崩溃恢复机制选LeaderZAB协议用来保持数据一致性,主要有两种模式,第一是消息广播模式;第二是崩溃恢复模式除此之外我门还应该了解Leader的选出机制消息广播模式在zookeeper集群中数据副本的传递策略就是采用消息广播模式。ZAB协议中Leader等待follower的ACK反馈是指”只要半数以上的follower成功反馈即可,不需要收到全部follower反馈”;下图中展示了消息广播的具体流程图:zookeeper中消息广播的具体步骤如下:客户端发起一

    2022年8月8日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号