Hallo, das obige will ich tun ;) Da die normalen C-Funktionszeiger bei mir nicht funktioniert haben, wollte ich es per inline asm versuchen. Nach verschiedenfachem rumexperimentieren funktioniert nun das da: asm volatile( "push r16\n\t" "push r17\n\t" "mov r16, %0 \n\t" "mov r17, %1 \n\t" "movw r30, r16\n\t" "icall\n\t" "pop r17\n\t" "pop r16\n\t" :: "e" (pointer_lowbyte), "e" (pointer_highbyte)); Allerdings sieht das verdächtig nach überflüssigem Code aus. Das wäre noch nicht so schlimm. Aber ich traue dem Braten nicht, denn folgende frühere Version: asm volatile( "mov r30, %0 \n\t" "mov r31, %1 \n\t" "icall\n\t" :: "e" (pointer_lowbyte), "e" (pointer_highbyte)); funktionierte zwar zuerst, aber der Kompiler hat unvorhersagbar die Register durcheinandergewürfelt. Aus einem mov-Kommando macht er nämlich ein ld (aus der Adresse, die er kennt, in ein Zwischenregister) und dann ein mov (vom Zwischenregister in das angegebene Zielregister (z.B.r30)). Als Zwischenregister hat er aber unterschiedliche genommen, auch mal r30 oder r31, und damit jeweils das andere Byte überschrieben, was zu sehr merkwürdigen Sprungadressen geführt hat, was auch sonst... Die obere Funktion funktioniert nun, aber ich frage mich wie lange. Denn es ist ja immer noch nicht vorgegeben, was der Compiler für ein Zwischenregister benutzt, und damit kann dasselbe Problem auch oben auftreten. Also die Frage: wie rufe ich eine Funktion auf, die durch einen Pointer adressiert ist (und natürlich keine Übergabeparameter hat)? Bzw. wie bekomme ich den Pointer sicher in inline asm und führe einen call aus? Um ehrlich zu sein: ich blicke durch inline asm nicht wirklich durch, z.B. die echten Auswirkungen der compiler constraints, und das Geschehen bei Übergabe von Parametern/Variablen sind mir noch etwas schleierhaft. Vielleicht lässt sich ja die Registerbelegung steuern? Ich hab mal als Alternative "O" ausprobiert, dachte, das muss er doch akzeptieren als uint8_t oder so, aber da kamen nur Fehlermeldungen. Ich hatte noch eine Alternative ausprobiert, und zwar die Pointervariable an Register zu binden: register uint8_t pL asm("r3"); register uint8_t pH asm("r4"); ...code... asm volatile( "mov r30, r3 \n\t" "mov r31, r4 \n\t" "icall\n\t" :: ); Aber das binding hat gar nicht funktioniert, die Variablen lagen nicht in den angegebenen Registern. Habe ich die Syntax auch nicht verstanden? Danke schonmal, Grüße, Henning
. "Da die normalen C-Funktionszeiger bei mir nicht funktioniert haben, " Was spricht dagegen, genau dieses Problem zu lösen? Der Versuch, das mit Inline-Assembler zu "emulieren", dürfte aufgrund der gesteigerten Komplexität noch eher zum Scheitern verurteilt sein.
Hallo Rufus, jedes gelöste Problem ist zwar ein schönes Problem, aber so ists für meinen Fall praktischer. Ich sitze an einem kompakten Menü, wo jeder Eintrag u.a. einen Pointer und ein Typ-Flag besitzt. Je nach Typ kann nun entweder eine Funktion aufgerufen werden, die den Variablentyp hinter Pointer bearbeitet, oder mit derselben Pointervariable direkt eine benutzerdefinierte Spezialfunktion. So spare ich mir viele Bedingungsabfragen. Mit C habe ich da einen Typen-Konflikt (vielleicht ist avr-gcc aber auch toleranter, muss ich mal probieren). Zweitens habe ich die Auswahl zwischen 2 Problemen. Das hier hat schon gezeigt, dass es laufen kann. Ich muss nur einen Weg finden, die Register unter Kontrolle zu halten. Daher wollte ich es so probieren... Die Definition von Funktionszeigern jedenfalls mochte der avr-gcc bisher nicht (in meinen Versuchen).
Ich nehm alles zurück. Ich hab gestern stundenlang getüftelt. Eben hab ich in 5 Minuten mal alles auf Funktionszeiger umgeschrieben, und es läuft auf Anhieb perfekt, problemlos, übersichtlich. ...glaub ich bin überarbeitet... :)) Danke für den Hinweis auf den "normalen Weg zurück"... Grüße, Henning
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.