怎样使用ioctl
1.用户系统调用
int ioctl(int fd,int cmd,...)
省略号后面代表有些操作还需要命令
比如设置波特率
ioctl(fd,SET_BAUD_RATE,115200);
2.cmd命令码格式
推荐把cmd分成4个字段;
用户空间与linux内核中定义需一致;
设备类型:‘k’ ;//这个’k‘是一个魔数或者称幻数,是一个特殊的标识,检查它,可以防止错误的传达指令,'k’可以任意指定,但是最好不要和别人重名。
#define HELLO_MAGIC 'k'
#define CHAR_ONE _IO(CHAR_MAGIC,1);
#define CHAR_ONE _IO(CHAR_MAGIC,2);
_IO()
序列号:表示操作命令的序号
方向:这条命令表示是否要在用户空间和内核空间之间交换数据,交换数据的方向。
比如:
00:不交换
01:内核---->用户
10:用户---->内核
11:双向交换
数据尺寸:表示交换多大的数据
_IOR()
比如_IOR(‘K’,20,int);
R;指的是数据方向,从内核空间到用户空间
int:表示sizeof(int)=4;
_IOW()
_IOW(‘k’,10,long)
_IOWE()
_IOWR(‘k’,5,double)
capable(CAP_SYS_ADMIN)
检查应用程序是否有root权限,有很多设备,root才能进行某些操作。
面试题:
已知一个结构体变量中某个成员的地址,求出这个结构体变量本身的地址。注意结构体的内容是可能变化的,需要一个公式来求。
#include <stdio.h>
struct AA
{
int x;
short y;
int d;
double f;
}
int main()
{
struct AA a;
printf("%p\n",&a);//这个是要求的结果
return 0;
}
假设我们已知成员d的地址,求a的地址。
解:
关键是要求出偏移量
#include <stdio.h>
struct AA
{
int x;
short y;
int d;
double f;
}
int main()
{
struct AA a;
//怎么求偏移量
printf("%p\n",&(((struct AA)*0)->d));
printf("%p\n",(char*)&a.d-(unsigned long)&(((struct AA)*0)->d));
return 0;
}