Forum: Mikrocontroller und Digitale Elektronik Pointer auf Hardwareadresse in Mikrocontroller


von Visitor (Gast)


Lesenswert?

Hi Leuts,
ich glaub ich stell mich grad doof an bei der Zeigerarithmetik.
Folgendes ich möchte in eine bestimmte Adresse im Mikrocontroller einen 
Wert reinschreiben und wieder auslesen.

Bisheriger Ansatz(in etwa):
(die Variablentypen UINT8 usw sind extern festgelegt)

#define ADRESS 0x00801000





//Ansatz 1:
/*Reinschreiben*/
 UINT8 *pTest1 = (UINT8*)ADRESS;
 *pTest1=0xFF;

//Ansatz 2:
/*Reinschreiben*/
volatile UINT8 u8test;
u8test= *(volatile UINT32*)(BTLDR_APPL_VERSION_POS);
u8test=0x11;

//Ansatz 1
//Auslesen
//In Wert sollte nun 0xFF
Wert=(UINT8)(*pTest);

//Ansatz 2
//Auslesen
Wert=(UINT8)(u8Test);

Bei allen Ansätzen hab ich nachher in Wert irgendwas anderes drin stehn.
Ich denke über mehrere Fehlerquellen nach.
- irgendwo Fehler in der Zuweisung der Pointer
- da bei mir mehrer C-Code sources evt dort der Fehler
- Fehler in der Größe der Zugewiesenen Variablen

Ich weis nicht warum aber irgendwie stell ich mich grad doof an... .
Über eure Hilfe wäre ich sehr dankbar.

Danke schonmal!

Grüße
Visistor

von Thomas K. (rlyeh_drifter) Benutzerseite


Lesenswert?

ADRESS ist leider >8bit, woher? Architektur?

von Visitor (Gast)


Lesenswert?

Jo also es geht um STM32.
Und was ich machen will ist an die Adresse in ADDRESS einen Wert mit 8 
Bit zu schreiben. Sorry das ich das nicht gleich explizit geschrieben 
hab.
Danke.

von Thomas K. (rlyeh_drifter) Benutzerseite


Lesenswert?

Visitor schrieb:
> Und was ich machen will ist an die Adresse in ADDRESS einen Wert mit 8
> Bit zu schreiben. Sorry das ich das nicht gleich explizit geschrieben
> hab.

Ok, schnapp dir nochmal ein C-Buch:

Deine Daten haben 8 bit Breite.
1
*pTest1=0xFF;
passt also, der "Wert" deiner Adresse hat jedoch 32bit, weshalb
1
UINT8 *pTest1 = (UINT8*)ADRESS;
nicht passt.

von Floh (Gast)


Lesenswert?

Visitor schrieb:
> #define ADRESS 0x00801000

ähm, wieviel RAM hat dein uC?

von Peter D. (peda)


Lesenswert?

1
  *(uint8_t *)0x1234 = 0xAB;
2
3
  PORTB = *(uint8_t *)0x1235;


Peter

von Oliver (Gast)


Lesenswert?

Thomas Klima schrieb:
> der "Wert" deiner Adresse hat jedoch 32bit, weshalb
>UINT8 *pTest1 = (UINT8*)ADRESS;
>
> nicht passt.

Wieviel bit sollte ""Wert" deiner Adresse" denn deiner Meinung nach 
haben?
Und gleich die 50-Euro-Frage hinterher: Wofür steht die 32 in STM32?

Oliver

von Peter II (Gast)


Lesenswert?

Oliver schrieb:
> Thomas Klima schrieb:
>> der "Wert" deiner Adresse hat jedoch 32bit, weshalb
>>UINT8 *pTest1 = (UINT8*)ADRESS;
>> nicht passt.

> Wieviel bit sollte ""Wert" deiner Adresse" denn deiner Meinung nach
> haben?
> Und gleich die 50-Euro-Frage hinterher: Wofür steht die 32 in STM32?
> Oliver

sicher das das nicht passt.
Denn ein (UINT8*) ist gleich gross wie ein (UINT32*) es sind beiden 
zeiger und ein Zeiger ist doch durch die Platform definiert. Die größe 
worauf er zeigt spielt doch an dieser stelle keine rolle.

Ich denke ist ist so richtig

von Arne (Gast)


Lesenswert?

Ich hab mir zwei Makros gebastelt (Peek & Poke)
1
#define IOREAD(ADDR,SIZE)  (*(volatile uint ## SIZE *)(ADDR))
2
#define IOWRITE(ADDR,SIZE,DATA) (*((volatile uint ## SIZE *)(ADDR)) = (DATA))

Musst nur das uint an Deine Typbezeichnung anpassen. Läuft so u.a. auch 
auf STM32 hier.

von Oliver (Gast)


Lesenswert?

Direkter Zugriff mit volatile:
>(*(volatile uint8_t *)(ADRESS)) = 0xFF;

oder

>volatile uint8_t *pwert = (volatile uint8_t *)(ADRESS );
>*pwert = 0xFF;

Voraussetzung ist natürlich, das es an der Adresse 0x00801000 überhaupt 
auf diese Art beschreibbares Ram gibt.

Oliver

von Visitor (Gast)


Lesenswert?

Danke schonmal an alle die sich gemeldet haben.

Die Version von Peter Danneger is auch so etwa was ich mir vorgestellt 
hab. Und ich hab mir das auch so gedacht wie Peter2, das es so trotzdem 
passen müsste.

Aus Dannegers Version hab ich soweit das hier gemacht.

// Zuweisung der 32 bit Adresse auf die Variable Test

  UINT8 Test=*(UINT8 *)ADDRESS;

//Schreiben des 8 bit Wertes an die Position der 32 Bit Adresse. Egal ob 
//dort die größe 32 Bit wären müsste es die 8 Bit rein schreiben
//also wenn der Adressbereich nur 32 adressierbar ist müsste er bei der 
//folgenden Zuweisung 0x000000FF reinschreiben aber macht es nicht
  Test=0xFF;

(ich hoffe das stimmt so)

Das Problem liegt nun vermutlich im Mikrocontrollerbereich. Irgendwie 
steht nach dem reinschreiben nichts drin.

Deswegen war meine andere ursprüngliche Variante auch mit static und 
volatile versuchen geschmückt. Hat wer ne Idee?

Bin über Vorschläge dankbar.

Gruß

von Visitor (Gast)


Lesenswert?

Ah es gibt 2 neue Beiträge das muss ich erst ausprobieren.
Danke

von Thomas K. (rlyeh_drifter) Benutzerseite


Lesenswert?

Oliver schrieb:
> Wieviel bit sollte ""Wert" deiner Adresse" denn deiner Meinung nach
> haben?

Ja, "Wert" ist natürlich flapsig formuliert (Wert der Pointervariable 
hätte auch besser getroffen), meiner Erfahrung nach begreifen Anfänger 
das jedoch so leichter.

von Stefan E. (sternst)


Lesenswert?

Thomas Klima schrieb:
> Ja, "Wert" ist natürlich flapsig formuliert (Wert der Pointervariable
> hätte auch besser getroffen), meiner Erfahrung nach begreifen Anfänger
> das jedoch so leichter.

Nein, der Punkt (und was Oliver sagen wollte) ist, dass du schlicht 
Unsinn geschrieben hast. Die Größe des Pointers und dessen, worauf er 
zeigt, haben rein gar nichts miteinander zu tun.

von Visitor (Gast)


Angehängte Dateien:

Lesenswert?

Hi Leuts,
ich hab euch mal das Memory Mapping von dem MCU angehängt.

also ich Versuche in den Flash zu schreiben und aus dem Flash zu lesen.
Denke also die Adresse 0x0800 1000 sollte verwendbar sein oder?

#define ADDRESS = 0x0801 0000 (32 Bit Adresse)

das ist hier nur ein Beispiel aber man sollte schon in den Flash 
schreiben könnt und daraus lesen oder irre ich mich da?

Gruß

von Peter D. (peda)


Lesenswert?

Visitor schrieb:
> also ich Versuche in den Flash zu schreiben und aus dem Flash zu lesen.

Das dürfte nicht gehen, ein Flash ist kein SRAM.

Um den Flash zu schreiben, muß man eine Page in den SRAM lesen, die Page 
löschen, das zu ändernde Byte ändern und dann die Page zurückschreiben.
Dazu gibt es spezielle Funktionen im Bootloader-API.


Peter

von Oliver J. (skriptkiddy)


Lesenswert?

Schau dir mal die AN2594[1] von ST an. Dabei handelt es sich um eine 
EEPROM-Emulation für den Flash. Das könnte eventuell das sein, was du 
brauchst.

[1] 
http://midibox.org/forums/topic/13969-stm32-on-chip-non-volatile-storage/

Gruß Skriptkiddy

von Arne (Gast)


Lesenswert?

Lesen geht logischerweise, aber zum Flashen musst Du natürlich erst die 
Page löschen usw. Schreiben ins Flash geht beim STM32 nur 16bit weise 
IIRC.
Bastel Dir doch einfach Makros - wie ich oben - zum Lesen/Schreiben ins 
RAM oder die I/O Register.

von Visitor (Gast)


Lesenswert?

ok lassen wir das Flash schreiben mal
würde es denn funktionieren so einen Wert in den SRAM zu schreiben?

uint8_t *pwert = (uint8_t *)(0x20000000);

*pwert = 0x00;

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

Visitor schrieb:
> also ich Versuche in den Flash zu schreiben und aus dem Flash zu lesen.
> Denke also die Adresse 0x0800 1000 sollte verwendbar sein oder?

Das Flash lässt sich nicht so einfach wie ein RAM beschreiben. Beim 
STM32 erfolgt dies gemäß der in der Anleitung PM0042 "STM32F10xxx Flash 
programming" beschriebenen Verfahren.

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.