compat_ioctl和unlocked_ioctl的使用场景

背景

接上一篇《蓝牙遥控器连接流程分析》,我们这次正式开始蓝牙遥控器的调试。按理来说,有了上一篇文章的理论支撑,要调试一款蓝牙遥控器应该就不难了,实际也是这样。但是调试过程中,还是遇到了一些问题,在此记录一下。

正文

在上一篇文章我们可以看到,以前在安卓平台想要创建/dev/input/eventX和/dev/hidrawX节点,蓝牙协议栈中一般有一下操作:

int fd = open(/dev/uhid);
write(fd, ...);

不过在我调试的这款cypress 20704蓝牙芯片中,厂家提供的协议栈(协议栈名叫bsa,不是Linux官方的bluez)并不是通过uhid驱动去操作的,而是有他自己的bthid驱动。不过流程相似,只是名字不同而已。我们先简单看一下bthid驱动中的流程。
 

static const struct file_operations bthid_fops =
{
    .owner = THIS_MODULE,
    .open = bthid_open,
    .release = bthid_release,
    .write = bthid_write,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
    .unlocked_ioctl = bthid_ioctl
#else
    .ioctl = bthid_ioctl
#endif
};

static struct miscdevice bthid_misc =
{
    .fops = &bthid_fops,
    .minor = BTHID_MINOR,
    .name = BTHID_NAME
};

static int __init bthid_init(void)
{
    int ret;
    ret = misc_register(&bthid_misc);
    if (ret)
    {
        BTHID_ERR("misc driver registration error\n");
    }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
    ret = hid_register_driver(&bthid_driver);
    if (ret)
    {
        BTHID_ERR("hid driver registration error\n");
    }
#endif
    return ret;
}

流程和uhid驱动一样,注册一个misc设备,并且也挂载到hid总线。将编译出来的bthid驱动注册进系统后,就会多出一个/dev/bthid文件。这个就和/dev/uhid类似了。所以在协议栈中肯定有一个打开/dev/bthid文件的操作,现在我们搜索一下协议栈的代码,果不其然,在某个源码中有一下动作:

#define APP_HH_BTHID_PATH "/dev/bthid"
int app_bthid_open(void)
{
    int bthid_fd;

    /* Open bthid device.  Return if failed */
    bthid_fd = open(APP_HH_BTHID_PATH, O_RDWR);
    if (bthid_fd < 0)
    {
        APP_ERROR1("Failed to open %s : %d", APP_HH_BTHID_PATH, errno);
        return -1;
    }
    APP_DEBUG1("fd=%d", bthid_fd);

    return bthid_fd;
}

所以我们可以猜测,注册完bthid驱动后,再调用协议栈中上面的这段代码,就大功告成了?我也是这么想的,但是做完这些工作,却迟迟没有看到创建/dev/input/eventX和/dev/hidrawX节点。加了很多打印也没找到原因,只是知道在协议栈中调用ioctl时失败了,却没找到为什么失败,后来网上看到一位大神的文章,恍然大悟。在bthid驱动中,ioctl的接口用的是unlocked_ioctl,但在32位系统64位的内核上面会走compat_ioctl接口,这就是compat_ioctl存在的意义,由于我使用的Linux系统是32位,内核编译的是Arm64,这应该就是这个Bug产生的原因,替换成compat_ioctl,问题就解决了,谢天谢地!
参考链接:https://blog.csdn.net/qq_25402181/article/details/77985143

static const struct file_operations bthid_fops =
{
    .owner = THIS_MODULE,
    .open = bthid_open,
    .release = bthid_release,
    .write = bthid_write,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
    .compat_ioctl = bthid_ioctl
#else
    .ioctl = bthid_ioctl
#endif
};

结束

这只是调试蓝牙遥控器遇到的一个小问题,后续调试过程中如果遇到有价值的问题,会继续写文章总结。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值