Opcodes aus Funktion lesen



  • Folgendes: Ich muss die Interrupttabelle eines ARM einrichten. Bekanntermaßen erwartet das Teil dort statt eines Pointers einen Assemblerbefehl, der zum eigentlichen handler springt.
    Mein Problem ist jetzt: Wie kann ich diesen 4Byte-Opcode möglichst elegant in die Interrupttabelle schreiben?

    Ich habe bis jetzt eine kleine Funktion in einem Assembler-File geschrieben, die nur die entsprechende 4-Byte-Instruktion enthält.
    In meinem C-File habe ich dieselbe Funktion (selber Name) als "Prototyp" so definiert:

    void IRQ_opc ();
    

    Das Ganze wird zusammengelinkt und gibt dabei auch keine Fehlermeldungen.

    Dann habe ich versucht, via (int)IRQ_opc oder (int)*IRQ_opc diese 4-Byte Opcodes auszulesen. Klappt aber nicht - ich kriege stattdessen jedes Mal einen Wert zurück, der eigentlich nur die Adresse der Funktion sein kann.

    Kann mir wer weiter helfen?
    Benutzt wird hier gcc und binutils als ARM crosscompilergefrickel.



  • Habe es jetzt hinbekommen, indem ich diese Funktion als

    int IRQ_opc; extern;
    

    deklariert habe.
    Funktioniert aber immer noch nicht. Curse you, ARM. 😡
    Ich glaube das hat dann aber nichts mehr mit C zu tun.



  • nimm die 'unconditional branch instruction' B (bzw. manchmal auch BAL genannt). opcode+24bit offset == 4 bytes. damit kannst du 32MB vor- und rückwärts springen.
    🙂



  • genervter haptiker schrieb:

    H
    Curse you, ARM. 😡

    ARM ist geil. GCC ist kacke!
    🙂



  • Dieser Thread wurde von Moderator/in Nobuo T aus dem Forum ANSI C in das Forum Assembler verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • So, hier passt es jetzt besser.

    ~fricky schrieb:

    ARM ist geil. GCC ist kacke!
    🙂

    Na das so wie so. 😃
    Zudem fuchst es einfach tierisch, wenn man stundenlang 1000e Seiten Dokumentation waelzt, im Hintergrund groehlende Baetscholeros, die sich wie bloed aufregen/freuen, waehrend sie an ihrer ersten Hausaufgabe basteln. 😡

    ~fricky schrieb:

    nimm die 'unconditional branch instruction' B (bzw. manchmal auch BAL genannt). opcode+24bit offset == 4 bytes. damit kannst du 32MB vor- und rückwärts springen.

    Da der Rechner nur 64MB SDRAM hat, macht sich das fuer den SWI bestimmt ganz gut. Fuer den IRQ (in diesem Fall vom PIT ausgeloest), der mich gerade besonders beschaeftigt, hat dieses Teil (der Atmel AT91RM9200, falls es interessiert) eine Besonderheit im Interrupt-Controller, die es erlaubt, mit einem geschmeidigen

    ldr	PC,[PC, #-0xF20]
    

    durch Auslesen eines Registers je nach IRQ sofort aus der IVT an verschiedene Adressen zu springen. 🙂
    Theoretisch zumindest, denn praktisch funktioniert es wie gesagt (noch) nicht und ich weiss auch noch nicht sicher, woran es liegt. 😞



  • Nobuo T schrieb:

    ...eine Besonderheit im Interrupt-Controller, die es erlaubt, mit einem geschmeidigen

    ldr	PC,[PC, #-0xF20]
    

    durch Auslesen eines Registers je nach IRQ sofort aus der IVT an verschiedene Adressen zu springen. 🙂
    Theoretisch zumindest, denn praktisch funktioniert es wie gesagt (noch) nicht und ich weiss auch noch nicht sicher, woran es liegt.

    das ist doch nix besonderes. weil die ARMs im prinzip nur zwei interrupts haben (IRQ und FIQ), haben sehr viele ARM-basierte chips so einen controller drauf, damit man ganz einfach dedizierte interrupt-handler für verschiedene komponenten schreiben kann. was funzt nicht bei dir? wohin springt er denn? kannst du im asm-code debuggen?
    tip: die iar embedded workbench für ARM gibts als testversion zum freien download. du brauchst noch 'nen JTAG-adapter und dann geht's los.
    von GCC, OpenOCD, und dieser ganzen GNU-grütze würde ich die finger lassen. du ärgerst dich sonst schwarz damit.
    🙂



  • ~fricky schrieb:

    Nobuo T schrieb:

    ...eine Besonderheit im Interrupt-Controller, die es erlaubt, mit einem geschmeidigen

    ldr	PC,[PC, #-0xF20]
    

    durch Auslesen eines Registers je nach IRQ sofort aus der IVT an verschiedene Adressen zu springen. 🙂
    Theoretisch zumindest, denn praktisch funktioniert es wie gesagt (noch) nicht und ich weiss auch noch nicht sicher, woran es liegt.

    das ist doch nix besonderes. weil die ARMs im prinzip nur zwei interrupts haben (IRQ und FIQ), haben sehr viele ARM-basierte chips so einen controller drauf, damit man ganz einfach dedizierte interrupt-handler für verschiedene komponenten schreiben kann.

    Die von Atmel stellten ihr "vectoring" in ihrem Gewaelze als etwas Besonderes dar. Tja, so viele Arm-Systeme habe ich noch nicht programmiert... 😉

    ~fricky schrieb:

    was funzt nicht bei dir? wohin springt er denn?

    Kann ich nicht genau sagen, weil ich nicht direkt debuggen kann. Aber es scheint so, als springt er nirgendwo hin, bzw. als wuerde ueberhaupt kein IRQ auftreten.
    Ich vermute, das liegt daran, dass ich vergessen hatte, das I-Bit im CPSR zu loeschen. Kann das aber erst naechste Woche ausprobieren. 🙂

    ~fricky schrieb:

    tip: die iar embedded workbench für ARM gibts als testversion zum freien download. du brauchst noch 'nen JTAG-adapter und dann geht's los.
    von GCC, OpenOCD, und dieser ganzen GNU-grütze würde ich die finger lassen. du ärgerst dich sonst schwarz damit.
    🙂

    Tja, gibt es nicht, werde ich mir fuer dieses 1-semester Uni-Projekt auch sicher nicht extra anschaffen. Auch mit anderen Toolchains ist es wohl eher Essig... Eine 30-Tage-Version reicht jedenfalls nicht.
    Auf welchem OS soll diese IAR Workbench ueberhaupt laufen? Sah nach Windows aus, stand dort aber nirgendwo (oder ich bin blind). Die Etwicklungsrechner sind AFAIK irgendwelche Ubuntu-Workstations.



  • Nobuo T schrieb:

    ~fricky schrieb:

    was funzt nicht bei dir? wohin springt er denn?

    Kann ich nicht genau sagen, weil ich nicht direkt debuggen kann. Aber es scheint so, als springt er nirgendwo hin, bzw. als wuerde ueberhaupt kein IRQ auftreten.
    Ich vermute, das liegt daran, dass ich vergessen hatte, das I-Bit im CPSR zu loeschen.

    im prinzip musst du drei dinge tun:
    1. global interrupts enablen
    2. interrupt handler für peripherie-komponente beim interrupt-controller registrieren
    3. das entsprechende peripheral so programmieren, dass es interrupts auslöst.
    dann sollte er schon in deine ISR hüpfen.

    Nobuo T schrieb:

    ~fricky schrieb:

    tip: die iar embedded workbench für ARM gibts als testversion zum freien download. du brauchst noch 'nen JTAG-adapter und dann geht's los.
    von GCC, OpenOCD, und dieser ganzen GNU-grütze würde ich die finger lassen. du ärgerst dich sonst schwarz damit.
    🙂

    Tja, gibt es nicht, werde ich mir fuer dieses 1-semester Uni-Projekt auch sicher nicht extra anschaffen. Auch mit anderen Toolchains ist es wohl eher Essig... Eine 30-Tage-Version reicht jedenfalls nicht.

    nach meinem letzten kenntnisstand gibt/gab es zwei testversionen
    1. eine vollversion, die nur 30 tage läuft
    2. eine unbegrenzt lauffähige wersion, mit der man aber nur 8k(?) grosse images erzeugen kann.

    Nobuo T schrieb:

    Auf welchem OS soll diese IAR Workbench ueberhaupt laufen? Sah nach Windows aus, stand dort aber nirgendwo (oder ich bin blind). Die Etwicklungsrechner sind AFAIK irgendwelche Ubuntu-Workstations.

    normalerweise ist der kram für windows. kann natürlich sein, dass die mitllerweile auch 'ne linux-version haben.

    btw, wenn du etwas im internet suchst, findest du auch cracks und keygens für EWARM 4.41A
    🙂


Log in to reply