www.mikrocontroller.net

Forum: Compiler & IDEs Makro mit Anweisung und Abfrage möglich?


Autor: Sebastian B. (mircobolle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo liebe Makro-Freunde und Freundinne,

folgendes Problem:

ich möchte folgende Anweisungen in ein Makro packen:

1)  x += 1;
2)  x =  x % y;

Jetzt kommt noch die Abfrage:

3) if (x == 0) { ... }

ist es möglich das ALLES in EIN Makro zu packen??

Ich habe jetzt mal sowas probiert:
#define MACRO(X,Y) X+=1;X=X%Y;

aber ne Abfrage ist hier nicht mehr möglich?!

Jemand eine Idee ??

Danke!!

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst in das Makro so ziemlich alles packen, was du lustig bist,
also auch if-Konstrukte, Funktionen, Datenstrukturen oder auch nur
Fragmente davon. Ich sehe gerade dein Problem nicht ganz.

Da der Präprozessor nur Text ersetzt, musst du allerdings darauf achten,
dass die Ersetzung im Kontext des Makroaufrufs zu einem sinnvollen
Ergebnis führt. Besonders zu beachten ist hier die richtige Klammerung
und die Verwendung von Semikola.

Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#define MACRO(X,Y) do { X++; X%=Y; if (X == 0) {...} } while(0)

Autor: Sebastian B. (mircobolle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Volker wrote:
> #define MACRO(X,Y) do { X++; X%=Y; if (X == 0) {...} } while(0)

danke für die Antworten.

Ich habe mich wahrscheinlich nicht klar genug ausgedrückt.

Was ich eigentlich will ist eine Art MACRO Schedule Hilfe.

x += 1;  -> zählt den Counter hoch, das ganze wird im 1 ms Takt 
aufgerufen

x = x % y; -> y ist die Task-Zeit z.b. 3 - alle 3 ms

und dieser Task() soll dann aufgerufen werden, wenn x == 0 ist!

ich könnte natürlich sowas schreiben:

#define MACRO(X,Y) X+=1;X=X%Y;

aber dann geht ja sowas nicht:
if (MACRO(X,10) == 0){ // Syntax Error
   Task();
}

wenn ich das IF ins makro packe, dann ist ja der Task Aufruf aussen vor!

Ich hoffe mein Problem ist jetzt etwas deutlich geworden. :)

Danke

Autor: Nubsi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1.)  Nenn es nicht MACRO, gibt ihm einen aussagekräftigen Namen.

2.) Was du willst, könnte sich relativ leicht durch eine Funktion 
erledigen lassen.

Autor: Christian S. (manatarms)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es geht doch MACRO(X,Y,TASK)

Packst du halt den Funtkionsnamen mit rein.

Autor: Sebastian B. (mircobolle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nubsi wrote:
> 1.)  Nenn es nicht MACRO, gibt ihm einen aussagekräftigen Namen.
das mit MACRO war jetzt nur ein Beispiel fürs Forum. Im Code setzt ich 
natürlich vernünftige Namen ein.

> 2.) Was du willst, könnte sich relativ leicht durch eine Funktion
> erledigen lassen.
Naja, aber ich wollte mir halt den Funktionsoverhead durch ein Makro 
sparen. So hätte ich ja einen Funktionssprung pro Task Überprüfung.

Insgesamt sind es 10 Task.

Autor: Sebastian B. (mircobolle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian S. wrote:
> Es geht doch MACRO(X,Y,TASK)
>
> Packst du halt den Funtkionsnamen mit rein.

du meinst
#define TASK_SCHEDULER(X,Y,TASK) X+=1;X=X%Y; (X==0)?TASK;

wie würde ich das dann effektiv verwenden?
So?
TASK_SCHEDULER (TASK_1_COUNTER,TASK_1_COMPARE,Task_1());

Danke!

(ungetestet)

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
schonmal das Wort inline gehört?
static inline void funktion ( void );

eine so deklarierte Funktion wird vom Compiler an der stelle eingesetzt 
ohne, dass Overhead entsteht.
Dazu muss aber die Optimierung aktiviert sein.

Autor: Sebastian B. (mircobolle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gast wrote:
> schonmal das Wort inline gehört?
>
>
> static inline void funktion ( void );
> 
>
> eine so deklarierte Funktion wird vom Compiler an der stelle eingesetzt
> ohne, dass Overhead entsteht.
> Dazu muss aber die Optimierung aktiviert sein.

inline kenne ich schon, aber dann müsste ich dieser Funktion ja einen 
Funktionspointer auf meinen Task geben oder 10 inline Funktionen 
definieren, schließlich habe ich ja auch 10 Task.

Aber danke für den Tipp!!

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sebastian B. wrote:

> #define MACRO(X,Y) X+=1;X=X%Y;
>
> aber dann geht ja sowas nicht:
>
>
> if (MACRO(X,10) == 0){ // Syntax Error
>    Task();
> }
> 

Wenn du das Macro in einem Ausdruck verwenden willst, darfst du 
natürlich erst einmal kein Semikolon verwenden. Bei deinem speziellen 
Problem eignet sich der Kommaoperator:
#define MACRO(X,Y) (X+=1,X%Y)
Oder man schreibt es gleich in einen Ausdruck:
#define MACRO(X,Y) (++X%Y)

Autor: Sebastian B. (mircobolle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So lässt sich das Makro nun compilieren:
#define mSYSTEM_MANAGER_Task(X,Y,TASK) X+=1;X=X%Y;if(X==0){TASK();}

und so aufrufen
     /* BUTTON TASK */ 
     if (SYSTEM_MANAGER_ExecTask(SYSTEM_MANAGER_TASK_BUTTON)==true){
        mSYSTEM_MANAGER_Task(u8_button_sample,10,BUTTON_Sample);
     }

Hinweis: SYSTEM_MANAGER_ExecTask prüft ob der Task im momentanen 
Systemzustand ausgeführt werden darf.

viele grüße

Autor: Christian S. (manatarms)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#define MACRO(X,Y,TASK) {X++;X=X%Y;TASK();}

So meinte ich das.

Autor: Christian S. (manatarms)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
UPS..

Eigentlich mit if... aber hast es ja schon raus bekommen.

Autor: Sebastian B. (mircobolle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian S. wrote:
> UPS..
>
> Eigentlich mit if... aber hast es ja schon raus bekommen.

Nochmals ein DICKES DANKE in das Forum :-)

Der Code sieht jetzt um einiges übersichtlicher aus! :-)

Danke && Ciao ;-)

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich glaub du hast gerade ein Brett vor dem Kopf vor lauter Makro ;-)
Meinte das mit der inline Funktion anders.
if ( funktion ( x, y ) == 0 )
{
  task();
}

Autor: Sebastian B. (mircobolle)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gast wrote:
> Ich glaub du hast gerade ein Brett vor dem Kopf vor lauter Makro ;-)
> Meinte das mit der inline Funktion anders.
>
>
> if ( funktion ( x, y ) == 0 )
> {
>   task();
> }
> 

achso, ja, das wäre natürlich auch eine schlanke Möglichkeit!
Danke für den Tipp. ;-)

Autor: Marcus Harnisch (mharnisch) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sebastian B. wrote:
> inline kenne ich schon, aber dann müsste ich dieser Funktion ja einen
> Funktionspointer auf meinen Task geben

Und wo genau ist da das Problem? Funktionen und (globale) Variablen 
werden doch letztlich sowieso über Adressen referenziert.

Das hier
static inline void fSYSTEM_MANAGER_Task(unsigned char *X, unsigned char Y,
                                        void (TASK)(void))
{
    *X += 1;
    *X  = *X % Y;
    if (*X == 0) {
        TASK();
    }
}

Aufruf mit:
fSYSTEM_MANAGER_Task(&u8_button_sample,10,BUTTON_Sample);

resultiert bei mir in genau dem gleichen Code wie die Variante mit Makro 
und kann -- im Gegensatz zum Makro -- bei Bedarf auch noch einfach 
entfehlert werden. Typüberprüfung zwecks Illusion einer gewissen 
Sicherheit gibt's gratis dazu.

Gruß
Marcus

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.