LED를 작동시키기 위해 hid-sony.c에서 생성된 버즈 컨트롤러 HID 장치에 어떻게 기록합니까?

LED를 작동시키기 위해 hid-sony.c에서 생성된 버즈 컨트롤러 HID 장치에 어떻게 기록합니까?

나는 한동안 노력했지만 Game 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 라이브러리에서 참조합니까? 아니면 쉘에서 컨트롤러에 어떻게 쓰나요?

답변1

셸 스크립트 관점에서 보면 상대적으로 간단하지만 전송할 올바른 콘텐츠를 알아야 합니다. /dev/hidraw 장치는 "raw"라고 불립니다. 왜냐하면 그것이 바로 그것이기 때문입니다.이 기사오래 전에 발견한 개발자Fusion이라는 사이트(구체적으로 "그림 3")에서 저자는 장치가 4개의 LED(각 LED(1개)와 4개의 " 플레이어" 컨트롤러)가 켜지거나 꺼집니다. 간단히 말해서, 그들은 6바이트 1-6에 대해 다음과 같이 사용된다는 것을 발견했습니다.

바이트 1: 상관없음 - 0x00을 권장함
바이트 2: 상관없음 - 0x00을 권장함
바이트 3: 0x00(꺼짐) 또는 0xFF(켜짐) - 핸드셋 1
바이트 4: 0x00(꺼짐) 또는 0xFF(켜짐) - 핸드셋 2
바이트 5: 0x00(꺼짐) 또는 0xFF(켜짐) - 핸드셋 3
바이트 6: 0x00(꺼짐) 또는 0xFF(켜짐) - 핸드셋 4

그래서 몇 가지 실험을 거친 후 다음과 같이 이름이 지정되거나 심볼릭 링크된 "Buzz" 컨트롤러가 있는 udev 시스템(?)의 경우 /dev/hidraw0각 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" 문자가 필요합니다. 또는 기사 작성자가 6바이트 대신 7바이트가 사용된다는 것을 숨기는 언어(.NET/c#)의 인공물일 수 있습니다. 그 언어는 나에게 완전히 낯설었습니다. 올바른 길이의 문자열을 사용하지 않으면 마지막 바이트가 무시된다는 사실을 발견했습니다. 적어도 첫 번째 문자열이 전송된 후에는 문자열이 인식되지 않습니다. 이는 "고정 보고서 길이" 요구 사항을 준수한다고 가정합니다.

udev를 사용하여 이러한 장치에 의미 있는 이름을 지정함으로써 작업을 더 간단하게 만들고 싶었기 때문에 /lib/udev/rules.d/10-local.rulesDebian Linux "Jessie" PC용 파일을 만들었습니다("systemd" 대신 sysV "init" 사용).

ACTION!="추가|변경", GOTO="종료"

# Sony 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

태그="끝"

고유 번호를 제공합니다. 특히 여러 버즈 컨트롤러가 있는 허브에 연결하고 동시에 여러 장치를 추가하거나 제거하는 경우 /sbin/unique_numberSE 어딘가에서 가져온 다음을 사용했습니다. (유효한 저작자 표시/저작권을 제공하기 위해 편집됨을 허용합니다. ...):

#!/bin/bash

# 저작권 (C) 2015 작성자: Stephen Lyons -[이메일 보호됨]
#
# Unique_number: 이 스크립트는 파일에 고유한 접미사를 제공하는 데 사용됩니다.
# 주어진 디렉토리의 파일

if [ $# -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" 명령을 실행합니다. 일반적으로 패키지(debian의 경우 linux-headers-x.yy.zz-your_arch)에서 사용할 수 있는 Linux 커널 헤더를 설치해야 합니다. 그러면 .ko 파일이 생성되며, insmod 명령(루트 필요)을 사용하여 커널에 로드할 수 있습니다.

답변3

Sony 드라이버를 로드한 후 드라이버는 표준 LED 커널 인터페이스를 제공합니다.

echo 255 > /sys/class/leds/*buzz1/brightness
echo 0 > /sys/class/leds/*buzz1/brightness

관련 정보