
In Vorbereitung auf das jährliche IT-Forum kam die Idee auf, einen einfachen Manipulator zu entwickeln, der von einem drahtlosen Gamepad gesteuert wird, um die Funktionen von Mikrocontrollern und Single-Board-Computern zu demonstrieren. Zur Hand waren ein TRIC-Controller, mehrere Servomotoren, ein Eisenkonstrukteur und ein Monat vor dem Start des Forums.
„Alles läuft nach Plan“, aber in diesem Fall nicht.
Stufe 1. Vorbereitung
TRIC an Bord von Linux war eine Pleite für einen solchen Manipulator, aber "die Sache ist banale Benutzerfreundlichkeit und Wartung" ( ClusterM- Zitat über Linux in einer intelligenten Gegensprechanlage ).
Nach dem Lesen der Spezifikation wurde festgestellt, dass es Bluetooth hat. Wenn Sie mit diesem Controller gearbeitet haben, wissen Sie, dass die Übertragung von Programmen über WLAN erfolgt und es keine anderen bequemen Möglichkeiten gibt, mit ihm zu kommunizieren. Bluetooth wird im Menü nicht erwähnt. Aber wie so?
Mit SSH, einem Schraubenzieher und Neugierde bewaffnet, begann ich nach Bluetooth zu suchen. Das System umfasste hcitool, hciconfig und den Bluetoothd-Daemon. Alle sagten, er sei nicht da.
root@trik-7dda93:~
root@trik-7dda93:~
root@trik-7dda93:~
Ich rief Freunde auf der Suche nach einem externen USB-Modul an und suchte weiter.
Nach dem Zerlegen des Controllers wurde das Modul Jorjin WG7311-0A gefunden. Die Spezifikation besagt, dass es wirklich Wi-Fi, Bluetooth und sogar ein FM-Radio gibt. Die Schnittstelle für die Kommunikation mit Bluetooth ist UART und wird über BT_EN eingeschaltet.

Nachdem ich gelesen hatte, wie das Bluetooth-Modul über UART über hcitool verbunden ist, versuchte ich mein Glück und nichts. Zwei der drei freien UART-Ports waren stumm.
Aber wir haben Kontakt BT_EN! Möglicherweise wird das Modul einfach ausgeschaltet und reagiert nicht auf Anfragen. Nach der Untersuchung des Linux-Kernelgeräts auf ARM-Geräte wurde eine Datei gefunden, in der alle von SoC verwendeten Kontakte registriert sind. Durch Öffnen von arch/arm/mach-davinci/board-da850-trik.c
im Kernel-Quellcode wurde tatsächlich ein GPIO-Kontakt für Bluetooth gefunden. Sieg! Dachte ich.
static const short da850_trik_bluetooth_pins[] __initconst = { DA850_GPIO6_11, DA850_GPIO6_10, -1 };
Stufe 2. Offensive
Um einen Kontakt über GPIO zu aktivieren, müssen Sie die End-to-End-Seriennummer ermitteln. Wir finden die folgende Zeile im Kernel-Code mit der Aufforderung, den BT_EN_33-Kontakt in arch/arm/mach-davinci/board-da850-trik.c
:
ret = gpio_request_one(GPIO_TO_PIN(6, 11), GPIOF_OUT_INIT_LOW, "BT_EN_33")
Es verwendet das Makro GPIO_TO_PIN. Siehe die arch/arm/mach-davinci/include/mach/gpio-davinci.h
in arch/arm/mach-davinci/include/mach/gpio-davinci.h
:
#define GPIO_TO_PIN(bank, gpio) (16 * (bank) + (gpio))
Mit ihm finden Sie die End-to-End-Kontaktnummer. Wir erhalten diese 16 * 6 + 11 = 107. Nun wenden wir uns der Einbeziehung des Kontakts zu.
echo 1 >> /sys/devices/virtual/gpio/gpio107/value
0 oder 1 im Echo-Befehl ist der Status des Kontakts.
Führen Sie den Befehl zum Verbinden und ...
root@trik-7dda93:~
für uns (im Moment) unverständliche Fehlermeldungen. Wir versuchen das Gerät über hcitool zu konfigurieren:
root@trik-7dda93:~
Es gibt keine Geräte, obwohl die Initialisierung angeblich bestanden hat. Wir versuchen ein zweites Mal eine Verbindung herzustellen, jedoch mit einem anderen Adaptertyp:
root@trik-7dda93:~
Und wieder nichts. Kehren wir zum ersten Fehler zurück und wenden die Englischkenntnisse an:
Warning: cannot find BTS file: /lib/firmware/TIInit_7.6.15.bts
Wir öffnen den Ordner / lib / firmware mit Firmware und finden die benötigte Datei nicht. Nach einer langen Suche im Internet finden wir die gewünschte Datei im TI-Repository und laden sie herunter. Andere Versionen derselben Datei haben sich geweigert zu funktionieren.
curl -k https://git.ti.com/wilink8-bt/ti-bt-firmware/blobs/raw/45897a170bc30afb841b1491642e774f0c89b584/TIInit_7.6.15.bts > TIInit_7.6.15.bts cp TIInit_7.6.15.bts /lib/firmware/TIInit_7.6.15.bts
Wir starten den Controller neu und stellen die Verbindung wieder her:
root@trik-7dda93:~
Hurra! Die Firmware wurde gestartet. Überprüfen von hciconfig:
root@trik-7dda93:~
Wir starten den Bluetooth-Dienst, suchen nach Geräten und erkennen unser Modul:
root@trik-7dda93:~
Eine Computersuche findet ein Gerät:

Um Bluetooth zu aktivieren, können Sie ein Skript erstellen:
Und füge es zu autorun hinzu:
cp init-bluetooth /etc/init.d/init-bluetooth update-rc.d init-bluetooth enable 99
Das Neustarten und Herunterfahren des Moduls verhält sich unvorhersehbar, daher haben die Stopp- und Neustartoptionen keine Befehle.
Stufe 3. Kommunikationsprüfung
Der einfachste Weg, die Kommunikation in beide Richtungen zu überprüfen, ist der COM-Port-Dienst. Schalten Sie es mit ein paar Befehlen ein :
root@trik-7dda93:~
Wir verbinden uns über das Telefon und sehen eine Einladung zum Betreten des Systems:

Keines der getesteten Terminals durfte ein leeres Benutzerkennwort eingeben, daher musste ich in einer SSH-Sitzung Anmeldeinformationen mithilfe der Thread-Umleitung senden.
Wenn Sie den Anweisungen zum Anschließen eines Gamepads an Linux folgen, treten die folgenden Probleme auf:
- BlueZ in der Distribution ist veraltet und versteht die Befehle des Sixad-Daemons nicht, wodurch eine Verbindung zum Gamepad hergestellt wird
- Die neue BlueZ-Version aus dem Quellcode kann aufgrund vieler Abhängigkeiten nicht kompiliert werden
- Für BlueZ von Fresh Debian sind udev und systemd erforderlich, die in der aktuellen Distribution fehlen
Die einzige Abhängigkeit, die erfüllt werden konnte, war das uinput-Kernelmodul.
Dafür:
- Rufen Sie die Konfiguration des aktuellen Kernels auf dem Gerät ab
cp /proc/config.gz config.gz gunzip config.gz
- Kernel-Code herunterladen
- Toolchain herunterladen und installieren
- Kopieren Sie die Kernelkonfiguration in den Ordner mit dem Kernelcode
- Fügen Sie das uinput-Modul zur Konfiguration hinzu
echo "CONFIG_INPUT_UINPUT=m" >> config
- Starten Sie die Montage, indem Sie zuerst die Toolchain einschalten
source /opt/trik-sdk/environment-setup-arm926ejste-oe-linux-gnueabi make
- Kopieren Sie die Kernelmodule auf die Speicherkarte
make INSTALL_MOD_PATH=/mnt/trik-sd modules_install
- Erstellen Sie das uBoot-Image und kopieren Sie es nach / boot
make uImage cp arch/arm/boot/uImage /mnt/trik-sd/boot/uImage-3.6.7
Jetzt schwört das Programm nicht auf das Fehlen eines Kernelmoduls, aber dann können wir nichts tun. Anweisungen für das Gamepad werden später nützlich sein.
Stufe 5. Brei aus der Axt kochen
Kommen zum Plan "Tyap-Blooper". Da es keine bequeme Möglichkeit gibt, die erforderlichen Programme in die ursprüngliche Distribution aufzunehmen, werden wir etwas Populäres einfügen. Der Prozessor verfügt über eine ARMv5TE-Architektur, dh es gibt Verteilungen dafür.
Wir versuchen, Universal Arch Linux für ARM zu entpacken und auszuführen. Beim Laden in die Konsole stellen wir fest, dass systemd eine neuere Kernelversion benötigt, die wir nicht haben. Versuche, den 4.16-Kernel zu übertragen, waren erfolglos und es dauerte zu lange.
Wir gehen zu einer anderen Option über - Debian. Ein Disk-Image mit einem installierten System für ARM ist vorhanden. Es ist jedoch besser, ein sauberes System mit den für uns erforderlichen Paketen und Einstellungen zu erstellen.
Installation in QEMU
Laden Sie das Installationsimage (Link zu .iso ) herunter und installieren Sie QEMU.
Wir benötigen auch den Kernel und das initrd-Image, um die Installation zu starten, die hier heruntergeladen werden kann .
Erstellen Sie ein Image einer Speicherkarte mit der Größe einer echten Speicherkarte (in diesem Fall 4 GB):
qemu-img create -f raw debian.img 4G
Wir starten die Installation:
qemu-system-arm -M versatilepb -kernel vmlinuz-3.2.0-4-versatile -initrd initrd.gz -hda debian.img -cdrom debian-7.11.0-armel-CD-1.iso
Wenn Sie ein Festplattenlayout für eine nicht standardmäßige relative Originaldistribution erstellen möchten, lassen Sie zuerst die Root-Partition, andernfalls müssen Sie die Kernel-Boot-Parameter in uBoot ändern. Es gibt die Nummer der Partition, auf der sich das Root-Dateisystem befindet.
Standard-Markup enthält:
- EXT4-Partition für ≈ 1,3 GB Root-Dateisystem
- FAT32-Partition zum Speichern von Benutzerdaten ≈ 500 MB groß
Die fdisk-Ausgabe für das Image der Originaldistribution:
Disk: trik-distro.img geometry: 893/64/63 [3604478 sectors] Signature: 0xAA55 Starting Ending
Nachdem wir die Parameter eingestellt haben, lassen wir ein paar Tassen Tee trinken, weil Der Emulator ist nicht viel schneller als ein echter ARM-Prozessor.
Um das installierte System zu starten, benötigen Sie ein weiteres initrd-Image, das von hier aus aufgenommen werden kann .
Wir starten das System:
qemu-system-arm -M versatilepb -kernel vmlinuz-3.2.0-4-versatile -initrd initrd.img-3.2.0-4-versatile -hda debian.img -append "root=/dev/sda1"
Systemeinrichtung
Nach dem Start rufen wir den Superuser auf, überprüfen die Verbindung zum Internet, aktualisieren die Repositorys und das System und geben die Mindestanzahl an Programmen ein:
apt-get update apt-get upgrade apt-get install curl git mc htop joystick
Terminals
Wir bearbeiten /etc/inittab
, entfernen unnötige Terminals, schalten den für uns benötigten UART ein und fügen automatische Eingaben für den richtigen Benutzer hinzu (verwenden Sie root nur beim Debuggen). Die automatische Eingabe ist nützlich, wenn Sie die Shell zur Steuerung auf dem Controller ausführen möchten.
1:2345:respawn:/sbin/getty 38400 tty1 --autologin root
Bluetooth und WiFi
Installieren Sie bluez-utils und wpasupplicant, um auf Wi-Fi und Bluetooth zuzugreifen.
apt-get install bluez-utils wpasupplicant
Wir deaktivieren die eth0-Schnittstelle und konfigurieren die wlan1-Schnittstelle in /etc/network/interfaces
:
# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8) # The loopback interface auto lo iface lo inet loopback # Wireless interfaces auto wlan1 iface wlan1 inet dhcp wireless_mode managed wireless_essid any wpa-driver wext wpa-conf /etc/wpa_supplicant.conf
Fügen Sie das Netzwerk im Voraus zu /etc/wpa_supplicant.conf
, weil Dies auf dem Controller selbst zu tun ist nicht so bequem:
wpa_passphrase ssid password >> /etc/wpa_supplicant.conf
Wenn Sie keinen Wi-Fi-Zugang haben, können Sie UART für die weitere Konfiguration verwenden. Beachten Sie jedoch, dass der Kernel standardmäßig alle Fehler für dieses Terminal anzeigt. Daher kann Sie während des Betriebs eine plötzliche Nachricht vom Kernel oder Dienst unterbrechen.
Fügen Sie ein Skript hinzu, um Bluetooth zu aktivieren. Ändern /etc/init.d/bluetooth
diesmal /etc/init.d/bluetooth
:
139: case $1 in start) echo 1 >> /sys/devices/virtual/gpio/gpio107/value 168: hciattach /dev/ttyS0 texas log_end_msg 0 ;;
Daher führen alle Dienste, für die der Bluetooth-Dienst erforderlich ist, die zum Initialisieren erforderlichen Befehle aus.
Wischen Sie nach links, wischen Sie nach rechts
Wir entfernen unnötige Programme und Dienste, die mit htop angezeigt werden können, da sie einen wertvollen Platz im RAM einnehmen:

In diesem Fall verfügt der ConsoleKit-Dienst über viele Prozesse . Verschieben Sie die Datei dieses Dienstes im Falle einer Wiederherstellung in den Stammordner:
mv /usr/share/dbus-1/system-services/org.freedesktop.ConsoleKit.service /root/
Vor dem Herunterfahren des Dienstes betrug der RAM-Verbrauch 19 MB und nach - 16 MB.
Systemabschnitte
Obwohl uBoot das Gerät, auf dem sich die Root-Partition befindet, an den Kernel überträgt, lohnt es sich aus /etc/fstab
Zuverlässigkeit, es in /etc/fstab
zu schreiben. Wir ändern die erste Zeile, die für den Stammabschnitt verantwortlich ist:
/dev/mmcblk0p1 / auto defaults 1 1 proc /proc proc defaults 0 0 devpts /dev/pts devpts mode=0620,gid=5 0 0 usbdevfs /proc/bus/usb usbdevfs noauto 0 0 tmpfs /run tmpfs mode=0755,nodev,nosuid,strictatime 0 0 tmpfs /var/volatile tmpfs defaults 0 0
Wenn Sie die Root-Partition nicht zur ersten gemacht haben, vergessen Sie nicht, die gewünschte Partitionsnummer anzugeben.
Wenn Sie die zweite FAT-Partition für Benutzerdaten verlassen haben, müssen Sie einen Ordner erstellen, um die Partition darin bereitzustellen
mkdir /usr/share/trik
und schreibe den Abschnitt in /etc/fstab
:
/dev/mmcblk0p2 /usr/share/trik vfat defaults 0 0
Stufe 6. Wir probieren unseren Brei
Nachdem Sie das System-Image konfiguriert haben, müssen Sie es bereitstellen, um die Kernelmodule und den Kernel selbst zu installieren:
Dabei ist NNNN = Sektorgröße * Abschnittsanfang. Die Standardsektorgröße beträgt 512 Byte.
Wir montieren auch die ursprüngliche Distribution:
fdisk -l trik-distro.img mount -o loop,offset=NNNN trik-distro.img /mnt/trik-clean
Wir entfernen den Kernel für QEMU und seine Module als Sie sind nicht für unsere Plattform bestimmt. Wir kopieren den neuen Kernel und die neuen Module, genau wie bei der ursprünglichen Distribution.
rm -rf /mnt/debian/boot/ rm -rf /mnt/debian/lib/modules/3.2.0-4-versatile rm -rf /mnt/debian/lib/modules/3.2.0-5-versatile mkdir /mnt/debian/boot/ cp arch/arm/boot/uImage /mnt/debian/boot/ make INSTALL_MOD_PATH=/mnt/debian modules_install
Wir benötigen Firmware für das Wi-Fi-Modul, das sich in der ursprünglichen Distribution im Ordner / lib / firmware befindet, sowie die Bluetooth-Firmware, die wir zuvor gefunden haben.
cp /mnt/trik-clean/lib/firmware/* /mnt/debian/lib/firmware/ cp TIInit_7.6.15.bts /mnt/debian/lib/firmware/
Trennen Sie die Datenträgerabbilder:
umount /mnt/trik-clean umount /mnt/debian
Kopieren Sie das Bild mit dd auf die Speicherkarte:
# ( ) lsblk dd if=debian.img of=/dev/sdX bs=4M
Stufe 7. Die Ziellinie
Wir kompilieren die Programme zum Verbinden des Gamepads auf dem neuen System und installieren den Sixad-Daemon.
Wir verbinden das Gamepad über USB mit dem Controller und führen das Programm aus, um ein Paar zu erstellen:
root@trik:~/bt
Wenn das Gamepad angeschlossen ist, passiert nichts und der Sixad-Dienst ist stumm:
sixad-bin[2675]: started sixad-bin[2675]: sixad started, press the PS button now sixad-bin[2675]: unable to connect to sdp session
Aber die Raspberry Pi-Community hat bereits eine „Krücke“ gebaut, um die Verbindung zu reparieren.
Wir bauen das Programm neu auf und freuen uns.
sixad-bin[2833]: started sixad-bin[2833]: sixad started, press the PS button now sixad-bin[2833]: unable to connect to sdp session sixad-sixaxis[2836]: started sixad-sixaxis[2836]: Connected 'PLAYSTATION(R)3 Controller (00:**:**:**:**:09)' [Battery 02]
Jetzt steht das Gamepad dem System als Eingabegerät zur Verfügung und das Programm jstest zeigt den Status aller Tasten und analogen Sensoren an:
root@trik:~# ls /dev/input/ by-path event0 event1 event2 event3 js0 js1 js2 mice root@trik:~# jstest --normal /dev/input/jsX Driver version is 2.1.0. Joystick (PLAYSTATION(R)3 Controller (00:**:**:**:**:09)) has 29 axes (X, Y, Z, Rx, Ry, Rz, Throttle, Rudder, Wheel, Gas, Brake, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, (null), (null), (null), (null), (null), (null), (null), (null)) and 17 buttons (Trigger, ThumbBtn, ThumbBtn2, TopBtn, TopBtn2, PinkieBtn, BaseBtn, BaseBtn2, BaseBtn3, BaseBtn4, BaseBtn5, BaseBtn6, BtnDead, BtnA, BtnB, BtnC, BtnX). Testing ... (interrupt to exit) Axes: 0: 0 1: 0 2: 0 3: 0 4: -7150 5: -7746 6:-32767 7: 0 8: 0 9: 0 10: 0 11: 0 12: 0 13: 0 14: 0 15: 0 16: 0 17: 0 18: 0 19: 0 20: 0 21: 0 22: 0 23: 0 24: 0 25: 0 26: 0 27: 0 28: 0 Buttons: 0:off 1:off 2:off 3:off 4:off 5:off 6:off 7:off 8:off 9:off 10:off 11:off 12:off 13:off 14:off 15:off 16:off
Dabei ist X standardmäßig die Gerätenummer im System - 2. Die Anzahl der Tasten und Achsen kann hier angezeigt werden .
In der Praxis anwenden
Video zeigt das Gamepad auf YouTube .
Nützliche Links
Programme zum Anschließen des Dualshock 3-Gamepads - Sixpair und Sixad .
Für Gamepads und andere Eingabegeräte gibt es eine leichte C-Bibliothek - libenjoy .
Der Quellcode des Programms zur Steuerung von Servomotoren und Motoren ist das GitHub-Repository .
Alle Konfigurationsdateien aus dem Artikel für ein provisorisches Distributionskit sind das GitHub-Repository .
Die Kernelquelle ist das GitHub-Repository .
Interessante Fakten zum Controller
- Die Spezifikation besagt, dass RAM 256 MB beträgt. Wenn Sie jedoch htop ausführen, werden Sie feststellen, dass nur 128 MB verfügbar sind. Dies wird durch die Kerneloptionen eingeschränkt, die in der uBoot-Konsole angezeigt werden können:
mem=128M console=ttyS1,115200n8 rw noinitrd rootwait root=/dev/mmcblk0p1 vt.global_cursor_default=0 consoleblank=0
Der Speicherchip ist mit 3PC22 D9MTD von Micron gekennzeichnet. Es war nicht möglich, Informationen über das aktuelle Volumen zu finden.
- uBoot wird im SPI-Flash-Speicher gespeichert, in dem auch der Kernel verkabelt ist, und wird nicht verwendet. Sie können versuchen, diesen Ort für Ihre Aufgaben zu verwenden oder einen neuen Kernel zu kopieren und uBoot so zu konfigurieren, dass er verwendet wird.
Adressen von Bildern aus dmesg:
[ 11.598170] 0x000000000000-0x000000040000 : "uboot" [ 11.642985] 0x000000040000-0x000000080000 : "uboot-env1" [ 11.706256] 0x000000080000-0x0000000c0000 : "uboot-env2" [ 11.761827] 0x0000000c0000-0x000000100000 : "config-periph" [ 11.805129] 0x000000100000-0x000000400000 : "kernel" [ 11.861864] 0x000000400000-0x000001000000 : "RootFS"
- Der Bildschirm des Controllers ist zwar klein, verfügt jedoch über einen Widerstandssensor. Ob der Sensor selbst angeschlossen ist, ist unbekannt.
- Dualshock 3 verfügt über LEDs am USB-Anschluss, die die Nummer des Gamepads / Joysticks anzeigen. Es gibt ein Gamepad im Video, aber seine Nummer ist 3. Dies ist kein Fehler, weil Es gibt zwei weitere „Joysticks“ im System: einen Beschleunigungsmesser und ein Gyroskop.
Probleme bei der Verwendung
- Der Roboter hängt manchmal fest, ohne die Servomotoren auszuschalten, wodurch sie ihre Position aufgrund von Rauschen auf der Datenleitung ändern können. Dies wurde sogar bei einer Standardverteilung beobachtet .
- Die Einbeziehung von PWM-Controllern unterscheidet sich von den Angaben in der Dokumentation . Zumindest in reinem C hat dies nicht funktioniert.
- USB funktioniert manchmal nicht mehr unter Debian.