Forum: Compiler & IDEs Pointerproblem auf STM32


von Stefan (Gast)


Lesenswert?

Hallo,

ich habe mir eine Funktion geschrieben um etwas ins Flash zu schreiben:
1
typedef struct __attribute__((__packed__)) {
2
  uint8_t data[1024];
3
} cmd_flash_sector_t;
4
5
void writeflash(uint32_t address, void *data, int len) {
6
  uint32_t *temp = (uint32_t*) data;
7
8
  for (int i =0; i<len; i+=4) {
9
    FLASH_ProgramWord(address + i, *temp);
10
    temp++;
11
  }
12
}
13
14
writeflash(pageadr, cmd_flash_sector->data, 1024);


Aber es wird nichts in Flash geschrieben; Folgendes hat hingegen 
funktioniert:
1
uint32_t val;
2
for (i=0; i<1024; i+=4) {
3
  val = cmd_flash_sector->data[i];
4
  val |= cmd_flash_sector->data[i + 1] << 8;
5
  val |= cmd_flash_sector->data[i + 2] << 16;
6
  val |= cmd_flash_sector->data[i + 3] << 24;
7
  FLASH_ProgramWord(pageadr + i, val);
8
      }

Sieht jemand das Problem? Lock/Unlock habe ich natürlich jeweils vorher 
und nachher gemacht...

von Eric (Gast)


Lesenswert?

Mir fällt da auf dem ersten Block nichts auf. Es könnte ein 
Timing-Problem sein (zu schneller Zugriff aufs Flash) oder das Problem 
liegt in dem Teil der Code, den du hier nicht zeigst.

von Stefan (Gast)


Lesenswert?

Es muss ein Pointerproblem oder dergleichen sein; wenn ich im ersten 
Beispiel folgendes verwende:
1
FLASH_ProgramWord(address + i, 0x12345678);

kommen die Daten auch ins Flash.

von Flaschlöscher (Gast)


Lesenswert?

Flash muss vor dem Schreiben gelöscht werden.
Ich seh nix davon.

von Stefan (Gast)


Lesenswert?

>Flash muss vor dem Schreiben gelöscht werden.
Obligatorisch. Mache ich, das 2. Beispiel funktionert auch...

von Arne S. (Gast)


Lesenswert?

das  __attribute__((_packed_)) erscheint mir überflüssig. Wo sollen in 
einem array of uint8_t padding-bytes auftreten?
Ich hab vor sechs Jahren für die Firma ein eigenes BSP geschrieben für 
IAR EWARM. Damals musste ich für die Release-Version (Volle Optimierung 
auf size) einige Funktionen des Flashtreibers mit #pragma optimze=none 
klammern.

Edit:
kann sein, dass ich mich irre, aber gilt das Unlocken für beliebig viele 
Takte oder lockt der STM32 nach n-Takten wieder automatisch? Da gibts 
eine eigenes Flashmanual von ST - der Flashkram steht nicht im RM0008 
(für STM32F103).

von Stefan (Gast)


Lesenswert?

> Wo sollen in einem array of uint8_t padding-bytes auftreten?

Da sind noch einige uint8_t Member in der Struktur, die habe ich 
vorrübergehend raus um nicht vom wesentlichen abzulenken...

von Lötkolben (Gast)


Lesenswert?

Die Speicherausrichtung stimmt nicht.
Ein 32-Bit-Zeiger muss auf 32 Bit ausgerichtet (aligned) sein, somit ist 
eine Zuweisung von einem 8-Bit-Zeiger auf einen 32-Bit-Zeiger in 3 von 4 
Fällen falsch.
Einige Architekturen unterstützen das Zugreifen auf unausgerichtete
Speicherwörter z.B. x86, ARM tut dies nicht.

Mit diesem Attribut
1
typedef struct __attribute__((__packed__,aligned(4))) {
2
  uint8_t data[1024];
3
} cmd_flash_sector_t;

kann der Fehler behoben werden, sauberer ist jedoch die zweite Variante,
bei der auch endian-unabängig geschrieben wird.

von (prx) A. K. (prx)


Lesenswert?

Lötkolben schrieb:
> Einige Architekturen unterstützen das Zugreifen auf unausgerichtete
> Speicherwörter z.B. x86, ARM tut dies nicht.

Manche ARMs können es (Cortex M3), manche nicht (Cortex M0).

von Stefan (Gast)


Lesenswert?

Es ist ein M0 :-(

Vielen Dank! Verstanden und sehr geholfen, und zwar nachhaltig!

Stefan

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.