Hallo Zusammen
Ich möchte einen String aus dem FlashRom eines AVR (ATemga32) ins Ram
kopieren. Das ist genau das, was pgm_read_byte aus der avr-libc macht.
Nur verwende ich diese Library nicht und schreibe daher eine eigene.
Jetzt bin ich auf der Suche nach source der Funktion pgm_read_byte. Wo
krieg ich diese? Sie kann auch in Assembler sein.
Vielen Dank für eure Hilfe!
Gruss
Lorenz
@Karl: FLASH, nicht EEPROM
@Lorenz:
Wenn Du den AVR-GCC Compiler verwendest, dann werfe mal einen Blick in
die Dokumentation bzw Library Referenc zur avr-libc. In der Beschreibung
zu <avr/pgmspace.h>: "Program Space String Utilities" findest Du Makros
wie zum Beispiel: pgm_read_byte(address_short)
MfG Peter
Im Grunde hat man immer 2 Möglichkeiten:
1.Man vertraut darauf das die Lib vernünftig arbeitet und kann damit
leben das es keine 100%ig Massgeschneiderte Lösung ist.Dann benutzt man
sie.
2.Man will wissen was unter der Haube passiert oder kann aus irgendeinem
Grund nicht mit der Lib leben (zuviel unbenötigte Features,zu gross,zu
langsam,etc)
Da es hier allerdings nicht um ein gewachsenes Stück Software in dem
viele Mann-Stunden Arbeit stecken handelt,reicht ein Blick ins
Datenblatt.Dieser offenbart,zumindest bei Controllern die selbigen
Unterstützen,dass der Assembler-Befehl LPM (Load Program Memory) das
zusammengesetzte Register Z (R31:R30) als Zeiger in den Programmspeicher
benutzt und das entsprechende Byte in das Register R0 laden
kann.Weiterhin würde man erfahren,ob der verwendete Controller eventuell
auch flexiblere addressierungsmöglichkeiten besitzt,das der Flash
wort-weise organisiert ist und welche Bedingungen erfüllt werden
müssen,um mit SPM auch Daten ins Flash schreiben zu können.Von den
unterschiedlichen Addressräumen für SRAM,EEPROM und Flash mal
abgesehen...
peter wrote:
> @Karl: FLASH, nicht EEPROM>
Wie bin ich bloss auf EEPROM gekommen.
Egal. Auf derselben Seite finden sich auch die
Flash Routinen. Er wird ja hoffentlich doch so
intelligent sein und ein bischen rumscrollen.
Oliver wrote:
> G O O G L E
Unsinn. Einfach den Sourcecode des avr-libc-Projektes nehmen.
Allerdings dürfte im Falle von pgm_read_byte() wirklich alles
bereits im Headerfile <avr/pgmspace.h> stehen.
> Und welchen Compiler willst du verwenden?
Diese Frage erübrigt sich in diesem Forum. ;-)
Lorenz fragt:
"...was pgm_read_byte aus der avr-libc macht...Jetzt bin ich auf der
Suche nach source der Funktion pgm_read_byte. Wo krieg ich diese?"
Antwort 1: "G O O G L E"
Antwort 2: "Einfach den Sourcecode des avr-libc-Projektes nehmen."
ROTFL
Oliver
P.S. Das nächste mal gibt es immer ganz viele :-) :-) :-) dazu
>"...was pgm_read_byte aus der avr-libc macht...Jetzt bin ich auf der>Suche nach source der Funktion pgm_read_byte. Wo krieg ich diese?">Antwort 1: "G O O G L E">Antwort 2: "Einfach den Sourcecode des avr-libc-Projektes nehmen."
... oder bei OBI...
Vielen Dank für eure ausführlichen Antworten
@Ronny: Ich bin der Typ, welcher 2. bevorzugt und verwende daher die
avr-libc nicht.
Zudem muss ich gestehen, dass ich praktisch nichts von Assembler
verstehe. Ich wurde natürlich schon einige Male damit konfrontiert doch
ein eigenes Programm habe ich noch nie in Assembler geschrieben.
Seit ich Software für uC schraube benutze ich den AVR-GCC-Compiler (dies
sollte in diesem Forum eigentlich wirklich klar sein :)).
Daher fürchte ich mich davor aus dem Datenblatt selber diese Funktion zu
implementieren.
Also einfach den Source-Code der avr-libc zu verwenden dachte ich auch
schon. Das Haederfile rpmspace.h fand ich. Nur fand ich dann nirgens ein
C-File wo diese Funktion implementiert war. Und ganz allgemein finde ich
mich in dieser Library überhaut nicht zurück (dutzende Ordner die alle
AVR heissen und ineinander stecken etc.).
Und noch zu GOOGLE. In diesem Fall bin ich einfach zu blöd zum googlen.
Denn ich habe die source nicht gefunden. Zurzeit findet man unter
"pgm_read_byte +source" an erster Stelle diese Topic :)
Danke für eure Hilfe!
Lorenz
@Lorenz
>@Ronny: Ich bin der Typ, welcher 2. bevorzugt und verwende daher die>avr-libc nicht.
Was schon mal nicht sehr sinnvoll ist . . .
>Daher fürchte ich mich davor aus dem Datenblatt selber diese Funktion zu>implementieren.
. . . nicht nur aus diesem Grund.
>Also einfach den Source-Code der avr-libc zu verwenden dachte ich auch>schon. Das Haederfile rpmspace.h fand ich. Nur fand ich dann nirgens ein>C-File wo diese Funktion implementiert war. Und ganz allgemein finde ich
Wozu auch. Binde das header-File ein und benutzt die Funktion gemäss
Doku der avr-libc und alles läuft. Wo ist das Problem? Vor allem mit
deinen nichtvorhanden Assemblerkentnissen wirst du keine bessere Lösung
als die in der avr-libc hinbekommen.
MfG
Falk
P.S. Man muss das Rad nicht neu erfinden.
> Nur fand ich dann nirgens ein> C-File wo diese Funktion implementiert war
Das gibt es nicht. Wie ich schon weiter oben schrob, ist sie komplett
im Headerfile implementiert.
Am einfachsten ist das, wenn du dir ein Stück C-Programm schreibst:
@Falk: Dass man das Rad nicht neu erfinden muss ist schon richtig. Als
ich jedoch (vor ca. 2 Jahren) mit der Programmierung vor AVRs begonnen
habe habe ich mich zuerst entschieden die Programme in C zu schreiben,
da ich schon einiges auf Java geschrieben habe. Auf das Lernen von
Assembler habe ich zuerst einmal verzichtet. Das schien mir zu
aufwendig.
Die avr-libc war für mich dann anfangs eine riesige Black-Box. Ich
wollte nicht verstehen, wie der avr-gcc funktioniert, denn das werde ich
wohl in meinem Leben nie, doch ich wollte verstehen, was ich ihm
füttere. Daher habe ich das io.h File mehr oder weniger kopiert und
sonst noch ein paar Sachen herauskopiert (für die Interrupts etc.) und
damit begonnen zu programmieren. Ich hatte dann also eine Library,
welche anfangs nur wenige Hundert Zeilen umfasst. Nun habe meine io.h
Files schon relativ stark modifiziert (zB. verstehe ich nicht, wieso
dort *#define PA7 7* drinn steht, denn PA7 ist doch länger zum tippen
als 7, nicht?).
Zudem arbeite ich mit anderen Typen-Bezeichnern: byte, int8, word,
int16, dword, int32 etc. Ich weiss dass dies eigentlich nur unpraktisch
ist, doch bis jetzt hatte ich noch keine Lust dies zu ändern.
@Jörg: Vielen Dank für deine geniale Hilfe. Ich habe bis jetzt nicht
verstanden, dass pgm_read_byte eine reine Präprozessor Angelegenheit
ist. Ich habe mir die entsprechende Zeile nun in meine Library kopiert
und es funktioniert perfekt.
Vielleicht hört man sich ja einmal auf der QRG...
Gruss Lorenz
@Lorenz
>da ich schon einiges auf Java geschrieben habe. Auf das Lernen von>Assembler habe ich zuerst einmal verzichtet. Das schien mir zu>aufwendig.
Ist erstmal OK.
>Die avr-libc war für mich dann anfangs eine riesige Black-Box. Ich
Das soll sie auch sein. Dich (und vor allem MICH) interessiert nicht WIE
eine Funktion im Inneren aufgebaut ist, sondern wie ich sie nutzen kann.
>wollte nicht verstehen, wie der avr-gcc funktioniert, denn das werde ich>wohl in meinem Leben nie, doch ich wollte verstehen, was ich ihm>füttere.
Ja eben.
>Daher habe ich das io.h File mehr oder weniger kopiert und>sonst noch ein paar Sachen herauskopiert (für die Interrupts etc.) und>damit begonnen zu programmieren. Ich hatte dann also eine Library,
DAS ist aber genau NICHT der Weg, eine Bibliothek zu nutzen. Und du bist
sicher, dass du grundlegende Dinge beim Programmieren verstanden hast?
Ich fürchte nein.
>welche anfangs nur wenige Hundert Zeilen umfasst. Nun habe meine io.h>Files schon relativ stark modifiziert (zB. verstehe ich nicht, wieso>dort *#define PA7 7* drinn steht, denn PA7 ist doch länger zum tippen>als 7, nicht?).
Du hast nicht! :-(
Weil PA7 intuitiv verstanden wird (PortA, Bit 7) während 7 alles und
nichts bedeuten kann.
Du solltest DRINGEND mal ein Buch zum Thema Stuckturierter
Softwareentwurf lesen. Dir fehlen wichtige Grundlagen.
>Zudem arbeite ich mit anderen Typen-Bezeichnern: byte, int8, word,>int16, dword, int32 etc. Ich weiss dass dies eigentlich nur unpraktisch>ist, doch bis jetzt hatte ich noch keine Lust dies zu ändern.
Starrköpiger Einzelkämpfer? Schon mal was von Standardisierung gehört?
Und welche Vorteile sie bringt?
MfG
Falk
Sicher.
Man kann sich auch zur Drehbank stellen und sich seine
M4 Schrauben selber drehen, einen schönen Sechskant drauffeilen
und ein Gewinde schneiden.
Man kann aber auch in den nächsten Baumarkt gehen und sich
für wenig Geld eine Handvoll M4 Schrauben kaufen.
Was hat man gelernt, wenn man seine Schrauben selber fertigt?
Im Grunde .... gar nichts.
Man hat nur sinnlos ein paar Stunden an der Drehbank gestanden.
Ou, das wird ja immer schwieriger meinen Standpunkt zu vertreten.
Ich muss gestehen, ich habe noch nie in einem Team Software entwickelt.
Und in einigen Punkt hast du, Falk, sicher recht. Eigene
Typen-Bezeichnungen zu verwenden ist absolut sinnlos. Doch als ich
angefangen habe mit dem avr-gcc zu arbeiten wurde es mir schnell zu
blöde signed char zu schreiben. Daher habe ich mir einfach einen eigenen
Typ definiert. Das nun int8_t vielleicht schlauer ist, ist mir jetzt
auch klar. Nur ist die Wahrscheinlichkeit, dass ich zu dieser Zeit genau
auf die selbe Idee gekomemen wäre schon ziemlich gering. Daher ist halt
int8 draus geworden. Ich sollte dies einmal ändern, ja, nur hatte ich
bis jetzt noch nie den Mumm dazu.
Dann noch was zu PA7.
Ob ich jetzt "sbi(DDRA,PA7);" oder "sbi(DDRA,7)" schreibe spielt für
mich vom Verständnis der Source eigentlich keine Rolle. Daher nehme ich
das Zweite, weil es kürzer ist.
>Das soll sie auch sein. Dich (und vor allem MICH) interessiert nicht WIE>eine Funktion im Inneren aufgebaut ist, sondern wie ich sie nutzen kann.
Das stimmt bezogen auf mich zumindest am Anfang nicht. Ich hatte das
Datenblatt, dort stand in Worten drinn, wie die Hardware des AVRs zu
bedienen ist. Ich war nun einfach neugierig zu sehen, wie man dies
Implementieren kann. Ich habe einen USART Treiber, eine sehr
ausführliche I2C Bibliotheck (mit Fifo-Buffern beim Senden und Empfagen
für alle 4 Modis geschrieben) eine eigene Library für LCD-Display. Klar
wäre ich schneller gewesen, wenn ich einfach eine fertige Library
verwendet hätte, doch dann hätte ich nie so viel gelernt. Wenn du daran
intressiert bist den Drehbank bedienen zu lernen ist es unter umständen
schon sinnvoll eine M4-Schraube selber herzustellen. Hey, ich
programmiere diese Kontroller als Hobby und nicht weil ich möglichst
effizient etwas erreichen möchte.
>Starrköpiger Einzelkämpfer? Schon mal was von Standardisierung gehört?>Und welche Vorteile sie bringt?
Vermutlich schon ja, denn ich bin auf die Standardisierung nicht
angewiesen, da ich nun mal bis jetzt alleine Arbeite. Der Punkt wo ich
mich an Normen halten werde wird bald kommen, die Vorteile kenne ich.
Lorenz wrote:
> Ich muss gestehen, ich habe noch nie in einem Team Software entwickelt.
Das hat nichts mit Team zu tun.
Das hat eher was damit zu tun sein Werkzeug zu kennen. Werkzeug
ist in diesem Fall die Programmiersprache UND die zugehörigen
Bibliotheken.
Beides sind integraler Bestandteile, das eine macht ohne
das andere wenig Sinn.
Wenn du Schwierigkeiten mit der eigentlich überschaubaren
Standardlibrary und mit den noch viel überschaubareren
AVR-Erweiterungen hast, dann warte erst mal, bis du auf
einem Desktop System mit einer grafischen Oberfläche
programmierst. Da geht ohne die Verwendung von Bibliotheken
gar nichts mehr. Und da sind es dann plötzlich 300 oder 400
Funktionen die man so einigermassen im Kopf haben soll und
nicht 30 wie hier.
> Und in einigen Punkt hast du, Falk, sicher recht. Eigene> Typen-Bezeichnungen zu verwenden ist absolut sinnlos. Doch als ich> angefangen habe mit dem avr-gcc zu arbeiten wurde es mir schnell zu> blöde signed char zu schreiben. Daher habe ich mir einfach einen eigenen> Typ definiert. Das nun int8_t vielleicht schlauer ist, ist mir jetzt> auch klar. Nur ist die Wahrscheinlichkeit, dass ich zu dieser Zeit genau> auf die selbe Idee gekomemen wäre schon ziemlich gering. Daher ist halt> int8 draus geworden. Ich sollte dies einmal ändern, ja, nur hatte ich> bis jetzt noch nie den Mumm dazu.
Ach was. Machs einfach. Ich hab nach 20 Jahren noch mal umgelernt.
Der springende Punkt ist:
Wenn du nur für dich im eigenen Keller arbeitest, ist es piep-
schnurz-egal. In dem Moment, in dem aber die Welt da draussen
auf der Bildfläche auftaucht, kann es nur von Vorteil sein,
wenn eine gemeinsame Sprache gesprochen wird. Dadurch ist
gewährleistet, dass alle dasselbe meinen wenn ein bestimmter
Begriff fällt.
>> Dann noch was zu PA7.> Ob ich jetzt "sbi(DDRA,PA7);" oder "sbi(DDRA,7)" schreibe spielt für> mich vom Verständnis der Source eigentlich keine Rolle. Daher nehme ich> das Zweite, weil es kürzer ist.
Du sollst sbi überhaupt nicht mehr verwenden.
DDRA |= ( 1 << PA7 );
Kürzer ist nicht unbedingt besser.
>>>Das soll sie auch sein. Dich (und vor allem MICH) interessiert nicht WIE>>eine Funktion im Inneren aufgebaut ist, sondern wie ich sie nutzen kann.> Das stimmt bezogen auf mich zumindest am Anfang nicht. Ich hatte das> Datenblatt, dort stand in Worten drinn, wie die Hardware des AVRs zu> bedienen ist.
Ich bin beeindruckt. Ohne Scheiss. Endlich mal jemand der
sich das Datenblatt reinzieht.
> Ich war nun einfach neugierig zu sehen, wie man dies> Implementieren kann.
Dagegen ist auch nichts einzuwenden.
> Ich habe einen USART Treiber, eine sehr> ausführliche I2C Bibliotheck (mit Fifo-Buffern beim Senden und Empfagen> für alle 4 Modis geschrieben) eine eigene Library für LCD-Display.
Moment.
Das ist schon eine ganz andere Kategorie.
Sozusagen ein ganz anderer Level auf dem eine Library
aufsetzt.
Die Library um die es geht (die Zugriffe auf das Flash
ermöglicht) ist Bestandteil vom WinAVR. Das heist: die kriegst
du, weil du WinAVR benutzt. Die ist also automatisch Bestandteil
deines Werkzeugkastens.
Es gibt absolut keinen Grund die nicht zu benutzen.
Da mal reinzuschauen, wie es gemacht wird, ist ok.
Das heist aber nicht, das es schlau ist, danach nicht einfach
"Aha, so machen die das" zu sagen, das File zuzumachen, im
Code ganz einfach den include zu machen und die angebotene
Funktionalität zu benutzen.
> Klar> wäre ich schneller gewesen, wenn ich einfach eine fertige Library> verwendet hätte, doch dann hätte ich nie so viel gelernt. Wenn du daran> intressiert bist den Drehbank bedienen zu lernen ist es unter umständen> schon sinnvoll eine M4-Schraube selber herzustellen.
Nicht wirklich.
Wenn du mit einer Drehbank umgehen lernen willst, dann machst
du ein Lot, oder sonst irgendeinen Teil, den du später auch
gebrauchen kannst. Eine normale M4-Schraube machst du damit nicht,
die holst du dir aus dem Magazin.
In gleicher Manier ist es sinnlos, in einem C-Programm eigene
Assembler inline Funktionen für eine 16-Bit Addition zu schreiben,
sondern du benutzt die, die der Compiler sowieso mitbringt. In
gleicher Weise ist es sinnlos eigene Funktionen zum Flash auslesen
zu schreiben. Mit deinem Compiler hst du welche mitbekommen,
die perfekt funktionieren und die du nur einsetzen musst.
Der Sinn dieser mitgelieferten Funktionen ist es ja gerade,
dass du dich nicht um die Details kümmern musst. Du benutzt
sie einfach.
> Hey, ich> programmiere diese Kontroller als Hobby und nicht weil ich möglichst> effizient etwas erreichen möchte.
Darum geht es nicht.
nur weil er kein Assembler lernen möchte, sollte doch über noch mal
drüber nachdenken :-)
Ich nehme da doch lieber C, mit der passenden libc. Egal, auf welchem
System.
Oliver
@Oliver
>Warum haben denn eigenlich alle solche Angst vor Assembler?
Ich nicht ;-)
>Wer so etwas (auch noch freiwillig) in C nachprogrammiert,>int>foo(void)>{> unsigned char bar = (__extension__({ uint16_t __addr16 = (uint16_t)>((uint16_t)((void *)42)); uint8_t __result; _asm_ ( "lpm" "\n\t" "mov %>0, r0"
"\n\t" : "=r" (__result) : "z" (__addr16) : "r0" ); __result; }));
> return bar;>}>nur weil er kein Assembler lernen möchte, sollte doch über noch mal>drüber nachdenken :-)
NIEMAND programmiert sowas in C, das ist ein aufgelöstes Macro, was man
praktisch nie zu Gesicht bekommt. Man schreibt lediglich
unsigned char bar = pgm_read_byte((void *)42);
MfG
Falk
P.s. Jaja, der Macroprogrammierer programmiert das, aber nur einmal.