Forum: Mikrocontroller und Digitale Elektronik Wie den Inhalt von bestimmter Adresse lesen?


von Systroup (Gast)


Lesenswert?

Moin!

Ich möchte von einem Freescale DSP56F8025 aus dem Ram und/oder Flash von 
einer bestimmten Adresse den Inhalt lesen. Das ganze soll zum Debuggen 
sein und im Betrieb ermöglichen, Fehlercodes, die an definierten 
Adressen gespeichert werden, auszulesen. Entwicklungsumgebung ist der 
Metroworks Codewarrior 8.22 und natürlich in C.
Bislang hatte ich gedacht dass ich mit

us_Wert = * (unsigned short*) us_Adresse;

dahin käme. Leider ist der Kompiler anderer Meinung.
Ich hab das ganze mal etwas entzerrt und folgendes gemacht:

unsigned short us_Wert;
unsigned short us_Adresse;
unsigned short *pus_Pointer;

...
us_Adresse wird ein Wert über Kommunikation mitgeteilt.
...

pus_Pointer = (unsigned short *) us_Adresse;
us_Wert = *pus_Pointer;

Das hat zur folge, dass im Debugger der Pointer auf die Gewünschte 
Adresse zeigt. Aber die Übergabe des Inhalts an us_Wert funktioniert 
nicht. Stattdessen wird die Adresse übergeben.

Hat jemand eine Idee wie ich entweder den Codewarrior dazu kriege den 
Wert zu nehmen oder eine andere Idee, wie man den Inhalt einer gegebenen 
Adresse ausliest?

Mit freundlichen Grüßen, Systroup

von Karl H. (kbuchegg)


Lesenswert?

Systroup wrote:

> Bislang hatte ich gedacht dass ich mit
>
> us_Wert = * (unsigned short*) us_Adresse;
>
> dahin käme. Leider ist der Kompiler anderer Meinung.

Nämlich welcher?

> Hat jemand eine Idee wie ich entweder den Codewarrior dazu kriege den
> Wert zu nehmen oder eine andere Idee, wie man den Inhalt einer gegebenen
> Adresse ausliest?

Zeig mal ein komplettes Beispiel.

von eProfi (Gast)


Lesenswert?

Wenn ich mich recht erinnere:

Es gibt die Macros memWrite, memRead, IOmemWrite, IOmemRead, die habe 
ich analysiert, um dahinter zu kommen.

Beitrag "Adresse von Variabel festlegen"

Klammerung ist wichtig.

Du kannst die Variable aber auch im linker.cmd explizit festlegen. Dort 
ist z.B. der Beginn der IO-Registerblöcke definiert.

von Alexander I. (daedalus)


Lesenswert?

Inwiefern ist der Compiler denn "anderer Meinung"? Ich kenne den 
Controller zwar nicht, aber in der reinen C-Denkweise sollte das schon 
so klappen, zumindest für den RAM-Zugriff. Für's Flash bzw. EEPROM 
(sofern vorhanden) würde ich mal das Handbuch nach etwaigen Intrinsics, 
Macros und Pragmas befragen.

Bei dem Controller dürfte "unsigned short" 16-bittig sein. Evtl. 
Alignment-Problem?

von Systroup (Gast)


Lesenswert?

Mhm, da hab ich mich schlecht ausgedrückt. Der Kompiler meckert nicht, 
aber der Fehler ist wie schon beschrieben. Das heisst, statt des Inhalts 
bekomme ich die Adresse zurückgegeben.

Das obige Konstrukt habe ich schonmal erfolgreich auf einem NEC 
eingesetzt.

Festlegungen im Linker scheiden hier aus, da völlig verschiedene 
Speicherbereiche ausgelesen werden sollen. Auch mit der Möglichkeit, den 
kompletten Speicher auszulesen.

Der Controller ist ein 16 Bitter, und auf das Alignment wurde schon 
geachtet.

MfG, Systroup

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Harvard oder von Neumann?

von eProfi (Gast)


Lesenswert?

Rufus: Daten (X) und Programm (P) getrennt


So geht es auf jeden Fall bei mir (direkt, d.h. ohne eigenen Pointer):
  static UWord16 Speicherinhalt,testAdr = 0x1234;
  Speicherinhalt = *(UWord16*)testAdr;

wird übersetzt in
  move    X:FtestAdr$4,R0
  nop
  move    X:(R0),X0
  move    X0,X:FSpeicherinhalt

...

FtestAdr$4    DC    4660


Wie übersetzt er bei Dir?

von Mario G. (suicided)


Lesenswert?

Hallo Forum!

Wenn es gestattet ist, häng ich mich hier mal mit ran - hänge auch 
gerade an diesem Problem.
Bei mir handelt es sich um einen 8051 mit dem IAR Compiler. Ich versuche 
die SFRs (0x80 bis 0xFF) auszulesen und in einen Puffer zu schreiben. 
Hier der dazugehörige Code:
1
  j=0x80;
2
  do {
3
    bufferSPI[j-0x80] = (*((volatile char *) j));
4
  } while (++j);

Mach ich das so, steht danach irgendwelcher Murks im Puffer - jedenfalls 
nicht die SFR-Werte.
1
  j=0x80;
2
  do {
3
    asm("MOV R0,#temp");
4
    asm("MOV @R0,j   ");
5
    bufferSPI[j-0x80] = temp;
6
  } while (++j);

Das ist die originale Schreibweise des IAR-Compilers beim Auslesen eines 
SFRs - also die beiden Assembler Zeilen. Nur steht statt "#temp" die 
Adresse von temp und statt "j" der Name des SFRs bzw. dessen Adresse.
Mir scheint es so, als gäbe es ein Problem mit "j", denn selbt das 
funktioniert nicht:
1
  j=0xF4;
2
  asm("MOV R0,#temp");
3
  asm("MOV @R0,j   ");

Ich muss zugeben, dass ich nicht sondelich bewandert bin, was solche 
Dinge angeht. Sieht vielleicht jemand von euch meinen Fehler?


Viele Grüße
mario

von skua (Gast)


Lesenswert?

Die SFR kann man LEIDER nicht indirekt adressieren.

von Mario G. (suicided)


Lesenswert?

Ach ja... da war ja was. Das heißt also, dass ich jedes SFR einzeln 
lesen muss - oder? Das wäre ganz schön umständlich, wenn ich das mal so 
sagen darf.

Danke erstmal!

von Route_66 (Gast)


Lesenswert?

Hallo!
Ja, beim 8051 werden die SFR's direkt addressiert, weil auf den gleichen 
internen Speicherplätzen (0x80..0xFF) RAM liegt. Dieser kann NUR 
indirekt adressiert werden (also so, wie Du es machst).

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
Noch kein Account? Hier anmelden.