首页 > 其他分享 >Android Qcom USB Driver学习(十)

Android Qcom USB Driver学习(十)

时间:2024-08-27 16:40:43浏览次数:9  
标签:hdev struct Driver hid device Qcom Android include hidraw

本章主要是基于之前的学习,实现一个hidraw的驱动,发现有两种用于识别usb设备的方式,放别是usb_device_id和hid_device_id

hid_probe

(1)hid_device_id

kernel/msm-4.19/drivers/hid/usbhid/hid-core.c
bus = usb usb_register  注册驱动        -> sys/bus/usb/driver

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

kernel/msm-4.19/drivers/hid/hid-core.c
bus = hid  hid_register_driver 注册驱动  -> sys/bus/hid/driver

hid bus本身没有探测的能力,都是需要其他模块来进行hid_add_device,

(2)usb_device_id

kernel/msm-4.19/drivers/hid/usbhid/usbmouse.c  
static const struct usb_device_id usb_mouse_id_table[] = {
    USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
                USB_INTERFACE_PROTOCOL_MOUSE)

usb探测的过程如下

usb_new_device -> usb_enumerate_device + announce_device + device_add -> bus_probe_device -> device_initial_probe 

    -> driver_match_device -> usb_device_match (driver.c)-> usb_match_id  (usb_device_id usbmouse.c)                   
    -> driver_probe_device ->  really_probe -> usb_mouse_probe -> input_register_device(usbmouse.c)
                                            -> usbhid_probe (usbhid/hid-core.c)-> hid_add_device -> device_add

        -> driver_match_device ->  hid_bus_match (hid/hid-core.c) -> hid_match_id   (hid_device_id hid-generic.c)    
        -> driver_probe_device ->   hid_device_probe(hid/hid-core.c) -> hid_generic_probe (hid/hid-generic.c)

issues

E hidraw 0003: 0C2E:1007.0001: device has no listeners, quitting
.raw_event =     hidraw_raw_event, //hidwar必须要实现这个函数

CONFIG_HIDRAW=y //需要打开这个函数,不然会调用hidraw.h中的空函数

hidraw_demo

android的源码中没有只有hidraw的驱动,只有一些定义在hidraw.c中的api, 通过这些参数实现了hidraw接口的功能并测试通过

/* Copyright (c) 2014-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/hid.h>
#include <linux/hid-debug.h>
#include "hid-ids.h"
#include "usbhid/usbhid.h"
#include <linux/usb.h>
#include <linux/vmalloc.h>
#include <linux/completion.h>
#include <linux/uaccess.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/poll.h>
#include <linux/device.h>
#include <linux/major.h>
#include <linux/slab.h>
#include <linux/hid.h>
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/hidraw.h>

#define hidtype 0//1:use clamied , 0: use connect_mask

struct hidraw_data {
    struct hid_device *hdev;
};

static int hidraw_raw_event(struct hid_device *hdev,
        struct hid_report *report, u8 *raw_data, int size)
{
    struct hidraw_data *data = hid_get_drvdata(hdev);
    int ret = 0;
    if (!data)
        return 1;

    hidraw_report_event(hdev, raw_data, size);
    return ret;
}
#ifdef CONFIG_PM
static int hidraw_suspend(struct hid_device *hdev, pm_message_t message)
{

    return 0;
}
static int hidraw_resume(struct hid_device *hdev)
{
    return 0;
}
static int hidraw_reset_resume(struct hid_device *hdev)
{
    return 0;
}
#endif

static int hidraw_probe(struct hid_device *hdev,
             const struct hid_device_id *id)
{
    struct hidraw_data *data;
    int error = -ENOMEM;
    struct usbhid_device *usbhid = hdev->driver_data;

    if(usbhid->ifnum != 0) {
        hid_err(hdev, "usbhid ifnum = %d\n", usbhid->ifnum);
        return error;
    }

    //hidraw_init();

    data = kzalloc(sizeof(struct hidraw_data), GFP_KERNEL);
    if (data == NULL) {
        hid_err(hdev, "failed to kzallocc \n");
        error = -ENOMEM;
        goto err_kzalloc;
    }

    data->hdev = hdev;

    hid_set_drvdata(hdev, data);
    error = hid_parse(hdev);
    if (error) {
        hid_err(hdev, "failed to parse \n");
        goto err_kzalloc;
    }

    hdev->quirks = HID_QUIRK_NO_INIT_REPORTS;
#if hidtype
    hdev->claimed = HID_CLAIMED_HIDRAW;
    error = hid_hw_start(hdev, 0);
#else
    error = hid_hw_start(hdev, HID_CONNECT_HIDRAW );
#endif
    if (error) {
        hid_err(hdev, "failed to hw start\n");
        goto err_drvdata_null;
    }
#if hidtype
    hidraw_connect(hdev);
#endif
    return 0;

err_kzalloc:
    kfree(data);
err_drvdata_null:
    hid_set_drvdata(hdev, NULL);
    return error;

}

static void hidraw_remove(struct hid_device *hdev)
{
    struct hidraw_data *data = hid_get_drvdata(hdev);

    hid_hw_stop(hdev);
#if hidtype
    hidraw_disconnect(hdev);
#endif
    hid_set_drvdata(hdev, NULL);

    //hidraw_exit();
    kfree(data);
}

static const struct hid_device_id hidraw_devices[] = {
    { HID_USB_DEVICE(USB_VENDOR_ID_xxx, USB_DEVICE_ID_xxx) },
    { }
};
MODULE_DEVICE_TABLE(hid, hidraw_devices);

static struct hid_driver hidraw_driver = {
    .name =          "hid-own",
    .id_table =      hidraw_devices,
    .probe =         hidraw_probe,
    .remove =        hidraw_remove,
    .raw_event =     hidraw_raw_event,
#ifdef CONFIG_PM
    .suspend =       hidraw_suspend,
    .resume =        hidraw_resume,
    .reset_resume =  hidraw_reset_resume,
#endif
};


//module_hid_driver(hidraw_driver);

static int __init hidown_init(void)
{
    int result;
    hidraw_init();

    result = hid_register_driver(&hidraw_driver);    
    return result;

}

static void __exit hidown_exit(void)
{
    hid_unregister_driver(&hidraw_driver);
    hidraw_exit();
}

module_init(hidown_init);
module_exit(hidown_exit);

MODULE_DESCRIPTION("Hid Raw Demo");
MODULE_LICENSE("GPL v2");

标签:hdev,struct,Driver,hid,device,Qcom,Android,include,hidraw
From: https://www.cnblogs.com/linhaostudy/p/18382979

相关文章

  • Android开发 - synchronized 关键字控制多个线程对共享资源的访问解析
    什么是synchronizedsynchronized一个关键字,用于实现线程同步。其主要作用是控制多个线程对共享资源的访问,确保被synchronized修饰的代码块或方法同一时间只有一个线程可以执行,从而避免数据不一致的问题为什么需要synchronized在多线程编程中,多个线程可能同时访问和修改......
  • Android Qcom USB Driver学习(九)
    本章主要是基于之前的学习,实现一个hidraw的驱动,发现有两种用于识别usb设备的方式,放别是usb_device_id和hid_device_idhid_probe(1)hid_device_idkernel/msm-4.19/drivers/hid/usbhid/hid-core.cbus=usbusb_register注册驱动->sys/bus/usb/driver↓↓↓↓↓↓......
  • Android taskset用法详解
    一、简介taskset命令用于设置或者获取一直指定的 PID 对于CPU核的运行依赖关系。通过taskset命令可将某个进程与某个CPU核心绑定,使得其仅在与之绑定的CPU核心上运行关于绑核的解释绑核,其实就是设定某个进程/线程与某个CPU核的亲和力(affinity)。设定以后,Linux调......
  • Android systrace环境的搭建和使用
    一、systrace简介Systrace是Android4.1中新增的性能数据采样和分析工具。它可帮助开发者收集Android 关键子系统(如SurfaceFlinger/SystemServer/Kernel/Input/Display等Framework部分关键模块、服务,View系统等)的运行信息,从而帮助开发者更直观的分析系统瓶颈,改进性能。S......
  • Android Launcher启动过程
    ##Launcher的启动流程: 1.Zygote进程–>SystemServer进程–>startOtherService方法–>ActivityManagerService的systemReady方法–>startHomeActivityLocked方法–>ActivityStackSupervisor的startHomeActivity方法–>执行Activity的启动逻辑,执行scheduleResume......
  • Android开发 - LayoutInflater 类将 XML 布局文件转换成对应的 View 对象解析
    LayoutInflater是什么LayoutInflater用于将XML布局文件转换成对应的View对象。它可以理解为一个“布局解析器”,帮助我们将静态的XML文件转换为可以动态操作的Java对象(View及其子类)LayoutInflater的主要作用在Android开发中,我们通常会在res/layout文件夹中......
  • Android开发
    开发工具AndroidStudio软件官网地址:https://developer.android.google.cn/studio#项目构建工具介绍Gradle和Maven都是Java项目的构建工具,但它们有一些区别:1.语法:Gradle使用Groovy语言进行编写,而Maven使用XML。Groovy更加灵活易读,XML更加严谨易于重用。2.性能:Gradle比Maven......
  • Android开发 - BluetoothDevice 类蓝牙连接、通信以及获取设备信息解析
    BluetoothDevice是什么BluetoothDevice是用于表示远程蓝牙设备的类。它提供了与设备进行连接、通信以及获取设备信息的功能。在蓝牙通信中,BluetoothDevice对象代表一个实际的物理设备,比如蓝牙耳机、智能手表、蓝牙音箱等BluetoothDevice的主要作用获取蓝牙设备的信息通......
  • selenium4在使用 下载驱动的时候报错: THIRD_PARTY_NOTICES.chromedriver
    在使用seeleniun自动下载驱动时报错:THIRD_PARTY_NOTICES.chromedriver原来的代码运行一直没有错误的,现在运行后下载下来的驱动是上面的格式导致运行报错,在github和google上查了官方已经修复在4.0.2版本中已经修复通过重新安装或者升级安装pipuninstallwebdriver-manag......
  • Android开发 - StringBuilder 类处理字符串解析
    StringBuilder是什么StringBuilder是Java中用于处理字符串的一个类。相较于String类,它更高效,尤其是在需要频繁修改字符串内容的场景下String的不可变性String是不可变的,也就是说,一旦创建了一个String对象,它的内容就无法再改变了。例如,执行以下代码时:Stringstr......