Hallo zusammen, ich möchte im Flash meines ATMEGA88 Start- und Endadresse eines Bereiches ablegen, über den eine CRC berechnet werden soll. Die Adressinformation erzeuge ich über das Linkerskript mit __CHECKSUM_START = .; und __CHKSUM_END = .; Nun deklariere ich diese Symbole entsprechend mit extern const uint32 __CHECKSUM_START; extern const uint32 __CHKSUM_END; Definieren möchte ich dann eine Variable mit const uint32 PROGMEM ChksumStartAddr = &__CHECKSUM_START; Aber der Compiler macht mir einen Strich durch die Rechnung: error: initializer element is not computable at load time Kann mir jemand sagen, was ich verkehrt mache? Danke und viele Grüße
Mal ohne & probiert? Oliver
Jap, da steigt der GCC dann aber gleich aus mit: error: initializer element is not constant
Gast
#5781288
Jay K. schrieb: > const uint32 PROGMEM ChksumStartAddr = &__CHECKSUM_START Welchen Sinn hat das überhaupt? Kannst du nicht einfach __CHECKSUM_START statt ChksumStartAddr nutzen? Ist ja eh konstant. Kann übrigens sein dass das in C++ geht. Probier es mal aus...
Dr. Sommer schrieb: > Welchen Sinn hat das überhaupt? Der Sinn ist, dass diese Werte während des Builds vom Hauptprogramm eben im Flash abgelegt werden und dann zur Laufzeit von einer anderen Instanz (z.B. dem Bootloader) ausgelesen und zur CRC Berechnung genutzt werden können
Eigentlich müsste es gehen. Zum Vergleich, in meinem Code (ist zwar ARM-GCC, aber dafür spielt das ja keine Rolle) sieht das so aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
und im Linkerscript:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
Vielleicht hilft das ja... PS: Gerade ausprobiert:
1 | |
im Code compiliert einwandfrei. Also sollte dein Beispiel eigentlich auch gehen... Muss wohl eine AVR-Spezialität sein. Kannst du denn eine nicht-PROGMEM-Variable damit initialisieren?
Gast
#5781328
Hallo Tassilo, danke für das Beispiel. So wie ich das sehe ist es nicht ganz das Gleiche. Du arbeitest hier mit dem Linkersymbol nach der Definition der (lokalen) Variablen. Zudem ist der ARM keine Harvard-Architektur...vielleicht ist da auch ein Problem?
Habe gerade nochmal probiert: Eine globale variable:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
funktioniert auch. Die liegt auch im Flash und nicht im RAM, da const. Wenn der GCC das beim ARM zur Linkzeit eintragen kann, müsste das doch beim AVR auch gehen?!
Also mit einer "nicht-progmem" Variablen geht es auch nicht. Ich habe nun folgendes probiert: const uint32_t startaddr = __CHKSUM_START; Funktioniert auch nicht. Fehlermeldung ist wieder error: initializer element is not computable at load time Ich denke wirklich, es ist hier eine AVR-GCC Spezialität Edit: Brauch ich noch ein spezielles Compiler-Flag oder einen zusätzlichen Link-Run oder so etwas?
Jay K. schrieb: > Ich denke wirklich, es ist hier eine AVR-GCC Spezialität Das ist keine Limitation des Compilers, sondern des Linkers. Ich glaube ich hatte mit const auch schon ähnliche Probleme. Interessanter weise scheint das hier bei mir zu gehen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
Hallo Daniel, vielen Dank, damit läuft es jetzt bei mir auch durch! Geholfen hat der void* als Typ und bei der extern Deklaration das uint8 / char Array. extern uint8_t __CHECKSUM_START[]; const void* ptrStartAddr = __CHECKSUM_START;
Gast
#5784072
Daniel A. schrieb: > Interessanter weise scheint das hier bei mir zu gehen: Na sowas... Eine andere Möglichkeit wäre, es folgendermaßen komplett übers Linkerscript zu machen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
Im C-Code braucht man gar nichts mehr zu schreiben. Wenn man die Adressen auslesen will kann man wie gehabt extern benutzen:
1 | |
2 | |
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.