Forum: Mikrocontroller und Digitale Elektronik [STM32] In den FLASH schreiben/lesen


von Prutheus (Gast)


Lesenswert?

Ich möchte in den Flash schreiben und anschließend prüfen, ob 
erfolgreich geschrieben wurde indem ich es wieder auslese:
1
  RCC->APB2ENR |= RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO;
2
  GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
3
  GPIOA->CRH = _BV(8) | _BV(9) | _BV(28) | _BV(29);
4
5
  FLASH_Status status = FLASH_COMPLETE;
6
  FLASH_Unlock();
7
  FLASH_ClearFlag(FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR | FLASH_FLAG_EOP);
8
  FLASH_ProgramWord((uint32_t)FLASH_ADDR, (uint32_t)0x11111111);
9
  FLASH_Lock();
10
11
  while(1) {
12
    uint16_t len = 0;
13
    int i = 0;
14
15
    // _gets((char*)&len, 2);
16
    // _printf("%d\r\n", len); // debug
17
18
    if(len == 0x4141) {
19
      FLASH_Unlock();
20
      status = FLASH_ProgramWord((uint32_t)FLASH_ADDR, (uint32_t)0x0);
21
      // _printf("%d\r\n", status);
22
      // while(status != FLASH_COMPLETE)
23
      //   status = FLASH_GetStatus();
24
      FLASH_Lock();
25
      // _printf("erase\r\n");
26
    } else {
27
      GPIOA->ODR ^= _BV(15);
28
      FLASH_Unlock();
29
      status = FLASH_ProgramWord((uint32_t)FLASH_ADDR, (uint32_t)0x11111111);
30
      // _printf("%d\r\n", status);
31
      // while(status != FLASH_COMPLETE)
32
      //   status = FLASH_GetStatus();
33
      FLASH_Lock();
34
      // _printf("write\r\n");
35
    }
36
37
    for(int n = 0; n < 5000000; n++) {}
38
39
    if(*(uint32_t*)FLASH_ADDR == (uint32_t)0x11111111) {
40
      GPIOA->ODR &= ~_BV(10);
41
    } else {
42
      GPIOA->ODR |= _BV(10);
43
    }
44
  }

Allerdings ist die LED PA10 immer an, es wurde also nicht korrekt 
geschrieben! Was habe ich falsch gemacht? Die anddresse in die ich 
versuche zu schreiben ist 0x08002400 .

von Arduinoquäler (Gast)


Lesenswert?

Prutheus schrieb:
> Die anddresse in die ich
> versuche zu schreiben ist 0x08002400 .

Und du meinst weil es nur einen STM32 Controller gibt
brauchst du ihn nicht angeben?

Und du meinst die

"Wichtige Regeln - erst lesen, dann posten!"

gelten nicht für dich?

>>Formatierung (mehr Informationen...)
>>
>>    [c]C-Code[ /c]

von Sebastian K. (sek)


Lesenswert?

Dein sinnfreies Programm schreibt immer 0x11111111 an die Speicherstelle 
FLASH_ADDR. Und das gleich zweimal. GPIOA->ODR &= ~_BV(10) wird daher 
immer ausgeführt.
Ist die LED active low, würde dein Programm funktionieren.

Wenn nicht, dann schau dir nach dem Schreibvorgang doch mal die 
Statusflags im FLASH_SR Register an und/oder prüfe im Memory-Fenster des 
Debuggers die Speicheradresse auf Veränderung.

von STM Apprentice (Gast)


Lesenswert?

Prutheus schrieb:
> Ich möchte in den Flash schreiben und anschließend prüfen, ob
> erfolgreich geschrieben wurde indem ich es wieder auslese:

Also ich würde nach STM's Flash Programming Manual vorgehen.

Aber das wäre zu einfach ... da müsste man nur suchen ...
und downloaden ... ach so, lesen und verstehen müsste man es
auch noch ... und zuletzt auch noch umsetzen. Zuviel verlangt.

Ich kann jedenfals nach den hier angebotenen Code-Fragmenten
keine Parallelen zum Manual erkennen.

von Prutheus (Gast)


Lesenswert?

Sebastian, wenn ich dann prüfe ob dort 0x11111111 steht, dann leuchtet 
sie, gut, active low, stimmt, aber wenn ich auf 0, 0x01010101 oder sonst 
was prüfe, dann leuchtet sie auch!?

von Prutheus (Gast)


Lesenswert?

STM Apprentice schrieb:
> Prutheus schrieb:
>> Ich möchte in den Flash schreiben und anschließend prüfen, ob
>> erfolgreich geschrieben wurde indem ich es wieder auslese:
>
> Also ich würde nach STM's Flash Programming Manual vorgehen.
>
> Aber das wäre zu einfach ... da müsste man nur suchen ...
> und downloaden ... ach so, lesen und verstehen müsste man es
> auch noch ... und zuletzt auch noch umsetzen. Zuviel verlangt.
>
> Ich kann jedenfals nach den hier angebotenen Code-Fragmenten
> keine Parallelen zum Manual erkennen.

Dann sag mir was fehlt, ich habe mit vielen Beispielen abgeglichen, und 
mich dann entschieden, die STDPeriph-Funktionen zu nutzen, ich sehe hier 
nicht was fehlt.
Ich suche hier Hilfe und keine dummen Kommentare.

von STM Apprentice (Gast)


Lesenswert?

Prutheus schrieb:
> ich sehe hier nicht was fehlt.

Die Kentnisse die man gewinnt wenn man das Flash Programming Manual
liest.

von STM Apprentice (Gast)


Lesenswert?

Prutheus schrieb:
> Ich suche hier Hilfe und keine dummen Kommentare.

Ich suche hier logische Vorgehensweise und keine dummen Ansätze.

von Prutheus (Gast)


Lesenswert?

STM Apprentice schrieb:
> Prutheus schrieb:
>> Ich suche hier Hilfe und keine dummen Kommentare.
>
> Ich suche hier logische Vorgehensweise und keine dummen Ansätze.

Ich habe es eben nochmals gelesen, ich unlocke den flash, schreibe rein 
und das wars. Wo habe ich was übersehen?

von STM Apprentice (Gast)


Angehängte Dateien:

Lesenswert?

Ohne Worte, mit Bild.

von Prutheus (Gast)


Lesenswert?

STM Apprentice schrieb:
> Ohne Worte, mit Bild.

Und was meinst du mache ich!?

von ♪Geist (Gast)


Lesenswert?

Wie es aussieht, löschst du vor dem Schreibvorgang nicht. Das geht beim 
Flasch natürlich nicht. Du musst den Pageinhalt sichern, die page 
löschen, Inhalt ändern und schreiben.
Schaue Mal auf meiner Webseite, da findest du ein funktionierendes 
Beispiel:
http://engsta.com/stm32-flash-memory-eeprom-emulator/

von Felix F. (wiesel8)


Lesenswert?

Ich stehe gerade vor einem ähnlichen Problem.
Ich möchte bei meinem STM32F4 das Flash als EEPROM verwenden. Habe mir 
dazu das Beispiel für die SPL heruntergeladen und eingebunden und auf 
meine Bedürfnisse angebunden:
8KB Page Size (2x8 = 16KB)
Adresse: 512 - 16 = 496KB
1
/* Define the size of the sectors to be used */
2
#define PAGE_SIZE               (uint32_t)0x2000  /* Page size = 8KByte */
3
4
/* EEPROM start address in Flash */
5
#define EEPROM_START_ADDRESS  ((uint32_t)0x0807C000) /* EEPROM emulation start address: 496 Kb */
6
7
/* Pages 0 and 1 base and end addresses */
8
#define PAGE0_BASE_ADDRESS    ((uint32_t)(EEPROM_START_ADDRESS + 0x0000))
9
#define PAGE0_END_ADDRESS     ((uint32_t)(EEPROM_START_ADDRESS + (PAGE_SIZE - 1)))
10
#define PAGE0_ID               FLASH_Sector_2
11
12
#define PAGE1_BASE_ADDRESS    ((uint32_t)(EEPROM_START_ADDRESS + PAGE_SIZE))
13
#define PAGE1_END_ADDRESS     ((uint32_t)(EEPROM_START_ADDRESS + (2 * PAGE_SIZE - 1)))
14
#define PAGE1_ID               FLASH_Sector_3

Leider verstehe ich nicht ganz, wie ich nun ein Byte an Adresse XY 
lesen/schreiben kann?
Im enthaltenen Beispielcode wird einfach ein Array mit 3 Words und den 
Adressen 0x5555, 0x6666 und 0x7777 angelegt und dann jeweils ein paar 
Hundert mal auf eine der Adressen geschrieben. Kann mir das jemand 
erklären?

mfg

von Micha (Gast)


Lesenswert?

♪Geist schrieb:
> Schaue Mal auf meiner Webseite, da findest du ein funktionierendes
> Beispiel:
> http://engsta.com/stm32-flash-memory-eeprom-emulator/

Und hier 
https://github.com/pikim/HIDIRT-STM32x1xx/blob/master/src/application.c 
das Ganze für die HAL-Lib.

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.