Forum: Compiler & IDEs pgmspace.h Base64 SRAM sparen


von Franz W. (wizzy450)


Lesenswert?

Hallo Leute,
mal wieder ein kniffeliges Problem:
Ich habe auf einem AVR-Mega Controller folgende Funktionen laufen, um 
Base64 zu kodieren.
1
const char basis_64[] =
2
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
3
4
int Base64encode_len(int len)
5
{
6
    return ((len + 2) / 3 * 4) + 1;
7
}
8
9
int Base64encode(char *encoded, const char *string, int len)
10
{
11
  int i;
12
  char *p;
13
14
  p = encoded;
15
  for (i = 0; i < len - 2; i += 3) 
16
  {
17
    *p++ = basis_64[(string[i] >> 2) & 0x3F];
18
    *p++ = basis_64[((string[i] & 0x3) << 4) |
19
    ((int) (string[i + 1] & 0xF0) >> 4)];
20
    *p++ = basis_64[((string[i + 1] & 0xF) << 2) |
21
    ((int) (string[i + 2] & 0xC0) >> 6)];
22
    *p++ = basis_64[string[i + 2] & 0x3F];
23
  }
24
  
25
  if (i < len) 
26
  {
27
    *p++ = basis_64[(string[i] >> 2) & 0x3F];
28
    if (i == (len - 1)) 
29
    {
30
      *p++ = basis_64[((string[i] & 0x3) << 4)];
31
      *p++ = '=';
32
    }
33
    else 
34
    {
35
      *p++ = basis_64[((string[i] & 0x3) << 4) |
36
      ((int) (string[i + 1] & 0xF0) >> 4)];
37
      *p++ = basis_64[((string[i + 1] & 0xF) << 2)];
38
    }
39
    *p++ = '=';
40
  }
41
42
  *p++ = '\0';
43
  return p - encoded;
44
}

Wie man unschwer erkennen kann, ist oben eine art Look-Up-Table 
eingebaut, auf die die untere Funktion zugreift.
Das ganze funktioniert wunderbar, nur möchte ich nun SRAM sparen und die 
Loop-Up-Table im Flash belassen.

Dazu gibt es die schöne Anweisung PROGMEM, in der Art:
1
const char basis_64[] PROGMEM =
2
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

und weil man die Doku gelesen hat (ich hoffe nur gut genug) verwandelt 
man den unteren Code zu z.B.:
1
pgm_read_byte(basis_64[(string[i] >> 2) & 0x3F]);

usw...

Dann klappt die Funktion aber nicht mehr.

Hab ich da was krass verkehrt gemacht.
Die pgmspace.h ist auch korrekt eingebunden.

Hat jemand eine Idee?

Lg - Franz

von Stefan E. (sternst)


Lesenswert?

Du hast schlicht das & vergessen:
pgm_read_byte(basis_64[(string[i] >> 2) & 0x3F]);
->
pgm_read_byte(&basis_64[(string[i] >> 2) & 0x3F]);

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.