RFM12 im iPAQ: Unterschied zwischen den Versionen

Aus Ethersex_Wiki
Wechseln zu: Navigation, Suche
(Seite importiert.)
(kein Unterschied)

Version vom 27. März 2009, 17:09 Uhr

iPAQ funke!

Nachdem es inzwischen ja den Funk2Duo gibt, muss natürlich gleich die nächste Hardware-Modifikation sein. Wir bauen ein Funkmodul in den iPAQ ein - der nächste Schritt zu Jochens ultimativer Fernbedienung.

Nur dass es zu keinen Missverständnissen kommt, wir übernehmen für das hier beschriebene Vorgehen keine Verantwortung. Wenn Du meinst, dass Du Dir die Modifikation zutraust, bitte. Aber das hier ist definitiv nichts für schwache Nerven__, und überleg' Dir was Dir lieber ist, ein iPAQ mit Funkmodul oder ein iPAQ der leblos im Schrank liegt.

Serial Peripheral Interface ...

... ist das, was der h3600_micro-Treiber zu können verspricht. Er bringt den sich auf dem iPAQ befindlichen Atmel AVR auch dazu, dieses Protokoll zu sprechen. Dennoch ist da ein Haken: es gibt vier verschiedene SPI-Modes, der Microcontroller auf der iPAQ-Platine spricht leider den Falschen. Ebenso werden vor den Nutzdaten immer noch zwei oder drei Bytes rausgeclockt, die den RFM12 ebenfalls aus dem Konzept bringen würden ...

... kurzum, hilft nichts. Wenn schon, dann dürfen wir nicht kleckern, wir müssen klotzen: der AVR braucht eine neue, geänderte Firmware. Ach übrigens, wenn Du noch nie etwas mit einem Mikrocontroller gemacht hast, fang besser gar nicht erst an, das hier nachzubauen (:cry:)

Während ich die Firmware modifiziert habe, habe ich natürlich einiges über deren Aufbau usw. gelernt. Was mir dabei auffiel und interessant vorkam, habe ich unter IpaqAvrHacking zusammen getragen. Dort finden sich auch diverse Interna zum RFM12-Hack :-)


Hardware modifizieren ...

Verdrahtung des Funkmoduls, zur besseren Übersicht
fliegend verdrahtetes RFM12 Modul am iPAQ

Zunächst musst Du Kontakt zu ein paar Pins des Mikrocontrollers knüpfen: MISO, MOSI, SCK, PEN_IRQ (PD3), LED_ON (PB4) und RESET. Dass Du Vcc und GND brauchst, ist wohl klar. Anfangs ist es wohl am geschicktesten, wenn Du den Programmieradapter und das RFM12-Modul gleichzeit anschließst. Beim RFM12 brauchst Du einen Pullup (z.B. 10k) am nFFS. Die Interruptpins haben wir via Diode und einem kleinen Widerstand (10k) verbunden. Die Diode natürlich Richtung RFM12, da das Signal invertiert ist, der Widerstand soll nur Schutzcharakter haben, dass keine (für die Technik gefährlichen) Fehlströme fließen können (vom RFM12 über das Touchpad oder ähnliches). Der Widerstand sollte nicht zu groß gewählt werden, da auf Seite des AVRs noch etwas dagegen hält (dieses unerforschte Etwas fällt bei verschiedenen iPAQs unterschiedlich aus, z.T. können auch Widerstände mit 47k verbaut werden, bei manchen nicht)

Nicht erschrecken, wenn Du den iPAQ jetzt einschaltest, kannst Du das Touchpad nicht mehr verwenden, da der RFM12 den Interrupt-Pin auf low zieht und nicht mehr los lässt, bis man ihn mittels SPI ausfrägt (was die alte Firmware ja noch nicht tut).

Firmware modifizieren

WICHTIG: Jetzt erstmal das EEPROM und den Flashspeicher auslesen und gut aufbewahren. Insbesondere das EEPROM(:exclaim:), nach dem Flashen der Firmware (Stichwort Chip-Erase) ist das EEPROM erstmal leer.

Wenn Du fleißig sein möchtest, kannst Du erstmal nachsehen, welche Firmwarerevision Du hast. Das geht entweder im Assemblercode (die Version-ACK-Stelle suchen, leicht zu erkennen an der Sequenz

ldi     r28, 0xc0       ; 192
sts     0x00d1, r28
ldi     r16, 0x02       ; 2
st      Y+, r16 

... kurz darunter solltest Du eine Reihe von ldi-Befehlen sehen, die die Versionsnummer (in ASCII-Ziffern, also hex 0x3n) ausgeben. Den Punkt solltest Du als 0x2E ebenfalls leicht finden) ... oder Du schaltest den iPAQ ein und guckst in /proc/hal/version. Ich hab' bislang die Versionen 1.07 sowie 1.04 in den Fingern gehabt. Die nehmen sich beide nicht viel und man kann in einen iPAQ auf dem die 1.04-er war auch problemlos die 1.07-er Firmware flashen -- soll heißen, die Hardware scheint kompatibel...

Solltest Du eine andere Version installiert haben, schick' mir doch bitte eine eMail und häng' da das Image dran (:rolleyes:)

Die von mir modifizierte Firmware ist inzwischen relativ weit gediehen, d.h. ein bißchen senden und empfangen funktioniert. Die Firmware kannst Du hier herunterladen. Die Datei original.asm enthält die unmodifizierte 1.7-er Firmware; ein simples make versucht diese Datei auch neu zu assemblieren und vergleicht sie mit dem mitgelieferten Hexfile. Sollte dabei was schief gehen, bricht der make-Vorgang ab -- das sprich dann für ein kaputtes avr-gcc environment (:wink:). Die rfm12-mod.S ist die von mir modifizierte Firmware-Variante, ein make sollte ein rfm12-mod.hex erstellen, welches ein make load automatisiert in den AVR befördern sollte (funktionsfähigen avrdude vorausgesetzt)

Treiber installieren

Du musst zunächst den Hardware Abstraction Layer des Linux Kernels patchen (Patch gibt's hier), kompilieren und die geänderten Module h3600_micro.o und ipaq_hal.o tauschen.

Dann kannst Du dir den Quellcode des h3600_rfm12-Treibers aus meinem Git-Repository herunterladen (snapshot anklicken) und kompilieren (make). Vorher musst Du die Variable TOPDIR ins Environment exportieren, diese sollte auf das Hauptverzeichnis der Kernel-Trees zeigen. Nach erfolgreichem make solltest Du eine h3600_rfm12.o vorfinden, die Du auf deinen iPAQ befördern solltest.

Dort ein

modprobe h3600_rfm12
ifconfig rfm12 192.168.5.23 up
route add default gw 192.168.5.1

... und Dein iPAQ sollte funken können.

Zu kompliziert?

einfacher ist's gleich die Binärmodule zu nehmen, diese gibt's hier. Ich habe diese für die Kernelversion 2.4.19-rmk6-pxa1-hh42 gebaut. Wenn Du eine (deutlich) andere Version hast, wird's natürlich nichts.

IPv6 muss schon sein

Das h3600_rfm12 Modul unterstützt grundsätzlich IPv6. Allerdings gibt's da einen Haken, was IPv6 in Komination mit unserem RFM12-Protokoll angeht: wir können wegen dem AVR maximal 173 Bytes übertragen. Das ist insoweit problematisch, als der IPv6-Standard vorsieht, dass die MTU mindestens 1280 Bytes beträgt.

Der Kernel kennt und berücksichtigt diese Grenze, soll heißen, man kann keine IPv6-Adresse an ein Gerät zuweisen, wenn die MTU kleiner ist. Falls Du dennoch IPv6 verwenden möchtest, kannst Du diesen Patch verwenden, der die Adresse trotzdem zuweist (und nur eine Warnmeldung protokolliert).

Auf iPAQ-Seite sind damit alle Probleme gelöst. Der Kernel kennt die lokale MTU und richtet sich danach.

Der Weg zum iPAQ ist ein bißchen problematischer. Okay, grundsätzlich funktioniert es schon, aber beim Handshake des TCP-Protokolls empfiehlt jede Verbindungsseite der Gegenstelle eine maximale Segmentgröße (MSS). Der Linux Kernel orientiert sich dabei an der MTU des ersten Routers, in unserem Fall also 173. Das ist ein bißchen klein, wenn man bedenkt, dass auch locker ein Kilobyte übertragen werden könnte. Es empfiehlt sich also, hier ein wenig zu tricksen: der Kernel kann überzeugt werden, dass er größere Mindestwerte angibt, dazu dient die Datei /proc/sys/net/ipv4/route/min_adv_mss. Für IPv6 gibt's eine schönere Möglichkeit: der Routing-Eintrag kann um die Option advmss ergänzt werden (vgl. die Manpage von ip).