AVR231: AES Bootloader Frage zu "TYPE_PREPARE" Record

#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...

#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.

#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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren