Forum: Compiler & IDEs Frage zur Erstellung von Libraries


von Detlev T. (detlevt)


Lesenswert?

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
void foo_init(void);
3
void bar1(void);
4
void bar2(void);
5
6
/* foo.c */
7
#include "foo.h"
8
9
void foo_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
void bar1(void)
23
{
24
// Tu was
25
}
26
27
/* bar2.c */
28
#include "foo.h"
29
30
void bar2(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

von Karl H. (kbuchegg)


Lesenswert?

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

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Detlev T. schrieb:
> Hallo Leute,
>
1
/* foo.h */
2
> void foo_init(void);
3
> void bar1(void);
4
> void bar2(void);
5
> 
6
> /* foo.c */
7
> #include "foo.h"
8
> 
9
> void foo_init(void)
10
> {
11
>   // Tu was
12
> }
13
> 
14
> ISR (SIG_OUTPUT_COMPARE0A)
15
> {
16
>   // Tu was
17
> }
18
>

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

von Detlev T. (detlevt)


Lesenswert?

@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

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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?

von Detlev T. (detlevt)


Lesenswert?

@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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Stefan E. (sternst)


Lesenswert?

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.

von Detlev T. (detlevt)


Lesenswert?

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

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.