Wenn Sie den folgenden Code in eine AVR C-Quelle aufnehmen, können Sie die Sicherungen anscheinend direkt programmieren, ohne dass ein zusätzlicher Befehl oder eine zusätzliche .hex-Datei erforderlich ist:
#include <avr/io.h>
FUSES = {
.low = LFUSE_DEFAULT ,
.high = HFUSE_DEFAULT ,
.extended = EFUSE_DEFAULT ,
};
Gibt es einen ähnlichen Trick wie bei Programmwerten im EEPROM?
Ich habe überprüft, /usr/lib/avr/include/avr/fuse.h
wo ich einige Kommentare zu einem Makro finden kann, aber ich kann keinen ähnlichen Kommentar in finden, /usr/lib/avr/include/avr/eeprom.h
und die Interpretation des Präprozessor-Materials ist etwas außerhalb meiner Liga.
Es wäre sehr praktisch, wenn ich Standard-EEPROM-Werte in den C-Quellcode aufnehmen könnte. Weiß jemand, wie man das erreicht?
edit1:
Dieser FUSES-Trick wird nur zur ISP-Zeit ausgeführt, nicht zur RUN-Zeit. Es werden also keine Sicherungen im resultierenden Baugruppencode in der Steuerung programmiert. Stattdessen durchläuft der Programmierer automatisch einen zusätzlichen FUSES-Programmierzyklus.
edit2:
Ich benutze die Toolkette avr-gcc und avrdude unter Linux.
Antworten:
Mit avr-gcc kann das
EEMEM
Makro für die Definition einer Variablen verwendet werden. Weitere Informationen finden Sie in denlibc
Dokumenten und in einem Beispiel hier :deklariert das Zeichenarray in einem Abschnitt mit dem Namen ".eeprom", der dem Programmierer nach der Kompilierung mitteilt, dass diese Daten in das EEPROM programmiert werden sollen. Abhängig von Ihrer Programmiersoftware müssen Sie dem Programmierer möglicherweise explizit den Namen der ".eep" -Datei geben, die während des Erstellungsprozesses erstellt wurde, oder er findet sie implizit selbst.
quelle
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 ihex $(src).elf $(src).eeprom.hex
avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U eeprom:w:$(src).eeprom.hex
Ja, Sie können Standarddaten im Quellcode manuell in das EEPROM schreiben. Schauen Sie sich zuerst diese fantastische Anleitung zum EEPROM mit AVR an: Dean's AVR EEPROM Tutorial. Außerdem sollte ich hinzufügen, dass es eine bessere Idee ist, eine .eep-Datei mit den EEPROM-Daten unter Verwendung des Makefiles zu erstellen, das zusammen mit dem Quellcode auf dem Gerät programmiert wird. Wenn Sie jedoch mit verschiedenen Makefile- und Linker-Vorgängen nicht vertraut sind, können Sie diese weiterhin in Ihrer Quellcodedatei ausführen. Dies geschieht nur, sobald die Schaltung mit Strom versorgt wird und die anfängliche Programmoperation blockiert.
Zu Beginn des Programms (vor jeder Art von Hauptschleife) können Sie Folgendes tun:
Die Funktion "Aktualisieren" prüft zuerst, ob dieser Wert bereits vorhanden ist, um unnötige Schreibvorgänge zu sparen und die Lebensdauer des EEPROM zu erhalten. Dies für sehr viele Standorte zu tun, kann jedoch einige Zeit in Anspruch nehmen. Es ist möglicherweise besser, einen einzelnen Standort zu überprüfen. Wenn dies der gewünschte Wert ist, können die restlichen Aktualisierungen vollständig übersprungen werden. Beispielsweise:
Wenn Sie große Datenmengen aktualisieren möchten, verwenden Sie die anderen Funktionen wie z
eeprom_update_block(...)
. Und lesen Sie auf jeden Fall dieses Tutorial; es ist gut geschrieben.Sie können alle EEPROM-Aktualisierungsanweisungen in eine einzige bedingte Präprozessoranweisung einfügen. Dies ist sehr einfach zu tun:
Dieses Codebit wird erst kompiliert, wenn Sie Folgendes tun:
Sie können dies als Kommentar hinterlassen und dann auskommentieren, wenn Sie die Standard-EEPROM-Werte ändern müssen. Weitere Informationen zum C-Präprozessor finden Sie in diesem Online-Handbuch . Ich denke, Sie interessieren sich vielleicht am meisten für die Abschnitte über Makros und bedingte Anweisungen.
quelle
Ch. 7 Setting Initial Values
.EEMEM
Variablen kümmert sich der Compiler darum, zu verwalten, welche Variable sich wo im EEPROM befindet. Auf diese Weise bearbeiten Sie beim Zugriff auf die Daten nur (konstante, vom Compiler generierte) Zeiger auf Variablen. Wenn Sie andererseits explizit die Adresse definieren, an der sich jede Variable befindet, müssen Sie sich selbst um diese Adressen kümmern, einschließlich der Sicherstellung, dass keine Variablen versehentlich dieselbe Adresse belegen und sich gegenseitig überschreiben. oder alle Adressen neu berechnen, falls sich die Speichergröße einer Variablen in Zukunft ändert usw.