Hallo, mein Problem: möchte gerne eine Funktion erstellen, die mittels Zeiger ein Zeichen-Array bearbeitet; Das Array ist aber entweder im Flash oder im SRAM abgelegt, je nachdem was der Rest des Programms damit macht, d.h. ich muss den Pointer wahlweise als Flash-Pointer oder als SRAM-Pointer definieren können. Sowas in dieser Form (bitte nicht lachen, es funktioniert natürlich nicht :-))): void func_blabla ( unsigned char mode ) { unsigned char a, b, c; .... if (mode) flash char *p; else char *p; .... p = text_array; .... } wie gesagt, obige Konstruktion funktioniert natürlich nicht... Wie kann ich denn sowas elegant machen? Danke für Eure Vorschläge! PS: benutze CodeVision
CodeVision, also AVR? (Schreibt doch bitte immer die Architektur dazu, Leute!) Elegant? Gar nicht! Auch für mich das größte Ärgernis bei der AVR-Architektur ist die allzu konsequente Trennung in Programm- und Datenspeicher. Wäre vermeidbar. Naja. Abhilfe? In Assembler. Es werden immerhin verschiedene Befehle und unterschiedliche Adressierungsarten benutzt.
Bei IAR und Keil gibt es generic Pointer. Die wissen, auf welchen Speichertyp sie zeigen.
Hi Leute! Ja, es geht um CodeVision AVR; da gibt es drei Zeigertypen: zum FLASH, zum SRAM und zum EEPROM, die man dann nicht verwechseln kann/darf... Na ja, da sind wir wohl auf die Grenzen gestossen... Danke für Eure Antworten!
Zwei Möglichkeiten die ich benutze: 1.) Jeder Funktion die auf FLASH/SRAM usw. zugreift gibst du einen weiteren Paramater mit. Dieser bestimmt dann wie die Funktion den übergebenen Pointer auszuwerten hat. Meistens heist der Paramater bei mir "IsFlashStored". D.h. ist IsFlashStored != 0 dann greift die Funktion mit von "LPM" unddem Zeiger auf den Flash zu, ansonsten mit "LD" auf den SRAM. 2.) Jeder Funktion die auf Daten zugreifen will, bekommt einen weiteren Parameter -> eine Lese-Schreib-Callback. Bei jedem Zugriff innerhalb der Funktion auf die Daten ruft diese die Callback auf. Innerhalb der Callback wird dann entsprechend zum Pointer entweder auf den SRAM, FLASH, EEPROM oder sogar MMC/SD, CF, I2C EEPROM etc. pp. zugegriffen. Ich persönlich nutze diese Möglichkeit immer bei Bibliotheken, zB. in der GLCD Grafik Library. Die Daten stellen die Fonts dar die eben an x'beliebiger, zur Entwicklungszeit nicht vorhersehbarer Stelle,gespeichert sein können. Statt aber bei jeder Funktion eine solche Callback zu übergeben versuche ich diese als Globale Variable zu benutzen. Damit fällt dieser zusätzliche Parameter weg. D.h. die GLCD benötigt als Daten ihre Fonts, der aktuell eingestellte Font samt Lesecallback wird mit einer Setup-Funktion in globalen Variablen gespeichert. Gruß Hagen
Hallo folgenden Code finde ich sehr praktisch, allerdinggs muss die Datei mit einem C++ Compiler compiliert werden. Dazu wird die Funktion mehrfach "überladen". Der Compiler unterscheidet überladene Funtionen anhand ihrer Signatur. Er erkennt, dass die erste Funktion einen Pointer auf char nutzt und die zweite Funktion einen const pointer auf char. Es gibt zwei Nachteile 1. RAM Variablen die als const char X[] = "xxxx";>> definiert sind werden falsch gehandelt. 2. Das AVR Extended COFF Format hat Probleme mit C++, eine definierte "struct" meldet avr-objcopy als "class type not supported in coff-ext-avr". Debugging über Extended COFF geht dann nicht. Klaus
Hm, wird "const char" nicht auch im Flash abgelegt???
> Hm, wird "const char" nicht auch im Flash abgelegt??? Nein, nicht bei AVR. "const" bedeutet nicht "Konstante" sondern eher "Read Only", die Variable darf trotzdem im RAM stehen. Für Flash Daten gibt man deshalb das Attribut PROGMEM mit.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.