linux 设备驱动之IOCTRL

1,where come from?

ioctrl(或者说unlocked_ioctl/compat_ioctl)是file_operations结构体的函数指针

struct file_operations {

...

long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);

long (*compat_ioctl) (struct file *, unsigned int, unsigned long);

...

};

2,who am i

在用户空间,ioctl是一个系统调用, 作用于一个文件描述符; 它接收一个确定要进行的命令的数字和(可选地)另一个参数, 常常是一个指针.这些命令可以内核空间和用户空间之间进行数据交互。这些命令可以从驱动拷贝相关的数据结构到用户空间。

3,所谓的命令(CMD)是什么?

在Kernel层,对于一个32bit的系统,分成了4个域,分段如下@include/uapi/asm-generic/ioctl.h

2bits(读写区)_IOC_DIRBITS 14bits(数据大小区)_IOC_SIZEBITS 8bits(Magic)_IOC_TYPEBITS 8bits(命令序号)_IOC_NRBITS

31 30/29 28 ... 17 16/15
14 ... 9 8/7 6 ... 1 0

所谓的Magic区,无非就是不同驱动使用一个字母来标识。比如LDD3,

#define SCULL_IOC_MAGIC  ‘k‘

#define SCULL_IOCSQUANTUM _IOW(SCULL_IOC_MAGIC,  1, int)

4,为什么不使用“粗暴”的,一个unsigned int值来代替一个cmd?

我认为,使用一个32bit的不同位来表示一个cmd,能包含更多的信息,节省了内存

5,如何使用?

5.1,在应用层和Kernel使用同一个CMD定义的h文件,来使用cmd

在应用层:#define REMOTE_IOC_SET_REPEAT_KEY_MAPPING       _IOW_BAD(‘I‘,20,sizeof(short))

在Kernel层:#define REMOTE_IOC_SET_REPEAT_KEY_MAPPING   _IOW_BAD(‘I‘,20,sizeof(short))

5.2,

在应用层调用这个命令,device_fd为对应的设备文件

val = (i<<16) | repeat_key_map[i];

ioctl(device_fd, REMOTE_IOC_SET_REPEAT_KEY_MAPPING, &val);

在Kernel层,将会做相应的处理

先把&val传进来的值copy_from_user,然后使用这个val值

static long remote_config_ioctl(struct file *filp, unsigned int cmd, unsigned long args)

{

void __user *argp = (void __user *)args;

ret = copy_from_user(&val, argp, sizeof(unsigned long));

case REMOTE_IOC_SET_REPEAT_KEY_MAPPING:

remote->key_repeat_map[remote->map_num][val >> 16] = val & 0xffff;

break;

...

}

6,另外:IOCTL相关的宏,读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)))

#define _IOR_BAD(type,nr,size)     _IOC(_IOC_READ,(type),(nr),sizeof(size))

#define _IOW_BAD(type,nr,size)     _IOC(_IOC_WRITE,(type),(nr),sizeof(size))

#define _IOWR_BAD(type,nr,size)     _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))

时间: 2024-12-25 23:17:49

linux 设备驱动之IOCTRL的相关文章

linux设备驱动第五篇:驱动中的并发与竟态

综述 在上一篇介绍了linux驱动的调试方法,这一篇介绍一下在驱动编程中会遇到的并发和竟态以及如何处理并发和竞争. 首先什么是并发与竟态呢?并发(concurrency)指的是多个执行单元同时.并行被执行.而并发的执行单元对共享资源(硬件资源和软件上的全局.静态变量)的访问则容易导致竞态(race conditions).可能导致并发和竟态的情况有: SMP(Symmetric Multi-Processing),对称多处理结构.SMP是一种紧耦合.共享存储的系统模型,它的特点是多个CPU使用共

Linux设备驱动中的阻塞和非阻塞I/O

[基本概念] 1.阻塞 阻塞操作是指在执行设备操作时,托不能获得资源,则挂起进程直到满足操作所需的条件后再进行操作.被挂起的进程进入休眠状态(不占用cpu资源),从调度器的运行队列转移到等待队列,直到条件满足. 2.非阻塞 非阻塞操作是指在进行设备操作是,若操作条件不满足并不会挂起,而是直接返回或重新查询(一直占用CPU资源)直到操作条件满足为止. 当用户空间的应用程序调用read(),write()等方法时,若设备的资源不能被获取,而用户又希望以阻塞的方式来访问设备,驱动程序应当在设备驱动层的

Linux设备驱动开发 - 平台设备驱动

Linux2.6的内核中引入了一种新的设备驱动模型-平台(platform)设备驱动,平台设备驱动分为平台设备(platform_device)和平台驱动(platform_driver),平台设备的引入使得Linux设备驱动更加便于移植. 一.平台设备平台设备结构体: 1 struct platform_device { 2 const char * name; /* 设备名 */ 3 int id; 4 struct device dev; /* 设备结构体 */ 5 u32 num_res

linux设备驱动第三篇:写一个简单的字符设备驱动

在linux设备驱动第一篇:设备驱动程序简介中简单介绍了字符驱动,本篇简单介绍如何写一个简单的字符设备驱动.本篇借鉴LDD中的源码,实现一个与硬件设备无关的字符设备驱动,仅仅操作从内核中分配的一些内存. 下面就开始学习如何写一个简单的字符设备驱动.首先我们来分解一下字符设备驱动都有那些结构或者方法组成,也就是说实现一个可以使用的字符设备驱动我们必须做些什么工作. 1.主设备号和次设备号 对于字符设备的访问是通过文件系统中的设备名称进行的.他们通常位于/dev目录下.如下: [plain] vie

Linux设备驱动开发学习(1):前言

虽然网络上已经有很多Linux设备驱动开发学习的文章和博客,更是有很多经典的Linux设备驱动开 发的书籍,写这些博文似乎意义不大,但把自己的学习过程.学习心得记录下来,一方面有着强化巩固的 意义,另一方面也是把所学知识转化为自己所得的必要途径之一,这是我写这些的博客的原始动力.

linux设备驱动中的并发控制

并发指的是多个执行单元同时.并行被执行,而并发的执行单元对共享资源的访问则很容易导致竞态 linux内核中主要竞态1.多对称处理器的多个CPU  2.单CPU内进程与抢占它的进程 3.中断(硬中断.软中断.Tasklet.下半部)与进程之间访问共享内存资源的代码区称为“临界区”,临界区需要被以某种互斥机制加以保护,中断屏蔽.原子操作.自旋锁和信号量等是linux设备驱动中可采用的互斥途径. 这几个互斥的介绍: 1.中断屏蔽,这个主要用于单CPU,中断屏蔽将使得中断和进程之间的并发不再发生.使用方

深入浅出~Linux设备驱动中的阻塞和非阻塞I/O

今天意外收到一个消息,真是惊呆我了,博客轩给我发了信息,说是俺的博客文章有特色可以出本书,,这简直让我受宠若惊,俺只是个大三的技术宅,写的博客也是自己所学的一些见解和在网上看到我一些博文以及帖子里综合起来写的,,总之这又给了额外的动力,让自己继续前进,,希望和大家能够分享一些自己的经验,,在最需要奋斗的年级以及在技术的领域踽踽独行的过程中有共同的伙伴继续前进~ 今天写的是Linux设备驱动中的阻塞和非阻塞I/0,何谓阻塞与非阻塞I/O?简单来说就是对I/O操作的两种不同的方式,驱动程序可以灵活的

linux设备驱动系列:如何处理竞态关系

综述 在上一篇介绍了linux驱动的调试方法,这一篇介绍一下在驱动编程中会遇到的并发和竟态以及如何处理并发和竞争. 首先什么是并发与竟态呢?并发(concurrency)指的是多个执行单元同时.并行被执行.而并发的执行单元对共享资源(硬件资源和软件上的全局.静态变量)的访问则容易导致竞态(race conditions).可能导致并发和竟态的情况有: SMP(Symmetric Multi-Processing),对称多处理结构.SMP是一种紧耦合.共享存储的系统模型,它的特点是多个CPU使用共

20150220 IMX257 linux设备驱动之Cdev结构

20150220 IMX257 linux设备驱动之Cdev结构 2015-02-20 21:17 李海沿 一.CDEV结构 /*   *内核源码位置   *linux2.6.38/include/linux/cdev.h   */        struct cdev {       struct kobject kobj;       struct module *owner;   //一般初始化为:THIS_MODULE       const struct file_operations