如何写入由 hid-sony.c 创建的 Buzz 控制器 HID 设备以运行 LED?

AJF*_*day 3 linux drivers usb hid

我已经尝试了一段时间,但一直无法找到一种方法来控制 Buzz 游戏(有线,来自 Playstation 2)中一组控制器上的灯光。您可以在 Stack Overflow 上的问题中看到我的一些失败尝试

因此,我转向了一种更基本的 linux 消息发送方法,但也未能通过将数据传送到 /dev/hidraw0 来实现。

然后我在 linux 存储库中发现了一个文件,它专门指的是 buzz 控制器(/linux/drivers/hid/hid-sony.c),并且它们有一个灯。它甚至有一个名为 buzz_set_leds 的方法(第 1512 行):

static void buzz_set_leds(struct sony_sc *sc)
Run Code Online (Sandbox Code Playgroud)

所以我 100% 确定这是代码完成我正在尝试做的事情。

我已经尝试将其包含在 ac 文件中,但无法包含 hid-sony,因为我似乎缺少这些文件。

#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/leds.h>
#include <linux/power_supply.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/idr.h>
#include <linux/input/mt.h>

#include "hid-ids.h"
Run Code Online (Sandbox Code Playgroud)

在编译中,我收到此错误:

hid-sony.c:29:26: fatal error: linux/device.h: No such file or directory
 #include <linux/device.h>
                          ^
compilation terminated.
Run Code Online (Sandbox Code Playgroud)

对不起,我是一个没有 C 背景的 Ruby 程序员。

如何获取这些丢失的“linux/”文件并从我的 c 库中引用它们 - 或者如何从 shell 写入控制器?

Sly*_*ven 7

从 shell 脚本来看,它相对简单,但需要知道要发送的正确内容。/dev/hidraw 设备被称为“原始”,因为它们只是(我怀疑)-来自我很久以前在名为 developerFusion 的网站上发现的这篇文章(特别是“图 3”)-作者报告说该设备希望向其发送一个 6 字节的报告,以打开或关闭 4 个 LED(四个“播放器”控制器中的每一个中的一个)。简而言之,他们发现,对于六个字节 1-6,它们被使用:

字节 1:不在乎 - 建议使用 0x00
字节2:不在乎 - 建议使用 0x00
字节 3:0x00(关闭)或 0xFF(开启)- 手机 1
字节 4:0x00(关闭)或 0xFF(开启)-手机 2
字节 5:0x00(关闭)或 0xFF(开启) - 手机 3
字节 6:0x00(关闭)或 0xFF(开启)- 手机 4

因此,经过一些实验,我发现,对于 udev 系统(?)已命名/符号链接到/dev/hidraw0以下内容的“Buzz”控制器将按顺序闪烁每个 LED:

#!/bin/bash

延迟=0.1 而[真]; 做 echo -e "\x00\x00\x00\x00\x00\x00\x00" > /dev/hidraw0 睡眠 ${延迟} echo -e "\x00\x00\x00\x00\x00\xff\x00" > /dev/hidraw0 睡眠 ${延迟} echo -e "\x00\x00\x00\x00\xff\x00\x00" > /dev/hidraw0 睡眠 ${延迟} echo -e "\x00\x00\x00\xff\x00\x00\x00" > /dev/hidraw0 睡眠 ${延迟} echo -e "\x00\x00\xff\x00\x00\x00\x00" > /dev/hidraw0 睡眠 ${延迟} echo -e "\x00\x00\x00\x00\x00\x00\x00" > /dev/hidraw0 睡眠 ${延迟} 完毕

认为需要最后一个 ASCII“nul”字符来结束字符串,或者它可能是该文章作者使用的语言(.NET/c#)的人工制品,它隐藏了使用七个字节而不是六个字节 - 但那么这些语言对我来说是完全陌生的。我发现,如果不使用正确长度的字符串,最后一个字节将被忽略——该字符串不会被识别,至少在发送的第一个字符串之后,我认为这与“固定报告长度”要求一致。

我想通过使用 udev 为此类设备提供有意义的名称来使事情变得更简单,因此我/lib/udev/rules.d/10-local.rules为我的 Debian Linux“Jessie”PC创建了一个文件(使用 sysV“init”而不是“systemd”):

行动!=“添加|更改”,转到=“结束”

# 为指向任何 Sony Buzz 控制器的 buzz 符号链接分配一个唯一编号
SUBSYSTEM=="usb", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="1000", PROGRAM=="/sbin/unique_number /dev buzz", SYMLINK+="buzz%c", TAG+= "嗡嗡声", OPTIONS+=last_rule
SUBSYSTEM=="usb", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="0002", PROGRAM=="/sbin/unique_number /dev buzz", SYMLINK+="buzz%c", TAG+= "嗡嗡声", OPTIONS+=last_rule

标签=“结束”

并提供唯一编号 - 特别是在我插入带有多个 Buzz 控制器的集线器并且将同时添加或删除多个设备的情况下,我使用了以下/sbin/unique_number源自 SE 某处的以下内容 -(我会接受编辑以提供有效的归属/版权...):

#!/bin/bash

# 版权所有 (C) 2015 by Stephen Lyons - slysven@virginmedia.com
#
# unique_number:此脚本用于为一个
# 指定目录下的文件

如果 [ $# -ne 2 ]; 然后
    echo "用法:$0 位置前缀\n\n" >&2
    echo " 查找第一个未使用的整数 # 后缀文件"
    在位置给定的目录中回显“形式前缀#”,
    回声“并打印该数字。”
    出口 1
菲

位置="$1"
前缀="$2"

指数=0

而 [ -e "/var/lock/unique_number.lock" ]; 做
    睡眠 0.1;
完毕

触摸“/var/lock/unique_number.lock”

直到 [ !-e "${location}/${prefix}${index}" ]; 做
    ((索引++));
完毕
回声“$index”

rm "/var/lock/unique_number.lock"
退出 0

然而,虽然这确实提供了我想要的 /dev/buzz0、/dev/buzz1,但这种组合不能提供可以替换/dev/hidraw0第一个脚本中的东西等的东西。