Hi, ich bin ein AVR neuling und möchte in C ein ATMega324P programmieren. Mein Problem (aber ich bin mir sicher dass viele andere ein solche Macro brauchen könnten) ist eine sehr schnelle und effektive Umsetzung der Switch Case Anweisung für die Programmierung von Statusmaschinen. Ein Macro könnte da helfen. Ich nenne es CHOICE(char index) Eine Variable enthält die Adressen von bis zu 255 Labels. Diese Macro springt entsprechend dem Index in die Labels ,führt das Programmteil aus und springt dann am ende zu CHOICE_END. Der Vorteil ist das man nur ein Sprung benötigt statt bis zu 255 Abfragen. Mit Codevision habe ich eine ähnliche Lösung schon realisiert: eine Menge an Funktionen in der Form.... void Status1(void){....} void Status2(void){....} einen Feld.... int Z_choice[2...] (void)= {Status1, Status2...}; der Aufruf.... (*choice[index])(); Der Nachteil ist der relativ große Overhead durch Calls und die etsprechende push und pops, die mehr resourcen als das nutzprogramm verbrauchen. Hat jemand ein Vorschlag wie ein solcher Macro aussehen könnte?
rapid schrob: > der Aufruf.... > (*choice[index])(); > > Der Nachteil ist der relativ große Overhead durch Calls und die > etsprechende push und pops, die mehr resourcen als das nutzprogramm > verbrauchen. > > Hat jemand ein Vorschlag wie ein solcher Macro aussehen könnte? Warum sollen das Funktionen sein? Wenn du den Call-Overhead sparen willst tun's doch auch switch/case. Einguter Conmpiler macht da keine 256 Verleiche, sondern arbeitet entweder über ne Sprungtabelle oder splittet die Vergleiche binär, so daß man mit ner handvoll Vergleichen am Ziel ist. Und Calls brauchen nicht soo viel Overhead in nem optimierenden Compiler. Falls du Hack magst, bleibt noch die Möglichkeit von computed goto (GNU-C)
1 | void foo (int i) |
2 | {
|
3 | void ** ll[] = { &&L1, &&L2, ...}; |
4 | |
5 | goto *(ll[i]); |
6 | |
7 | L1: ... |
8 | L2: ... |
9 | ...
|
10 | }
|
Und es gibt die Möglichkeit, Funktionen zu inlinen, was ebenfalls Optimierungspotential offen legt. Weil die Funktionen wohl (statisch) nur 1x aufgerufen werden (was ein guter Compiler ebenfalls ausnutzt, wenn du ihm die Info gibst, d.h. es muss nichtmal explizit geinlint werden). ...und du bist im falschen Forum...
Hallo Johann, vielen Dank für dein Vorschlag. Immerhin bist Du sachlich, im Gegensatz zu den viele Schlauberger danach. Ich bin mir sicher, dass auch sie mal feuchte Windeln hatten und Gott sei dank war jemand da der sie gewechselt hat...oder doch nicht? Leider funktioniert das computed goto nicht mit mein Compiler (Codevision 2) und es ist unnötig zu sagen was ein gute Compiler machen würde wenn.... ja wenn.. die Götter mit dem Programmierer gesprochen hätten... Diese Compiler macht es nun mal nicht. switch() case wird in assembler als eine Ansammlung von if blabla else blabla realisiert. Er akzeptiert LabelNamen nicht als Pointer und kann kein void ** ll[] = { &&L1, &&L2, ...}; und goto *(ll[i]); Das ist ein Manko in Codevision 2. Den habe ich für teures Geld gekauft und nun muss ich damit leben. In meine HW-Anwendung zählt jede us, denn diese und manche andere Routinen werden ständig wiederholt. Meine Idee war ein Assembler macro ein zu setzen der im Grunde ein computed Goto realisiert und nicht vom Compiler abhängig ist. Trotz Recherchen habe ich nichts dergleichen gefunden. Ich bin überzeugt dass ein solche Macro universell verwendbar ist. PS.: wenn ich im falschem Forum bin gibt es hier was besseres?
Rapid wrote: > Hallo Johann, > vielen Dank für dein Vorschlag. > Immerhin bist Du sachlich, im Gegensatz zu den viele Schlauberger > danach. Ich bin mir sicher, dass auch sie mal feuchte Windeln hatten und > Gott sei dank war jemand da der sie gewechselt hat...oder doch nicht? Ich hoffe nicht, dass du mich damit gemeint hast. Ich wollte mit meinem Beitrag nur ausdrücken, dass dies ein häufiges Problem, gerade auch für Anfänger ist und man es deshalb im Tutorial behandeln sollte. > switch() case wird in assembler als eine Ansammlung von if blabla else > blabla realisiert. Der Compiler (Codevision vermutlich auch) hat normal eine Heuristik mit der er versucht die bessere Lösung zu finden. Jump tables werden z.B. dadurch verhindert, dass der Wertebereich der Variablen nicht bekannt ist (kann man dem GCC durch Definition eines enum mitteilen) oder die abgefragten Werte nicht zusammenhängend sind. Vielleicht hilft dir auch das weiter: http://www.netrino.com/node/137
@rapid: Ja, ich war auch mal AVR Anfänger. Aber zu dem Zeitpunkt, war ich schon ca. 10 Jahre lang in der Lage, folgenden Satz zu verstehen: > Wenn ihr eigene Programme oder Anleitungen geschrieben habt könnt ihr sie > hier posten. Fragen werden gelöscht!
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.