linux驱动中ioctl使用
在驱动头文件中定义幻数
/* 定义幻数 */
#define OLED_IOC_MAGIC 'k'
/* 定义命令 */
#define OLED_IOC_OPEN _IO(OLED_IOC_MAGIC, 1)
#define OLED_IOC_CLOSE _IO(OLED_IOC_MAGIC, 2)
#define OLED_IOC_SET_POINT _IOR(OLED_IOC_MAGIC, 3, int)
#define OLED_IOC_SET_STRING _IOW(OLED_IOC_MAGIC, 4, int)
#define OLED_IOC_REFRESH _IO(OLED_IOC_MAGIC, 5)
#define OLED_IOC_CLEAR _IO(OLED_IOC_MAGIC, 6)
#define OLED_IOC_MAXNR 6
在驱动源文件中实现ioctl函数
static int oled12864_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int err = 0;
int ret = 0;
/* 检测命令的有效性 */
if (_IOC_TYPE(cmd) != OLED_IOC_MAGIC)
return -EINVAL;
if (_IOC_NR(cmd) > OLED_IOC_MAXNR)
return -EINVAL;
/* 根据命令类型,检测参数空间是否可以访问 */
if (_IOC_DIR(cmd) & _IOC_READ)
err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));
else if (_IOC_DIR(cmd) & _IOC_WRITE)
err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));
if (err)
return -EFAULT;
/* 根据命令,执行相应的操作 */
switch(cmd) {
/* 打印当前设备信息 */
case OLED_IOC_OPEN:
OLED_DisPlay_On();
printk("<--- CMD OLED_IOC_OPEN Done--->\n\n");
break;
/* 打印当前设备信息 */
case OLED_IOC_CLOSE:
OLED_DisPlay_Off();
printk("<--- CMD OLED_IOC_CLOSE Done--->\n\n");
break;
case OLED_IOC_REFRESH:
OLED_Refresh();
break;
case OLED_IOC_CLEAR:
OLED_Clear();
break;
/* 获取参数 */
case OLED_IOC_SET_POINT:
{
pointData tmp;
//定义结构体,从用户空间传入结构体数据,再进行解析
copy_from_user((unsigned char *)&tmp,(unsigned char *)arg,sizeof(stringData));
// OLED_Clear();
if(tmp.on = 0){
OLED_ClearPoint(tmp.p.x, tmp.p.y);
}else{
OLED_DrawPoint(tmp.p.x, tmp.p.y);
}
printk("<--- In Kernel = %d %d %d %d--->\n\n", tmp.p.x, tmp.p.y, tmp.on, 16);
}
break;
/* 设置参数 */
case OLED_IOC_SET_STRING:
{
stringData tmp;
copy_from_user((unsigned char *)&tmp,(unsigned char *)arg,sizeof(stringData));
// OLED_Clear();
OLED_ShowString(tmp.p.x, tmp.p.y, tmp.data, tmp.len);
OLED_Refresh();
printk("<--- In Kernel = %d %d %s %d--->\n\n", tmp.p.x, tmp.p.y, tmp.data, 16);
}
break;
default:
return -EINVAL;
}
return ret;
}
ops操作集合
static const struct file_operations oled12864_ops = {
.owner = THIS_MODULE,
.open = oled12864_open,
.read = oled12864_read,
.write = oled12864_write,
.unlocked_ioctl = oled12864_ioctl,
.release = oled12864_release,
};