Hallo Leute,
ich habe eine Frage zu Libraries. Ich würde gern wissen, ob das, was ich
vorhabe, so überhaupt funktioniert. Ich weiß zumindest schon soviel,
dass man die Funktionen auf möglichst viele Dateien verteilen muss, weil
der Linker auf Objektebene arbeitet. Nehmen wir an ich hätte die Dateien
foo.h, foo.c, bar1.c und bar2.c erstellt und dann die Objektdateien in
libfoo.a zusammengefasst. Beim Compilieren des Hauptprogrammes nutze ich
-lfoo.
1
/* foo.h */
2
voidfoo_init(void);
3
voidbar1(void);
4
voidbar2(void);
5
6
/* foo.c */
7
#include"foo.h"
8
9
voidfoo_init(void)
10
{
11
// Tu was
12
}
13
14
ISR(SIG_OUTPUT_COMPARE0A)
15
{
16
// Tu was
17
}
18
19
/* bar1.c */
20
#include"foo.h"
21
22
voidbar1(void)
23
{
24
// Tu was
25
}
26
27
/* bar2.c */
28
#include"foo.h"
29
30
voidbar2(void)
31
{
32
bar1();
33
// Tu was
34
}
Meine Fragen:
1.) Wenn ich im Hauptprogamm foo_init() verwende, funktioniert dann die
ISR? Wird also der entsprechende Vektor gesetzt?
2.) Wenn ich im Hauptprogamm bar2() verwende, wird dann auch bar1()
automatisch mit eingebunden?
Vielen Dank für eure Hilfe.
Gruß, DetlevT
Detlev T. schrieb:
> Meine Fragen:> 1.) Wenn ich im Hauptprogamm foo_init() verwende, funktioniert dann die> ISR? Wird also der entsprechende Vektor gesetzt?
Da bin ich mir nicht sicher. Probiers einfach aus.
Allerdings würde ich das so nicht machen. Wenn du mehrere Libraries
gleichzeitig benutzt, wirst du sehr schnell die Übersicht verlieren, wer
den welchen Interrupt Vektor angemeldet hat.
Ich würde in den sauren Apfel beissen und eine InterruptHandler Funktion
in die Library mit aufnehmen. Eine ganz normale Funktion mit der
Auflage, dass der Anwendungsprogrammierer, der die Funktionalität
benutzen will, sich selbst darum kümmern muss, eine ISR zu schreiben und
dann von der ISR diese Funktion aufrufen kann.
> 2.) Wenn ich im Hauptprogamm bar2() verwende, wird dann auch bar1()> automatisch mit eingebunden?
Ja
Klar, hier wird natürlich ein Eintrag in die Vektortabelle erstellt.
Beim Anlegen von Multilibs musst du aber sicher sein, daß alle Derivate,
für die die Multilib-Variante gedacht ist, die gleiche IRQ-Nummer haben!
Johann
@Karl heinz Buchegger,
O.K., ich habe es ausprobiert und es geht offenbar nicht . Die
ISR-Routine landet zwar im Ausgangsfile, der entsprechende Vektor wird
jedoch nicht gesetzt. Wenn ich das ohne den Umweg über eine Library
mache, ist alles in Ordnung.
Schade eigentlich.
Damit hat sich eigentlich auch der zweite Teil fast erledigt. Muss ich
noch einmal sehen.
Hintergrund der Aktion ist, dass ich ein Testboard mit einer Menge
Hardware drauf erstellen will. Dazu soll(te?) es eine einzige Library
mit den entsprechenden Routinen geben, um diese Hardware bequem
anzusprechen und von der eben nur die Funktionen eingebunden werden, die
man aktuell braucht ohne dass man groß darüber nachdenken muss.
Vielleicht gibt es ja eine Zwischenlösung, wo man die ISR in einem .c
File definiert, aber nur diejenigen mit compiliert, deren .h Dateien
aktuell eingebunden sind. Die anderen Funktionen könnte man vielleicht
doch in eine Library packen. Ob das mit den gemeinsamen Variablen
funktioniert, muss ich noch einmal schauen.
Notfalls muss ich irgendetwas mit Macros machen und bestimmte Funktionen
aus einer großen board.c via #ifdef halt einbinden oder nicht. Das ist
weniger komfortabel und effizient, aber wenigstens das sollte gehen.
@Johann L.
Es geht nur um ein Derivat, ein bestimmtes Board mit einem bestimmten
Controller. Der Eintrag in die Vektortabelle wurde bei meinem Test
nicht erstellt, wenn die ISR in der libfoo.a definiert war. Habe ich
foo.c ganz normal als .o gelinkt, funktionierte das hingegen.
Danke für eure Hilfe.
Gruß, DetlevT
Detlev T. schrieb:
> Der Eintrag in die Vektortabelle wurde bei meinem Test> nicht erstellt, wenn die ISR in der libfoo.a definiert war. Habe ich> foo.c ganz normal als .o gelinkt, funktionierte das hingegen.
Das lässt eher darauf schliessen, daß die Tools falsch angewandt wurden.
Die Bibliother sammelt ja auch nur Objekte.
Johann
Wichtig ist für die ISR nur, dass es auch wirklich so gemacht wird,
wie du das da oben geschrieben hast: die ISR muss in einem Objektmodul
stehen, aus dem noch (mindestens) ein weiteres Symbol referenziert
wird, ansonsten hat der Linker keine Veranlassung, den Modul zu linken.
Jörg Wunsch schrieb:
> Wichtig ist für die ISR nur, dass es auch wirklich so gemacht wird,> wie du das da oben geschrieben hast: die ISR muss in einem Objektmodul> stehen, aus dem noch (mindestens) ein weiteres Symbol referenziert> wird, ansonsten hat der Linker keine Veranlassung, den Modul zu linken.
Das externally_visible und used-Zeug hat keinen Einfluß aufs Objekt?
@Jörg Wunsch
Ich habe es so gemacht und der Code der ISR-Routine landet auch in der
Ausgangsdatei. Nur der Vektor wird nicht automatisch gesetzt.
Wenn ich hingegen dieselbe Objektdatei, die ich zur Erstellung der
Library erzeugt hatte, direkt linke, stimmt der Vektor.
Gruß, DetlevT
Detlev T. schrieb:
> Ich habe es so gemacht und der Code der ISR-Routine landet auch in der> Ausgangsdatei. Nur der Vektor wird nicht automatisch gesetzt.
Dann müsste man sich nochmal angucken, wie der ganze weak-Krams
eigentlich funktioniert. crtXXX.o definiert ja die komplette
Vektortabelle, wobei alle diese Definitionen `weak' markiert sind.
Damit bekommt eine gleichnamige Definition aus der Applikation
dann Vorrang (ohne `weak' wäre es ein Doppeldefinitionsfehler).
Offenbar wird `weak' wohl ignoriert, wenn der Modul aus einer
Bibliothek entnommen wird.
Auf so profane Dinge, wie beim Compilieren der Lib die richtige MCU
anzugeben, hast du geachtet?
Vergleiche doch mal, welche Symbole in der reinen Objektdatei, und
welche in der Library definiert sind. Würde mich nicht wundern, wenn du
dort einen Namensunterschied beim Vector findest.
Vor einiger Zeit hatte ich selbst mal eine ISR in eine Library gepackt,
und da hat es anstandslos funktioniert.
Hallo Leute,
unverkennbar bin ich Anfänger, was die Libraries betrifft. Vielleicht
kann jemand etwas von euch damit anfangen. nm -s libbtn.a (so heißt die
Library wirklich) gibt am Anfang folgendes aus:
1
Archive index:
2
btn_init in btn_init.o
3
__vector_14 in btn_init.o
4
key_state in btn_init.o
5
key_press in btn_init.o
6
key_release in btn_init.o
7
btn_countdown in btn_init.o
8
btn_key_pressed in btn_key_pressed.o
9
btn_key_released in btn_key_released.o
10
11
btn_init.o:
12
00000034 a __CCP__
13
0000003e a __SP_H__
14
0000003d a __SP_L__
15
0000003f a __SREG__
16
U __do_clear_bss
17
U __do_copy_data
18
00000000 a __tmp_reg__
19
00000024 T __vector_14
20
00000001 a __zero_reg__
21
00000001 C btn_countdown
22
00000000 T btn_init
23
00000001 b ct0.1241
24
00000000 b ct1.1242
25
00000001 C key_press
26
00000001 C key_release
27
00000001 C key_state
Ich habe realen Code verwendet (für die Software-Entprellung von
Tasten). key_state, key_press, key_release_btn_countdown sind (volatile)
Variablen. Damit gibt es beim Linken keine Fehlermeldung. btn_init() ist
in derselben .c Datei wie die ISR. btn_key_pressed und btn_key_released
jeweils in eigenen.
Der Teil mit ct01241 / ct1.1242 taucht nur bei dieser Datei auf. Ich
vermute, das hat etwas mit dem Vektor zu tun. Das wisst ihr aber
wahrscheinlich besser.
Gelinkt habe ich das mit dem Zusatz "-L. -lbtn". Fehlt da vielleicht
noch irgendein Parameter, damit diese Informationen übernommen werden?
Gruß, DetlevT