DM816X 实现 USB HID Gadget 鼠标键盘功能

开发环境:
平台: DM8168
内核 :linux 2.6.32
RDK:DVRRDK_04.00.00.03
USB口:DM8168有两个USB口可供选择,因为特殊原因我选择的是USB1,请根据实际需要选择USB口
,下面的配置会稍微有些不同。

1配置内核

依据参照http://processors.wiki.ti.com/index.php/DM81xx_AM38XX_USB_User_Guide#Introduction
http://processors.wiki.ti.com/index.php/Usbgeneralpage#One_port_as_host_and_other_port_as_Gadget_.28for_DM81XX.29。
摘录如下:

1) Select host and gadget support

Menuconfig->Device Drviers->USB Support
<*> Support for Host-side USB
[ ] USB verbose debug messages
[*] USB announce new devices
* Miscellaneous USB options *
……
<*> USB Gadget Support —>

2) Select USB OTG support (for TI816X)

Menuconfig->Device Drviers->USB Support
<*> Inventra Highspeed Dual Role Controller (TI, ADI, …)
* Platform Glue Layer *
< > TUSB6010
< > OMAP2430 and onwards
< > AM35x
<*> TI81XX
TI816X usb connector’s ID pin control (from software setting) —>
Force TI816X USB0 to (Host mode) —>
Force TI816X USB1 to (Host mode) —>
Driver Mode (Both host and peripheral: USB OTG (On The Go) Device) —>
[ ] Disable DMA (always use PIO)
[*] Enable debugging messages

3) Select Gadget device controller and gadget driver as modules

Menuconfig->Device Drviers->USB Support
<*> USB Gadget Support —>
— USB Gadget Support
[ ] Debugging messages (DEVELOPMENT) (NEW)
[ ] Debugging information files (DEVELOPMENT) (NEW)
[ ] Debugging information files in debugfs (DEVELOPMENT) (NEW)
(2) Maximum VBUS Power usage (2-500 mA) (NEW)
USB Peripheral Controller (Inventra HDRC USB Peripheral (TI, ADI, …)) —>
USB Gadget Drivers
Gadget Zero (DEVELOPMENT)
[ ] HNP Test Device (NEW)
< > Audio Gadget (EXPERIMENTAL) (NEW)
Ethernet Gadget (with CDC Ethernet support)
[*] RNDIS support (NEW)
[ ] Ethernet Emulation Model (EEM) support (NEW)
< > Gadget Filesystem (EXPERIMENTAL) (NEW)
< > Function Filesystem (EXPERIMENTAL) (NEW)
File-backed Storage Gadget
[*] File-backed Storage Gadget testing version

4) Unselect the OTG Targeted Peripherals list

Menuconfig->Device Drviers->USB Support
<*> Support for Host-side USB
….
[*] USB runtime power management (autosuspend) and wakeup
-*- OTG support
[ ] Rely on OTG Targeted Peripherals List
[ ] Disable external hubs
(–转载请注明出处,其他用途请联系mail:ren_yongke@163.com)
完成以上步骤,先保存退出。

2设备注册

为了实现设备被识别,需加入设备注册。修改hid.c 路径: DVRRDK_04.00.00.03/ti_tools/linux_lsp/kernel/linux-dvr-rdk/drivers/usb/gadget。
由于鼠标键盘为常见USB设备,设备描述符很好得到,如果是要自定义hid设备请参照usb协议.pdf(网络上很容易找到)。
修改如下

#include <linux/usb/g_hid.h>/* hid descriptor for a keyboard */
static struct hidg_func_descriptor pcdm8168_keyboard_data = {.subclass        = 0, /* No subclass */.protocol        = 1, /* Keyboard */.report_length        = 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 (Kana) */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 (Keyboard) */0x19, 0x00,    /* USAGE_MINIMUM (Reserved) */0x29, 0x65,    /* USAGE_MAXIMUM (Keyboard Application) */0x81, 0x00,    /* INPUT (Data,Ary,Abs) */0xc0        /* END_COLLECTION */}
};
/*hid descriptor for a mouse*/
static struct hidg_func_descriptor pcdm8168_mouse_data = {.subclass = 0,  /*NO SubClass*/.protocol = 2,  /*Mouse*/.report_length = 4,.report_desc_length = 52,.report_desc={0x05,0x01,  /*Usage Page (Generic Desktop Controls)*/0x09,0x02,  /*Usage (Mouse)*/0xa1,0x01,  /*Collction (Application)*/0x09,0x01,  /*Usage (pointer)*/0xa1,0x00,  /*Collction (Physical)*/0x05,0x09,  /*Usage Page (Button)*/0x19,0x01,  /*Usage Minimum(1)*/0x29,0x03,  /*Usage Maximum(3) */ 0x15,0x00,  /*Logical Minimum(1)*/0x25,0x01,  /*Logical Maximum(1)*/0x95,0x03,  /*Report Count(5)  */0x75,0x01,  /*Report Size(1)*/0x81,0x02,  /*Input(Data,Variable,Absolute,BitFiled)*/0x95,0x01,  /*Report Count(1)*/0x75,0x05,  /*Report Size(5) */0x81,0x01,  /*Input(Constant,Array,Absolute,BitFiled) */0x05,0x01,  /*Usage Page (Generic Desktop Controls)*/0x09,0x30,  /*Usage(x)*/0x09,0x31,  /*Usage(y)*/0x09,0x38,  /*Usage(Wheel)*/0x15,0x81,  /*Logical Minimum(-127)*/0x25,0x7f,  /*Logical Maximum(127)*/0x75,0x08,  /*Report Size(8)*/0x95,0x02,  /*Report Count(2)  */0x81,0x06,  /*Input(Data,Variable,Relative,BitFiled)*/0xc0,   /*End Collection*/0xc0    /*End Collection*/}
};static struct platform_device pcdm8168_hid_keyboard = {.name = "hidg",.id            = 0,.num_resources = 0,.resource    = 0,.dev.platform_data = &pcdm8168_keyboard_data,
};static struct platform_device pcdm8168_hid_mouse = {.name = "hidg",.id            = 1,.num_resources = 0,.resource    = 0,.dev.platform_data = &pcdm8168_mouse_data,
};static int __init hidg_init(void)
{int status;status = platform_device_register(&pcdm8168_hid_keyboard);if (status < 0){printk("platform_driver hid keyboard:*****wrong\n");platform_device_unregister(&pcdm8168_hid_keyboard);return status;}status = platform_device_register(&pcdm8168_hid_mouse);if (status < 0){printk("platform_driver hid mouse:*****wrong\n");       platform_device_unregister(&pcdm8168_hid_mouse);    return status;}status = platform_driver_probe(&hidg_plat_driver,hidg_plat_driver_probe);if (status < 0){printk("platform_driver_probe:*****wrong\n");return status;}status = usb_composite_probe(&hidg_driver, hid_bind);if (status < 0)platform_driver_unregister(&hidg_plat_driver);return status;
}
static void __exit hidg_cleanup(void)
{platform_driver_unregister(&hidg_plat_driver);platform_device_unregister(&pcdm8168_hid_keyboard);platform_device_unregister(&pcdm8168_hid_mouse);usb_composite_unregister(&hidg_driver);
}

3编译

继续完成内核配置的后续操作
1)Build uImage and usb gadget modules

Build the kernel image and the two usb gadget as modules (like
g_ether.ko, g_file_storage.ko, g_mass_storage.ko or g_zero.ko ..etc).

编译内核 以及 上方修改的代码 ,根据自己的开发环境编译
我的是 make lsp

4测试

通过USB线把8168板子和PC机 连接接起来。
1)Insert the two gadget modules

Load the kernel image and Make sure above setup is done before insert
the modules. Insert the gadget modules for usb0 port.

# insmod .ko (eg: #insert g_ether.ko) Insert the gadget
module for usb1 port.

# insmod .ko (eg: #insert g_file_storage.ko file= stall=0 buflen=65536)

8168上电,进入工作目录,make init 和 make load(个人需要)
由于我所用板子使用的是USB1,没有使用USB0,但是由于8168的特性,USB0也必须进行配置,
我的配置如下:
insmod g_ether.ko
insmod g_hid.ko

这时打开PC的设别管理器会发现,8168已经被识别成鼠标和键盘。
为了测试其功能是否正常需要写一小测试程序,
如下:

#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>#define BUF_LEN 512struct options{const char *opt;unsigned char val;
};static struct options kmod[] = {{.opt = "--left-ctrl",        .val = 0x01},{.opt = "--right-ctrl",        .val = 0x10},{.opt = "--left-shift",        .val = 0x02},{.opt = "--right-shift",    .val = 0x20},{.opt = "--left-alt",        .val = 0x04},{.opt = "--right-alt",        .val = 0x40},{.opt = "--left-meta",        .val = 0x08},{.opt = "--right-meta",        .val = 0x80},{.opt = NULL}
};static struct options kval[] = {{.opt = "--return",    .val = 0x28},{.opt = "--esc",    .val = 0x29},{.opt = "--bckspc",    .val = 0x2a},{.opt = "--tab",    .val = 0x2b},{.opt = "--spacebar",    .val = 0x2c},{.opt = "--caps-lock",    .val = 0x39},{.opt = "--f1",        .val = 0x3a},{.opt = "--f2",        .val = 0x3b},{.opt = "--f3",        .val = 0x3c},{.opt = "--f4",        .val = 0x3d},{.opt = "--f5",        .val = 0x3e},{.opt = "--f6",        .val = 0x3f},{.opt = "--f7",        .val = 0x40},{.opt = "--f8",        .val = 0x41},{.opt = "--f9",        .val = 0x42},{.opt = "--f10",    .val = 0x43},{.opt = "--f11",    .val = 0x44},{.opt = "--f12",    .val = 0x45},{.opt = "--insert",    .val = 0x49},{.opt = "--home",    .val = 0x4a},{.opt = "--pageup",    .val = 0x4b},{.opt = "--del",    .val = 0x4c},{.opt = "--end",    .val = 0x4d},{.opt = "--pagedown",    .val = 0x4e},{.opt = "--right",    .val = 0x4f},{.opt = "--left",    .val = 0x50},{.opt = "--down",    .val = 0x51},{.opt = "--kp-enter",    .val = 0x58},{.opt = "--up",        .val = 0x52},{.opt = "--num-lock",    .val = 0x53},{.opt = NULL}
};int keyboard_fill_report(char report[8],char buf[BUF_LEN],int *hold)
{char *tok = strtok(buf, " ");int key = 0;int i = 0;for (; tok != NULL; tok = strtok(NULL, " ")) {if (strcmp(tok, "--quit") == 0)return -1;if (strcmp(tok, "--hold") == 0) {*hold = 1;continue;}if (key < 6) {for (i = 0; kval[i].opt != NULL; i++)if (strcmp(tok, kval[i].opt) == 0) {report[2 + key++] = kval[i].val;break;}if (kval[i].opt != NULL)continue;}if (key < 6)if (islower(tok[0])) {report[2 + key++] = (tok[0] - ('a' - 0x04));continue;}for (i = 0; kmod[i].opt != NULL; i++)if (strcmp(tok, kmod[i].opt) == 0) {report[0] = report[0] | kmod[i].val;break;}if (kmod[i].opt != NULL)continue;if (key < 6)fprintf(stderr, "unknown option: %s\n", tok);}return 8;
}static struct options mmod[] = {{.opt = "--b1", .val = 0x01},{.opt = "--b2", .val = 0x02},{.opt = "--b3", .val = 0x04},{.opt = NULL}
};int mouse_fill_report(char report[8],char buf[BUF_LEN],int *hold)
{char *tok = strtok(buf, " ");int mvt = 0;int i = 0;for (; tok != NULL; tok = strtok(NULL, " ")) {if (strcmp(tok, "--quit") == 0)return -1;if (strcmp(tok, "--hold") == 0) {*hold = 1;continue;}for (i = 0; mmod[i].opt != NULL; i++)if (strcmp(tok, mmod[i].opt) == 0) {report[0] = report[0] | mmod[i].val;break;}if (mmod[i].opt != NULL)continue;if (!(tok[0] == '-' && tok[1] == '-') && mvt < 2) {errno = 0;report[1 + mvt++] = (char)strtol(tok, NULL, 0);if (errno != 0) {fprintf(stderr, "Bad value:'%s'\n", tok);report[1 + mvt--] = 0;}continue;}fprintf(stderr, "unknown option: %s\n", tok);}return 3;
}void print_options(char c)
{int i = 0;if (c == 'k') {printf("    keyboard options:\n""        --hold\n");for (i = 0; kmod[i].opt != NULL; i++)printf("\t\t%s\n", kmod[i].opt);printf("\n    keyboard values:\n""        [a-z] or\n");for (i = 0; kval[i].opt != NULL; i++)printf("\t\t%-8s%s", kval[i].opt, i % 2 ? "\n" : "");printf( "    --quit to close\n");printf("\n");} else if (c == 'm') {printf("    mouse options:\n""        --hold\n");for (i = 0; mmod[i].opt != NULL; i++)printf("\t\t%s\n", mmod[i].opt);printf("\n    mouse values:\n""        Two signed numbers\n""   --quit to close\n");}
}int main(int argc,const char *argv[])
{const char *filename = NULL;int fd = 0;char buf[BUF_LEN];int cmd_len;char report[8];int to_send = 8;int hold = 0;fd_set rfds;int retval,i;if (argc < 3) {fprintf(stderr, "Usage: %s devname mouse|keyboard\n",argv[0]);return 1;}if(argv[2][0] != 'k' && argv[2][0] != 'm'){return 2;}filename = argv[1];if ((fd = open(filename, O_RDWR, 0666)) == -1) {perror(filename);return 3;}print_options(argv[2][0]);while (42) {FD_ZERO(&rfds);FD_SET(STDIN_FILENO, &rfds);FD_SET(fd, &rfds);retval = select(fd + 1, &rfds, NULL, NULL, NULL);if (retval == -1 && errno == EINTR)continue;if (retval < 0) {perror("select()");return 4;}if (FD_ISSET(fd, &rfds)) {cmd_len = read(fd, buf, BUF_LEN - 1);printf("recv report:");for (i = 0; i < cmd_len; i++)printf(" %02x", buf[i]);printf("\n");}if (FD_ISSET(STDIN_FILENO, &rfds)) {memset(report, 0x0, sizeof(report));cmd_len = read(STDIN_FILENO, buf, BUF_LEN - 1);if (cmd_len == 0)break;buf[cmd_len - 1] = '\0';hold = 0;memset(report, 0x0, sizeof(report));if (argv[2][0] == 'k')to_send = keyboard_fill_report(report, buf, &hold);else if (argv[2][0] == 'm')to_send = mouse_fill_report(report, buf, &hold);if (to_send == -1)break;if (write(fd, report, to_send) != to_send) {perror(filename);return 5;}if (!hold) {memset(report, 0x0, sizeof(report));if (write(fd, report, to_send) != to_send) {perror(filename);return 6;}}}}close(fd);return 0;
}

需要交叉编译器进行编译,我使用的是arm-none-linux-gnueabi-gcc-4.3.3

编译完成后,把生成的执行文件cp到设备中分别执行
./pcdm8168_hid /dev/hidg0 k和./pcdm8168_hid /dev/hidg1 m
根据提示进行操作即可。


声明:上文是参考http://www.oschina.net/question/1174645_135969完成的,思路和代码大体是按其思路,只有修改了个别设备描述符。

–转载请注明出处,其他用途请联系mail:ren_yongke@163.com

DM816X 实现 USB HID Gadget 鼠标键盘功能相关推荐

  1. stm32 USB HID+CDC 鼠标键盘串口 组合设备配置解析

    前言 查阅网上的博客与代码,很多都是关于USB的鼠标配置.USB的键盘配置.USB的虚拟串口配置,稍微深入一点的会将鼠标键盘合在一起,但移植起来就会报很多错误,要么是检测不到,要么是警告,这很正常,因 ...

  2. usb hid gadget驱动

    一 usb gadget框架层次 1 驱动层 2 复合层 3 控制器驱动层 二 初始化流程 1 驱动层介绍 2 hidg驱动初始化详解 1 至上而下遍历搜索绑定驱动和设备 2 至下而上遍历完成初始化 ...

  3. usb gaghet hid 模拟鼠标键盘的绝对值描述

    调试模拟键盘鼠标花了我接近一周的时间,到处查找资料,结果东平西凑.靠上厕所的灵感,终于调通了, 主要注意的是绝对值坐标和相对坐标的表达不一样 最后在这里找到了答案,感谢21ic tanganrong ...

  4. win10 无法识别所有usb设备(鼠标/键盘等)

    又如usb3.0 可扩展主控器无法识别,设备无法启动错误代码10 这个一般是内存引起的,解决办法如下 1.首先用触摸板打开,打开设备管理器 win10右键windows(电脑左下角),左键设备管理器 ...

  5. STM32 keyboard USB HID键盘功能的实现

    参考地址:https://blog.csdn.net/a65135793/article/details/80287250 相关文章 ·1.STM32完成USB_Keyboard的实验总结----ht ...

  6. Android 12.0 通过驱动实现禁用usb鼠标和usb键盘功能

    1.1概述 在12.0的系统产品定制化开发中,在进行定制中有关于usb键盘和usb鼠标的需求中,产品要求禁止usb口挂载usb鼠标和usb键盘,所以需要要求在usb挂载类型的时候 判断如果是usb鼠标 ...

  7. 电脑USB接口实现鼠标和键盘功能

    接口是一种引用数据类型,是方法的集合.接口内部主要封装了方法. 使用 interface 关键字定义,会被编译成.class文件. 接口不能创建对象,但是其他类可以使用 implements 实现接口 ...

  8. 8修改host_正点原子【STM32-F407探索者】第五十九章 USB 鼠标键盘(Host)实验

    1)资料下载:点击资料即可下载 2)对正点原子Linux感兴趣的同学可以加群讨论:935446741 3)关注正点原子公众号,获取最新资料更新 上一章我们向大家介绍了如何利用 STM32F4 的 US ...

  9. STM32 keyboard USB键盘功能的实现

    原文地址::http://blog.csdn.net/u011318735/article/details/17429789 相关文章 ·1.STM32完成USB_Keyboard的实验总结----h ...

最新文章

  1. mysql 数字区间_币投君0904丨数字货币暴跌原因何在
  2. 上海国际区块链赋能传统产业峰会-王伟:道道人才链启动
  3. 《逻辑与计算机设计基础(原书第5版)》——3.9 二进制加法器
  4. 人工智障学习笔记——强化学习(5)DRL与DQN
  5. ubuntu简单的小命令
  6. Shell.NavBarIsVisible=“false“
  7. 一年总结:2016.7.9 - 2017.7.9
  8. [编程] C语言变量和数据类型总结练习题
  9. 九度搜索引擎点击优化_「九度搜索引擎点击优化软件」网站推广方案
  10. 成语小秀才云开发代码 成语答题小程序源码
  11. 注册mysql确认邮件_如何在MySQL中使用电子邮件ID选择@之前的所有内容?
  12. Scrapy学习第四课
  13. springcloudconfig使用教程
  14. php取word表格一行内容,如何提取出word表格中的内容 值得一看
  15. python 双精度浮点_Python双精度浮点数运算并分行显示操作示例
  16. 用JS改变html样式
  17. 电路板PCBA清洗工艺
  18. VS运行错误提示:未处理的异常0xC000 0005
  19. mysql5.7.10 二进制包_mysql 32 位安装教程mysql5.7 二进制包安装
  20. java国密 C#国密 golang国密 NodeJS国密汇总(三)

热门文章

  1. 传播正能量-IT的笑傲江湖
  2. gRPC 中监听 Sream 和 Transport 的事件
  3. Qt Quick Qml 之QML与C++ 混合编程学习
  4. 大数据日知录理解(1)
  5. Mybatis源码日知录
  6. mysql 命令(二)表操作
  7. 171103 Matlab subplot 用法
  8. div边框颜色和背景颜色
  9. 基于奇异值分解的图像压缩与除噪
  10. 基于物联网可移动医疗设备智能监测节能应用研讨