Benutzen ATMegas mit 128KB Flash (z.B. ATMega 1284P) im Vergleich zu den 64KB-Versionen (z.B. pinkompatibler ATMega 644) eine 24bit- oder 32-bit Adressierung statt 16bit - weil mit 16 bit nur 0-64K dargestellt werden können? Werden Binaries grösser? Oder ist der Speicher wortweise organisiert und Byte-Zugriff in C wird von gcc organisiert, so dass sich gar nichts ändert?
Das Flash wird wortweise adressiert, jedenfalls was Programmspeicher angeht. Daher wird es für den Code erst jenseits 128KB interessant. 16-bit adressierte Daten sind natürlich nur in den ersten 64KB möglich, darüber sind schlicht andere Zugriffsfunktionen zuständig - transparent war das in avr-gcc ja sowieso nie. Bei den 256KB Typen sorgt der Compiler dafür, dass alle Codeadressen, die irgendwie in Pointern landen könnten, in den ersten 128KB liegen. Notfalls steht da bloss ein Sprung nach hinten.
Der folgende Code aus einem Bootloader wird für eine 128KB ATMega 1284P mit einer Warnung übersetzt, die ich nicht verstehe:
1 | // erase entire chip before first page is written
|
2 | |
3 | if (erased == false) |
4 | {
|
5 | uint8_t *erase; |
6 | |
7 | for (erase = NULL; erase < (uint8_t *)BOOTSTART; erase += SPM_PAGESIZE) |
8 | {
|
9 | boot_page_erase((uint32_t)erase); |
10 | |
11 | boot_spm_busy_wait(); |
12 | |
13 | boot_rww_enable(); |
14 | }
|
15 | |
16 | erased = true; |
17 | }
|
../main.c:458: warning: cast from pointer to integer of different size (das ist die Zeile mit boot_page_erase((uint32_t)erase) Wenn man den Cast testweise durch boot_page_erase((uint16_t)erase) ersetzt (was keinen Sinn ergibt, da man in 16 bit keine Byte-Adressen in der Gegend von 128KB spezifizieren kann), ist die Warnung weg. Jetzt frage ich micht: Was ist hier sizeof(uint8_t *)? Kann ich mir das vom Compiler irgendwie ausgeben lassen?
Dietmar schrieb: > Jetzt frage ich micht: Was ist hier sizeof(uint8_t *)? Kann ich mir das > vom Compiler irgendwie ausgeben lassen? Pointer sind bei avr-gcc immer gleich gross, unabhängig vom Typ und unabhängig vom Controller. Bei AVR 2 Bytes. Auch bei 128K und 256K Versionen. Ich würde mir eher Sorgen um den Vergleich erase < (uint8_t *)BOOTSTART machen. "erase" kann nicht mehr als 64KB adressieren. Umgang mit Flash-Adressen jenseits der ersten 64KB ist ein Minenfeld. Kann sein man kommt durch, kann sein es geht eine hoch. Der Compiler wird mit seinen Warnungen nur eine eher begrenzte Hilfe sein.
> Jetzt frage ich micht: Was ist hier sizeof(uint8_t *)? Kann ich mir das > vom Compiler irgendwie ausgeben lassen? Das ist hier unerheblich, weil Du im Flash arbeiten willst. Theoretisch sollte boot_page_erase() hier auf __boot_page_erase_extended() umgebogen werden (und das wiederum auf das passende Assemblerfragment, das mit $viel Flash umgehen kann) - das will einen uint32_t (keinen Zeiger! und schon gar nicht auf einen uint8_t!). Ergo solltest Du auch nicht mit uint8_t* hantieren sondern mit uint32_t. Lass doch mal den Präprozessor drüberlaufen um zu sehen, was der tatsächlich ersetzt. Wenn der nämlich __boot_page_erase_normal() nimmt, dann klappt das (natürlich) nicht, und das würde zur angeführten Fehlermeldung passen. HTH
Nachtrag: 's? und schon gar nicht auf einen uint8_t!??g;' Listigerweise wird der Flash tatsächlich byteweise adressiert. </ingrid>
Dietmar schrieb: > Jetzt frage ich micht: Was ist hier sizeof(uint8_t *)? Kann ich mir das > vom Compiler irgendwie ausgeben lassen? Indirekt:
1 | #include <stdint.h> |
2 | |
3 | int
|
4 | main(void) |
5 | {
|
6 | static int a1[1-2*(sizeof(uint8_t *) <= 1)]; |
7 | static int a2[1-2*(sizeof(uint8_t *) <= 2)]; |
8 | static int a3[1-2*(sizeof(uint8_t *) <= 3)]; |
9 | static int a4[1-2*(sizeof(uint8_t *) <= 4)]; |
10 | }
|
Kompilieren und schauen, bei welcher Zeile er sich als erstes beschwert, dass die Grösse des Arrays negativ ist (bei AVR: a2). In dieser Zeile steht dann die Grösse des Datentyps als Vergleichswert hinter dem "<=" (also hier dann 2). Aufsteigende Reihenfolge der Werte beachten! Andreas
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.