====== RZ_Raven_USB Stick (AT90USB1287) External RAM Erweiterung (XRAM) über die XMEM Schnittstelle ======
Da der interne SRAM des RZ Raven USB Sticks (AT90USB1287) mit 8KByte relativ klein ist, entstehen immer wieder Probleme, welche meist durch einen Überlauf des Stacks in den Heap oder umgekehrt entstehen können, siehe folgende Abbildung.
{{:contiki:malloc-std.png?500|}}
Besonders beim Einsatz als RPL Border Router ([[contiki:raven_usb_rpl_border_router|Der Jackdaw Raven USB Stick als RPL Border Router]]), gelangt der SRAM mit 96% Auslastung nach der Kompilierung an seine Grenze. Der Betrieb von weiteren Protothreads wie z.B. das Contiki SNMP ist somit auf dem RZ Raven USB Stick nicht möglich, siehe hierzu [[contiki:snmp_rz_raven_usb_jackdaw|RZ Raven USB Stick als RPL Border Router mit SNMPv3 Support und RPL MIB]].
===== Benötigte Hardware =====
Glücklicherweise haben die Entwickler des Raven USB Sticks für solche Fälle bereits Vorbereitungen getroffen und innerhalb des Platinenlayouts Leiterbahnen zum Anschluss eines zusätzlichen externen SRAMS inegriert. Im folgenden Schaltplan ist dieser unter der Bezeichnung U6 zu finden.
{{:contiki:circuit_rzravenusb.png?500|}}
Da um Pins zu sparen der Datenbus und die High Order Adress Bits über die gleichen Pins gesteuert werden, ist zusätzlich ein Latch erforderlich, welches mit der Bezeichnung U5 im Schaltplan zu finden ist. Die folgende Abbildung verdeutlicht den prinzipiellen Aufbau.
{{:contiki:ravenusb_extsram.png?400|}}
Außerdem ist pro Chip jeweils ein [[http://www.cypress.com/?docID=31807|Abblockkondensator]] vorgesehen (C19 und C20).
Auf dem Raven USB Stick sind die Bauteile auf der Platinenunterseite zu finden.
{{:contiki:ravenusb_fb.png?500|}}
{{:contiki:ravenusb_back.jpeg?500|}}
Empfohlen werden laut [[http://www.atmel.com/Images/doc8117.pdf|RZ Raven Hardewareguide]] Kapitel 3.4.2 die ICs ''74AHC573PW'' als Addresslatch und der ''BS62UV256TCP-10'' als SRAM (32KByte). Das Addresslatch ist ohne Probleme zu beziehen, z.B. von [[http://de.farnell.com/jsp/search/productdetail.jsp?CMP=i-ddd7-00001003&sku=9590587|Texas Instruments bei Farnell]]. Beim empfohlenen SRAM wird das Ganze schon etwas schwieriger, da das Bauteil scheinbar nicht mehr hergestellt wird. Es gibt jedoch einige Alternativen, das wichtigste ist die Gehäuseform ''TSOP-28'' sowie die 32KByte in Anordnung 32x8 und 3,3V Nennspannung, z.B. [[http://de.farnell.com/jsp/search/productdetail.jsp?CMP=i-ddd7-00001003&sku=2101285|INTEGRATED SILICON SOLUTION (ISSI) - IS62LV256AL-45TLI]].
===== Register Konfiguration zur Aktivierung des externen SRAMs =====
Um den neuen externen SRAM nun zugänglich zu machen, muss dieser aktiviert werden. Dazu muss das Register ''XMCMRA'', genauer PIN7 von ''XMCMRA'' auf High gesetzt werden.
{{:contiki:xmcra.png?500|}}
Die restlichen PINs 0-6 (''SLR0''-''SLR2'', ''SRW10'', ''SRW11'', ''SRW00'' und ''SRW01'') sind zur Einstellung von "Wait-States" vorgesehen, was es ermöglicht den Addressraum in verschiedene Sektoren aufzuteilen, was bei den hier verwendeten 32KByte jedoch nicht notwendig ist.
Ebenfalls nicht benötigt werden die Einstellung von Register ''XMCRB'', welches es ermöglicht einzelne Address Bits zu maskieren um den vollen Addressraum auszunutzen.
Umgesetzt in C Code kann folgende Funktion verwendet werden:
void xram_enable(void)
{
XMCRA = ((1 << SRE)); //enable XMEM interface with 0 wait states,
//switch Bit 7 of XMCRA on to enable XMEM usage
XMCRB = 0; //use all Port C Pins for XRAM Addresses, Port C7 no needed,
//but we don't need it till it is not connected to anything
}
==== Umsetzung in Contiki ====
Um die Funktion sinnvoll in Contiki zu platzieren, bietet es sich an dies im Ordner ''platform/avr-ravenusb/'' zu tun. Der Aufruf kann dann sinvoller Weise in der Datei ''contiki-raven-main.c'' innerhalb der lowlevel Initialisierung geschehen.
Dazu bietet sich folgendes Vorgehen an (alles im Ordner ''platform/avr-ravenusb/''):
- Erstellen der C und Header Datei, z.B. [[contiki:avr-xram.c|avr-xram.c]] und [[contiki:avr-xram.h|avr-xram.h]] und Platzierung innerhalb des ''platform/avr-ravenusb/'' Ordners.
- Integration von [[contiki:avr-xram.c|avr-xram.c]] in das ''Makefile'' [[contiki:makefile.ravenusb|Makefile.ravenusb]]
- Aufruf innerhalb der Lowlevel Initialisierung ''static void initialize(void)'' in der Datei [[contiki:contiki-raven-main.c|contiki-raven-main.c]] (Änderungen markiert mit /*sz*/
- Optional: An und Abschalten des externen RAMS durch Makro in [[contiki:contiki-conf.h-ravenusb|contiki-conf.h]] (''#define AVR_XRAM'')
===== Sinnvolle Nutzung des SRAMS =====
Es stellt sich nun die Frage, wie die zusätzlichen 32KByte sinnvoll genutzt werden können. Eine Möglichkeit ist z.B. den internen Speicher für den Stack zu Nutzen und den Heap sowie die .data und .bss Sections in den externen RAM zu verschieben, siehe folgende Abbildung.
{{:contiki:malloc-x1.png?700|}}
Um dies umzusetzen, muss das Vorhaben dem Linker mitgeteilt werden. Dazu genügt es beim kompilieren GCC mit folgendem Anweisungen aufzurufen.
-Wl,--section-start,.data=0x802100,--defsym=__heap_end=0x80a0ff
Dadurch beginnt die .data Section ab der Adresse ''0x2100''. Die .bss und der Heap werden automatisch danach platziert. Lediglich das Heap Ende muss noch mitgeteilt werden. Der Stack bleibt wie gehabt beginnend beim Ende des internen Speichers, wächst abwärts und muss nicht geändert werden.
Die Adresse ''0x2100'' ergibt sich durch die internen 8KByte ( 8*1024= 8192 Byte = ''0x2000'') sowie die Register von ''0x0000'' bis ''0x00FF'' (255 Byte) = ''0x20FF'' = letzte Adresse des internen SRAMs.
{{:contiki:ram_kompl.png?300|}}
Das Ende des Heap, also das Ende des externen SRAMS ergibt sich dann durch Addition der 32KByte (32*1024=32768=''0x8000'') mit ''0x20FF'' + ''0x8000'' = 8192 + 255 + 32768 = 41215 = ''0xA0FF'' = letzte Adresse des externen SRAMS = Ende Heap.
Innerhalb von Contiki lässt sich die Linker Anweisung einfach in das Makefile mit dem Zusatz ''CFLAGS +=...'' integrieren, Bsp Makefile im Ordner [[contiki:makefile.ravenusbstick-xram|/examples/ravenusbstick/Makefile.ravenusbstick]].
Überprüfen lässt sich die Änderung der Grenzen nach der Kompilierung mit dem Tool ''avr-readelf''. Also z.B. mit dem Befehl ''avr-readelf -e ravenusbstick.elf''. Die anschließende Suche nach z.B, ''__heap_end'', liefert dann die Möglichkeit zur Überprüfung.
===== Ermöglichung der Nutzung des kompletten 32KByte SRAMS =====
Vielleicht taucht beim Lesen die Frage auf, wie der komplette SRAM genutzt wird. Da der externe SRAM nach dem internen SRAM gemappt wird, führt eine Adressierung der ersten 8448 Byte immer zum internen RAM und nicht zum externen RAM. Das bedeutet, dass normalerweise der externe RAM erst ab dem 8449. Byte addressiert werden kann, wodurch ein Speicherbereich mit der Größe des internen SRAMS nicht genutzt werden kann.
Um dieses Problem zu umgehen, haben die Entwickler des Raven USB Sticks das Adressbit A15, welches normalerweise das höchste Addressbit darstellt nicht mit dem externen SRAM verbunden (siehe Schaltplan weiter oben). Das führt dazu, dass ab dem Nutzen der Adresse ''0x8000'' der unterste Teil des SRAMS adressiert wird, da durch das fehlen des höchsten Adressbits die Adresse 0x8000 als ''0x0000'' erscheint. Die folgende Abbildung verdeutlicht diesen Vorgang.
{{:contiki:ram_kompl_nutz.png?400|}}