Ich habe in meinem Programm ein globales Array mit Funktionspointern,
das im Flashspeicher liegen soll. Das Programm funktioniert wie es soll,
allerdings bekomme ich beim Compilieren eine Warnung (siehe unten). Hier
erstmal die relevanten Codeteile:
Damit ich von verschiedenen Programmteilen auf das Array zugreifen kann,
habe ich es in einem Headerfile als extern deklariert:
1
// vtimer_config.h
2
3
#define VTIMER_CLIENT_NUM 2
1
// vtimer.h
2
3
#include"vtimer_config.h"
4
5
// Callback function prototype
6
typedefvoid(*vtimer_callback_t)(void);
7
8
// Callback function array (must be defined by user)
Es funktioniert auch alles so weit. Allerdings bekomme ich beim
Compilieren von vtimer.c folgende Compilerwarnung:
1
In function '__vector_11':
2
[Pfad]\vtimer.h(20,40): uninitialized variable 'vtimer_callback' put into program memory area [-Wuninitialized]
Hat das etwas zu bedeuten? Wird das Array wirklich nochmal in vtimer.c
angelegt? Das Programm funktioniert wie gesagt, verwendet wird also
offensichtlich schon das Array aus main.c. Soll ich die Warnung
ignorieren? Bzw. gibt es eine Möglichkeit, sie loszuwerden?
Ich benutzte AVR-Studio 6.0 mit dem AVR-GCC 4.6.2, der standardmäßig
dabei ist.
Danke schonmal!
xfr schrieb:> uninitialized variable 'vtimer_callback' put into> program memory area [-Wuninitialized]>> Hat das etwas zu bedeuten?
Es bedeutet, daß du folgende Optionen hast:
• Mit der Warnung leben
• -Wno-uninitialized (oder eine Obermenge davon) deaktivieren.
• Auf eine avr-gcc Version oder Distribution umsteigen, die einen
Fix für PR51756 hat, z.B. 4.6.3 oder neuer.
Alles klar, vielen Dank!
Dann war ja tatsächlich mal der Compiler Schuld ... :)
Die Warnung verschwindet übrigens auch, wenn man in der Deklaration das
"PROGMEM" weglässt. Allerdings ist das ja eine essentielle Information
für denjenigen, der das Array definieren soll, also keine Lösung.
xfr schrieb:> Dann war ja tatsächlich mal der Compiler Schuld ... :)
Nein, der Compiler ist unschuldig. Ich war Schuld.
> Die Warnung verschwindet übrigens auch, wenn man in der Deklaration das> "PROGMEM" weglässt. Allerdings ist das ja eine essentielle Information> für denjenigen, der das Array definieren soll, also keine Lösung.
Es genügt wenn das progmem Attribut an der Definition steht.
Johann L. schrieb:> Es genügt wenn das progmem Attribut an der Definition steht.
Aus Sicht des Compilers ja, zur Selbstdokumentation allerdings nicht.
Wenn sich jemand nur die Header-Datei ansieht, kann er ja nicht ahnen,
dass das Array im Flash abgelegt werden soll (bzw. ist, wenn man es
andersrum verwenden würde). Man könnte es natürlich entsprechend
kommentieren, bleibt aber unsauber.
Naja, habe noch mal grundsätzlich drüber nachgedacht und es jetzt anders
gelöst: Das Array kommt mit static-Attribut in die vtimer_config.h und
wird nur in vtimer.c eingebunden. Dann stehen auch die Anzahl der
Einträge und die Einträge selbst an einer Stelle.
Nachteil ist, dass ich in vtimer_config.h jetzt die Header zu allen
Funktionen einbinden muss, auf die ich verweise. Die wären in main.c
halt schon da. Außerdem kann ich in in main.c nicht mehr Funktionen ohne
Header-Datei definieren und als Callbacks benutzten. Aber gut, man kann
nicht alles haben ...
Danke nochmal für den Hinweis. :)
xfr schrieb:> Johann L. schrieb:>> Es genügt wenn das progmem Attribut an der Definition steht.>> Aus Sicht des Compilers ja, zur Selbstdokumentation allerdings nicht.> Wenn sich jemand nur die Header-Datei ansieht, kann er ja nicht ahnen,> dass das Array im Flash abgelegt werden soll (bzw. ist, wenn man es> andersrum verwenden würde). Man könnte es natürlich entsprechend> kommentieren, bleibt aber unsauber.
Die Krise an dieser Stelle ist, dass das PROGMEM hier beim extern im
Grunde auch nichts anderes als eine Dokumentation ist.
Ob es da ist oder nicht, spielt keinen Walzer. Weder wirst du vom
Compiler gezwungen, da irgendwas spezielles damit zu machen und du wirst
auch nicht vom Compiler gezwungen hier
((vtimer_callback_t) pgm_read_word(&vtimer_callback[i]))();
einen pgm_read_word anzuwenden, anstatt den Funktionsaufruf direkt über
das Array zu machen.
So gesehen: ob du einen Kommentar machst, oder ob du da PROGMEM
hinschreibst, ist Jacke wie Hose. OK, PROGMEM sieht ein wenig
offizieller aus.
Stimmt schon, mehr als ein Hinweis ist es nicht. Wenn das PROGMEM in der
Deklaration steht, könnte man sie halt einfach kopieren und zu einer
Definition machen, ohne das PROGMEM zu vergessen. Das beste ist aber
wahrscheinlich, die ganzen PROGMEM-Geschichten möglichst lokal zu halten
und nicht nach außen zu zeigen.
Falls es jemanden interessiert, hab es jetzt so gemacht:
Gewinnt sicher auch keinen Schönheitspreis. Aber damit befindet sich
immerhin alles, was mit PROGMEM zu tun hat, nur noch in vtimer.c und
kann bei Bedarf auch geändert werden, ohne die Konfigurations-Dateien
der Anwendungen anfassen zu müssen.
xfr schrieb:> Gewinnt sicher auch keinen Schönheitspreis.
Find ich jetzt ehrlich gesagt gar nicht soooo wild. Man muss halt im
Hinterkopf halten, dass es da ein potentielles Problem gibt, welches du
so 'entschärfst'. Von daher finde ich das sogar gar keine schlechte
Lösung.