C und Bibliotheken

Hallo allerseits,

angenommen ich habe eine Bibliothek aus test1.c test2.c test3.c erstellt und nenne diese test.a.
Wie müsste meine main.c aussehen, damit die test.a auch korrekt geladen wird? Soweit ich das mit dem Compiler verstanden habe, holt er sich vordefinierte Funktionen aus den Headern, um zu wissen, welche Abhängigkeiten bestehen und ob die Struktur soweit ok ist. Beim Funktionsaufruf nutzt er dann die Funktion aus der test.a im fertigen Programm.

Daher denke ich, dass in main.c die testi.h alle includiert werden müssen. Sehe ich das soweit korrekt?
 
Warum probierst du es nicht einfach aus?

Weil ich eine Bibliothek habe mit knapp 12 Headern. Wenn ich diese 12 einbinde erhalte ich mehrere Fehler. Mein Ziel ist es eigentlich die FourQlib von Microsoft einzubinden und die "ecc_tests" umzuschreiben, sodass entweder grün oder rot blinkt und keine USART-Schnittstelle nötig wird.

Sind überhaupt alle Header wichtig, oder kann ich ungenutzte weglassen?
 
Wie müsste meine main.c aussehen, damit die test.a auch korrekt geladen wird?
Da wird nix "geladen". Es wird statisch oder dynamisch gelinkt.

Ich empfehle dir wirklich, mal die Grundlagen der Sprache zu checken, besonders den Präprozessor.
Und dazu die grundlegenden Konzepte beim Bauen/Linken.

C ist da wirklich eine andere Hausnummer als "modernere" Sprachen. Das sollte man nicht unterschätzen.
 
Hey,
also ich habe mir jetzt mal den Code im Detail angeschaut und einige Elemente auskommentiert. Es wurde z.B. ein GPIO & USART-Paket von einer OpenSource Quelle genutzt, welche mit meiner Arbeitsoberfläche und anderen libs, die ich nutze, nicht so ohne weiteres kompatibel ist.
Dabei habe ich nun die Gelegenheit genutzt und den Code umgeschrieben, sodass dieser F429 kompatibel ist. Ich müsste noch mehr Zeit investieren, um F429 uns USART3 anzusteuern, da die Pins für USART2 anders genutzt werden als beim F407.

Insgesamt funktioniert nun aber alles soweit :)
 
Weitere Frage zur Nutzung von Libs:
Wenn eine Funktion aus einer Lib nicht funktioniert, wie kann man herausfinden, warum diese nicht läuft? Ich verfüge über die C-Files, muss diese aber getrennt von meinem Projekt verarbeiten, sodass ich nur die Lib habe.

Um es etwas genauer zu beschreiben: Ich habe hier zwei Prozessoren (MPU) STM32F407 und STM32F429. Auf dem 407 läuft das Programm, nach den Tests der Entwickler zur Folge, korrekt. Auch wenn ich das Programm auf die Stellen reduziere, die ich benötige und auch alle (meiner Meinung nach) unnötigen Pakete entferne, läuft es fehlerfrei auf dem 407.
Wechsle ich zum 429 und ändere ausschließlich die Ausgabemethode von USART auf Pin-blinken, bricht das Programm beim Aufruf einer bestimmten Funktion ab. Nun bleibt mir derzeit nur die Möglichkeit die Funktion durchzulesen und zu gucken, ob es da irgendwo einen Fehler gibt. Gibt es hier eine Abkürzung zu? Etwas, dass die Ausführung überwacht und mir sagt, in der Zeile entsteht der Error.

Viele Grüße
 
[/FONT][/COLOR]
Dieses in-circuit Debugging mit OSS-Tools ist leider nicht ganz so isi, da der Code ja nativ im ST läuft und die Debug Info irgendwie zum PC rueber muss.
Dafür brauchst du einen "gdb Server" der via st-link angesprochen wird. Gängig ist OpenOCD und das sollte auch unter Windows funktionieren.

STM32F4 – In-circuit Debugging | Iztok's HW/SW Sandbox
STM32F4-Discovery Debugging mit Eclipse - Mikrocontroller.net

Ob Windows oder Linux ist mir erstmal egal, habe beides auf der Maschine und einen Shared-Folder :) Das läuft bislang problemlos. Ich muss nur (noch) unter Windows compilieren und kann unter Linux dann den Code verwenden. Der gcc in Linux packt es noch nicht so ganz für ARM zu compilieren. Die Stack (?) version ist vermutlich veraltet und ich muss von externer Quelle installieren.

Die Links gucke ich mir beide an. Danke. :)

Nachfolgend gehe ich davon aus, dass niemand die Dateien und Inhalte kennt. Daher beschreibe ich einfach alles entsprechend, wie es relevant scheint. Unter [1]

Das Problem konnte ich nun eingrenzen auf eine Funktion "ecc_mul" aus der libFourQ.a, welche in der Datei "eccp2.c" definiert wird. (Lieferte mir die Ausgabe des arm-none-eabi-gcc compilers). Gehe ich nun in diese Datei, werden am Anfang einige Headerdatei eingebunden:
Code:
#include "FourQ_internal.h"
#include "FourQ_params.h"
#include "FourQ_tables.h"
#include "ARM/fp_arm.h"
die ersten drei kann ich ohne Probleme einbinden und verwenden. Die Datei fp_arm.h bindet noch
Code:
#include "table_lookup.h"
ein. Die Warnungen und Uncompilierbarkeit entstehen beim Einbinden der letzten zwei genannten Headerfiles. Die Warnungen unter [2]. Zusammengefasst wird gewarnt, dass die Funktionen mehrfach definiert werden. Unter [1] können die entsprechenden Dateien kurz eingesehen werden. In "table_lookup.h" werden zwei "void Funktionen" definiert, die LUTs repräsentieren. Die Datei "fp_arm.h" definiert u.a. "low-level" Arithmetik.

Da eccp2.c diese Dateien bereits einbindet und ich sie in meiner test.c einbinde, kommt es sehr wahrscheinlich zu diesem Problem. Lasse ich diese Dateien weg, klappt zwar die Compilierung, aber die Funktion bricht ab oder bleibt in einer endlosen Schleife gefangen. (Ich habe vor dem Funktionsaufruf eine LED kurz aufblinken lassen und danach theoretisch ebenso. Jedoch wird das Ende nicht erreicht.)

Die Umgebung, die ich verwende, bietet einen Debugger. Nur ist der für mich nicht sehr hilfreich. Evtl. kann ich den Debugger nicht richtig auslesen?
Kurze Beschreibung:
Die GUI ist bislang drei-geteilt: Links sind Informationen und verwendete Dateien vom Projekt gelistet, rechts der Code, unten zwei Fenster mit je zwei Reitern "Console/Debug" und "Semihosting/Variables".
Eben fand ich noch einen Button für "Disassembly".
Da ich noch nie mit einem Debugger gearbeitet habe und keine weiteren Informationen hierzu habe, fällt es mir doch recht schwer, dies genau einzuordnen, worauf ich zu achten habe. Ich gehe mal [3] durch. Möglicherweise bin ich dann, was das Debuggen angeht, schlauer. Leider ist [3] nur eine Übersicht und wird nicht ordentlich gewartet. Also nicht wirklich schlauer dadurch.

In [4] habe ich mal die Funktion extrahiert. Eine weitere Probe hat ergeben, dass der Fehler in ecc_precomp liegt.

[1] FourQlib/FourQ_ARM at master * Microsoft/FourQlib * GitHub

[2] Anhang anzeigen 4326

[3] WIKI

[4]
Code:
bool ecc_mul(point_t P, digit_t* k, point_t Q, bool clear_cofactor)
{ // Variable-base scalar multiplication Q = k*P using a 4-dimensional decomposition
  // Inputs: scalar "k" in [0, 2^256-1],
  //         point P = (x,y) in affine coordinates,
  //         clear_cofactor = 1 (TRUE) or 0 (FALSE) whether cofactor clearing is required or not, respectively.
  // Output: Q = k*P in affine coordinates (x,y).
  // This function performs point validation and (if selected) cofactor clearing.
	point_extproj_t R;
	point_extproj_precomp_t S, Table[8];
	uint64_t scalars[NWORDS64_ORDER];
	unsigned int digits[65], sign_masks[65];
	int i;

	point_setup(P, R);                                        // Convert to representation (X,Y,1,Ta,Tb)
	decompose((uint64_t*)k, scalars);                         // Scalar decomposition

	if (ecc_point_validate(R) == false) {                     // Check if point lies on the curve
		return false;
	}

	if (clear_cofactor == true) {
		cofactor_clearing(R);
	}
	recode(scalars, digits, sign_masks);                      // Scalar recoding
	ecc_precomp(R, Table);                                    // Precomputation
	table_lookup_1x8(Table, S, digits[64], sign_masks[64]);   // Extract initial point in (X+Y,Y-X,2Z,2dT) representation
	R2_to_R4(S, R);                                           // Conversion to representation (2X,2Y,2Z)

	for (i = 63; i >= 0; i--)
	{
		table_lookup_1x8(Table, S, digits[i], sign_masks[i]); // Extract point S in (X+Y,Y-X,2Z,2dT) representation
		eccdouble(R);                                         // P = 2*P using representations (X,Y,Z,Ta,Tb) <- 2*(X,Y,Z)
		eccadd(S, R);                                         // P = P+S using representations (X,Y,Z,Ta,Tb) <- (X,Y,Z,Ta,Tb) + (X+Y,Y-X,2Z,2dT)
	}
	eccnorm(R, Q);                                            // Conversion to affine coordinates (x,y) and modular correction. 

    return true;
}
 
Zuletzt bearbeitet:
multiple definition

Die Prototypen definierst du offenbar mehr als einmal - das ist ein schnell lösbares Problem.
Vermutlich haste den entsprechenden Header einfach irgendwo doppelt drin.

Da eccp2.c diese Dateien bereits einbindet und ich sie in meiner test.c einbinde, kommt es sehr wahrscheinlich zu diesem Problem. Lasse ich diese Dateien weg, klappt zwar die Compilierung, aber die Funktion bricht ab oder bleibt in einer endlosen Schleife gefangen. (Ich habe vor dem Funktionsaufruf eine LED kurz aufblinken lassen und danach theoretisch ebenso. Jedoch wird das Ende nicht erreicht.)

Na dann weißt du doch bereits wo du ansetzen musst - prüfe die Funktion.

Die Umgebung, die ich verwende, bietet einen Debugger. Nur ist der für mich nicht sehr hilfreich. Evtl. kann ich den Debugger nicht richtig auslesen?
Kurze Beschreibung:
Siehe meine Links und google das Stichwort ARM in-circuit Debugging..
 
Add-On: Wenn du das USART Zeug am laufen hast, dann solltest du intensiven Gebrauch von printf() machen, bzw, die eine einfache Logging Funktion schreiben.
Das bringt dich meistens schneller vorwärts als im Debugger herumzuwühlen.

 
Add-On: Wenn du das USART Zeug am laufen hast, dann solltest du intensiven Gebrauch von printf() machen, bzw, die eine einfache Logging Funktion schreiben.
Das bringt dich meistens schneller vorwärts als im Debugger herumzuwühlen.


Leider funzt das USART Zeugs auf dem F429 noch nicht. Ich muss da ein paar Änderungen vornehmen. (Ich glaube, dass USART2 am F429-DISCO durch das Display belegt ist)


Ich habe den Fehler noch weiter eingegrenzt.
In ecc_precomp wird R1_to_R2(P, T) aufgerufen. T wurde allerdings in ecc_mul als Table[4] leer initialisiert und seither gab es keine Änderungen.
In der Funktion R1_to_R2 ist P=P und Q=T[0] (beim ersten Aufruf) und die Funktion wird ausgeführt:
Code:
fp2add1271(P->ta, P->ta, Q->t2);

in dieser liegt nun ein Fehler, sodass der µC nicht weiter rechnet sondern abbricht.
Diese Funktion sieht wie folgt aus:

Code:
void fp2add1271(f2elm_t a, f2elm_t b, f2elm_t c)
{// GF(p^2) addition, c = a+b in GF((2^127-1)^2)

    fp2add1271_a(a, b, c);
}

Diese Funktion habe ich noch nicht gefunden. (Außer in FourQ_internal.h)
 
Zuletzt bearbeitet:
Ich habe die Funktion nun gefunden. Sie ist in Assembler geschrieben.

Da ich keine Ahnung von Assembler habe, vermute ich nur, dass dieser Code nicht auf meinem Prozessor läuft, da er ja auf dem 407 ausführbar ist.

Edit: Warum auch immer aus diesem Code eine Tabelle gefertigt wurde...

Edit2: Ich habe die Tabelle entfernt. Hier der Link auf den Code [1]. Darin nach fp2add1271_a suchen.

[1] FourQlib/fp2_1271_arm_Cortex-M4.S at 350724441ce8607cb20b851697780266a45e84c2 * Microsoft/FourQlib * GitHub
 
Zuletzt bearbeitet:
Ich habe die Funktion nun gefunden. Sie ist in Assembler geschrieben.

Als Mathematiker solltest du die Rechenoperation in C schreiben und die aktuelle ASM Routine damit ersetzen ;)
Später kannst du die ursprüngliche Routine ja wieder in ASM umsetzen. Im Rahmen deiner Optimierungsbestrebungen kommst du um ASM ohnehin nicht herum.
 
Als Mathematiker solltest du die Rechenoperation in C schreiben und die aktuelle ASM Routine damit ersetzen ;)
Später kannst du die ursprüngliche Routine ja wieder in ASM umsetzen. Im Rahmen deiner Optimierungsbestrebungen kommst du um ASM ohnehin nicht herum.

Das ist tatsächlich eine gute Idee :D Daran hatte ich noch nicht gedacht, die rudimentären Funktionen umzuschreiben. :thumb_up:
 
Zurück
Oben