当前位置: 首页 > news >正文

iMX6ULL驱动开发 | 让imx6ull开发板支持usb接口FC游戏手柄

手边有一闲置的linux开发板iMX6ULL一直在吃灰,不用来搞点事情,总觉得对不住它。业余打发时间就玩起来吧,总比刷某音强。从某多多上买来一个usb接口的游戏手柄,让开发板支持以下它,后续就可以接着在上面玩童年经典游戏啦。

 我使用的是正点原子的I.MX6U-ALPHA 开发板,板子资源很丰富。计划搞一个系列在上面玩各种有意思的事情。包含linux驱动开发和应用开发,最终学以致用,在玩中学,兴趣是最好的老师。

 展示下我买的FC游戏手柄长这样,普普通通,但便宜啊,还是经典的味道。

驱动移植过程

确定设备类型

要让板子支持这一USB接口的FC游戏手柄,首先得知道这个手柄是使用的什么接口协议。插到win10电脑上看了下,是一个USB协议接口的HID类型的设备。USB-HID是Universal Serial Bus-Human Interface Device的缩写,由其名称可以了解HID设备是直接与人交互的设备,例如键盘、鼠标与游戏杆等。

USB的硬件端口是统一的,但是USB设备却是多种多样的,USB主机根据USB设备的描述符来区分不同的USB设备。每一个USB设备都有自己的描述符,当插入USB设备之后,主机会向从机发送命令,从机收到命令之后,会返回特定的描述符信息。主机通过解析收到的描述符,来识别从机设备的相关信息,这个过程,就是设备枚举(enumeration)过程。

获取USB的VID和PID信息

我的这个FC手柄插到电脑上后识别出了usb-hid设备。查看到它的vid和pid信息,直接在电脑的设备管理器里能够查看到,这个信息很有用,后面驱动移植需要用到。

已启动设备 HID\VID_0810&PID_0001\6&1eff4ed2&0&0000。驱动程序名称: input.inf

查找linux内核源码,锁定相关驱动

在linux内核源码的linux/drivers/hid/路径下,有跟HID相关的驱动源码。打开hid-core.c文件(HID support for Linux),查看下该源文件中是否包含该usb设备的VID和PID信息。如果没有,则在hid_have_special_driver添加上VID和PID信息。这个里面的一些宏定义在文件hid-ids.h中可以查看。

torvalds大神linux源码的github地址:

GitHub - torvalds/linux: Linux kernel source tree

/** A list of devices for which there is a specialized driver on HID bus.** Please note that for multitouch devices (driven by hid-multitouch driver),* there is a proper autodetection and autoloading in place (based on presence* of HID_DG_CONTACTID), so those devices don't need to be added to this list,* as we are doing the right thing in hid_scan_usage().** Autodetection for (USB) HID sensor hubs exists too. If a collection of type* physical is found inside a usage page of type sensor, hid-sensor-hub will be* used as a driver. See hid_scan_report().*/
static const struct hid_device_id hid_have_special_driver[] = {{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) },{ HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) },{ HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0xf705) },//......}

查找近似hid的游戏手柄驱动

通过make menuconfig打开内核配置选项查看。

 找到有个DragonRise Inc, game controller。虽然不确定它跟我的这款FC手柄完美匹配,但至少从名字上看,这就是个游戏手柄的hid设备。

 如果有默认的内核配置选项文件,也可以直接添加选项开关:

CONFIG_HID_DRAGONRISE=y

跟这个相关的驱动源文件是linux/drivers/hid/hid-dr.c。打开这个文件,添加上我的usb设备的VID和PID信息。

static const struct hid_device_id dr_devices[] = {{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006),  },{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011),  },{ HID_USB_DEVICE(0x0810, 0x0001),  },{ }
};

编译内核驱动

#使用Yocto SDK里的GCC 5.3.0交叉编译器编译出厂Linux源码,可不用指定ARCH等,直接执行Make
source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi
#编译前先清除
make distclean
#配置defconfig文件
make imx_v7_defconfig -j 16
#开始编译zImage
make zImage -j 16

这之后,更新板子上的内核并重启设备。把该USB游戏手柄插上去,输入dmesg查看内核日志信息,看是否识别到该设备节点。

dmesg

查看输入设备、获取输入事件信息

/dev/input/目录

/dev/input/目录下的事件都是在驱动中调用input_register_device(struct input_dev *dev)产生的。我的/dev/input/目录中的文件如下:

$ ls /dev/input/
by-id  by-path  event0  event1  event2  event3 

每个event代表一个事件。那么如何知道每个事件分别与哪个设备对应?可以借助于/proc/bus查看。

/proc/bus/input/devices

/proc/bus/input/devices存放了与event对应的相关设备信息。我的板子上查看到的内容如下:

$ cat /proc/bus/input/devices

可以看到,每一项的“H:”一行后边的内容中就是对应的event。 

直接读取/dev/input/eventx

使用cat查看输入事件的内容,操作相应输入设备,事件会上报内容。以字符串方式解读会呈现乱码。所以可以使用hexdump读取十六进制的数据。

测试读取demo

linux内核使用 input_event结构体描述所有的输入事件。

/** The event structure itself*/struct input_event {struct timeval time;__u16 type;__u16 code;__s32 value;
};

为了验证该usb的游戏手柄是否工作,以及获取它对应的键值,写一个小的demo测试读取下。

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h> #define _EV_KEY         0x01    /* button pressed/released */
#define _EV_ABS         0x03    
#define _EV_MSC         0x04   int main() {printf("hello,usb hid joystick key test\n");int fd = open("/dev/input/event3", O_RDONLY);struct input_event e;while(1) {read(fd, &e, sizeof(e));switch(e.type) {case _EV_KEY:printf("type: %d, code: %d,value: %d, time: %d\n", e.type, e.code,e.value, e.time);break;case _EV_ABS:printf("type: %d, code: %d,value: %d, time: %d\n", e.type, e.code,e.value, e.time);break;case _EV_MSC:printf("type: %d, code: %d,value: %d, time: %d\n", e.type, e.code,e.value, e.time);break;default:if(e.type != 0){printf("type:%d, code: %d,value: %d, time: %d\n",e.type, e.code,e.value, e.time);}}}close(fd);return 0;
}

evtest测试工具

在开发input子系统驱动时,常常会使用evtest工具进行测试。evtest是打印evdev内核事件的工具,它直接从内核设备读取并打印设备描述的带有值和符号名的事件,可以用来调试鼠标、键盘、触摸板等输入设备。通常用于调试输入设备的问题。

输出数据中,“type”是input类型,可以是“EV KEY”、“EV SW”、“EV SND”、“EV LED”或数值;“value”可以是十进制也可以是十六进制,或者是查询的kev/开关/声音/LED的常量名。

evtest工具下载安装

下载地址:Index of /debian/pool/main/e/evtest/ | 南阳理工学院开源镜像站 | Nanyang Institute of Technology Open Source Mirror

交叉编译安装

#解压缩
$ tar   -xjvf   evtest_1.33.orig.tar.bz2
$ cd evtest-1.33/#加载环境
source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi#生成makefile,指定交叉编译
.confiqure --host=arm-linux#编译
make

evtest工具使用

 运行示例

time:事件产生的时间。

type:事件类型,常见的有:EV_KEY(键盘)、EV_REL(相对坐标)、EV_ABS(绝对坐标)、,定义在[input-event-codes.h] (https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h#LC35) 或 input.h 中。

code:事件的代码,对事件进一步的描述,如:键盘事件的键值(KEY_NUMLOCK、KEY_ESC、KEY_1、KEY_A)。

value:事件的值,对事件更具体地描述,如:按键的按下/抬起。

以下是使用devtest工具,(各按一次上,下,左,右,选择,开始等按键), 抓取的各个按键的反馈信息:

手柄上的键值确定

FC手柄上一般包含以下键。左,右,上,下,start,select,A,B,X,Y。

     /*** FC手柄 bit 键位对应关系 真实手柄中有一个定时器,处理 连A  连B* 0  1   2       3       4    5      6     7* A  B   Select  Start  Up   Down   Left  Right*/

如果你买的usb接口的FC游戏手柄是DragonRise Inc. game这家的,估计就不用以上这么的测试键值了,直接启用就能用。但是我随便买的这款需要测试下对应起来才能用。

 经过以上测试,最终确定键值的对应关系如下:

游戏手柄按键读出的键值
左侧方向键上type: 3, code:1,value: 0
type: 3, code:1,value: 127
左侧方向键下type: 3, code:1,value: 255
type: 3, code:1,value: 127
左侧方向键左type: 3, code:0,value: 0
type: 3, code:0,value: 127
左侧方向键右type: 3, code:0,value: 255
type: 3, code:0,value: 127
SELECT键type: 1, code:296,value: 1
type: 1, code:296,value: 0
START键type: 1, code:297,value: 1
type: 1, code:297,value: 0
右边数字键1type: 1, code:288,value: 1
type: 1, code:288,value: 0
右边数字键2type: 1, code:289,value: 1
type: 1, code:289,value: 0
右边数字键3type: 1, code:290,value: 1
type: 1, code:290,value: 0
右边数字键4type: 1, code:291,value: 1
type: 1, code:291,value: 0

最后试了下控制完全没问题,还很流畅呢!可以愉快的玩耍啦,带上个充电宝,这个就是我的移动游戏机,支持无限多个好玩的经典游戏!关于Nes模拟器的移植后面逐一揭晓,欢迎关注收藏。 

其他资源

USB HID_Soc点灯大师的博客-CSDN博客

为了V3S不吃灰,移植NES游戏 / 全志 SOC / WhyCan Forum(哇酷开发者社区)

V3S移植nes游戏模拟器(附带游戏合集)_v3s编译游戏模拟器_qq_46604211的博客-CSDN博客

Linux下查看输入设备、获取输入事件的详细方法_evtest命令_蓝天居士的博客-CSDN博客

linux驱动开发学习笔记九:menuconfig过程详解

开发者搜索-Beta-让技术搜索更简单高效
Linux系统struct input_event结构体分类型(鼠标、键盘、触屏)详解与例子_wkd_007的博客-CSDN博客开发者搜索-Beta-让技术搜索更简单高效
 

USB_HID基础_usbhid_jansert的博客-CSDN博客

玩转USB HID系列:Linux下使用C语言和libusb开发USB HID_whstudio123的博客-CSDN博客

i.MX6ULL驱动开发 | 20 - Linux input 子系统_imx6ull input驱动框架_Mculover666的博客-CSDN博客

GitHub - torvalds/linux: Linux kernel source tree

嵌入式Linux:V3s移植NES游戏,声音,游戏手柄_全志v3s 移植nes_liefyuan的博客-CSDN博客

相关文章:

iMX6ULL驱动开发 | 让imx6ull开发板支持usb接口FC游戏手柄

手边有一闲置的linux开发板iMX6ULL一直在吃灰&#xff0c;不用来搞点事情&#xff0c;总觉得对不住它。业余打发时间就玩起来吧&#xff0c;总比刷某音强。从某多多上买来一个usb接口的游戏手柄&#xff0c;让开发板支持以下它&#xff0c;后续就可以接着在上面玩童年经典游戏啦…...

Java 实现 SCP 携带密码拷贝文件

背景说明 涉及通过程序进行机器间的文件Copy的场景&#xff0c;我们一般会使用ssh连接机器&#xff0c;通过scp命令进行文件copy。 此种方案的前提是&#xff1a;机器间事先要配置免密码互通。 但是&#xff0c;如果客户现场机器数量过多&#xff0c;配置免密操作比较麻烦&a…...

Flink CEP(三)pattern动态更新

线上运行的CEP中肯定经常遇到规则变更的情况&#xff0c;如果每次变更时都将任务重启、重新发布是非常不优雅的。尤其在营销或者风控这种对实时性要求比较高的场景&#xff0c;如果规则窗口过长&#xff08;一两个星期&#xff09;&#xff0c;状态过大&#xff0c;就会导致重启…...

抽象工厂模式(C++)

定义 提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”&#xff0c;无需指定它们具体的类。 使用场景 在软件系统中&#xff0c;经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化&#xff0c;往往存在更多系列对象的创建工作。如何应对这种…...

程序员面试金典17.*

文章目录 17.01 不用加号的加法17.04 消失的数字17.05字母与数字17.06 2出现的次数17.07 婴儿名字17.08 马戏团人塔17.09 第k个数17.10 主要元素17.11 单词距离17.12 BiNode17.13 恢复空格&#xff08;未做&#xff0c;字典树dp&#xff09;17.14 最小K个数17.15 最长单词17.16…...

【瑞吉外卖项目复写】基本部分复写笔记

Day1 瑞吉外卖项目概述 mysql的数据源配置 spring:datasource:druid:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/regie?serverTimezoneAsia/Shanghai&useUnicodetrue&characterEncodingutf-8&zeroDateTimeBehaviorconvertTo…...

用html+javascript打造公文一键排版系统15:一键删除所有空格

现在我们来实现一键删除所有空格的功能。 一、使用原有的代码来实现&#xff0c;测试效果并不理想 在这之前我们已经为String对象编写了一个使用正则表达式来删除所有空格的方法&#xff1a; //功能&#xff1a;删除字符串中的所有空格 //记录&#xff1a;20230726创建 Stri…...

苍穹外卖day12(完结撒花)——工作台+Spring_Apche_POI+导出运营数据Excel报表

工作台——需求分析与设计 产品原型 接口设计 工作台——代码导入 将提供的代码导入对应的位置。 工作台——功能测试 Apache POI_介绍 应用场景 Apache POI_入门案例 导入坐标 <!-- poi --><dependency><groupId>org.apache.poi</groupId><ar…...

SQL与NoSQL概念(详细介绍!!)

先搞清楚全称 SQL全称为Structured query language &#xff0c;即结构化查询语言&#xff0c;可以把他理解为一门特殊的编程语言。 那么nosql是什么意思呢&#xff1f;这里的no并不仅是not&#xff0c;而是not only的意思&#xff0c;所以nosql全称应该是Not Only Structure…...

node debian 镜像 new Date 获取时间少 8 小时问题

问题 在 node debian 镜像中&#xff0c;用 (new Date()).getHours() 与系统时间&#xff08;东 8 区&#xff09;少了 8 小时 系统时间 $ node > (new Date()).getHours() 11容器中的时间 $ node > (new Date()).getHours() 3原 Dockerfile FROM node:20.5-bullsey…...

【N32L40X】学习笔记13-软件IIC读写EEPROM AT24C02

AT24C02 8个字节每页,累计32个页 通讯频率MAX 400K AT24C02大小 2K 芯片地址 对于at24c02 A2A1A0 这三个引脚没有使用 写时序 由于设备在写周期中不会产生ACK恢复&#xff0c;因此这可用于确定周期何时完成&#xff08;此特性可用于最大限度地提高总线吞吐量&#xff09;…...

JVM 调优

点击下方关注我&#xff0c;然后右上角点击...“设为星标”&#xff0c;就能第一时间收到更新推送啦~~~ JVM调优是一项重要的任务&#xff0c;可以提高Java应用程序的性能和稳定性。掌握JVM调优需要深入了解JVM的工作原理、参数和配置选项&#xff0c;以及历史JVM参数的调整和优…...

DP-GAN剩余代码

在前面计算完损失后&#xff0c;该进行更新&#xff1a; 1&#xff1a;netEMA是模型的生成器&#xff1a; 遍历生成器的state_dict&#xff0c;将每一个键对应的值乘以EMA_decay。 接着根据当前迭代步数计算num_upd&#xff0c;每1000,2500,10000代倍数就执行一次。 当num…...

在word的文本框内使用Endnote引用文献,如何保证引文编号按照上下文排序

问题 如下图所示&#xff0c;我在word中插入了一个文本框&#xff08;为了插图&#xff09;&#xff0c;然后文本框内有引用&#xff0c;结果endnote自动将文本框内的引用优先排序&#xff0c;变成文献[1]了&#xff0c;而事实上应该是[31]。请问如何能让文本框内的排序也自动…...

SpringBoot项目上传至服务器

1.服务器安装JDK1.8 通过包管理器安装 2.服务器安装数据库 参考链接&#xff1a; CentOS 7 通过 yum 安装 MariaDB - 知乎 1. 安装之后没有密码&#xff0c;所以需要设置密码&#xff0c;使用下面的语句 set password for rootlocalhost password(111111); 2.在数据库中建…...

C++中实现多线程的三种方式

目录 1 背景2 方法 1 背景 力扣1116题 打印零和奇偶数。 2 方法 方法1&#xff1a;原子操作 class ZeroEvenOdd { private:int n;atomic<int> flag 0; public:ZeroEvenOdd(int n) {this->n n;}// printNumber(x) outputs "x", where x is an integer.…...

程序员副业指南:怎样实现年入10w+的目标?

大家好&#xff0c;这里是程序员晚枫&#xff0c;全网同名。 今天给大家分享一个大家都感兴趣的话题&#xff1a;程序员可以做什么副业&#xff0c;年入十万&#xff1f; 01 推荐 程序员可以从事以下副业&#xff0c;以获得一年收入10w&#xff1a; 兼职编程&#xff1a;可…...

excel 计算 分位值

_XLFN.QUARTILE.EXC(Result 1!G:G,2) 和 PERCENTILE 都可以用来计算一组数据的分位数&#xff0c;但是它们的计算方式略有不同。 _XLFN.QUARTILE.EXC(Result 1!G:G,2) 是 Excel 中的一个函数&#xff0c;在计算一个数据集的四分位数时使用。其中&#xff0c;第一个参数 Result…...

mongodb-windows-x86_64-4.4.23-signed.msi

...

一个SpringBoot 项目能处理多少请求?

这篇文章带大家盘一个读者遇到的面试题哈。 根据读者转述&#xff0c;面试官的原问题就是&#xff1a;一个 SpringBoot 项目能同时处理多少请求&#xff1f; 不知道你听到这个问题之后的第一反应是什么。 我大概知道他要问的是哪个方向&#xff0c;但是对于这种只有一句话的…...

如何一次删除iPad上的多个应用程序? - 5 种有效方法

随着时间的推移&#xff0c;您的 iPad 可能会积累许多不必要的应用程序&#xff0c;导致存储空间不足并影响设备性能。因此&#xff0c;最好的方法是删除这些应用程序。然而&#xff0c;逐个删除它们可能很耗时&#xff1b;一次性删除多个应用程序可以更有效地释放空间并提高设…...

BetterNCM Installer:让网易云音乐插件安装化繁为简的利器

BetterNCM Installer&#xff1a;让网易云音乐插件安装化繁为简的利器 【免费下载链接】BetterNCM-Installer 一键安装 Better 系软件 项目地址: https://gitcode.com/gh_mirrors/be/BetterNCM-Installer 你是否曾因复杂的插件安装流程望而却步&#xff1f;是否在面对命…...

从机械模型到控制算法:手把手教你用Adams 2020与MATLAB/Simulink搭建第一个联合仿真项目

Adams与Simulink联合仿真入门&#xff1a;零基础实现小球圆周运动控制 当多体动力学仿真遇上控制系统设计&#xff0c;Adams与MATLAB/Simulink的联合仿真能力为工程师打开了全新的可能性。本文将带你从零开始&#xff0c;完成第一个联合仿真项目——控制一个小球实现匀速圆周运…...

保姆级教程:在Ubuntu 20.04上搞定Isaac Gym Preview 4和强化学习环境(含常见libpython报错解决)

保姆级教程&#xff1a;在Ubuntu 20.04上搞定Isaac Gym Preview 4和强化学习环境&#xff08;含常见libpython报错解决&#xff09; 刚接触Isaac Gym的机器人/强化学习新手&#xff0c;往往会在环境配置阶段遇到各种依赖问题。本文将提供一个从零开始的详细安装指南&#xff0c…...

LoadRunner Developer实战:如何在VSCode中集成性能测试(含Jenkins流水线配置)

LoadRunner Developer实战&#xff1a;VSCode集成与Jenkins流水线配置全指南 在DevOps实践中&#xff0c;性能测试左移已成为提升软件质量的关键策略。作为Micro Focus推出的开发者友好型工具&#xff0c;LoadRunner Developer让开发团队能在编码阶段就发现性能瓶颈。本文将手…...

前端CSS样式详细笔记

文章目录一、CSS基础概念1. 什么是CSS2. CSS三大核心特性3. CSS基本语法结构二、CSS引入方式三、CSS选择器详解1. 基础选择器2. 组合选择器3. 属性选择器4. 伪类与伪元素四、选择器优先级规则1. 优先级计算方法2. 优先级实战示例3. 优先级注意事项五、CSS盒模型1. 盒模型组成2.…...

ai辅助开发:借助快马ai模型为直播应用添加弹幕情感分析与摘要生成功能

最近在开发一个直播应用时&#xff0c;发现弹幕互动是直播体验的重要组成部分&#xff0c;但海量弹幕中往往隐藏着观众的真实反馈和直播亮点。于是尝试用AI技术来增强直播应用的智能化功能&#xff0c;这里分享一下如何快速实现一个弹幕情感分析与摘要生成的工具页面。 项目构思…...

如何快速上手Jable视频下载工具:新手必备的完整指南

如何快速上手Jable视频下载工具&#xff1a;新手必备的完整指南 【免费下载链接】jable-download 方便下载jable的小工具 项目地址: https://gitcode.com/gh_mirrors/ja/jable-download 还在为无法保存Jable上的精彩视频而烦恼吗&#xff1f;今天我要为你介绍一款简单实…...

为什么选择Sammy.js:轻量级JavaScript框架的终极优势解析

为什么选择Sammy.js&#xff1a;轻量级JavaScript框架的终极优势解析 【免费下载链接】sammy Sammy is a tiny javascript framework built on top of jQuery, Its RESTful Evented Javascript. 项目地址: https://gitcode.com/gh_mirrors/sa/sammy 在当今前端开发领域&…...

Ostrakon-VL终端部署案例:单卡3090实现12路摄像头并发扫描

Ostrakon-VL终端部署案例&#xff1a;单卡3090实现12路摄像头并发扫描 1. 项目背景与核心价值 在零售与餐饮行业&#xff0c;传统的图像识别系统往往面临两个痛点&#xff1a;一是工业级UI操作复杂&#xff0c;员工培训成本高&#xff1b;二是多路摄像头并发处理需要昂贵的高…...