com o driver sony carregado, o driver fornece interfaces de kernel padrão:
echo 255 > /sys/class/leds/*buzz1/brightness
echo 0 > /sys/class/leds/*buzz1/brightness
Eu tenho tentado por um tempo, mas não consegui encontrar uma maneira de controlar as luzes em um conjunto de controles do jogo Buzz (com fio, do Playstation 2). Você pode ver algumas das minhas tentativas fracassadas nas minhas perguntas no Stack Overflow
Então eu mudei para um método linux mais básico de envio de mensagens, e falhei em fazer piping de dados para / dev / hidraw0 também.
Então eu descobri um arquivo no repositório linux que se refere especificamente aos controladores de buzz (), e o fato de que eles têm uma luz. Ele ainda tem um método chamado buzz_set_leds (linha 1512):
static void buzz_set_leds(struct sony_sc *sc)
Portanto, tenho 100% de certeza de que este código faz o que estou tentando fazer.
Eu tive a chance de incluir isso em um arquivo c, mas não consigo incluir o hid-sony porque parece que estou perdendo esses arquivos.
#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"
Na compilação, recebo este erro:
hid-sony.c:29:26: fatal error: linux/device.h: No such file or directory
#include <linux/device.h>
^
compilation terminated.
Desculpe, sou um programador Ruby sem experiência em C.
Como obtenho esses arquivos 'linux /' em falta e me refiro a eles em minha biblioteca c - ou como posso gravar nos controllers a partir do shell?
De um shell script é relativamente simples, mas requer o conhecimento da coisa certa a ser enviada. Dispositivos / dev / hidraw são chamados de "raw" porque eles são apenas isso (eu suspeito) - de este artigo em um site chamado developerFusion, que eu encontrei há muito tempo atrás (especificamente "figura 3") - esse autor relatou que o dispositivo queria que um relatório de seis bytes fosse enviado para ele LEDs (um em cada um dos quatro controladores "player") ligados ou desligados. Resumidamente, eles descobriram que, por seis bytes 1-6, eles foram usados:
Byte 1: não importa - sugira usar o 0x00
Byte 2: não importa - sugira usar o 0x00
Byte 3: 0x00 (desligado) ou 0xFF (ligado) - Monofone 1
Byte 4: 0 x 00 (desligado) ou 0xFF (ligado) - fone 2
Byte 5: 0x00 (desligado) ou 0xFF (ligado) - fone 3
Byte 6: 0x00 (desligado) ou 0xFF (ligado) - Monofone 4
Então, depois de algumas experiências eu descobri que, para um Controlador "Buzz" que o sistema udev (?) nomeou / symlinked para /dev/hidraw0
o seguinte irá piscar cada um dos LEDs em seqüência:
#!/bin/bashI acha que o último caractere ASCII "nul" é necessário para terminar a cadeia ou pode ser um artefato da linguagem que o autor do artigo estava usando (.NET / c #) que ocultava que sete bytes estavam sendo usados, não seis - mas essas línguas são completamente estranhas para mim. O que eu descobri foi que, se a string de comprimento certo não é usada, esse último byte é deixado de lado - a string não é reconhecida, pelo menos depois que a primeira string enviada é consistente com um requisito de "duração fixa do relatório".delay=0.1 while [ true ]; do echo -e "\x00\x00\x00\x00\x00\x00\x00" > /dev/hidraw0 sleep ${delay} echo -e "\x00\x00\x00\x00\x00\xff\x00" > /dev/hidraw0 sleep ${delay} echo -e "\x00\x00\x00\x00\xff\x00\x00" > /dev/hidraw0 sleep ${delay} echo -e "\x00\x00\x00\xff\x00\x00\x00" > /dev/hidraw0 sleep ${delay} echo -e "\x00\x00\xff\x00\x00\x00\x00" > /dev/hidraw0 sleep ${delay} echo -e "\x00\x00\x00\x00\x00\x00\x00" > /dev/hidraw0 sleep ${delay} done
Eu queria simplificar as coisas usando o udev para fornecer nomes significativos para esses dispositivos, então criei um arquivo /lib/udev/rules.d/10-local.rules
para o meu PC Debian "Jessie" (usando sysV "init" NOT "systemd"):
ACTION!="add|change", GOTO="end" # Assign a unique number to a buzz symbolic link to any Sony Buzz controllers SUBSYSTEM=="usb", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="1000", PROGRAM=="/sbin/unique_number /dev buzz", SYMLINK+="buzz%c", TAG+="buzz", OPTIONS+=last_rule SUBSYSTEM=="usb", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="0002", PROGRAM=="/sbin/unique_number /dev buzz", SYMLINK+="buzz%c", TAG+="buzz", OPTIONS+=last_rule LABEL="end"
e para fornecer um número único - especial no caso de eu conectar um hub com vários controladores Buzz e ter vários dispositivos adicionados ou removidos ao mesmo tempo, usei o seguinte /sbin/unique_number
que foi derivado de algum lugar no SE - (EU irei aceitar edições para atribuir atribuições / copyrights válidas ...):
#!/bin/bash # Copyright (C) 2015 by Stephen Lyons - [email protected] # # unique_number: This script is used to provide a unique suffix for a # file in a given directory if [ $# -ne 2 ]; then echo "Usage: $0 location prefix\n\n" >&2 echo " Finds the first unused integer # suffixed file" echo " of form prefix# in directory given by location," echo " and prints that number." exit 1 fi location="$1" prefix="$2" index=0 while [ -e "/var/lock/unique_number.lock" ]; do sleep 0.1; done touch "/var/lock/unique_number.lock" until [ ! -e "${location}/${prefix}${index}" ]; do (( index++ )); done echo "$index" rm "/var/lock/unique_number.lock" exit 0
No entanto, embora isso forneça / dev / buzz0, / dev / buzz1 como eu queria, essa combinação não funciona para fornecer algo que possa substituir /dev/hidraw0
etc. no primeiro script.
Bem, seu arquivo de origem corresponde a uma fonte de driver linux. Então você terá que compilá-lo como um módulo. Para compilá-lo fora da árvore fonte do kernel, recomendo que você use o seguinte 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
Copie este conteúdo para um arquivo que você nomeará "makefile" no mesmo local que seu código-fonte c, em seguida, execute o comando "make". Você precisará ter o cabeçalho do kernel do linux instalado, você normalmente pode obtê-los dos pacotes (linux-headers-x.yy.zz-your_arch no debian). Isto produzirá um arquivo .ko que você pode carregar no seu kernel com o comando insmod (precisa ser root).