项目运行环境
- 硬件环境:Raspberry Pi Zero W | 2019-09-26-raspbian-buster-lite
- 参考借鉴:通过shell来创建键鼠设备 | Zero当键盘的设置和定义
- 被测主机:Windows 10
编译所需模块
- 安装内核编译所需环境
1 | sudo apt install bc bison flex libssl-dev git raspberrypi-kernel-headers |
- 下载官方内核里g_hid实现的源码和依赖的头文件。请根据你的系统选择内核分支,我这里是rpi-4.19.y分支
1 | # 官方内核源码地址:https://github.com/raspberrypi/linux |
- 将下面内容复制当前目录下的补丁文件hid.patch中
1 | diff -uprN a/drivers/usb/gadget/legacy/hid.c b/drivers/usb/gadget/legacy/hid.c |
- 将下面内容复制当前目录下的Makefile中
1 | OBJECT_HEADER := input |
- 打补丁后编译该模块
1 | # 给下载后的源码打补丁使生成的模块加载后注册一个键盘和鼠标 |
- 如果想用生成的模块来替换自带的g_hid模块,那么请如下操作
1 | # 先把Makefile中OBJECT_HEADER := input的input为g_hid |
加载内核模块
- 加载模块
1 | # 加载input模块后被插入的主机上可发现多了键鼠设备 |
- 卸载模块
1 | sudo rmmod input.ko # 使用insmod加载的不在默认目录的模块必须用rmmod卸载 |
- 加载模块成功后在ZERO的内核日志会看到类似如下的信息
1 | # dmesg |
模块开机自启
假设你已经用生成的模块替换自带的g_hid模块,那么可如下使其开机自动加载
先在/boot/config.txt文末添加
dtoverlay=dwc2
开启dwc2,注意使用g_hid模块时不能同时使用g_ether模块模块g_hid依赖libcomposite模块,加载模块
modprobe g_hid
,移除模块modprobe -r g_hid
可使用
modinfo g_hid.ko | grep depend
来查看g_hid.ko模块的依赖开机加载g_hid模块,在/etc/modules文末添加如下两行:
1 | libcomposite |
键鼠实机测试
开机加载模块后将Zero靠近HDMI接口的MicroUSB通过数据线连接到Windows主机的USB口上
可以看到我们的树莓派zero已被成功识别为:
USB HID v1.01 Zero [Raspberry],“idVendor=1d6b, idProduct=0104”
的键鼠设备在ZERO中使用root用户输入以下指令可以在被插入的电脑里接收到按键动作
1 | # 按下 按键a 并松开 按键 (输出一个 a) |
- 运行测试程序来模拟其他功能
1 | # 下载测试程序源码 |
出现的问题点
由于无法同时使用两种模式,请不要使用g_ether模块通过USB连接到ZERO,且必须先添加dtoverlay=dwc2到/boot/config.txt后启动时加载才有效,在终端里加载dwc2模块是没有用的
dmesg出现警告:g_hid: loading out-of-tree module taints kernel,这是内核3.7后增加的为了Kernel安全的签名机制,模块能正常加载不会有影响的
insmod时出现错误: could not insert module input.ko: Unknown symbol in module,请执行modprobe libcomposite加载依赖模块
gadget的驱动依赖于udc模块和composite模块,而composite模块又依赖于udc模块,udc是硬件接口模块,直接操作USB寄存器等。composite为上层驱动提供操作UDC
必须通过root用户才能向/dev/hidg设备写入字符,使用sudo我这里无效