我已经尝试了一段时间,但一直无法找到一种方法来控制游戏 Buzz(有线,来自 Playstation 2)的一组控制器上的灯光。您可以在 Stack Overflow 上的问题中看到我的一些失败尝试
因此,我转向了一种更基本的 Linux 发送消息方法,但通过将数据管道传输到 /dev/hidraw0 也失败了。
然后我在 linux 存储库中发现了一个文件,该文件专门引用了嗡嗡声控制器(/linux/drivers/hid/hid-sony.c),以及它们有灯这一事实。它甚至有一个名为buzz_set_leds的方法(第1512行):
static void buzz_set_leds(struct sony_sc *sc)
所以我 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"
在编译中,我收到此错误:
hid-sony.c:29:26: fatal error: linux/device.h: No such file or directory
#include <linux/device.h>
^
compilation terminated.
抱歉,我是一名没有 C 背景的 Ruby 程序员。
如何获取这些丢失的“linux/”文件并从我的 c 库中引用它们 - 或者如何从 shell 写入控制器?
答案1
从 shell 脚本来看,它相对简单,但需要知道要发送的正确内容。 /dev/hidraw 设备被称为“原始”,因为它们就是这样(我怀疑) - 来自本文在一个名为developerFusion的网站上,我很久以前就发现了这个网站(特别是“图3”)——该作者报告说该设备需要向其发送一个六字节的报告来切换4个LED(每个LED一个)四个“玩家”控制器)打开或关闭。简而言之,他们发现,对于六个字节 1-6,它们被使用:
字节 1:不关心 - 建议使用 0x00
字节 2:不关心 - 建议使用 0x00
字节 3:0x00(关)或 0xFF(开)- 听筒 1
字节 4:0x00(关)或 0xFF(开)-听筒 2
字节 5:0x00(关闭)或 0xFF(打开) - 听筒 3
字节 6:0x00(关闭)或 0xFF(打开) - 听筒 4
因此,经过一些实验,我发现,对于 udev 系统(?)已命名/符号链接到以下内容的“Buzz”控制器,/dev/hidraw0
每个 LED 将按顺序闪烁:
#!/bin/bash我思考需要最后一个 ASCII“nul”字符来结束字符串,或者它可能是该文章作者所使用的语言(.NET / c#)的产物,该语言隐藏了正在使用的七个字节而不是六个字节 - 但随后那些语言对我来说完全陌生。我发现,如果未使用正确长度的字符串,则最后一个字节会被忽略 - 该字符串不会被识别,至少在发送第一个字符串之后,我认为这符合“固定报告长度”的要求。延迟=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 睡眠${延迟} 完毕
我想通过使用 udev 为此类设备提供有意义的名称来使事情变得更简单,因此我/lib/udev/rules.d/10-local.rules
为我的 Debian Linux“Jessie”PC 创建了一个文件(使用 sysV“init”而不是“systemd”):
ACTION!="添加|更改", GOTO="结束" # 为任何 Sony Buzz 控制器的嗡嗡声符号链接分配一个唯一的编号 SUBSYSTEM==“usb”,ATTRS{idVendor}==“054c”,ATTRS{idProduct}==“1000”,PROGRAM==“/sbin/unique_number /dev嗡嗡声”,SYMLINK+=“buzz%c”,TAG+= “嗡嗡声”,OPTIONS+=last_rule SUBSYSTEM==“usb”,ATTRS{idVendor}==“054c”,ATTRS{idProduct}==“0002”,PROGRAM==“/sbin/unique_number /dev嗡嗡声”,SYMLINK+=“buzz%c”,TAG+= “嗡嗡声”,OPTIONS+=last_rule 标签=“结束”
并提供一个唯一的编号 - 特别是在我插入带有多个 Buzz 控制器的集线器并且同时添加或删除多个设备的情况下,我使用了以下/sbin/unique_number
源自 SE 上某处的内容 - (我将接受编辑以提供有效的归属/版权...):
#!/bin/bash # 版权所有 (C) 2015,作者:Stephen Lyons -[电子邮件受保护] # # unique_number:此脚本用于为某个文件提供唯一的后缀 # 给定目录中的文件 如果 [ $# -ne 2 ];然后 echo "用法: $0 位置前缀\n\n" >&2 echo "查找第一个未使用的整数#后缀的文件" echo “在由位置给出的目录中的形式前缀#,” echo "并打印该数字。" 1号出口 菲 位置=“$1” 前缀=“$2” 索引=0 while [ -e "/var/lock/unique_number.lock" ];做 睡眠 0.1; 完毕 触摸“/var/lock/unique_number.lock” 直到 [ ! -e "${位置}/${前缀}${索引}"];做 ((索引++)); 完毕 回显“$索引” rm“/var/lock/unique_number.lock” 出口0
然而,虽然这确实提供了我想要的 /dev/buzz0、/dev/buzz1,这种组合不能提供可以替换/dev/hidraw0
第一个脚本中的等的东西。
答案2
那么,你的源文件对应于linux驱动程序的源。因此,您必须将其编译为模块。要从内核源代码树中编译它,我建议您使用以下 makefile:
ifneq ($(KERNELRELEASE),)
obj-m := hid-sony.o
else
KDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
endif
将此内容复制到与 c 源代码相同的位置中命名为“makefile”的文件,然后运行命令“make”。您需要安装 Linux 内核头文件,通常可以从软件包中获取它们(debian 上为 linux-headers-x.yy.zz-your_arch)。这将为您生成一个 .ko 文件,然后您可以使用 insmod 命令将其加载到内核中(需要是 root 用户)。
答案3
加载 sony 驱动程序后,该驱动程序提供标准 led 内核接口:
echo 255 > /sys/class/leds/*buzz1/brightness
echo 0 > /sys/class/leds/*buzz1/brightness