Hi Ich hab folgendes Problem. Ich hab eine globale Variable in meinem C-Code. Nun möchte ich die Interrupt Service Routine in ASM schreiben, da mir C da zuviele PUSH und POP's reinhaut. Ich mach also mein ASM File und definiere dort mit .global SIG_OUTPUT_COMPARE1B meinen Beginn der Routine. Soweit klappt ja alles noch problemlos. Ich muss aber aus diesem ASM Code auf eine globale C Variable zugreifen. Geht das, oder muss ich mir da irgendwas anderes einfallen lasen?? mfg Andreas -- Andreas Auer aauer1 (at) sbox.tugraz.at Student of Telematics http://home.pages.at/aauer1 Graz, University of Technology
Hi. Könntest mir vielleicht auch noch verraten wie es geht?? Ich bekomm immer eine Fehlermeldung beim Kompilieren, da er die Variable ja nicht finden kann. Muss ich in der ASM Datei auch noch irgendwas definieren?? mfg Andreas
Vielleicht beschreibst Du ja erstmal, was Du denn gemacht hast? Meine Kristallkugel ist leider gerade zur Reparatur...
Ok... ich geb hier mal ein kleines Beispielprog an, so wie meins in etwa aussieht. C-File: ~~~~~~~ unsigned char buffer[1024]; int main(void) { // alle möglichen init's // Timer1 Interrupt initialisieren und starten // Timer1 im Output Compare Mode, wobei der Output Pin toggelt sei(); // global Interrupt enable while(1); } Die Interrupt Service Routine in C ist mir klar. Aber die ist für meine Zwecke unbrauchbar, da sie zu langsam ist. Der Output Pin toggelt etwa alle 10us. Mein ASM File sieht vorerst nur so aus: #include <avr/io.h> .global SIG_OUTPUT_COMPARE1B: reti Damit wollte ich nur mal sehen, ob der Compiler und Linker auch alles richtig zusammensetzt. Hab mir das .lss File erzeugen lassen und es hat gepasst. Bei nem entsprechenden Interrupt wird diese Funktion aufgerufen. Jetzt noch das was ich will: In dem ASM File möchte ich in der ISR die globale C Variabel von oben ("unsigned char buffer[1024]") verwenden. Und zwar brauche ich ja nur die Adresse der Variable. Danach kann ich eh auf alle Werte zugreifen! Ich hab auch schon folgendes in der ISR versucht: ldi r16, high(buffer) Und genau hier liegt das Problem! Ich hoffe, dass ich es jetzt einigermaßen klar gemacht habe! mfg Andreas
Naja, man bekommt auch eine ISR in C durchaus flink, aber lassen wir das. > .global SIG_OUTPUT_COMPARE1B: Das wolltest Du sicher in zwei Zeilen aufteilen, eine mit dem .global, eine mit dem Doppelpunkt für den Label -- sonst nimmt es der Assembler nicht. > In dem ASM File möchte ich in der ISR die globale C Variabel von > oben ("unsigned char buffer[1024]") verwenden. Ja, das .global hast Du ja schon gefunden, da ist doch der Weg bis zum .extern gar nicht mehr weit? Die Typinformation und Größe des Arrays ist natürlich für den Assembler bedeutungslos, die mußt Du als Programmierer ja einhalten. .extern ist übrigens eine Art NOP: der Assembler nimmt alle Namen, die auftauchen und ihm nicht irgendwoher bekannt sind, als `global undefined' an, so daß sie der Linker auflößen muß. .extern dokumentiert aber, daß man sich nicht einfach irgendwas ausgedacht hat als Programmierer, sondern daß es die Definition dieses Objekts irgendwo außerhalb gibt. > ldi r16, high(buffer) Fast. ldi r16, lo8(buffer) ldi r17, hi8(buffer) Leider sind diese beiden Operatoren nicht dokumentiert. :-( (Wie auch alle anderen Erweiterungen im Assembler, die für den AVR gemacht worden sind.) Der einfachste Weg ist immer noch, sich den vom Compiler generierten Code direkt anzusehen (Quelldatei foo.c: "make foo.s", dann foo.s ansehen), da lernt man die paar zusätzlichen Operatoren recht einfach.
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.