完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
RK339的支持,程序在内核设备驱动程序中目录“kernels/u***”中,支持的设备如U盘、USB39/USB3键盘、USB网卡、USB键盘等,R99主板上提供有6个USB接口,其中的type-c接口是USB OTG接口,既支持USB HOST也支持USB DEVICE设备,要使RK3399配置成一个USB小工具设备(比如配置成一个隐藏键盘),就得在type- c上,实际中这个功能有广泛的应用,pc主机和RK3399进行数据通信,用这就是一种很好的方式,RK3399的USB type-c最终接口被配置成Firefly-RK3399和ADB接口时设备,如下图:
现在我们重新构建内核,把 RK3399 模拟成 USB 的 HID 设备。分以下步骤: 1、构建 RK3399 内核,进行构建 环境,参见:http://wiki.t- firefly.com/zh_CN/Firefly-RK3399/prepare_compile_android.html 官方推荐Ubuntu14.04运行,我安装的是Ubuntu16.04.1,可以完整安装android sdk: http ://wiki.t-firefly.com/zh_CN/ Firefly-RK3399/compile_android7.1_firmware.html 汇编的制作过程和机器人的配置是一个普通文件的,很多奇特的,很好地在比较过程中的环境问题中出现了一个环境问题,并仔细分析了整个过程。 2、修改成功,此文件在kernel/drivers/u***/gadget/legacy/目录下,增加以下内容: (1)增加hidg_func_descriptor {结构my_hid_data static struct hidg_func_descriptor my_hid_data = .subclass = 0, /* No subclass */ .protocol = 1 , /* 键盘 */ .report_length = 8, .report_desc_length = 63, .report_desc = { 0x05, 0x01, /* USAGE_PAGE (通用桌面) */ 0x09, 0x06, /* USAGE (键盘) */ 0xa1, 0x01, / *收集(应用程序)*/ 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */ 0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */ 0x15, 0x00, /* LOGICAL_MINIMUM (0) * / 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ 0x75, 0x01, /* REPORT_SIZE (1) */ 0x95 , 0x08, /* REPORT_COUNT (8) */ 0x81, 0x02, /* INPUT (Data,Var,Abs ) */ 0x95, 0x01, /* REPORT_COUNT (1) */ 0x75, 0x08, /* REPORT_SIZE (8) */ 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */ 0x95, 0x05, /* REPORT_COUNT (5) */ 0x75, 0x01, /* REPORT_SIZE (1) */ 0x05, 0x08, /* USAGE_PAGE (LEDs) */ 0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */ 0x29, 0x05, /* USAGE_MAXIMUM (假名) */ 0x91 , 0x02, /* OUTPUT (Data,Var,Abs) */ 0x95, 0x01, /* REPORT_COUNT (1) */ 0x75, 0x03, /* REPORT_SIZE (3) */ 0x91 , 0x03, /* 输出 (Cnst,Var,Abs) */ 0x95, 0x06, /* REPORT_COUNT (6) */ 0x75, 0x08, /* REPORT_SIZE (8) */ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ 0x25, 0x65, /* LOGICAL_MAXIMUM (101) */ 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ 0x19, 0x00, /* USAGE_MINIMUM (Reserved) */ 0x29, 0x65, /* USAGE_MAXIMUM (Keyboard Application) */ 0x81, 0x00, /* INPUT (Data,Ary,Abs) * / 0xc0 /* END_COLLECTION */ } }; (2)增加platform_device结构变量my_hid 静态结构平台设备 my_hid = { .name = "hidg", .id = 0, .num_resources = 0, .resource = 0, .dev.platform_data = &my_hid_data, }; (3)在hidg_init(void)函数中增加如下语句 status = platform_device_register(&my_hid); if (status < 0) { 返回状态; (4)在hidg_cleanup (void)函数中增加如下语句 platform_device_unregister(&my_hid); 修改后完整的hid.c文件如下: /* * hid.c -- HID Composite driver * * based on multi.c * * Copyright (C) 2010 Fabien Chouteau < fabien.chouteau@barco.com > * * 本程序为免费软件; 您可以根据* 自由软件基金会 发布的 GNU 通用公共许可证的条款重新分发和/或修改* 它; 许可证的第 2 版,或 *(由您选择)任何更高版本。 */ #include #include #include #include #include #包括 #define DRIVER_DESC "HID Gadget" #define DRIVER_VERSION "2010/03/16" #include "u_hid.h" /*------------- -------------------------------------------------- ---------*/ #define HIDG_VENDOR_NUM 0x0525 /* XXX NetChip */ #define HIDG_PRODUCT_NUM 0xa4ac /* Linux-USB HID gadget */ /*------------------------- ------------------------------------------------*/ 结构 hidg_func_node { 结构 u***_function_instance *fi; 结构 u***_function *f; 结构 list_head 节点; 结构 hidg_func_descriptor *func; }; 静态列表头(hidg_func_list); /*dhl**************************************************** ************************/ static struct hidg_func_descriptor my_hid_data = { .subclass = 0, /* 没有子类 */ .protocol = 1, /* 键盘 */ .报告长度 = 8, .report_desc_length = 63, .report_desc = { 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ 0x09, 0x06, /* USAGE (Keyboard) */ 0xa1, 0x01, /* COLLECTION (Application) */ 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */ 0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ 0x25, 0x01 , /* LOGICAL_MAXIMUM (1) */ 0x75, 0x01, /* REPORT_SIZE (1) */ 0x95, 0x08, /* REPORT_COUNT (8) */ 0x81, 0x02, /* INPUT (Data,Var,Abs) */ 0x95, 0x01, /* REPORT_COUNT (1) */ 0x75, 0x08, /* REPORT_SIZE (8) */ 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */ 0x95, 0x05, /* REPORT_COUNT (5) */ 0x75, 0x01, /* REPORT_SIZE (1) */ 0x05, 0x08, /* USAGE_PAGE ( LEDs) */ 0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */ 0x29, 0x05, /* USAGE_MAXIMUM (假名) */ 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ 0x95, 0x01, /* REPORT_COUNT (1) */ 0x75, 0x03, /* REPORT_SIZE (3) */ 0x91 , 0x03, /* OUTPUT (Cnst, Var,Abs) */ 0x95, 0x06, /* REPORT_COUNT (6) */ 0x75, 0x08, /* REPORT_SIZE (8) */ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ 0x25, 0x65, /* LOGICAL_MAXIMUM ( 101) */ 0x05, 0x07, /* USAGE_PAGE (键盘) */ 0x19, 0x00, /* USAGE_MINIMUM (保留) */ 0x29, 0x65, /* USAGE_MAXIMUM (键盘应用) */ 0x81, 0x00, /* INPUT (Data,Ary,Abs) */ 0xc0 /* END_COLLECTION */ } }; /*dhl**************************************************** ************************/ /*---------------------------- -----------------------------------------------------------*/ USB_GADGET_COMPOSITE_OPTIONS (); 静态结构u***_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, .bcdUSB = cpu_to_le16(0x0200), /* .bDeviceClass = USB_CLASS_COMM, */ /* .bDeviceSubClass = 0, */ /* .bDeviceProtocol = 0, */ .bDeviceClass = USB_CLASS_PER_INTERFACE, .bDeviceSubClass = 0, .bDeviceProtocol = 0, /* .bMaxPacketSize0 = f(hardware) */ /* 供应商和产品 id 可以被模块参数覆盖。*/ .idVendor = cpu_to_le16(HIDG_VENDOR_NUM), .idProduct = cpu_to_le16(HIDG_PRODUCT_NUM), /* .bcdDevice = f(硬件) */ /* .iManufacturer = DYNAMIC */ /* .iProduct = DYNAMIC */ /* 无序列号*/ .bNumConfigurations = 1, }; static const struct u***_descriptor_header *otg_desc[2]; /* 字符串 ID 是动态分配的 */ static struct u***_string strings_dev[] = { [USB_GADGET_MANUFACTURER_IDX].s = "", [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC, [USB_GADGET_SERIAL_IDX].s = "", { } /* 列表结束 */ }; static struct u***_gadget_strings stringtab_dev = { .language = 0x0409, /* en-us */ .strings = strings_dev, }; 静态结构 u***_gadget_strings *dev_strings[] = { &stringtab_dev, NULL, }; /****************************** 配置 ****************** ************/ static int do_config(struct u***_configuration *c) { struct hidg_func_node *e, *n; 整数状态 = 0; if (gadget_is_otg(c->cdev->gadget)) { c->descriptors = otg_desc; c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } list_for_each_entry(e, &hidg_func_list, node) { e->f = u***_get_function(e->fi); if (IS_ERR(e->f)) 转到放置; 状态 = u***_add_function(c, e->f); if (status < 0) { u***_put_function(e->f); 转到放置; } } 返回 0; 把: list_for_each_entry(n, &hidg_func_list, node) { if (n == e) break; u***_remove_function(c, n->f); u***_put_function(n->f); } 返回状态; } static struct u***_configuration config_driver = { .label = "HID Gadget", .bConfigurationValue = 1, /* .iConfiguration = DYNAMIC */ .bmAttributes = USB_CONFIG_ATT_SELFPOWER, }; /****************************** 小工具绑定 ***************** *************/ static int hid_bind(struct u***_composite_dev *cdev) { struct u***_gadget *gadget = cdev->gadget; 结构列表头 *tmp; 结构 hidg_func_node *n, *m; 结构 f_hid_opts *hid_opts; 整数状态,函数 = 0; list_for_each(tmp, &hidg_func_list) 函数++; 如果(!funcs) 返回-ENODEV; list_for_each_entry(n, &hidg_func_list, node) { n->fi = u***_get_function_instance("hid"); 如果(IS_ERR(n->fi)){ 状态= PTR_ERR(n->fi); 转到放置; } hid_opts = container_of(n->fi, struct f_hid_opts, func_inst); hid_opts->subclass = n->func->subclass; hid_opts->protocol = n->func->protocol; hid_opts->report_length = n->func->report_length; hid_opts->report_desc_length = n->func->report_desc_length; hid_opts->report_desc = n->func->report_desc; } |
|
|
|
/* 分配字符串描述符编号...注意字符串
* 的内容可以被复合开发胶水覆盖。 */ 状态 = u***_string_ids_tab(cdev, strings_dev); if (status < 0) goto put; device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; if (gadget_is_otg(gadget) && !otg_desc[0]) { struct u***_descriptor_header *u***_desc; u***_desc = u***_otg_descriptor_alloc(gadget); if (!u***_desc) goto put; u***_otg_descriptor_init(小工具,u***_desc); otg_desc[0] = u***_desc; otg_desc[1] = 空; } /* 注册我们的配置 */ status = u***_add_config(cdev, &config_driver, do_config); 如果(状态 < 0) 转到 free_otg_desc; u***_composite_overwrite_options(cdev, &coverwrite); dev_info(&gadget->dev, DRIVER_DESC ", 版本: " DRIVER_VERSION "n"); 返回0; free_otg_desc: kfree(otg_desc[0]); otg_desc[0] = NULL; 把: list_for_each_entry(m, &hidg_func_list, node) { if (m == n) break; u***_put_function_instance(m->fi); } 返回状态; } 静态 int hid_unbind(struct u***_composite_dev *cdev) { struct hidg_func_node *n; list_for_each_entry(n, &hidg_func_list, node) { u***_put_function(n->f); u***_put_function_instance(n->fi); } kfree(otg_desc[0]); otg_desc[0] = NULL; 返回0; } static int hidg_plat_driver_probe(struct platform_device *pdev) { struct hidg_func_descriptor *func = dev_get_platdata(&pdev->dev); 结构 hidg_func_node *entry; if (!func) { dev_err(&pdev->dev, "平台数据丢失n"); 返回-ENODEV; } entry = kzalloc(sizeof(*entry), GFP_KERNEL); 如果 (!entry) 返回 -ENOMEM; 入口->函数=函数; list_add_tail(&entry->node, &hidg_func_list); 返回0; } 静态 int hidg_plat_driver_remove(struct platform_device *pdev) { struct hidg_func_node *e, *n; list_for_each_entry_safe(e, n, &hidg_func_list, node) { list_del(&e->node); kfree(e); } 返回 0; } /****************************** 一些噪音 ****************** **************/ 静态结构 u***_composite_driver hidg_driver = { .name = "g_hid", .dev = &device_desc, .strings = dev_strings, .max_speed = USB_SPEED_HIGH, .bind = hid_bind, .unbind = hid_unbind, }; 静态结构 platform_driver hidg_plat_driver = { .remove = hidg_plat_driver_remove, .driver = { .name = "hidg", }, }; /*dhl**************************************************** *********************/ 静态结构平台设备 my_hid = { .name = "hidg", .id = 0, .num_resources = 0, .resource = 0, .dev.platform_data = &my_hid_data, }; /*dhl**************************************************** ************************/ MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR("Fabien Chouteau, Peter Korsgaard"); MODULE_LICENSE("GPL"); 静态 int __init hidg_init(void) { int status; /*dhl**************************************************** ************************/ printk("东海林输入隐藏n"); 状态 = platform_device_register(&my_hid); if (status < 0) { 返回状态; } /*dhl**************************************************** ************************/ status = platform_driver_probe(&hidg_plat_driver, hidg_plat_driver_probe); if (status < 0) 返回状态; 状态 = u***_composite_probe(&hidg_driver); if (status < 0){ platform_driver_unregister(&hidg_plat_driver); 返回状态; } 返回状态; } 模块初始化(hidg_init); 静态 void __exit hidg_cleanup(void) { u***_composite_unregister(&hidg_driver); platform_driver_unregister(&hidg_plat_driver); /*dhl**************************************************** ************************/ platform_device_unregister(&my_hid); /*dhl**************************************************** ************************/ } module_exit(hidg_cleanup); 用更高版本的hid.c文件替换“kernel/drivers/u***/gadget/legacy/”下的hid.c文件 3、重新构建内核 (1)内核配置 进入内核目录修改,首先执行make ARCH=arm64 firefly_defconfig生成配置文件 执行make menuconfig,按内核配置 Device Drivers->USB支持->USB Gad获取支持->具体配置如下图: 选择保存,配置保存到.config文件中。 (2)kernel目录下执行命令make clean (3)kernel下执行make -j8 ARCH=arm64 rk3399-firefly.img命令 (4)新内核,如下重新重新烧入新内核的安装图 ,重新启动RK3399后,通过下面的hound hound查看,没有u***设备,发现: (5)安装内核模块 将生成的内核模块libcomposite.ko、u***_f_hid. ko、g_hid.ko三个文件拷贝到RK3399的/sdcard/目录下,然后按以下顺序,执行命令 insmod libcomposite.ko insmod u***_f_hid.ko insmod g_hid.ko 当执行完最后一条命令后,正常情况下,你会听到你的电脑会发现新设备的提示声,到这里你就成功了。在看一下bus hound图: 进入RK3399的/dev/目录,查看会发现新生成的hidg0设备,执行命令echo "123">/dev/hidg0,在bus hound上查看,如下图: |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
基于米尔瑞芯微RK3576核心板/开发板的人脸疲劳检测应用方案
1070 浏览 0 评论
1248 浏览 1 评论
981 浏览 1 评论
2263 浏览 1 评论
3586 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-29 13:07 , Processed in 0.671020 second(s), Total 72, Slave 56 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号