www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Zeiger und Unterprogramm


Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie ist die Struktur definiert, von der Du ein Array namens "list" 
angelegt hast? Hier ist insbesondere das Strukturelement "call" 
interessant.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

typedef struct
  {
    unsigned char aktiv;     // High ist aktiv
    signed int time;         // Zeit
    unsigned int  *call;     // Task
  } task;

Gruß Siegfried

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>   unsigned int  *call;     // Task

Njet. Das Stichwort lautet 'Funktionspointer'

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn die Funktion eine unsigned int als Rückgabewert liefert und
keine Parameter hat, dann so deklarieren:
 unsigned int (*call)(void);

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
jetzt habe ich es. nochmals ganz klein angefangen

unsigned int list[5];
typedef void (*call)( void );
call my_call[5];

void TESTEN1()    //(void)
  {list[0]= 33;}

void TESTEN2()    //(void)
  {list[1] = 55;}

void list_call(void)
{
list[0] = 0;
list[1] = 0;
list[2] = 0;
list[3] = 0;
list[4] = 0;

my_call[0] = TESTEN1;      //FifoZeiger;
my_call[1] = TESTEN2;      //FifoZeiger;

 my_call[0]();
 my_call[1]();
}

vielen dank an alle
Gruß Siegfried

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
  ...

  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 ...
   ...

   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
   ...

   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
   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.

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Gruß Siegfried

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meinst Du mit "ID" den Index im Array?

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

int searchId( typedef_call function )
{
  int i;

  for( i = 0; i < sizeof( tasklist ) / sizeof(tasklist[0]); ++i )
    if( function == tasklist[i].my_call )
      return i;

  return -1;
}

int main()
{
  ...

  id = searchId( prozess_del );

  ...


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.

Autor: Phantomix Ximotnahp (phantomix) Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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?

#define PROZESS_DEL prozess_del
#define PROZESS_DEL_ID 6

{  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.

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Phantomix Ximotnahp


Beispiel erzeugt "task.c:147:Error: syntax error"

t_task tasklist[] =
{
//  aktiv,   time,  call
{  1,  0,   TOGGLE_LED_STATUS   },   TOGGLE_LED_STATUS_ID
{  0,  0,  BEEPER     },  BEEPER_ID
{  0,  0,  TRANSFER_SERVICE  },   TRANSFER_SERVICE_ID
{  0,  0,  FIND_SERVICE  },   FIND_SERVICE_ID
{  0,  0,  TRANSFER_BUS  },   TRANSFER_BUS_ID
{  1,  0,  FIND_BUS    },   FIND_BUS_ID
{  0,  0,  PROZESS_DEL  },   PROZESS_DEL_ID
{  0,  0,  PROZESS_ADD  },  PROZESS_ADD_ID
{  0,  0,  PROZESS_RUN  }   PROZESS_RUN_ID
};

Gruß Siegfried

Autor: Phantomix Ximotnahp (phantomix) Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast die defines dazu vergessen. Außerdem ein komma vor 
PROZESS_RUN_ID

Versuchs mal so
#define TOGGLE_LED_STATUS_ID 0
#define BEEPER_ID 1
#define TRANSFER_SERVICE_ID 2
#define FIND_SERVICE_ID 3
#define TRANSFER_BUS_ID 4
#define FIND_BUS_ID 5
#define PROZESS_DEL_ID 6
#define PROZESS_ADD_ID 7
#define PROZESS_RUN_ID 8

t_task tasklist[] =
{
//  aktiv,   time,  call
  {  1,  0,   toggle_led_status   },   TOGGLE_LED_STATUS_ID
  {  0,  0,  beeper     },  BEEPER_ID
  {  0,  0,  transfer_service  },   TRANSFER_SERVICE_ID
  {  0,  0,  find_service  },   FIND_SERVICE_ID
  {  0,  0,  transfer_bus  },   TRANSFER_BUS_ID
  {  1,  0,  find_bus    },   FIND_BUS_ID
  {  0,  0,  prozess_del  },   PROZESS_DEL_ID
  {  0,  0,  prozess_add  },  PROZESS_ADD_ID
  {  0,  0,  prozess_run  }   PROZESS_RUN_ID
};

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
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
};

kann ziemlich offensichtlich nicht stimmen, oder was sollen die Zahlen 
am jeweils rechten Rand jeder Zeile?

Autor: Phantomix Ximotnahp (phantomix) Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kam mir auch schon spanisch vor. ist das C2009? bin wohl zu lang mit 
Java beschäftigt gewesen

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Siegfried Saueressig (dieleena)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Phantomix Ximotnahp (phantomix) Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.