DerMaddin
19.10.2008, 20:13
Hallo ;)
Ich habe das Wissen aus dem Roboternetzforum zusammengetragen und alle Treiberfunktionen des ATMega32 und des RNControl Boards in einer Bibliothek untergebracht. Der gesamte Code ist in ISO C 99 geschrieben, von einem Codebeautifier formatiert (GreatCode) und einer statischen Codeanalyse mit SPLint unterzogen worden (und natürlich ohne Warnungen des SPLint kompiliert). Das ArchiveFile kann in eine Applikation eingebunden werden.
Ich stelle euch hier zwei Versionen zur Verfügung: Die kleinere ist ein normales Release - Build und die größere gibt auf dem Terminal aus, wenn eine Funktion oder ein Interrupt betreten oder verlassen wurde. Das ist beim Debuggen hilfreich.
Wer jetzt denkt, dass die 33k große Bibliothek nicht in den 32k großen Speicher des ATMega passt, liegt falsch. Denn beim Linken gegen diese Bibliothek werden nur die Informationen verwendet, die im Programm benötigt werden.
Eine Besonderheit gibt es beim Thema Interrupts zu beachten. Alle Interrupts werden prinzipiell immer in der Bibliothek abgefangen (IRQ_Enable() muss natürlich vorher einmal ausgeführt werden). Um jetzt Funktionssprünge aus der Bibliothek heraus in Interrupthander zu ermöglichen, existiert diese Variable:
FunctionPointer interruptCallbacks[21];
Dieses Array aus Funktionszeigern ist standardmäßig mit Nullen befüllt. Eine Applikation, die diese Bibliothek verwendet, definiert sich einen Funktionspointer und fügt diesen an die entsprechende Stelle in diesem Array. Ein Enumerator hilft dabei. Um ein Beispiel zu zeigen:
static void RS232ReceiveHandler(void)
{
UInt16 receivedData = RS232_ReadData();
…
}
void SetInterruptCallbacks(void)
{
interruptCallbacks[RS232ReceiveComplete] = &RS232ReceiveHandler;
}
Diese Funktionen müssen void zurückgeben und dürfen keinen Parameter erhalten, um mit der ArrayDeklaration konform zu sein. Alle Datentypen sind in einem extra Header zu finden. Ich stelle die gesamten Sourcen ebenfalls zur Verfügung, damit ihr mir sagen könnt, wo man noch tweaken kann.
Ich stelle diese Bibliothek noch nicht ins RN-Wissen, weil mir noch ein entscheidender Teil fehlt: Ich habe noch keine verlässliche Implementierung einer passiven und einer aktiven Waitfunktion. Heisst:
Ich versuche noch, ohne Verwendung von Gleitkommazahlen (!) eine Waitfunktion zu schreiben, die in einer Schleife solange zählt, bis eine vorgegebene Anzahl Millisekunden verstrichen ist. Diese Implementierung muss wahrscheinlich von der Taktrate des Controllers, also dem Define F_CPU abhängig sein. Ich suche auch noch eine weitere Funktion, nämlich zum passiven Warten. Sie soll einen Timer starten, in einen Sleepmodus wechseln und nach einer vorgegebenen Zeitspanne wieder aufwachen.
Das wechseln in einen geeigneten Sleepmodus ist ebenfalls nicht Bestandteil der Bibliothek. Vielleicht könnt ihr mir helfen, diese Funktionalitäten (ohne Verwendung von Gleitkommarechnungen) zu implementieren? Das wär cool :)
Warum ist es mir so wichtig, Gleitkommazahlen zu vermeiden? Ganz einfach: Der ATMega32 kann nicht direkt mit Gleitkommazahlen rechnen. Alles wird in Software implementiert und bei Verwendung der Schlüsselwörter „double“ oder „float“ dazu gelinkt. Dummerweise hat das den Effekt, dass die Bibliothek um 12kb größer wird! Das will ich unbedingt vermeiden.
Folgende Funktionalitäten der Lib habe ich mit einer geeigneten Applikation getestet:
Battery, Buttons, LEDs, Speaker, ADC, Interrupts (mit Handlerfunktionen), Memory, Ports, Reset, RS232, Timer, Watchdog.
Ungetestet sind I2C und PWM.
Und jetzt noch ein kurzes HowTo für das Linken gegen diese Lib:
Baut eure Objectfiles wie gehabt mit dem GCC und inkludiert avrlib.h. Erweitert eure LinkerKommandozeile um „-Lk:\\RoboterProject\\App\\Source –lavr”. Das ist das Setzen eines LibraryPaths und das Angeben der Lib, gegen die gelinkt werden soll. Zum Beispiel sieht die Kommandozeile dann so aus:
-mmcu=atmega32 k:\\RoboterProject\\App\\\\Output\\Release\\Interm ediate\\BatteryHandler.obj k:\\RoboterProject\\App\\\\Output\\Release\\Interm ediate\\ButtonHandlers.obj k:\\RoboterProject\\App\\\\Output\\Release\\Interm ediate\\GP2D12.obj k:\\RoboterProject\\App\\\\Output\\Release\\Interm ediate\\InterruptHandlers.obj k:\\RoboterProject\\App\\\\Output\\Release\\Interm ediate\\Main.obj k:\\RoboterProject\\App\\\\Output\\Release\\Interm ediate\\MemoryHandlers.obj k:\\RoboterProject\\App\\\\Output\\Release\\Interm ediate\\SurroundingScan.obj
-o k:\\RoboterProject\\App\\\\Output\\Release\\progra m.elf -Os --relax -Wall,-Map,k:\\RoboterProject\\App\\\\Output\\Release\\pr ogram.map -Lk:\\RoboterProject\\App\\Source -lavr
Helft mir also bitte, die Bibliothek zu vervollständigen, dann kann sie im RN Wissen landen ;)
Ich danke euch schon mal!!
Ich habe das Wissen aus dem Roboternetzforum zusammengetragen und alle Treiberfunktionen des ATMega32 und des RNControl Boards in einer Bibliothek untergebracht. Der gesamte Code ist in ISO C 99 geschrieben, von einem Codebeautifier formatiert (GreatCode) und einer statischen Codeanalyse mit SPLint unterzogen worden (und natürlich ohne Warnungen des SPLint kompiliert). Das ArchiveFile kann in eine Applikation eingebunden werden.
Ich stelle euch hier zwei Versionen zur Verfügung: Die kleinere ist ein normales Release - Build und die größere gibt auf dem Terminal aus, wenn eine Funktion oder ein Interrupt betreten oder verlassen wurde. Das ist beim Debuggen hilfreich.
Wer jetzt denkt, dass die 33k große Bibliothek nicht in den 32k großen Speicher des ATMega passt, liegt falsch. Denn beim Linken gegen diese Bibliothek werden nur die Informationen verwendet, die im Programm benötigt werden.
Eine Besonderheit gibt es beim Thema Interrupts zu beachten. Alle Interrupts werden prinzipiell immer in der Bibliothek abgefangen (IRQ_Enable() muss natürlich vorher einmal ausgeführt werden). Um jetzt Funktionssprünge aus der Bibliothek heraus in Interrupthander zu ermöglichen, existiert diese Variable:
FunctionPointer interruptCallbacks[21];
Dieses Array aus Funktionszeigern ist standardmäßig mit Nullen befüllt. Eine Applikation, die diese Bibliothek verwendet, definiert sich einen Funktionspointer und fügt diesen an die entsprechende Stelle in diesem Array. Ein Enumerator hilft dabei. Um ein Beispiel zu zeigen:
static void RS232ReceiveHandler(void)
{
UInt16 receivedData = RS232_ReadData();
…
}
void SetInterruptCallbacks(void)
{
interruptCallbacks[RS232ReceiveComplete] = &RS232ReceiveHandler;
}
Diese Funktionen müssen void zurückgeben und dürfen keinen Parameter erhalten, um mit der ArrayDeklaration konform zu sein. Alle Datentypen sind in einem extra Header zu finden. Ich stelle die gesamten Sourcen ebenfalls zur Verfügung, damit ihr mir sagen könnt, wo man noch tweaken kann.
Ich stelle diese Bibliothek noch nicht ins RN-Wissen, weil mir noch ein entscheidender Teil fehlt: Ich habe noch keine verlässliche Implementierung einer passiven und einer aktiven Waitfunktion. Heisst:
Ich versuche noch, ohne Verwendung von Gleitkommazahlen (!) eine Waitfunktion zu schreiben, die in einer Schleife solange zählt, bis eine vorgegebene Anzahl Millisekunden verstrichen ist. Diese Implementierung muss wahrscheinlich von der Taktrate des Controllers, also dem Define F_CPU abhängig sein. Ich suche auch noch eine weitere Funktion, nämlich zum passiven Warten. Sie soll einen Timer starten, in einen Sleepmodus wechseln und nach einer vorgegebenen Zeitspanne wieder aufwachen.
Das wechseln in einen geeigneten Sleepmodus ist ebenfalls nicht Bestandteil der Bibliothek. Vielleicht könnt ihr mir helfen, diese Funktionalitäten (ohne Verwendung von Gleitkommarechnungen) zu implementieren? Das wär cool :)
Warum ist es mir so wichtig, Gleitkommazahlen zu vermeiden? Ganz einfach: Der ATMega32 kann nicht direkt mit Gleitkommazahlen rechnen. Alles wird in Software implementiert und bei Verwendung der Schlüsselwörter „double“ oder „float“ dazu gelinkt. Dummerweise hat das den Effekt, dass die Bibliothek um 12kb größer wird! Das will ich unbedingt vermeiden.
Folgende Funktionalitäten der Lib habe ich mit einer geeigneten Applikation getestet:
Battery, Buttons, LEDs, Speaker, ADC, Interrupts (mit Handlerfunktionen), Memory, Ports, Reset, RS232, Timer, Watchdog.
Ungetestet sind I2C und PWM.
Und jetzt noch ein kurzes HowTo für das Linken gegen diese Lib:
Baut eure Objectfiles wie gehabt mit dem GCC und inkludiert avrlib.h. Erweitert eure LinkerKommandozeile um „-Lk:\\RoboterProject\\App\\Source –lavr”. Das ist das Setzen eines LibraryPaths und das Angeben der Lib, gegen die gelinkt werden soll. Zum Beispiel sieht die Kommandozeile dann so aus:
-mmcu=atmega32 k:\\RoboterProject\\App\\\\Output\\Release\\Interm ediate\\BatteryHandler.obj k:\\RoboterProject\\App\\\\Output\\Release\\Interm ediate\\ButtonHandlers.obj k:\\RoboterProject\\App\\\\Output\\Release\\Interm ediate\\GP2D12.obj k:\\RoboterProject\\App\\\\Output\\Release\\Interm ediate\\InterruptHandlers.obj k:\\RoboterProject\\App\\\\Output\\Release\\Interm ediate\\Main.obj k:\\RoboterProject\\App\\\\Output\\Release\\Interm ediate\\MemoryHandlers.obj k:\\RoboterProject\\App\\\\Output\\Release\\Interm ediate\\SurroundingScan.obj
-o k:\\RoboterProject\\App\\\\Output\\Release\\progra m.elf -Os --relax -Wall,-Map,k:\\RoboterProject\\App\\\\Output\\Release\\pr ogram.map -Lk:\\RoboterProject\\App\\Source -lavr
Helft mir also bitte, die Bibliothek zu vervollständigen, dann kann sie im RN Wissen landen ;)
Ich danke euch schon mal!!