Hallo,
Während der Laufzeit werden die Adresse verschiedene Unterprogramme in
einem Array gespeichert.
nur als Beispiel
ram unsigned int *FifoZeiger;
FifoZeiger = (unsigned int*)(void*)&TESTEN1;
list[0].call = FifoZeiger;
FifoZeiger = (unsigned int*)(void*)&TESTEN2;
list[1].call = FifoZeiger;
Danach möchte ich über die im Array gespeicherte Adresse auf das
Unterprogramm zugreifen.
so wollte ich es ausführen
list[1].call();
bekomme aber dieses Fehlermeldung.
call of non-function
The operand of the '()' function call post-fix operator must be of type
'pointer to function.' Most commonly, this is a function identifier.
Common causes include missing scope parentheses.
Gruß Siegfried
Siegfried Saueressig schrieb:
> Hallo,> Während der Laufzeit werden die Adresse verschiedene Unterprogramme in> einem Array gespeichert.>> nur als Beispiel> ram unsigned int *FifoZeiger;> FifoZeiger = (unsigned int*)(void*)&TESTEN1;
Autsch.
Du bist auf der Suche nach Funtkionszeigern.
http://www.mikrocontroller.net/articles/FAQ#Funktionszeiger
hallo,
nun bin ich ein Schritt weiter.
typedef void (*typedef_call)( void );
typedef struct
{
unsigned char aktiv; // if true: ready to run
signed int time; // desired wakeup time
typedef_call my_call;
} struct_task;
struct_task tasklist[5] ;
unsigned int list[5];
void TESTEN1() //(void)
{
list[0]= 33;
}
void TESTEN2() //(void)
{
list[1] = 55;
}
void run_task(void)
{
tasklist[0].my_call = TESTEN1;
tasklist[1].my_call = TESTEN2;
tasklist[0].my_call();
tasklist[1].my_call();
}
wie kann ich die Funktionzeiger direkt im Array verangern, ohne das ich
es im Code hochladen muß?
Gruß Siegfried
Siegfried Saueressig schrieb:
> wie kann ich die Funktionzeiger direkt im Array verangern, ohne das ich> es im Code hochladen muß?
Nochmal. Und diesmal bitte in einem deutschen Satz.
mal ganz einfach :
[/pseudocode]
typedef void (*typedef_call)( void );
typedef_call buffer[10];
in_den_buffer( typedef_call funktion )
{
buffer[i] = funktion ;
}
void task(void)
{
typedef_call funktion;
funktion = buffer[i];
buffer[i] = NULL ;
funktion();
}
aufruf :
in_den_buffer( TESTEN1) ;
in der main
while(1)
task();
da fehlen jez noch einige while oder für und die abfragen
und sicherheiten ...
ber vom prinzip her geht das so
auch ganz easy abzuändern mit parametern
Ich vermute, daß er das Array initialisieren will.
Das sollte so gehen:
struct_task tasklist[] = { { 0, 0, TESTEN1 }, { 0, 0, TESTEN2 } };
Es ist übrigens eine ganz schlechte Idee, Funktionsnamen komplett in
Versalien zu schreiben. Die Konvention sieht vor, daß dadurch
Präprozessordefinitionen gekennzeichnet werden.
hallo,
ups...
war keine gute Beschreibung von mir.
habe von @Rufus t. Firefly übernommen.
@Rufus t. Firefly
kannst du mir das erklären, bzw eine alternative beschreiben? Habe es
nie gelernt.
Es ist übrigens eine ganz schlechte Idee, Funktionsnamen komplett in
Versalien zu schreiben. Die Konvention sieht vor, daß dadurch
Präprozessordefinitionen gekennzeichnet werden.
Gruß Siegfried
Ist ganz einfach:
Die weltweit übliche Konvention lautet:
Namen, die komplett in Grossbuchstaben geschrieben sind, sind für Makros
reserviert.
Damit weiß jeder Programmierer weltweit, dass es sich bei
1
...
2
3
x=MAX(a,b);
bei MAX um ein Makro handelt. Und da er weiß, wie dieses Makro
üblicherweise implementiert wird, wird er ums verrecken das nicht
schreiben ...
1
...
2
3
x=MAX(a++,b--);
... weil je nach konkreten Zahlenwerten a sich auch um 2 erhöhen kann
(oder b um 2 verringern).
sieht er dagegen, diesen Code
1
...
2
3
x=max(a,b);
dann geht er davon aus, dass es sich um eine echte Funktion handelt und
bei Bedarf kann er dann auch schreiben
1
x=max(a++,b--);
und alles wird so funktionieren, wie man sich das erwartet.
Wie gesagt: Es handelt sich nur um eine Konvention. Aber es ist eine die
Sinn macht und an die sich alle halten. Es gibt keinen Grund, diese
Konvention leichtfertig als Einzelner über Bord zu werfen.
@Rufus t. Firefly
ja.
es geht mir darum, das ich in verschiedene Routinen per Name auf die
Einträge von -> prozess_del <- zugreifen kann.
möchte nicht innerhalb meines Projekt so zugreifen
-> tasklist[6].aktiv = 0; <- . Sollte ich die Reihenfolge in der Liste
ändern, müßte ich das ganze Projekt durchforsten zum ändern des Index.
Gruß Siegfried
Siegfried Saueressig schrieb:
> hallo,> habe folgendes geschrieben. Funktioniert.>> t_task tasklist[] => {> // aktiv, time, call ID> { 1, 0, toggle_led_status }, 0> { 0, 0, beeper }, 1> { 0, 0, transfer_service }, 2> { 0, 0, find_service }, 3> { 0, 0, transfer_bus }, 4> { 1, 0, find_bus }, 5> { 0, 0, prozess_del }, 6> { 0, 0, prozess_add }, 7> { 0, 0, prozess_run } 8> };>> Wie finde ich heraus, welcher ID z.B. -> prozess_del <- hat?
Ist das jetzt eine Fangfrage?
Du gehst das Array in einer Schleife durch, und wenn du auf einen
Eintrag stösst, dessen Funktionspointer identisch ist mit der
Startadresse von prozess_del, dann lieferst du den Index an dem du
fündig wurdest. Eine stinknormale Suchschleife, wie sie jeden Tag von
mindestens 3 Millionen C-Programmiereren geschrieben wird.
PS: Was dir wahrscheinlich fehlt, ist die Erkentnis, dass der Name einer
Funktion (also ohne die (), welche einen Aufruf der Funktion
kennzeichnen ) ganz einfach für die Adresse der Funktion steht. So wie
der Name eines Arrays ohne die [] für die Startadresse des Arrays steht.
> möchte nicht innerhalb meines Projekt so zugreifen> -> tasklist[6].aktiv = 0; <- . Sollte ich die Reihenfolge in> der Liste ändern, müßte ich das ganze Projekt durchforsten> zum ändern des Index.
Wie wärs mit einem define?
1
#define PROZESS_DEL prozess_del
2
#define PROZESS_DEL_ID 6
3
4
{0,0,PROZESS_DEL},PROZESS_DEL_ID
Dann verwendest du überall im Code nur noch PROZESS_DEL_ID und brauchst
die nur noch an einer Stelle ändern.
Siegfried Saueressig schrieb:
> @Phantomix Ximotnahp>>> Beispiel erzeugt "task.c:147:Error: syntax error"
Das kommt daher, dass du immer nur irgendwelche Codefetzen postest und
wir hier raten müssen, wie deine Datenstrukturen aussehen.
Auch wäre es vernünftig, wenn du selbst compilierbaren Code posten
könntest, denn schon deine Vorgabe
1
t_tasktasklist[]=
2
{
3
// aktiv, time, call ID
4
{1,0,toggle_led_status},0
5
{0,0,beeper},1
6
{0,0,transfer_service},2
7
{0,0,find_service},3
8
{0,0,transfer_bus},4
9
{1,0,find_bus},5
10
{0,0,prozess_del},6
11
{0,0,prozess_add},7
12
{0,0,prozess_run}8
13
};
kann ziemlich offensichtlich nicht stimmen, oder was sollen die Zahlen
am jeweils rechten Rand jeder Zeile?
Phantomix Ximotnahp schrieb:
> Du hast die defines dazu vergessen. Außerdem ein komma vor> PROZESS_RUN_ID>> Versuchs mal so
Vergiss es.
Seine Datenstruktur sieht ganz anders aus als du denkst.
@Phantomix Ximotnahp
>> Du hast die defines dazu vergessen.
nein, habe ich nur nicht gepostet.
>> Außerdem ein komma vor PROZESS_RUN_ID
darf nicht sein ?
nur ein kleiner Ausschnitt.
>> #define PROZESS_DEL prozess_del>> #define PROZESS_DEL_ID 6>> { 0, 0, PROZESS_DEL }, PROZESS_DEL_ID
so funktioniert es.
{ 0, 0, PROZESS_DEL }, // PROZESS_DEL_ID
greife dann über "PROZESS_DEL_ID" zu.
@Karl heinz Buchegger
funktioniert einwandfrei.
Gruß Siegfried
Siegfried Saueressig schrieb:
> so funktioniert es.> { 0, 0, PROZESS_DEL }, // PROZESS_DEL_ID>> greife dann über "PROZESS_DEL_ID" zu.>> @Karl heinz Buchegger> funktioniert einwandfrei.
Ach ja?
Dann sortiere mal deine Einträge um :-)
oder ändere um in
#define PROZESS_DEL_ID 17
Compiliert weiterhin einwandfrei. Macht aber enorme Laufzeitprobleme :-)
Guter Code zeichnet sich immer dadurch aus, dass der Programmierer bei
einem eventuellen Umbau in einem halben Jahr so wenig Fehler wie möglich
machen kann. Jeder Zusammenhang, jede Abhängigkeit, an die man sich als
Programmierer erinnern muss, ist eine potentielle Fehlerquelle zuviel.
ach SO war das gemeint, die Zahl dahinter ist ein Kommentar... brauchen
wir uns hier nicht wundern...
> { 0, 0, PROZESS_DEL }, // PROZESS_DEL_ID>> greife dann über "PROZESS_DEL_ID" zu.
ist kompletter Unsinn. Wenigstens stimmt jetzt dein typedef: die Zahl am
Ende gehört also nicht mit in den code sondern ist nur ein Kommentar.
Unsere Ersetzung mit define funktioniert deshalb, weil zufällig die
Zahlen im define mit dem Index im Array übereinstimmen. Das ist ja nicht
weiter schlimm - solltest du mal umsortieren musst du nur die defines
ändern...
> Guter Code zeichnet sich immer dadurch aus, dass der Programmierer> bei einem eventuellen Umbau in einem halben Jahr so wenig Fehler> wie möglich machen kann.unterschreib