Forum: Mikrocontroller und Digitale Elektronik AVR: Probleme mit Flash


von Henry (Gast)


Lesenswert?

Hallo,

ich habe hier zwei Funktionen:
1
void Fls_WritePage(uint16_t page, const uint8_t *buf)
2
{
3
  uint32_t addr = page * SPM_PAGESIZE;
4
5
  uint8_t sreg;
6
  // Disable interrupts.
7
  sreg = SREG;
8
  cli();
9
10
  // clear page
11
  eeprom_busy_wait ();
12
  boot_page_erase (addr);
13
  boot_spm_busy_wait (); // Wait until the memory is erased.
14
15
  for (uint16_t i=0; i<SPM_PAGESIZE; i+=2)
16
  {
17
    // Set up little-endian word.
18
    uint16_t w = *buf++;
19
    w += (*buf++) << 8;
20
    boot_page_fill (addr+i, w);
21
  }
22
23
  boot_page_write (page); // Store buffer in flash page.
24
  boot_spm_busy_wait(); // Wait until the memory is written.
25
  // Reenable RWW-section again. We need this if we want to jump back
26
  // to the application after bootloading.
27
  boot_rww_enable ();
28
  // Re-enable interrupts (if they were ever enabled).
29
  SREG = sreg;
30
}
31
32
void Fls_ReadPage(uint16_t page, uint8_t *buf)
33
{
34
  uint32_t addr = page * SPM_PAGESIZE;
35
36
  uint8_t sreg;
37
38
  // Disable interrupts.
39
  sreg = SREG;
40
  cli();
41
42
  for (uint16_t i=0; i<SPM_PAGESIZE; i+=2u)
43
  {
44
    uint16_t dataWord = pgm_read_word_far( addr+i );
45
46
    buf[0] = (uint8_t) dataWord;
47
    buf[1] = (uint8_t) (dataWord >> 8);
48
49
    buf += 2;
50
  }
51
52
  SREG = sreg;
53
}

Die erste sollte mir Daten in den Flash speichern, und zwar eine 
komplette Page auf einmal.
Die zweite liest eine komplette Page und schreibt sie in den Puffer.

Zum Testen schreibe ich:
1
uint8_t TEST_pbRead[256];
2
uint8_t TEST_pbWrite[256];
3
...
4
  for (uint16_t i=0; i<256; i++)
5
  {
6
    TEST_pbWrite[i] = i;
7
  }
8
...
9
...
10
Fls_WritePage(0, TEST_pbWrite);
11
...
12
...
13
Fls_ReadPage(0, TEST_pbRead);

Eigentlich einfach: ich fülle mir ein Array mit Daten, schreibe sie in 
Page 0.
Danach lese ich Page 0 in ein zweites Array.
Die Arrays gebe ich mir mittels UART später aus.

So, wo liegt also das Problem.
Grundsätzlich läuft das Ganze. Allerdings nur, wenn ich Page 0 
lese/schreibe.

Ändere ich den Code in Page 1,2,3 ... geht entweder das Lesen oder das 
Schreiben daneben.
Das Lesearray enthält dann nur lauter 0xFF, deswegen gehe ich davon aus 
dass aus einem jungfräulichen Flashbereich gelesen wird.

Passt evtl. was in der Adressenberechnung nicht?
Ich denke, alle Makros aus der avr-libc arbeiten mit Byteaddressen. Sagt 
zumindest die Doku.
Was mich eben irritiert ist dass es mit Page 0 klappt...
Jemand ne Idee?

Achja:
ATmega1284P, Code wird aus dem Bootloaderbereich ausgeführt.

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.