Es ist bestimmt ganz einfach, aber ich habe erst mit C angefangen und komme nicht drauf: Wie kann ich den Inhalt des Sram auslesen und an der seriellen Schnittstelle ausgeben? Also angefangen an einer Startadresse jeweils 16 Byte lesen und als Hexzahl senden. Das Senden ist kein Problem, aber wie adressiere ich den Sram? In Asm hätte ich einfach XL,XH auf die Adresse gesetzt und dann mit LD r,X+ abgefragt. Aber in C? Und dazu noch: Kann ich den Compiler anweisen, (globale) Variablen im Sram auf bestimmte Adressen zu legen, so daß ich die Variablen in meinem Sram-Dump wiederfinde? Das GCC-Tut geht darauf leider auch nicht ein.
Ich würde es bspw. so machen:
1 | uint8_t *memory_pointer; |
2 | uint8_t inhalt_zum_senden; |
3 | |
4 | memory_pointer = start_adresse; // start_adresse als hexwert. |
5 | |
6 | inhalt_zum_senden = *memory_pointer; |
7 | // Naechste Adresse
|
8 | memory_pointer++; // Aber auch mit Distanzen, ist besser, da sich |
9 | // die Basisadresse des Pointers nicht ändert!
|
10 | // mit Distanz
|
11 | inhalt_zum_send = *memory_pointer + 1; // wobei die 1 auch eine variable |
12 | // sein kann
|
Timm T. schrieb: > Und dazu noch: Kann ich den Compiler anweisen, (globale) Variablen im > Sram auf bestimmte Adressen zu legen, so daß ich die Variablen in meinem > Sram-Dump wiederfinde? Du kannst einfach den Inhalt der Variablen, die Dich interessieren, über die serielle Schnittstelle versenden. Was genau versprichst Du Dir von einem kompletten SRAM-Dump? Wie Deine Frage schon nahelegt, würdest Du darin die für Dich relevanten Daten schwerer wiederfinden als wenn Du einfach nur die Werte ausgibst, die Dich wirklich interessieren. Abgesehen davon ist die Antwort auf Deine Frage abhängig von dem verwendeten Compiler bzw. Linker. Siehe auch: http://stackoverflow.com/questions/4067811/how-to-place-a-variable-at-a-given-absolute-address-in-memory-with-gcc
:
Bearbeitet durch User
Mark B. schrieb: > Du kannst einfach den Inhalt der Variablen, die Dich interessieren, über > die serielle Schnittstelle versenden. Mach ich doch schon. Für die Werte, die nach außen interessant sind. Mark B. schrieb: > Was genau versprichst Du Dir denn von einem kompletten SRAM-Dump? Interne Variablen zu prüfen, die normalerweise nicht nach außen gehen, ohne jedesmal extra ein serielles Write festzulegen. Zum Beispiel sollen eine Menge Parameter im Eeprom gespeichert und ins Sram übernommen werden, in Arrays. Übernommen deswegen, weil bei ungültigen Parametern stattdessen Standardwerte aus dem Flash verwendet werden sollen. Für die Kontrolle der korrekten Übernahme soll ein Dump des Eeprom und des Sram möglich sein. Codix schrieb: > Ich würde es bspw. so machen Ach ja, die Pointer. Damit stehe ich noch auf Kriegsfuß. Sorry, es ist ein ATmega32. Da müßte der Pointer ein uint_16 sein, um den gesamten Ram zu adressieren, oder?
Timm T. schrieb: > Sorry, es ist ein ATmega32. Da müßte der Pointer ein uint_16 sein, um > den gesamten Ram zu adressieren, oder? Ein Zeiger wird danach deklariert, worauf er zeigt. Wenn er also auf ein Byte im Speicher zeigen soll, wird er mit uint8_t* deklariert. Die Größe der Zeigervariablen selbst hängt vom Prozessor ab.
Mark B. schrieb: > Ein Zeiger wird danach deklariert, worauf er zeigt. Wenn er also auf ein > Byte im Speicher zeigen soll, wird er mit uint8_t* deklariert. Ähm, der Pointer bekommt die Adresse, an der ausgelesen werden soll. Ich hab das jetzt mal so zusammengeklöppelt:
1 | void send_mem_sram(uint16_t addr) { |
2 | uint8_t k; |
3 | uint16_t *memptr; |
4 | |
5 | serial_write(Cssram); // Frame Sram senden |
6 | serial_hex4(addr); // Start Adresse senden |
7 | |
8 | memptr = (uint16_t*)addr; |
9 | for (k = 0; k < 8; k++) { |
10 | serial_write(','); |
11 | serial_hex4(*memptr); // Sram Wert |
12 | memptr += 2; |
13 | }
|
14 | serial_write('\n'); |
15 | }
|
Timm T. schrieb: > Mark B. schrieb: >> Ein Zeiger wird danach deklariert, worauf er zeigt. Wenn er also auf ein >> Byte im Speicher zeigen soll, wird er mit uint8_t* deklariert. > > Ähm, der Pointer bekommt die Adresse, an der ausgelesen werden soll. Wenn Du ein Byte lesen willst, dann dereferenzierst Du einen Zeiger, der auf ein Byte zeigt. Nicht auf zwei Byte. Beispielcode am PC mit Ausgabe:
1 | #include <stdint.h> |
2 | #include <stdio.h> |
3 | |
4 | int main() |
5 | {
|
6 | uint8_t zu_lesender_bytewert = 0x6F; |
7 | |
8 | uint8_t * zeiger; |
9 | |
10 | zeiger = &zu_lesender_bytewert; |
11 | |
12 | printf("Preisfrage: Wie gross ist die Zeigervariable selbst? Antwort: %d Bytes\n", sizeof(zeiger)); |
13 | printf("Und nicht etwa 1 Byte.\n"); |
14 | |
15 | return 0; |
16 | }
|
1 | Preisfrage: Wie gross ist die Zeigervariable selbst? Antwort: 4 Bytes |
2 | Und nicht etwa 1 Byte. |
Wenn Du verstehen willst warum, dann mache Dir klar dass der Datenbus und der Adressbus unterschiedliche Breiten haben können.
Mark B. schrieb: > Wenn Du ein Byte lesen willst, dann dereferenzierst Du einen Zeiger, > der auf ein Byte zeigt. Ok, verstanden. Nun lese ich ein Word aus dem Sram und übergebe es an serial_hex4(), um es als $FFFF zu senden. Sollte also so stimmen. Oder gibts in meinem Codebeispiel Unstimmigkeiten? Irgendwas, wo ein erfahrener C-Programmierer sagt: Das macht man aber anders?
Timm T. schrieb: > Das macht man aber anders? Durchaus.
1 | memptr = (uint16_t*)addr; |
2 | for (k = 0; k < 8; k++) { |
3 | serial_write(','); |
4 | serial_hex4(*memptr); // Sram Wert |
5 | memptr += 2; |
6 | }
|
7 | serial_write('\n'); |
Wenn Du byteweise lesen willst, solltest Du auch Bytes lesen:
1 | memptr = (uint8_t *) addr; |
C inkrementiert oder dekrementiert Zeiger abhängig davon, worauf sie zeigen, "von alleine" richtig. Das
1 | memptr += 2; |
ist deshalb hier jedenfalls verkehrt (damit überspringst Du ein Wort). Wenn Du einen Zeiger auf ein 16 Bit-Wort um eins inkrementierst, zeigt er auf das nächste Wort, nicht auf das nächste Byte. Wenn Du einen Zeiger auf ein Byte (uint8_t *) um eins inkrementierst, zeit er auf das nächste Byte.
:
Bearbeitet durch User
@ Timm Thaler (timm-thaler) >Wie kann ich den Inhalt des Sram auslesen und an der seriellen >Schnittstelle ausgeben? Über einen Pointer, wie hier schon mehrfach beschrieben. >In Asm hätte ich einfach XL,XH auf die Adresse gesetzt und dann mit LD >r,X+ abgefragt. Aber in C? Nahezu identisch. >Und dazu noch: Kann ich den Compiler anweisen, (globale) Variablen im >Sram auf bestimmte Adressen zu legen, so daß ich die Variablen in meinem >Sram-Dump wiederfinde? Vergiss diesen Unsinn, sonst kannst du gleich bei ASM bleiben. In C verwaltet der Compiler die Adressen der Variablen, und das ist gut so. Wenn du wissen willst, welche Variable an welcher Adresse steht, schau ins .map File.
Markus F. schrieb: > Wenn Du byteweise lesen willst, solltest Du auch Bytes lesen: Nope, ich will ein Word übergeben. Funktioniert jetzt auch. Markus F. schrieb: > memptr += 2; > ist deshalb hier jedenfalls verkehrt (damit überspringst Du ein Wort). Das hab ich auch gemerkt. Zu schlau, der Compiler. Falk B. schrieb: > In C > verwaltet der Compiler die Adressen der Variablen, und das ist gut so. Ja, das fliegt mir nur gerade um die Ohren: Die Eeprom-Arrays werden auch nach Lust und Laune platziert, und wenn ich ein Array ändere oder Eeprom-Variablen zufüge, liegen die zuvor im Eeprom gespeicherten Daten am falschen Platz. Das muß besser gehen, ich will nicht jedesmal, wenn ich den Code neu compiliere befürchten müssen, daß meine ganzen Eeprom-Parameter im Eimer sind und ich das Ding neu parametrieren muß.
Tim, in der Regel gibt es ein Tx Buffer, bzw legt den so an: uint8_t byBuffTx [16]; Wo das im Ram liegt ist doch egal. Mit einer For Schleife sendet man das dann: uint8_t i; for (i=0; i <sizeof (byBuffTx); i++) { while (!Uart frei...){}; Uart Tx Register = byBuffTx [i]; }
:
Bearbeitet durch User
Häh? Was willst Du jetzt mit dem Buffer? Natürlich gibt es einen Buffer für die RS232, aber das ist nicht meine Frage. Das Problem Speicherzugriff ist ja auch gelöst, mir geht es noch darum, die Variablen im Eeprom festzupinnen, damit sie immer an der gleichen Stelle stehen. Allerdings habe ich im Forum schon gesehen, daß das wohl nicht ohne größere Klimmzüge geht.
Du solltest dir überlegen, die Variablen, die Du da immer in der gleichen Reihenfolge (und am liebsten immer an der gleichen Adresse) vorfinden willst, in eine struct zu stecken. Dann wird der Compiler die für dich zusammenhalten und Du tust dir insgesamt leichter. Dann könntest Du - wenn's denn unbedingt sein muß (was ich aber nicht empfehlen würde), im Linkerscript einfacher dafür sorgen, daß die struct immer an der gleichen Stelle steht. Eleganter fände ich, die struct im ersten Wort mit einem eindeutigen Kenner zu versehen:
1 | struct globals |
2 | {
|
3 | const uint32_t marker; |
4 | const size_t size; |
5 | /* ab hier die nach außen interessanten Variablen */
|
6 | uint8_t var1; |
7 | uint8_t var2; |
8 | };
|
9 | |
10 | static struct globals my_vars = |
11 | {
|
12 | .marker = 0xaffeaffe, |
13 | .size = sizeof(struct globals), |
14 | .var1 = ... |
15 | };
|
und bei der Ausgabe das Datensegment nach diesem Kenner zu durchsuchen. Dann ist egal, wo die struct steht und Du mußt das Ding nie wieder anfassen, außer um neue Variablen einzubauen:
1 | uint8_t *addr = _data_start; |
2 | struct globals *glbls = NULL; |
3 | do
|
4 | {
|
5 | if ((uint32_t *)addr == 0xaffeaffe) |
6 | {
|
7 | glbls = (struct globals *) addr; |
8 | if (glbls->size == sizeof(struct globals)) |
9 | break; |
10 | glbls = NULL; |
11 | }
|
12 | } while (addr++ != _data_end); |
13 | |
14 | if (glbls != NULL) |
15 | {
|
16 | ...
|
17 | }
|
Besonders effektiv ist das natürlich nicht (muß es aber wohl auch nicht), aber einigermaßen robust.
@ Timm Thaler (timm-thaler) >> In C >> verwaltet der Compiler die Adressen der Variablen, und das ist gut so. >Ja, das fliegt mir nur gerade um die Ohren: Die Eeprom-Arrays werden >auch nach Lust und Laune platziert, und wenn ich ein Array ändere oder >Eeprom-Variablen zufüge, liegen die zuvor im Eeprom gespeicherten Daten >am falschen Platz. Tja, bisher war davon auch keine Rede! Man sollte die Netiquette beherzigen und das eigentliche Problem ansprechen und nicht vermeintliche Lösungen. >Das muß besser gehen, ich will nicht jedesmal, wenn ich den Code neu >compiliere befürchten müssen, daß meine ganzen Eeprom-Parameter im Eimer >sind und ich das Ding neu parametrieren muß. Sicher. Man muss nur die richtige Frage stellen. Pack alle EEPROM Variablen in ein Struct, dort ist die Reihenfolge fest. Und da es nur eine "Variable" im EEPROM gibt, nämlich das Struct, liegt das immer an der gleichen Adresse, meist 0.
Und ändere dann nicht die Reihenfolge der Struktur und auch nicht die Datentypen von z.b. 8 > 16 Bit. Dann fliegt dir das auch um die Ohren. Ps: Für neue Fragen solltest du auch ein neuen Tread auf machen und nicht mich anmachen weil ich zum eigentlichen Thema geantwortet habe.
@ Markus Müller (mmvisual) >Und ändere dann nicht die Reihenfolge der Struktur und auch nicht die >Datentypen von z.b. 8 > 16 Bit. Dann fliegt dir das auch um die Ohren. Wem DAS nicht klar ist, der sollte besser mit Murmeln spielen!
Mark B. schrieb: > Preisfrage: Wie gross ist die Zeigervariable selbst? Antwort: 4 Bytes > Und nicht etwa 1 Byte. auf dem AVR sicher nicht ;-)
Falk B. schrieb: > Sicher. Man muss nur die richtige Frage stellen. Pack alle EEPROM > Variablen in ein Struct, dort ist die Reihenfolge fest. Und da es nur > eine "Variable" im EEPROM gibt, nämlich das Struct, liegt das immer an > der gleichen Adresse, meist 0. Evtl noch als "packed" deklarieren, damit kein sinnloses Padding eingebaut wird ...
Mampf F. schrieb: > Evtl noch als "packed" deklarieren, damit kein sinnloses Padding > eingebaut wird ... Auf AVRs ist bereits alles packed. Noch "packender" geht nicht ;-)
"packed" wirkt doch nur auf CPUs mit >8Bit. Trotzdem wird dem GCC ein Compilerschalter direkt mitgegeben, zumindest beim alten AVR-Studio 4.18. Warum?
Mit avr-gcc kannst du ganz einfach aufs SRAM zugreifen:
1 | #include <stdint.h> |
2 | |
3 | extern uint8_t __data_start[]; |
Wenn du das 3. Byte des SRAM willst, dann ist das __data_start[2]. Falls du in 16-Bit Happen lesen willst, dann:
1 | extern uint16_t __data_start[]; |
Das Symbol __data_start wird im Linker-Description-File definiert.
Falk B. schrieb: > "packed" wirkt doch nur auf CPUs mit >8Bit. Jepp. > Trotzdem wird dem GCC ein > Compilerschalter direkt mitgegeben, zumindest beim alten AVR-Studio > 4.18. Ja, sehe ich bei mir auch im AVR-Studio 4.18. Scheint tatsächlich Default beim Anlegen eines AVR-Projekts zu sein, denn ich habs da bestimmt nicht hinzugefügt. (Interessanter fand ich allerdings Deine uralte gcc-Version :-P ) > Warum? Vielleicht Dummheit? Solls auch bei Atmel geben.
:
Bearbeitet durch Moderator
@ Frank M. (ukw) Benutzerseite >(Interessanter fand ich allerdings Deine uralte gcc-Version :-P ) Das ist der letzte offizielle winavr, der direkt mit AVR-Studio zusammenspielt. Es gibt zwar eine Anleitung, den aktuellen avr gcc ins alte AVR-Studio einzuklinken, das hat aber beim 1. VErsuch nicht funktioniert, dann hab ich es gelassen. Für meine Zwecke ist auch der alte avr gcc ausreichend. Die neuen ATXmegas kann man so oder so nicht im 4.x AVR Studio programmieren. >> Warum? >Vielleicht Dummheit? Solls auch bei Atmel geben. Vorsicht mit solchen vorschnellen Anschuldigungen! Der GCC, das Grundgerüst des avr gcc, ist ein ausgewachsener Compiler, der für "richtige" CPUs mit 16/32 Bit gemacht ist. Es wäre möglich, daß der ohne den -packed Compilerschalter IMMER von 16 Bit Alignment ausgeht, auch auf 8 Bit Maschinen. Schließlich macht er auch Integer-Promotion auf 16 Bit Ints, auch wenn das manchmal nicht nötig ist.
Mampf F. schrieb: > Mark B. schrieb: >> Preisfrage: Wie gross ist die Zeigervariable selbst? Antwort: 4 Bytes >> Und nicht etwa 1 Byte. > > auf dem AVR sicher nicht ;-) Deswegen steht ja auch "Beispielcode am PC" dabei :-)
:
Bearbeitet durch User
Falk B. schrieb: > Das ist der letzte offizielle winavr, der direkt mit AVR-Studio > zusammenspielt. Weiß ich. Hatte ich auch mal drauf. Aber es spielt auch jeder neuere avr-gcc mit AVR-Studio zusammen, s.u. > Es gibt zwar eine Anleitung, den aktuellen avr gcc ins > alte AVR-Studio einzuklinken, das hat aber beim 1. VErsuch nicht > funktioniert, dann hab ich es gelassen. Man muss die Toolchain nur irgendwo in einem Pfad ohne Leerzeichen entpacken und dann einen einzigen Registry-Eintrag ändern und schon wird jeder neuere avr-gcc zum Standard-Compiler für AVR-Studio. Schau mal in mein Bild. Da ist "Use WinAVR" angehakt :-) Ich mag nämlich das alte AVR-Studio auch lieber. Läuft viel flotter als jede Version, die danach kam. > Vorsicht mit solchen vorschnellen Anschuldigungen! Der GCC, das > Grundgerüst des avr gcc, ist ein ausgewachsener Compiler, der für > "richtige" CPUs mit 16/32 Bit gemacht ist. Ja, aber der avr-gcc ist NICHT direkt von Atmel. Jedoch die Default-Settings im AVR-Studio ;-) Ich kenne gcc seit Ende der Achtziger, habe ihn damals selbst für einige UNIX-68k-Derivate portiert. Du musst also nicht denken, dass ich hier das Blaue vom Himmel erzähle. > Es wäre möglich, daß der ohne > den -packed Compilerschalter IMMER von 16 Bit Alignment ausgeht, auch > auf 8 Bit Maschinen. Schließlich macht er auch Integer-Promotion auf 16 > Bit Ints, auch wenn das manchmal nicht nötig ist. Nein, es ist definitiv so: Bei ATmega/ATtiny ist alles packed. Kann Dir Johann auch so bestätigen, er muss es ja wissen :-) P.S. Im Anhang der Registry-Patch für avr-gcc 4.7.2, den man von http://sourceforge.net/projects/mobilechessboar/files/avr-gcc%20snapshots%20%28Win32%29/ herunterladen kann. Ist für mich die derzeit stabilste Version. Soviel ich weiß, hat diese Johann höchstpersönlich dort abgelegt. Du kannst also der Software dort vertrauen.
:
Bearbeitet durch Moderator
@Frank M. (ukw) Benutzerseite >Man muss die Toolchain nur irgendwo in einem Pfad ohne Leerzeichen >entpacken und dann einen einzigen Registry-Eintrag ändern und schon wird >jeder neuere avr-gcc zum Standard-Compiler für AVR-Studio. Schau mal in >mein Bild. Da ist "Use WinAVR" angehakt :-) Ok, werd ich mal probieren. >Ich mag nämlich das alte AVR-Studio auch lieber. Läuft viel flotter als >jede Version, die danach kam. Eben. >Ich kenne gcc seit Ende der Achtziger, habe ihn damals selbst für einige >UNIX-68k-Derivate portiert. Du musst also nicht denken, dass ich hier >das Blaue vom Himmel erzähle. Ohh, ein Insider! >Nein, es ist definitiv so: Bei ATmega/ATtiny ist alles packed. Kann Dir >Johann auch so bestätigen, er muss es ja wissen :-) Das glaub ich dir schon. >P.S. >Im Anhang der Registry-Patch für avr-gcc 4.7.2, den man von > http://sourceforge.net/projects/mobilechessboar/fi... >herunterladen kann. Ist für mich die derzeit stabilste Version. Soviel >ich weiß, hat diese Johann höchstpersönlich dort abgelegt. Du kannst >also der Software dort vertrauen. Danke, werde ich demnächst mal machen.
Falk B. schrieb: > Ok, werd ich mal probieren. Das klappt schon. Allerdings fehlen in der Toolchain make & Co. Das ist aber kein Problem: Einfach nach dem Auspacken den Ordner utils aus Deinem alten WinAVR20100110-Ordner in den neuen avr-gcc-4.7.2-Ordner kopieren. Wenn ich es richtig in Erinnerung habe, arbeitet auch avr-size.exe in späteren Versionen nicht mehr so wie früher. Wenn das bei Dir auch der Fall sein sollte, kopiere dann: C:\WinAVR20100110\bin\avr-size.exe nach C:\avr-gcc-4.7.2\bin\avr-size.exe Dann sollte alles so "wie früher sein", nachdem Du die REG-Datei ausgeführt hast. Die müsstest Du aber vielleicht vorher noch bearbeiten, denn da steht bei mir als Pfad drin:
1 | "UninstallString"="C:\\WinAVR\\avr-gcc-4.7.2\\WinAVR-20100110-uninstall.exe" |
Hintergrund ist der, dass ich für jede avr-gcc-Version (4.3.3, 4.7.2, 4.8.1, 4.9.2) einen eigenen Unterordner unter C:\WinAVR habe - und natürlich für jede Compiler-Version eine eigene REG-Datei. So kann ich bequem zwischen den verschiedenen Compilern per Doppelklick auf die REG-Datei umschalten. ;-) Ist aber nur was für Spezialisten, die sich den erzeugten Code unter verschiedenen Versionen anschauen wollen. Ich habe mich mittlerweile komplett auf den 4.7.2 eingeschossen und schon lange nicht mehr gewechselt. 4.8.1 hat leider eine Macke, dass es fälschlicherweise Meldungen über falsch geschriebene ISR-Vektornamen ausgibt (das übrigens Johann damals höchstpersönlich "verbockt hatte ;-) ), 4.9.2 hat auch irgendeine andere blöde Eigenheit, kann sein, dass es mit/ohne(?) LTO schlechteren Code als 4.7.2 erzeugte... weiß ich nicht mehr so genau. 5.2.1 ist relativ frisch, damit habe ich mich noch nicht näher beschäftigt. Fazit: Mit der 4.7.2 machst Du nichts falsch. Also mit der auf Sourceforge: avr-gcc-4.7.2-mingw32.zip 2012-09-25 Da liegt nämlich überflüssigerweise auch noch ein Release-Candidate (rc1) älteren Datums rum. Wenn Du fertig bist, kannst Du Dich freuen, dass die Compilate Deiner bisherigen Projekte nachher alle viel viel kleiner sind :-) Wenn Du es noch ganz perfekt machen willst, kannst Du auch noch die Umgebungsvariable PATH über die Systemsteuerung an den neuen avr-gcc-Pfad anpassen, dann kannst Du den neuen avr-gcc auch in einer Windows-Eingabeaufforderung ohne weitere Pfad-Angabe starten. Da wird nämlich sonst noch der alte von 2010 genommen. Achja: Falls Du Dich wunderst, dass diese in der REG-Datei angegebene WinAVR-20100110-uninstall.exe ja gar nicht existiert: Muss sie auch nicht! Denn das Magische daran ist: AVRStudio sucht nach dem Programmstart nach genau diesem Uninstall-String in der Registry und wählt als Kriterium, wo es den avr-gcc usw. findet, den Pfad davor(!) aus! Ist das nicht krank? Aber es funktioniert perfekt. :-) P.S. Ich habe schon öfters überlegt, ob ich diese Anleitung nicht mal im Wiki als Artikel anlgen sollte. Habs aber nicht gemacht, weil ich dachte, dass so viele Leute nicht mehr mit dem alten AVR-Studio arbeiten. Vielleicht lohnt es sich doch?
:
Bearbeitet durch Moderator
Frank M. schrieb: > 5.2.1 ist relativ frisch, damit habe ich mich noch nicht näher > beschäftigt Ich habe es gerade mal runtergeladen und exakt nach meiner obigen Anleitung installert - klappt. Mal schnell ein paar Projekte durchgejagt und verglichen: ca. 3-4% an Code-Ersparnis gegenüber 4.7.2. Die 5.2.1 werde ich mir in den nächsten Tagen wohl doch mal näher anschauen... könnte evtl. mein neuer Favorit werden.
:
Bearbeitet durch Moderator
@ Frank M. (ukw) Benutzerseite >> Ok, werd ich mal probieren. >Das klappt schon. Allerdings fehlen in der Toolchain make & Co. >Das ist aber kein Problem: Einfach nach dem Auspacken den Ordner utils >aus Deinem alten WinAVR20100110-Ordner in den neuen avr-gcc-4.7.2-Ordner >kopieren. Hier fangen meine Fußnägel langsam an, sich aufzurollen 8-0 Die alten Utils mit dem neuen Compiler? Sowas schreit immer nach Problemen. Darum greife ich hier immer nur auf Komplettpakete zurück, die (hoffentlich) von Profis getestet sind. >Wenn ich es richtig in Erinnerung habe, arbeitet auch avr-size.exe in >späteren Versionen nicht mehr so wie früher. Wenn das bei Dir auch der >Fall sein sollte, kopiere dann: > C:\WinAVR20100110\bin\avr-size.exe >nach > C:\avr-gcc-4.7.2\bin\avr-size.exe >Dann sollte alles so "wie früher sein", nachdem Du die REG-Datei >ausgeführt hast. Die müsstest Du aber vielleicht vorher noch bearbeiten, >denn da steht bei mir als Pfad drin: GENAU DAS MEINE ICH! "UninstallString"="C:\\WinAVR\\avr-gcc-4.7.2\\WinAVR-20100110-uninstall. exe" >Ist aber nur was für Spezialisten, die sich den erzeugten Code unter >verschiedenen Versionen anschauen wollen. Eben. Und das bin ich nicht. Es gibt beim 2010er winAVR keine Funktionen, die ich wirklich vermisse. __flash und andere Spielrein sind entbehrlich. Alles neuere läuft bei mir im Atmelstudio 6.2 (die lahme Ente!) > Ich habe mich mittlerweile >komplett auf den 4.7.2 eingeschossen und schon lange nicht mehr >gewechselt. 4.8.1 hat leider eine Macke, dass es fälschlicherweise >Meldungen über falsch geschriebene ISR-Vektornamen ausgibt (das übrigens >Johann damals höchstpersönlich "verbockt hatte ;-) ), 4.9.2 hat auch >irgendeine andere blöde Eigenheit, kann sein, dass es mit/ohne(?) LTO >schlechteren Code als 4.7.2 erzeugte... weiß ich nicht mehr so genau. >5.2.1 ist relativ frisch, damit habe ich mich noch nicht näher >beschäftigt. Never change a running system ;-) >Fazit: Mit der 4.7.2 machst Du nichts falsch. OK. >Wenn Du fertig bist, kannst Du Dich freuen, dass die Compilate Deiner >bisherigen Projekte nachher alle viel viel kleiner sind :-) Ich bin nich Moby. >Wenn Du es noch ganz perfekt machen willst, kannst Du auch noch die >Umgebungsvariable PATH über die Systemsteuerung an den neuen >avr-gcc-Pfad anpassen, dann kannst Du den neuen avr-gcc auch in einer >Windows-Eingabeaufforderung ohne weitere Pfad-Angabe starten. Mach ich so oder so nie. Ich bin nur ein Normaluser. Trotzdem Danke für die Tips. >Denn das Magische daran ist: AVRStudio sucht nach dem Programmstart nach >genau diesem Uninstall-String in der Registry und wählt als Kriterium, >wo es den avr-gcc usw. findet, den Pfad davor(!) aus! AUA!!!! >Ich habe schon öfters überlegt, ob ich diese Anleitung nicht mal im Wiki >als Artikel anlgen sollte. Habs aber nicht gemacht, weil ich dachte, >dass so viele Leute nicht mehr mit dem alten AVR-Studio arbeiten. >Vielleicht lohnt es sich doch? Keine Ahnung, tendentiell eher nicht. Du hast ja schon mehrere Beiträge dazu verfaßt.
Falk B. schrieb: > Hier fangen meine Fußnägel langsam an, sich aufzurollen 8-0 > Die alten Utils mit dem neuen Compiler? Wenn sie bisher ihren Dienst taten, dann tun sie es auch mit neuem Compiler. make macht auch nix anderes als vorher und hat auf das Compiler-Ergebnis keinen Einfluss :-) > Keine Ahnung, tendentiell eher nicht. Du hast ja schon mehrere Beiträge > dazu verfaßt. Okay. Ich nehme auch an, dass das AVR-Studio 4.18 sowieso wegen neueren Windows-Versionen irgendwann ausstirbt. Oder läuft das noch unter Windows 8 oder 10?
Um noch einmnal zum eigentlichen Problem des TE zurück zu kommen: Er hat das Problem seine Variablen im EEPROM nicht wieder zu finden. :) Der Ansatz einen Struct zu verwenden ist das vernünftigste. Ich baue meine Software immer so auf: - alle Konfigurationsdaten in eine struct (Padding erst einmal egal, i.d.R. hat man genügend EEPROM-SPeicher) - int EEPROM_read(uint16 addr) und int EEPROM_write(uint16 addr)-Funktionen programmieren, welche die Struktur unter der Adresse addr abspeichern - EEPROM_read() und EEPROM_write() nutzen zum Feststellen der Dateninegrität zum Beispiel einen CRC16 und lesen bzw. schreiben in diesem Falle 2 Bytes mehr EEPROM_write() speichert, und man liest die Daten mit EEPROM_read() zurück. Der Rückgabewert von EEPROM_read() signalisiert dann, ob der CRC-Check erfolgreich war. War er es nicht, werden entsprechende Defaults geladen. Den SRAM-Dump braucht man dafür nicht. Mit ein wenig Nachdenken hätte man aber schon auf so eine Lösung kommen können, wenn man davon ausgeht, dass sämtliche E/A-Daten auch vollkommener Müll sein können. Viele Grüße! Sven
Johann L. schrieb: > Mit avr-gcc kannst du ganz einfach aufs SRAM zugreifen:#include > <stdint.h> > > extern uint8_t __data_start[]; > Wenn du das 3. Byte des SRAM willst, dann ist das __data_start[2]. > > Falls du in 16-Bit Happen lesen willst, dann:extern uint16_t > __data_start[]; > > Das Symbol __data_start wird im Linker-Description-File definiert. Da sollte der Linker aber meckern! Zwei oder mehr Symbole auf die gleiche Adresse? Oder gibt es keine anderen Variablen im RAM?
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.