1.为什么要有ioctl操作 因为工程师想要驱动我们的外设,不仅需要具有读写设备的能力,还需要具备对硬件控制的能力,即非数据的操作。 例如我们需要设置串口传输的波特率、马达的转速等等。
2.ioctl的概念 ioctl函数是用来操作特殊文件的底层设备参数,特别的,许多的字符文件的操作特性都是通过ioctl进行控制的。 3.ioctl(应用层)函数原型: #include <sys/ioctl.h> int ioctl(int fd, unsigned long request, ...);
下面我们解释各个参数的含义。 1)fd是文件描述符。当我们的设备作为特殊文件被open()函数打开后,会返回一个文件描述符,通过操作这个文件描述符达到操作设备文件的目的。 2)request是命令码,应用程序通过下发命令码来控制驱动程序完成对应操作。 3)第三个参数“…”是可变参数arg,一些情况下应用程序需要向驱动程序传参,参数就通过ag来传递。ioctl函数中的“…”只能传递一个参数,但内核不会检查这个参数的类型。那么,就有两种传参方式:只传一个整数,传递一个指针。 如果ioctl执行成功,它的返回值就是驱动程序中ioctl接口给的返回值,驱动程序可以通过返回值向用户程序传参。但驱动程序最好返回一个非负数,因为用户程序中的ioctl运行失败时一定会返回-1并设置全局变量errorno。 errono不同的值代表的含义如下: EBADF:fd是一个无效的文件描述符。 EFAULT:在arg是指针的前提下,argp指向一个不可访问的内存空间。 EINVAL:request或argp是无效的。 ENOTTY:fd没有关联到一个字符特殊设备,或该request不适用于文件描述符fd引用的对象类型。(说人话就是fd没有指向一个字符设备,或fd指向的文件不 支持ioctl操作) 因此,在用户空间调用ioctl时,可以使用如下的错误判断处理。包括的两个头文件,string.h声明了strerror函数,errno.h定义了错误码errno。 示例如下: #include <string.h> #include <errno.h> int ret; ret = ioctl(fd, MYCMD); if (ret == -1) printf("ioctl: %s\n", strerror(errno));
|