From 56d9bdd39ed36c36e9a61411b86c76d5228b2133 Mon Sep 17 00:00:00 2001 From: sicarius Date: Sun, 11 Feb 2007 18:32:03 +0000 Subject: Added lot's of code-files used during work --- source/ct-Bot/Documentation/TWI-Treiber.htm | 70 ++++++++++ source/ct-Bot/Documentation/mmc-vm.html | 154 ++++++++++++++++++++++ source/ct-Bot/Documentation/mmc.jpg | Bin 0 -> 193468 bytes source/ct-Bot/Documentation/remote-calls.html | 33 +++++ source/ct-Bot/Documentation/select-behaviours.txt | 29 ++++ source/ct-Bot/Documentation/style.css | 128 ++++++++++++++++++ 6 files changed, 414 insertions(+) create mode 100644 source/ct-Bot/Documentation/TWI-Treiber.htm create mode 100644 source/ct-Bot/Documentation/mmc-vm.html create mode 100644 source/ct-Bot/Documentation/mmc.jpg create mode 100644 source/ct-Bot/Documentation/remote-calls.html create mode 100644 source/ct-Bot/Documentation/select-behaviours.txt create mode 100644 source/ct-Bot/Documentation/style.css (limited to 'source/ct-Bot/Documentation') diff --git a/source/ct-Bot/Documentation/TWI-Treiber.htm b/source/ct-Bot/Documentation/TWI-Treiber.htm new file mode 100644 index 0000000..524774d --- /dev/null +++ b/source/ct-Bot/Documentation/TWI-Treiber.htm @@ -0,0 +1,70 @@ + + + + + +

Carsten Giesen (info@cnau.de)

+

TWI-Treiber (I2C)

+

Die gesammte Kommunikation mit der TWI Schnittstelle steckt in TWI_driver.c +und TWI_driver.h.
Angesprochen wird der Treiber �ber "Send_to_TWI(tx_frame)" +daf�r sind aber ein paar Vorarbeiten n�tig.

+

Zur Vereinfachung hier ein Beispiel am Beispiel vom SRF10:

+


char +temp[2];                 +//Array um Platz f�r die Befehle zu schaffen
char +state;                     +//Platz f�r das Ergebniss der Aktion
tx_type +tx_frame[2];     //Hier wird der Container geschaffen

+

+

state = SUCCESS;         +//Vorbelegen, da manche Aktionen nur Sinn machen, wenn state=SUCCESS

+

//Jetzt gehts los:
tx_frame[0].slave_adr = address+W; //Die Adresse des +Ziel-Bausteins
tx_frame[0].size = 2; //Wie viele Befehle (Daten) sollen +�bertragen werden
tx_frame[0].data_ptr = temp; //der Pointer f�r die +Befehle
tx_frame[0].data_ptr[0] = SRF10_COMMAND;     +//Der erste Befehl ist normaler Weise das +Register, 
                                                                                        +//welches Angesprochen werden soll
tx_frame[0].data_ptr[1] = +metric_unit;                     +//Was soll gemacht werden (hier eine Messung in cm)
tx_frame[1].slave_adr = +OWN_ADR;                     +//Damit wird dem Treiber klar gemachtm das er fertig ist.
state = +Send_to_TWI(tx_frame);                             +//Und jetzt wird alles �bergeben

In State steht jetzt ob der Befehl +erfolgreich war, oder nicht.

Wie man Daten empf�ngt, am Beispiel Register +auslesen:

+

uint8 srf10_read_register(unsigned char srf10_register)
{
char +temp;                     +//Variable um Platz f�r die Befehle zu schaffen
char +value;                     +//Variable um Platz f�r die Resultate zu schaffen
char +state;                     +//Platz f�r das Ergebniss der Aktion
tx_type +tx_frame[3];     //Hier wird der Container +geschaffen
state = SUCCESS;         +//Vorbelegen, da manche Aktionen nur Sinn machen, wenn state=SUCCESS
value = +0;
tx_frame[0].slave_adr = +address+W;          //Die Adresse +des Ziel-Bausteins
tx_frame[0].size = +1;                                        +//Wie viele Befehle (Daten) sollen �bertragen werden
tx_frame[0].data_ptr = +&temp;                      +//der Pointer f�r die Befehle
tx_frame[0].data_ptr[0] = +srf10_register;     //Der erste Befehl ist normaler Weise +das +Register,
                                                                            +//welches Angesprochen werden soll
tx_frame[1].slave_adr = +address+R;             +//Die Adresse des Ziel-Bausteins +R f�r lesen
tx_frame[1].size = +1;                                         +//Wie viele Daten sollen gelesen werden
tx_frame[1].data_ptr = +&value;                     +//der Pointer f�r die Daten
tx_frame[2].slave_adr = +OWN_ADR;         //Damit wird dem +Treiber klar gemachtm das er fertig ist.
state = +Send_to_TWI(tx_frame);                 +//Und jetzt wird alles �bergeben
srf10_state = state;
return +value;
}

+

Man kann also gut sehen, das beide Aktionen, schreiben und lesen kombiniert +werden k�nnen.

diff --git a/source/ct-Bot/Documentation/mmc-vm.html b/source/ct-Bot/Documentation/mmc-vm.html new file mode 100644 index 0000000..e7ccaf3 --- /dev/null +++ b/source/ct-Bot/Documentation/mmc-vm.html @@ -0,0 +1,154 @@ + + + + + + + + + +c't-Bot - VM-Dokumentation + + + +

Dokumentation zur virtuellen Speicherverwaltung

+
+ +Eine allgemeine Übersicht
+Der virtuelle Speicher im Detail + +Der Zugriff auf ein FAT16-Dateisystem
+Etwas Statistik zur Leistungsbewertung
+Eine Übersicht aller Konfigurationsparameter
+ +

Eine allgemeine Übersicht

+

Das Speichersystem ist wie folgt organisiert:
+Man fordert eine beliebige Menge an Speicher an und bekommt eine virtuelle Adresse in 32 Bit zurück. +Diese Adresse entspricht der Adresse auf der MMC / SD-Card, was den Benutzer aber nicht weiter interessieren muss. Zum Arbeiten mit den Daten +erhält man eine "echte" SRAM-Adresse, die auf einen 512 Byte großen Speicherbereich zeigt. Dieser Cacheeintrag wird +auf die MMC / SD-Card zurückgeschrieben, sobald der maximal für den Cache zugeteilte Speicher komplett belegt ist, das +Ein- und Auslagern der Seiten auf die MMC / SD-Card macht die Speicherverwaltung also automatisch.
+Somit kann ein Verhalten beliebig viel (virtuellen) Speicher benutzen, siehe Abschnitt zum virtuellen Speicher. +Außerdem kann derselbe Adressraum und Cache auch für den Zugriff auf FAT16-Dateien benutzt werden, Näheres dazu gibt es hier.
+Die Bezeichnung "page" (oder "Seite") stellt durchgängig etwas logisches (virtuelles) dar, mit "Block" hingegen ist ein physischer Block auf dem verwendeten +Datenträger gemeint.
+Im Folgenden wird ausschließlich auf die Verwendung einer MMC / SD-Card als Speichermedium eingegangen, läuft der Code auf einem PC, so wird die +Speicherkarte mit Hilfe einer Datei emuliert, die Verwendung ist aber äquivalent (siehe auch pc/mmc-emu_pc.c). +

+ +

Der virtuelle Speicher im Detail

+

Die Speicherallokierung

+

Nach der Anforderung einer beliebige Menge an Speicher per mmcalloc(), bekommt man eine virtuelle Adresse des 32 Bit großen +Adressraums zurück. mmc_get_data(uint32 virtuelle_Adresse) liefert dann eine "echte" SRAM-Adresse auf einen 512 Byte +großen Puffer zurück, dessen Inhalt auf die MMC / SC-Card geschrieben wird, sobald er nicht mehr im SRAM gehalten werden kann.
+Die Funktion mmc_get_end_of_page(uint32 virtuelle_Adresse) hilft herauszufinden, bis wohin man diesen Pointer verwenden darf. +Benötigt man mehr Speicher, fordert man mit mmc_get_data(uint32 virtuelle_Adresse) einen neuen Pointer an.
+Zu beachten ist, dass nur soviel virtueller Speicher zur Verfügung steht, wie die intuitive Rechnung "letzter Sektor der MMC / SD-Card" minus +"Startadresse für den virtuellen Speicher" ergibt. Ansonsten liefert mmcalloc() null zurück. +

+ +

Ein kleines Beispiel

+

Das folgende Beispiel demonstriert, wie sich der virtuelle Speicher benutzen lässt:
+

+uint32 v_addr = mmcalloc(2048, 1); // wir wollen 2 KB Speicher
+uint8* p_addr = mmc_get_data(v_addr); // Pointer auf Puffer holen
+... // irgendwas sinnvolles tun
+if (i < 512) { // Ziel liegt noch im gleichen Block
+ p_addr[i] = my_data; // Daten speichern
+ i++;
+} else { // Blockende erreicht => zunaechst neuen Pointer holen
+ v_addr += i;
+ i = 0;
+ p_addr = mmc_get_data(v_addr);
+ p_addr[i] = my_data; // Daten koennen nun gespeichert werden
+} +

+Der zweite Parameter von mmcalloc() gibt an, ob man den angeforderten Speicher auf möglichst wenige Blöcke verteilt +haben möchte (also 512 Byte ausgerichtet), oder ob er einfach am nächsten freien Byte auf der Karte beginnen soll (1: aligned, 0: beliebig). Passt der +angeforderte Speicher noch komplett in einen bereits teilweise belegten Block, so wird er immer dort untergebracht. +

+ +

Die Schnittstelle zur Hardware

+

+Das folgende Diagramm zeigt die Beziehung der Funktionen des MMC-Codes und die entsprechenden Schnittstellen: +
mmc-Code +
Die grün gekennzeichneten Funktionen sind in den jeweiligen Header-Dateien deklariert und bilden zusammen +die Schnittstelle des MMC-Codes nach außen. Die rot Gekennzeichneten hingegen bleiben dem eigentlichen Code für MMC und virtual Memory vorbehalten.
+Die Abhängigkeiten untereinander sind durch die Pfeile dargestellt (in Aufrufrichtung).
+Den doppelt umrandeten Funktionen möge man besondere Aufmerksamkeit schenken - diese sind vorrangig in eigenen Verhalten zu verwenden. Die restlichen +(internen) Funktionen sind eher zur Dokumentation des Speichersystems an sich aufgeführt, für die Benutzung in Bot-Verhalten sind sie nicht so sehr +interessant. +

+ +

Einige Erläuterungen zum Cache

+

+Um den Zugriff auf die jeweiligen Daten möglichst performant zu halten, cached das Speichersystem eine vorgegebene Anzahl an 512 Byte großen +Blöcken im SRAM. Der Cache ist vollassoziativ, für das Zurückschreiben kommt das LRU-Verfahren zum Einsatz. Im Speicher wird er durch ein Array +vom Typ vm_cache_t (siehe auch mmc-vm.c) repräsentiert, die maximale Größe lässt sich mit einem +Konfigurationsparameter festlegen und wird bei Speichermangel automatisch reduziert. Es wird erst dann Cachespeicher belegt, wenn +auch Daten angefordert werden.
+Ein Aufruf der Funktion mmc_flush_cache() schreibt den kompletten Cache auf die Karte zurück, +mmc_page_write_back(uint32 virtuelle_Adresse) hingegen nur die Seite, die zu der übergebenen Adresse gehört. Letztere Funktion tut dies +unabhängig davon, ob die Seite seit der Einlagerung verändert wurde oder nicht und ermöglicht so einen "tieferen" Eingriff in das +sonst automatisch arbeitende System.
+Ein Verhalten sollte also vor seiner Beendigung dafür sorgen, dass der Cacheinhalt gesichert wird, wenn die gespeicherten Daten erhalten bleiben sollen! +

+ +

Der Zugriff auf ein FAT16-Dateisystems

+

+Die Unterstützung für FAT16-Dateien auf einer MMC / SD-Card ist wie folgt aufgebaut:
+ mmc_fopen(const char *filename) öffnet eine Datei im FAT16-Dateisystem der Karte und gibt die virtuelle Startadresse +zurück, so dass man mit mmc_get_data() Zugriff auf die Daten bekommt. Der Dateiname muss dabei ganz am Anfang in der Datei +stehen.
+Achtung: Öffnet man eine Datei, die bereits mit mmc_fopen() geöffnet wurde, ist das Verhalten bzgl. dieser Datei derzeit +undefiniert!
+ mmc_clear_file(uint32 file_start) leert eine Datei im FAT16-Dateisystem, die zuvor mit +mmc_fopen() geöffnet wurde. Die Datei wird komplett mit Nullen überschrieben, nur der erste Sektor mit dem "Dateinamen" und der +Größe bleibt erhalten.
+ mmc_get_filesize(uint32 file_start) gibt die Größe einer geöffneten Datei in Byte zurück. +

+ +

Etwas Statistik zur Leistungsbewertung

+

+Wenn VM_STATS_AVAILABLE definiert ist, lässt sich mit der Funktion mmc_get_vm_stats() eine Statistik +über die Leistung des Speichersystems erstellen. mmc_print_statistic() gibt solch eine Statistik in der Konsole aus, wenn der +Code auf einem PC läuft: + + + + + + + + + + + + + + + +
*** VM-Statistik ***
Groesse des Volumes:32 MByte
Groesse des VM:16 MByte
Belegter virt. Speicher:0 KByte
Groesse des Caches:1024 Byte
Auslastung des Caches:100 %
Seitenzugriffe:1375054
Seiteneinlagerungen:33770
Seitenauslagerungen:33768
Seitenzugriffe / s:5288
Seiteneinlagerungen / s:129
Seitenauslagerungen / s:  129
Cache-Hit-Rate:97.544096 %    
Messdauer:260 s

+Die hier ersichtlichen Daten stellen die Leistung des Speichersystems dar, unmittelbar nachdem ein Bot das Standardlabyrinth im c't-Sim komplett mit dem Wandfolger-Algorithmus +durchfahren und dabei eine Umgebungskarte erstellt hat.
+Für die MCU gibt es derzeit noch keine entsprechende Ausgabemöglichkeit. +

+ +

Eine Übersicht aller Konfigurationsparameter

+ + +

+

Valid XHTML 1.0 Transitional

+ + \ No newline at end of file diff --git a/source/ct-Bot/Documentation/mmc.jpg b/source/ct-Bot/Documentation/mmc.jpg new file mode 100644 index 0000000..d73357b Binary files /dev/null and b/source/ct-Bot/Documentation/mmc.jpg differ diff --git a/source/ct-Bot/Documentation/remote-calls.html b/source/ct-Bot/Documentation/remote-calls.html new file mode 100644 index 0000000..3691afe --- /dev/null +++ b/source/ct-Bot/Documentation/remote-calls.html @@ -0,0 +1,33 @@ + + + + + + + + +c't-Bot -Remote-Calls + + + +

Dokumentation zum Remote-Call-System

+
+

Funktionsweise der Remote-Calls für den c't-Bot:

+

Auf das Kommando CMD_REMOTE_CALL:SUB_REMOTE_CALL_LIST schickt der Bot +eine Liste mit den verfügbaren Remote-Calls an den PC.
+Jeder Listeneintrag kommt als eigenes Kommando (CMD_REMOTE_CALL:SUB_REMOTE_CALL_ENTRY).
+In der Payload steht neben dem Namen der Funktion auch, wie sie aufzurufen +ist und welche Parameter sie braucht. Das geschieht, indem die ganze interne +Datenstruktur (siehe call_t in remote_calls.h) übertragen wird.

+

Der PC kann jederzeit einen Remote-Call starten. Dazu schickt es das Kommando + CMD_REMOTE_CALL:SUB_REMOTE_CALL_ORDER. In der Payload steht zuerst der Name +der Funktion (null terminierter String). Danach kommen die Parameter. Jeder +Parameter muss dabei (unabhängig von seiner tatsächlichen Länge) 32 Bit belegen.

+

Ist der Bot fertig, antwortet er mit CMD_REMOTE_CALL:SUB_REMOTE_CALL_DONE +im DataL Feld steht eine 0, wenn das Verhalten nicht erfolgreich ausgeführt wurde. Steht dort eine 1, ist alles ok.

+

Um eigen Verhalten remote-aufrufbar zu machen, muss man ihre Botenfunktion nur in +die calls-Struktur in behaviour_remotecall.c eintragen. Wie das geht ist dort +ausführlich beschrieben. Alles andere übernimmt das Framework.

+ + + \ No newline at end of file diff --git a/source/ct-Bot/Documentation/select-behaviours.txt b/source/ct-Bot/Documentation/select-behaviours.txt new file mode 100644 index 0000000..64ef403 --- /dev/null +++ b/source/ct-Bot/Documentation/select-behaviours.txt @@ -0,0 +1,29 @@ +Frank Menzel(menzelfr@gmx.de) & Carsten Giesen (info@cnau.de): + +Auswahl von Verhalten ueber Fernbedienungstasten + +Anstelle des Counters koennen im Screen 3 nun alle Verhalten dargestellt werden, +jeweils 6 Stueck (2 neben-, 3 untereinander). Erst die Prioritaet und dann die Aktivitaet, +wobei 0 fuer ein inaktives und 1 fuer aktives Verhalten steht. Passen nicht +alle rauf, wird weitergeblaettert zu den naechsten Verhalten. Die aktuelle Verhaltens-Seite wird +durch die letzte Zahl in der ueberschrift dargestellt. +Folgende Vorgehensweise: +Mit der Screen-Toggle Taste (RC5_CODE_VIEW-bei meiner Hauppauge Fullscreen) werden die Screens +durchgeblaettert und im Screen 3 nun die Verhalten angezeigt. Die Tasten 1-6 sind den +Verhalten zugeordnet, wodurch diese damit getoggelt werden. Der angezeigte Aktivitaetswert +aendert sich von 0 nach 1 und umgedreht. Man kann nun alle Verhaltensseiten weiter +durchblaettern, beliebige ein- und ausschalten oder kombinieren und zum Schluss wird +die Taste RC5_CODE_SELECT betaetigt (bei meiner Hauppauge ist dies die Taste Source), +wodurch alle Verhalten entsprechend der Auswahl in ihrer Aktivitaet geaendert werden. + +Im Simulator gibt es leider die Tasten RC5_CODE_VIEW und RC5_CODE_SELECT (noch) nicht. Waehrend +hier aber die gelbe Taste den Verhaltens-Screen direkt anwaehlen kann, existiert fuer die Select-Taste +kein Aequivalent. So erhaelt die Taste 9 im Screen 3 diese Funktion. + +Moegliche Erweiterungen: +-Verhalten sind bis jetzt nur vorwaerts blaetterbar, ein Rueckwaertsblaettern koennte bei Bedarf noch +realisiert werden +-Wenn ein Verhalten ein oder mehrere andere Verhalten in ihrer Aktivitaet beeinflusst, ist dies im Moment + nicht online sichtbar. Die Anzeige und Wunschaenderungen gehen immer nur auf die Puffervariable des Verhaltens + und ist somit statisch. Ist die dynamische Variante gewuenscht, also dass man direkt online die Aktivitaeten + der Verhalten verfolgen kann, so ist dies relativ leicht realisierbar. diff --git a/source/ct-Bot/Documentation/style.css b/source/ct-Bot/Documentation/style.css new file mode 100644 index 0000000..c6a0821 --- /dev/null +++ b/source/ct-Bot/Documentation/style.css @@ -0,0 +1,128 @@ +/* das grosse Ganze */ +body { + margin: 20px 10px; + padding: 5px; + color: #000; + text-align: justify; + font-family: Verdana, "Lucida Grande", Lucida; + background-color: #e4e4e4; +} + +/* Seitenueberschrift */ +h1 { + color: #940000; + text-align: center; + text-decoration: underline; + font: 22pt Geneva, sans-serif, Helvetica, Arial; +} + +/* Themenueberschrift */ +h2 { + font-size: 18pt; + color: #000; + font-variant: small-caps; + margin-top: 40px; +} + +/* Unterueberschrift */ +h3 { + font-size: 16pt; + color: #000; + font-variant: small-caps; + margin: 0; + padding-top: 10px; +} + +/* Text */ +p { + font-size: 11pt; +} + +/* Quellcode hervorheben */ +.code { + color: #000; + font-family: Courier, mono; + background-color: #fff; + display: table; + margin-left: 10px; + padding: 5px; + margin-top: 10px; +} + +.keyword { + color: #9f0b55; +} + +.comment { + color: #008600; +} + +/* inline-Quellcode */ +.function { + color: #006900; + font-family: "Courier New", Courier, mono; + font-weight: bold; +} + +/* Konsolenausgaben hervorheben */ +.console { + color: #0f0; + background-color: #000; + display: table; + margin-left: 10px; + padding: 5px; + margin-top: 10px; + font: 10pt "Lucida Grande", Lucida, Verdana; +} + +/* alle Links sind gleich */ +a:link { + text-decoration: none; + color: #110086; +} + +a:visited { + text-decoration: none; + color: #110086; +} + +a:active { + text-decoration: underline; + color: #110086; +} + +a:hover { + color: #ff2021; + /*color: #5796ff;*/ + text-decoration: underline; +} + +/* oberes Menue */ +.menu { + line-height: 22px; +} + +/* Liste */ +ul { + margin: 0; + list-style-type: circle; + padding: 0 20px; + list-style-position: outside; +} + +/* Unterpunkte im Menue */ +ul.menu { + color: #110086; +} + +/* Grafiken */ +img { + margin: 10px 20px 5px 5px; + float: left; + border: 1px solid #000; +} + +/* IE-Workaround */ +ins { + text-decoration: none; +} \ No newline at end of file -- cgit v1.2.3