如何寫入由 hid-sony.c 創建的 Buzz 控制器 HID 設備以使 LED 工作?
我已經嘗試了一段時間,但還沒有找到一種方法來控制遊戲 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)
所以我 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 寫入控制器?
從 shell 腳本來看,它相對簡單,但需要知道要發送的正確內容。/dev/hidraw 設備被稱為“原始”設備,因為它們就是(我懷疑)——從很久以前我在一個名為 developerFusion 的網站上發現的這篇文章(特別是“圖 3”)——作者報告說該設備希望向其發送一個六字節的報告,以打開或關閉 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 而[真];做 迴聲 -e "\x00\x00\x00\x00\x00\x00\x00" > /dev/hidraw0 睡眠 ${延遲} 迴聲 -e "\x00\x00\x00\x00\x00\xff\x00" > /dev/hidraw0 睡眠 ${延遲} 迴聲 -e "\x00\x00\x00\x00\xff\x00\x00" > /dev/hidraw0 睡眠 ${延遲} 迴聲 -e "\x00\x00\x00\xff\x00\x00\x00" > /dev/hidraw0 睡眠 ${延遲} 迴聲 -e "\x00\x00\xff\x00\x00\x00\x00" > /dev/hidraw0 睡眠 ${延遲} 迴聲 -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”):ACTION!="add|change", GOTO="end" # 為任何 Sony Buzz 控制器的 Buzz 符號連結分配一個唯一編號 SUBSYSTEM=="usb", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="1000", PROGRAM=="/sbin/unique_number /dev buzz", SYMLINK+="buzz%c", TAG+= “嗡嗡聲”,選項+=last_rule SUBSYSTEM=="usb", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="0002", PROGRAM=="/sbin/unique_number /dev buzz", SYMLINK+="buzz%c", TAG+= “嗡嗡聲”,選項+=last_rule 標籤="結束"
並提供一個唯一的編號 - 特別是在我插入一個帶有多個 Buzz 控制器的集線器並且將同時添加或刪除多個設備的情況下,我使用了以下
/sbin/unique_number
從 SE 某處派生的 - (我將接受編輯以提供有效的歸屬/版權…):#!/bin/bash # Copyright (C) 2015 by Stephen Lyons - slysven@virginmedia.com # # unique_number:此腳本用於為 # 給定目錄中的文件 如果 [ $# -ne 2 ]; 然後 echo "用法:$0 位置前綴\n\n" >&2 echo " 查找第一個未使用的整數 # 後綴文件" 在位置給定的目錄中回顯“形式前綴#”, echo " 並列印該數字。" 1號出口 是 位置="$1" 前綴="$2" 索引=0 而 [ -e "/var/lock/unique_number.lock" ]; 做 睡眠 0.1; 完畢 觸摸“/var/lock/unique_number.lock” 直到 [ !-e "${location}/${prefix}${index}" ]; 做 ((索引++)); 完畢 迴聲“$索引” rm "/var/lock/unique_number.lock" 出口 0
但是,雖然這確實提供了我想要的 /dev/buzz0、/dev/buzz1,但這種組合不能
/dev/hidraw0
在第一個腳本中提供可以替換等的東西。
嗯,你的源文件對應一個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 使用者)。