私はアセンブリ言語とmicroblazeCPUにかなり慣れていませんが、割り込み処理を機能させるのに問題があります。
私は自分のスタートアップと初期化ルーチンを書くことを余儀なくされています。(通常はcrt0に含まれているもの)そして、指定されたアドレスの割り込みハンドラーへの分岐で何か問題が発生していると思います。ドキュメントでは、コードアドレス0x10から割り込みハンドラーに分岐すると言われていますが、私のテストプログラムでは機能しません。
ここでmicroblazeのドキュメントを見つけることができます。私はpを参照しています。102(割り込みおよび例外処理)
ここに「my_crt0_intc.asm」のコードが表示されます
bri _start
nop
bri _exception_handler
nop
bri _interrupt_handler
nop
bri _hw_exception_handler
nop
/* Starting Point */
.global _start
_start:
brlid r15, _init_routine
nop
/* Exception Handler *
.global _exception_handler
_exception_handler:
/**/
/* Interrupt Handler */
.global _interrupt_handler
_interrupt_handler:
/* set led 0010 */
ori r20, r20, 0x00000002
swi r20, r0, 0x81400000
rtid r14, 8
nop
/* HW Exception Handler *
.global _hw_exception_handler
_hw_exception_handler:
/**/
/* Init Routine */
.global _init_routine
_init_routine:
/*** Initialize Stack Pointer ***/
addi r1, r0, 0x00004000
/*** ***/
/*** Initialize Interrupts ***/
/** GPIO **/
/* enable interrupts in GIE */
addi r19, r0, 0x80000000
swi r19, r0, 0x8146011C
/* enable interrupts in channel 1 (and 2, not) in IER */
addi r19, r0, 0x00000003
swi r19, r0, 0x81460128
/** INTC **/
/* enable HW interrupts in INTC */
addi r19, r0, 0x00000003
swi r19, r0, 0x8180001C
/* enable interrupts in INTC IER */
addi r19, r0, 0xffffffff
swi r19, r0, 0x81800008
/** CPU, enable interrupts in MSR **/
msrset r19, 0x00000002
/*** ***/
/* Initialize Constants */
/* r11 = word size, for increment and decrement stack pointer */
/* addi r11, r0, 4 */
/*** call main function ***/
brlid r15, main
nop
/*** ***/
/*** halting loop ***/
_halting:
bri _halting
/*** ***/
/* Return */
rtsd r15, 8
nop
私のテストプログラム'test_interrupt_cpu_intc_gpio.asm'は、アドレス0x81400000のLEDを介して割り込みを通知することを目的としています。
/* Main */
.global main
main:
addi r20, r0, 0x0
_loop:
/* set/unset alive led 0001 */
andi r21, r20, 0x00000001
bnei r21, _unset_alive
_set_alive:
ori r20, r20, 0x1
swi r20, r0, 0x81400000
bri _no_alive
_unset_alive:
andi r20, r20, 0xfffffffe
swi r20, r0, 0x81400000
_no_alive:
/* if gpio isr is set, set led 0100 */
lwi r21, r0, 0x81460120
beqi r21, _unset_gpio
_set_gpio:
ori r20, r20, 0x4
swi r20, r0, 0x81400000
bri _noset_gpio
_unset_gpio:
andi r20, r20, 0xfffffffb
swi r20, r0, 0x81400000
_noset_gpio:
/* if intc isr is set, set led 1000 */
lwi r21, r0, 0x81800000
beqi r21, _unset_intc
_set_intc:
ori r20, r20, 0x8
swi r20, r0, 0x81400000
bri _noset_intc
_unset_intc:
andi r20, r20, 0xfffffff7
swi r20, r0, 0x81400000
_noset_intc:
/* begin time loop */
addi r21, r0, 0x004af080
_loop_time:
addi r21, r21, -1
bnei r21, _loop_time
/* end time loop*/
bri _loop
/* return 0*/
addi r3, r0, 0
rtsd r15, 8
nop
エラーの症状は次のとおりです。MSRで割り込みを有効にしない場合、LED 0001が点滅し、適切なボタンを押して割り込みをトリガーすると、LED1000と0100がアクティブになります。ただし、この状況ではもちろん、CPUは割り込みを処理せず、割り込みハンドラルーチンに分岐しません。
しかし、MSRで割り込みを有効にして割り込み処理を有効にすると、最初にLED0001が点滅します。割り込みをトリガーした後、led 0001は永続的に設定されます(または、割り込みが発生したときにled 0001がすでに設定解除されている場合は、それぞれunset)。LED 1000と0100は非アクティブのままです。これは、CPUが機能しなくなったようです。
mb-gccツールを使用して次のようにコードをコンパイルしました。
mb-as test_interrupt_cpu_intc_gpio.o -o test_interrupt_cpu_intc_gpio.o
mb-as my_crt0_intc.asm -o my_crt0_intc.o
mb-ld my_crt0_intc.o test_interrupt_cpu_intc_gpio.o -o ../executable.elf -N
どんな助けでも素晴らしいでしょう。この問題は本当に厄介で、私はこれに何日も取り組んでいます。私は本質的にコードの何かを見逃していると確信しています。追加情報が必要な場合は、お知らせください。
アップデート:
mb-gdbを信頼できる限り、私のプログラムはアドレス0x50から始まります。これが本当なら、これは私のブランチ操作が決して実行されない理由を説明します。
重要な指示を正しい位置に配置するために、いくつかのことを試みました(1)
.org 0x0
brai _start
.org 0x8
brai _exception_handler
.org 0x10
brai _interrupt_handler
.org 0x20
brai _hw_exception_handler
(2)mb-gccとオプションx1-mode-xmdstubでリンクしようとしました(ドキュメントに記載されているように、標準のcrt0.oはこのオプションを使用してリンクされていません)->しかし、この場合、エラーが発生します、_startの複数の定義
(3)mb-ld test_interrupt_cpu_intc_gpio.o my_crt0_intc.o -o../executable.elf-Nを試しました
このように、動作は変更されますが、test_interrupt_cpu_intc_gpio.asmがアドレス0x50で開始されるため、まだ正しくありません。
ありがとう、セマ