Hallo,
ich habe folgendes Problem in C. Ich möchte quasi einer Init Funktion
den Pointer von der List übergeben. Wie müsste der Übergabeparameter
lauten?
[test.h]
extern sElement List[10];
void Test_Init(....); <= ?????
[main.c]
sElement List[10];
//Aufruf Init Funktion
Test_Init(...);
Max schrieb:> ich habe folgendes Problem in C. Ich möchte quasi einer Init Funktion> den Pointer von der List übergeben. Wie müsste der Übergabeparameter> lauten?
sElement *
>> [test.h]> extern sElement List[10];
Das kann weg, wenn Du das sowieso sauber als Parameter übergibst.
> void Test_Init(....); <= ?????
void Test_Init(Element *list_ptr, size_t len);
> [main.c]> sElement List[10];
Das kann dann auch static sein.
> //Aufruf Init Funktion> Test_Init(List, sizeof(List) / sizeof(List[0]));
List muß dabei als Array-Deklaration sichtbar sein, was hier aber der
Fall ist.
Oliver S. schrieb:> sElement>> Oliver
void Test_Init(sElement* List);
Test_Init(List) oder Test_Init(&List[0])
In der Funktion kannst du dann sowas machen:
//i-tes Element aus Liste Array
sElement t = *(List+i);
oder:
sElement t = List[i]
Da Baby schrieb:> void Test_Init(sElement* List);
Geht, sollte man aber nicht so machen, weil die Funktion dann nicht
weiß, wie groß das Array ist. Idiomatisches C wäre wie in meinem
Vorschlag ein Pointer auf das erste Element und als zweiten Parameter
die Anzahl der Elemente.
Nop schrieb:> Geht, sollte man aber nicht so machen, weil die Funktion dann nicht> weiß, wie groß das Array ist.
Geht schon, wenn vereinbart wird, daß das Array nullterminiert ist, d.h.
mit einem Element endet, in dem alle Elemente Null sind.
Diese Vorgehensweise ist bei Strings in C sehr verbreitet, da ist ein
Element halt keine Struktur, sondern nur ein char, aber funktional
läuft das aufs gleiche raus.
Émile schrieb:> Geht schon, wenn vereinbart wird, daß das Array nullterminiert ist, d.h.> mit einem Element endet, in dem alle Elemente Null sind.
Zum Lesen geht das - aber beim Schreiben, was eine Init-Funktion ja tun
soll, müßte man dann vor dem Aufruf alle Elemente bis auf das letzte mit
einem ungültigen Wert ungleich null vorinitialisieren. Das ist recht
umständlich.
Vielen Dank für eure Hilfe.
Ich bin etwas unschlüssig wie das alles umsetzen soll. Ich habe quasi
eine Instanz in der 5 Elemente enthalten sind. Es stellt sich die Frage
soll ich eine Init Funktion erstellen die die Elemente initiallieren
soll, ja oder nein?
Max schrieb:> Ich habe quasi> eine Instanz in der 5 Elemente enthalten sind. Es stellt sich die Frage> soll ich eine Init Funktion erstellen die die Elemente initiallieren> soll, ja oder nein?
Womit werden die Elemente initialisiert? Mit konstanten Werten? Dann
brauchst Du keine Init-Funktion, sondern kannst Dein Array gleich beim
Definiteren auch initialisieren:
1
typedefstructElement
2
{
3
uint8_t*Name;
4
eTimerTypeType;
5
eTimerStateState;
6
uint32_tValueMillSec;
7
}sElement;
8
9
10
sElementArray[]=
11
{
12
{"Horst",type1,state1,34},
13
{"Detlef",type0,state7,123},
14
...etc.
15
};
(angenommen, daß "type1" etc. zu den vermutlich-enums passen).
Max schrieb:> Es stellt sich die Frage soll ich eine Init Funktion erstellen die die> Elemente initiallieren soll, ja oder nein?
Das hängt von mehreren fragen ab:
Was weiß die initfunktion, was du zur compilezeit nicht weißt? Woher
kommt der Speicher? Wer macht welche Annahmen über die Liste? Wer
garantiert, dass init vor Verwendung aufgerufen wird bzw. alle mit "0"
klarkommen.
Die Fragen sind vermutlich schwierig, dann beschreib lieber, was Du
machen willst.
Da es sich um einen Mikrocontroller handelt werde ich nichts dynam7sch
machen. Ich möchte die hardwarenahen Timerfunktionen in eine eigene
TimerLib verwenden. Diese TimerLib stellt dan die Funktionen nach außen
dar. Es sollen zunächst 6 Instanzen (6 Timer) erzeugt werden. Mir stellt
sich die Frage wie man sowas richtig umsetzen kann und wie die
Initialisierung aussehen könnte. Die Instanzen sollen auch wo anders
verwendet werden wie zum Beispiel in der uart, watchdog usw.
Max schrieb:> nichts dynam7sch machenMax schrieb:> Es sollen zunächst 6 Instanzen (6 Timer) erzeugt werden.
Wenn es eben geht, ist es einfacher/flexibler, wenn der Nutzer
(aufrufer) den Speicherplatz bereitstellt.
Aber ohne Beispiel-Pseudocode oder ein wenig mehr Erklärung ist kaum
erkennbar, was Du genau möchtest.
A. S. schrieb:> wenn der Nutzer (aufrufer) den Speicherplatz bereitstellt
... dann reicht meist ein Pointer in der Struktur für eine einfach
verkettete, 0-terminierte Liste, falls eine Liste notwendig ist.
Schleifen zerfallen dann zu
1
for(p=startPtr;p;p=p->next){...}
Es ist dann gleich, ob 3 oder 300 Timer genutzt werden.
Und Spar Dir gerne den Aufwand der doppelt-verketteten Liste, bis Du die
einfache beherrschst. Der Performancegewinn ist in diesem Stadium
vernachlässigbar.
Max schrieb:> Es sollen zunächst 6 Instanzen (6 Timer) erzeugt werden.
Dazu nimmt man typisch einen Scheduler, der von einem Timertick
ausgeführt wird, d.h. man braucht nur einen Hardwaretimer.
Der Vorteil ist, die Liste muß nur so groß sein, wie maximal Timer
gleichzeitig ausgeführt werden.
Guten Morgen,
das mit einer verketten Liste habe ich mir auch überlegt. Ich brauche
einen Timer für die UART, Watchdog usw. und auch für eventuell sonstige
Aufgaben in der Applikation. Wenn ich das mit einer verketten Liste
mache, dann muss ich zum Beispiel für die UART immer die Liste nach dem
Timer für die UART suchen. Ich werde manuell die Liste erzeugen und dann
jeweils zum Beispiel für die UARTT als Übergabeparameter einen Pointer
auf das jeweilige Elment von der List übergeben.
Max schrieb:> woher weis die Uart welchen Timer in der Liste für> ihn bestimmt ist?
Warum sollte eine Funktion (hier Uart_Init) eine Liste mit Timern
bekommen, wenn sie doch nur einen ganz bestimmten aus dieser Liste
benötigt?
Das macht keinen Sinn.
Max schrieb:> Ich muss ja der UART den zuständige Timer als Übergabeparameter> mitteilen.
Nö.
Du übergibst dem Scheduler nur die Ablaufzeit und den Callback. Der
Scheduler legt dann beides auf einem freien Platz in der Liste ab.
Die Ablaufzeit wird dabei schon richtig in die belegten Einträge der
Liste einsortiert. Der Timer muß also immer nur einen Eintrag
runterzählen.
Max schrieb:> Ok. Und vorher muss ich aber trotzdem wissen welche EIntrag von der List> für die Uart bestimmt ist.
Wofür brauchst Du denn eine Liste?
Im Uart legst Du den Timer
1
staticstructsTimerTimerUart;
lokal an. Und arbeitest mit ihm. Init, Start, Stop, Test, ... was immer.
Also z.B.
1
TimStart(&TimerUart);
WENN Du für irgendwas eine Liste brauchst (wofür auch immer), DANN
mach die mit einer Pointer-verkettung