AVR231: AES Bootloader Frage zu "TYPE_PREPARE" Record

OP #7653904
Lesenswert?
• ▲
▼

Hallo,

in der loader.c gibt es eine Stelle, die ich nicht verstehe:

1
address = (const unsigned char __memx *)((unsigned long)bits << 16);
2
address = (const unsigned char __memx *)((unsigned long)address | ((unsigned long)*p++ << 8));
3
address = (const unsigned char __memx *)((unsigned long)address | *p++);
4
[...]
5
// Prepare for incoming data chunks by copying the page
6
// contents into the page buffer
7
case TYPE_PREPARE:
8
            {
9
              unsigned char *q = pageBuffer;
10
              const unsigned char __memx *r = address;
11

12
              do
13
              {
14
                *q++ = *r++;
15
              }
16
              while (--size);
17
              break;
18
            }

In der Appnote nennt sich das "FLASH PAGE PREPARE"

So wie ich das verstehe, wird der Flash in den RAM geladen. Wofür braucht man das bei einem Bootloader?

(Firma: 1984now) #7654376
Lesenswert?
• ▲
▼

Tycho B. schrieb:

So wie ich das verstehe, wird der Flash in den RAM geladen.

Nein. Da wird RAM-Inhalt (ggf. auch aus externem RAM) in den page buffer geladen. Letzteres ist zwar sicher auch irgendwie RAM, aber nicht direkt im RAM-Adress-Space erreichbar. Er muss über ein spezielles Verfahren beschrieben werden.

Allerdings gibt es einen solchen page buffer nicht bei jedem AVR8. ES gibt ihn bei den "Classic"-Tinys und -Megas, aber nur bei ganz wenigen (oder sogar nur einer?) der neuen Baureihen. Die eine, von der mir das sicher bekannt ist, ist AVRxxEAyy.

Für weitere Details darfst du gerne auch selber die Datenblätter lesen. Das hat noch niemandem ernsthaft geschadet...

OP #7655755
Lesenswert?
• ▲
▼
1
union {
2
  struct {
3
    unsigned char m_rxBuffer[BUFFER_SIZE];  // Receive buffer
4
    unsigned char m_pageBuffer[PAGE_SIZE];  // Page is assembled here before
5
    // getting programmed to flash mem
6
  } part1;
7

8
  #if KEY_COUNT > 0
9
  struct {
10
    unsigned char m_tempbuf[256]; // Temp buffer for aesInit.
11
  } part2;
12
  #endif
13
} sharedbufs;
14

15
#define rxBuffer   sharedbufs.part1.m_rxBuffer
16
#define pageBuffer sharedbufs.part1.m_pageBuffer
17
#if KEY_COUNT > 0
18
#define tempbuf    sharedbufs.part2.m_tempbuf
19
#endif
20

21
switch (type)
22
          {
23
            // Erase page
24
            case TYPE_ERASE:
25
            spmErasePage(address);
26
            // Fall-through!
27

28
            // Prepare for incoming data chunks by copying the page
29
            // contents into the page buffer
30
            case TYPE_PREPARE:
31
            {
32
              unsigned char *q = pageBuffer;
33
              const unsigned char __memx *r = address;
34

35
              do
36
              {
37
                *q++ = *r++;
38
              }
39
              while (--size);
40
              break;
41
            }
42

43
            // Chunk of data is written into the page buffer
44
            case TYPE_DATA:
45
            {
46
              unsigned char *r = &pageBuffer[(unsigned long)(address) & 0xffff];
47

48
              do
49
              {
50
                *r++ = *p++;
51
              }
52
              while (--size);
53
              break;
54
            }
55

56
            // Program page buffer into flash page
57
            case TYPE_PROGRAM:
58
            {
59
              unsigned int *q = (unsigned int *)pageBuffer;
60
              const unsigned char __memx *r = address;
61

62
              do
63
              {
64
                wdt_reset();
65
                spmWriteWord(r, *q++);
66
                r += 2;
67
              }
68
              while (--size);
69

70
              spmErasePage(address);
71
              spmProgramPage(address);
72
              break;
73
            }

Nach meinem Verständnis wird mit case TYPE_DATA im normalen RAM eine Page aufgebaut. Dann macht case TYPE_PROGRAM das Laden in den eigentlichen PageBuffer. Danach wird mit spmErasePage(address) und spmProgramPage(address) geschrieben.

pageBuffer ist auch keine besondere Adresse, es wird ganz normal im RAM allokiert.

OP #7655786
Lesenswert?
• ▲
▼

Das heisst also, mit case TYPE_PREPARE liesst man den flash aus und kann dann mit case TYPE_DATA die ausgelesene Page im RAM modifizieren. Oder aber man liesst den flash gar nicht aus und benutzt case TYPE_DATA um die komplette Page erstmal im RAM aufzubauen. Danach wird geschrieben. Richtig so?

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.