IOT-Basisstation
Idee
Ein universelles Atmega1284P-Board mit Ethernet-Anschluß und Internet-Bootloader. Das Board soll günstiger und kompakter als ein Arduino Ethernet werden, und den neueren W5500 von WizNet (erhältlich bei TME) verwenden, der erheblich schnelle Übertragungen ermöglicht.
Hardware-Design Version V02
Verbesserungen und Korrekturen
- Luftlinie. Die Verbindung vom Reset-Pin des ISP-Headers zum Taster wurde nicht geroutet und musste mit 0.2mm-Kupferlackdraht auf der Rückseite gebrückt werden.
- Den Bestückungsaufdruck sollte man auch positionieren. Ich hatte alles so gelassen wie Eagle es anbot, und habe prompt beim Löten zwei Bauteile vertauscht. Hat gedauert den Fehler zu finden.
- VCC-Jumper wären hilfreich.
- JTAG-Jumper fehlt, und der Atmega1284P hat kein DebugWire.
- Footprint. Erst die Komponenten aussuchen, Lieferstatus checken und bestellen, dann den Footprint layouten. Mikro-SD-Buchse ist nicht gleich Mikro-SD-Buchse, und der Taster passt auch mal gerade so.
- DTR-Reset. Da ich die Arduino-Ethernet-Bibliotheken benutze bietet sich auch die Arduino-IDE zur Entwicklung an. Ich habe dafür die Hardware als neue Arduino-Komponente definiert, inklusive eines angepassten stk500v2-Arduino-Bootloaders (diesen mit Atmel Studio erstellt). Leider fehlt zur Kompatibilität mit dem Arduino Ethernet ein Jumper für die DTR-Leitung über einen Kondensator zu !RESET.
- GND→NC. Falls jemand der Schnitt an Pins 38-42 des W5500 auffällt: Datenblätter können sich ändern, in Version 1.0 waren die Pins „It must be tied to GND“, jetzt in 1.0.2 sind sie „NC“. Würde wohl auch mit Verbindung zu GND immer noch funktionieren, aber besser so wenige Fehlerquellen wie möglich.
- SD-SPI. Laut SD-Kartenspezifikation startet jede SD-Karte im SD-Busmodus. Wir benutzen aber den SPI-Busmodus und müssen die SD-Karte daher in diesen Modus umschalten. Schlimmer noch: Im SD-Busmodus haben die Pins der SD-Karte eine andere Bedeutung, und so kann (und wird) eine eingesteckte SD-Karte im SD-Busmodus die SPI-Kommunikation mit dem W5500 oder die Neuprogrammierung über ISP stören.
Internet-Bootloader
Im Gegensatz zu anderen Open-Source-Ansätzen (Sowerbutts, Ariadne, Ethernut, Ethersex, sowie diverse weitere in http://www.mikrocontroller.net) lädt der Bootloader die Software nicht über TFTP aus dem lokalen Netz, sondern über HTTP aus dem Internet. Dies macht den Einsatz bei Bekannten oder generell in beliebigen Netzen sowie den dortigen Software-Update möglich. Da dies ein Hobby-Projekt ist, werden MitM-Angriffe u.ä. hier nicht berücksichtigt.
Dazu ist im Eeprom neben einer MAC-Adresse eine URL abgelegt. Nach jedem Reset wird der Bootloader aktiv, lädt gegebenenfalls von der URL eine neue Anwendungssoftware und programmiert diese in den Flash-Speicher, aktiviert den Watchdog-Timer und startet die Anwendung. Die Anwendung muss also regelmäßig den Watchdog füttern, ansonsten wird ein Reset ausgelöst, welcher wieder den Bootloader aktiviert. Zur Zeit lädt der Bootloader nur bei einem Watchdog-Reset neue Software aus dem Internet, nicht aber nach einem Brownout, Power oder externen Reset (z.B. via Taster).
Im Eeprom können eigene IP-Adresse und Netzmaske sowie IP-Adresse des Routers und des DNS-Servers abgelegt werden. Diese Einstellungen kann der Bootloader aber auch automatisch über DHCP ermitteln. Die IP-Adresse des URL-Hosts wird über DNS erfragt.
In der URL sollte eine eindeutige Systemkennung (
hwid
) enthalten sein, um auf dem Bootserver im Internet eine Zuordnung zwischen Systemen und deren aktueller Software vornehmen zu können, etwa via phpmyadmin (siehe Fenster). Der Bootloader selbst übermittelt in der URL auch noch seine eigene Software-Kennung (loaderid
, zusammengesetzt aus __FILE__ " " __DATE__ " " __TIME__
) sowie den Grund des Resets (mcusr
, eine Zwei-Ziffer-Hexadezimalzahl). Der Bootloader erwartet, dass der Bootserver auf die HTTP GET Anfrage mit genau einer Intel_HEX-Datei antwortet. Zwar werden nur die Typen 00, 01 und 02 unterstützt, aber genau diese werden auch nur vom avr-gcc (Atmel Studio, Arduino) erzeugt.
Der Bootloader implementiert eine serielle Schnittstelle mit 57600 Baud, mit folgenden Kommandos:
Reset | Softwarekennung und Resetursache | \n SWID,MCUSR= MCUSR\n |
Prompt | Eingabeaufforderung | > |
[R |W ][E |F |S ] | Lesen (R ) oder schreiben (W ) von E eprom, F lash oder S ram | Daten im Intel_HEX-Format |
M | Resetursache | MCUSR: MCUSR\n |
B | Internet-B ootload | |
G | Starte Anwendung (G o) | |
T | T rigger Watchdog-Reset |
Der Bootloader führt kurz nach dem Start auch die Kommandosequenz aus, die eine eventuell eingesteckte SD-Karte in den SPI-Busmodus umschaltet, um das ober beschriebene SD-SPI-Problem zu umgehen.
Der vollständige Quellcode ist unter http://github.com/wangnick/httpboot zu finden.
Internet-Bootserver
Der Internet-Bootserver ist in meinem Fall ein einfaches Python-Skript mit Anbindung an eine MySQL-Datenbank. Er registriert und speichert jeden Bootvorgang auch noch in einer weiteren Tabelle. Dies ist hilfreich, um Reboot-Schleifen erkennen und beheben zu können. Dabei wird der Flash-Speicher allerdings nicht unnötig belastet: Der Bootloader prüft vor jedem Schreibvorgang, ob überhaupt Änderungen im Flash vorzunehmen sind, und überspringt komplett gleiche Flashseiten.