<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > GNU ARM匯編--(四)中斷匯編之非嵌套中斷處理

          GNU ARM匯編--(四)中斷匯編之非嵌套中斷處理

          作者: 時間:2016-11-26 來源:網(wǎng)絡 收藏
        1. ldrr2,=GPBDAT
        2. ldrr1,=0x0e0
        3. strr1,[r2]
        4. ldrr0,=EINTPEND
        5. ldrr1,=0xf0
        6. strr1,[r0]
        7. ldrr0,=SRCPND
        8. ldrr1,=0x3f@0b11111
        9. strr1,[r0]
        10. ldrr0,=INTPND
        11. ldrr1,=0x3f@0b11111
        12. strr1,[r0]
        13. movpc,lr
        14. delay:
        15. ldrr3,=0xffff
        16. delay1:
        17. subr3,r3,#1
        18. cmpr3,#0x0
        19. bnedelay1
        20. movpc,lr
        21. main:
        22. ledloop:
        23. ldrr1,=0x1c0
        24. strr1,[r2]
        25. bldelay
        26. ldrr1,=0x1a0
        27. strr1,[r2]
        28. bldelay
        29. ldrr1,=0x160
        30. strr1,[r2]
        31. bldelay
        32. ldrr1,=0x0e0
        33. strr1,[r2]
        34. bldelay
        35. bledloop
        36. undefined_instruction:
        37. nop
        38. software_interrupt:
        39. nop
        40. prefetch_abort:
        41. nop
        42. data_abort:
        43. nop
        44. not_used:
        45. nop
        46. fiq:
        47. nop

        48. lds文件:

          本文引用地址:http://www.ex-cimer.com/article/201611/321727.htm

          [cpp]view plaincopy
          1. OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm","elf32-littlearm")
          2. OUTPUT_ARCH(arm)
          3. ENTRY(_start)
          4. SECTIONS{
          5. .=0x00000000;
          6. .text:{
          7. *(.text)
          8. *(.rodata)
          9. }
          10. .dataALIGN(4):{
          11. *(.data)
          12. }
          13. .bssALIGN(4):{
          14. *(.bss)
          15. }
          16. }

          makefile:

          [cpp]view plaincopy
          1. CROSS=arm-linux-
          2. CFLAGS=-nostdlib
          3. int.bin:start.S
          4. ${CROSS}gcc$(CFLAGS)-c-ostart.ostart.S
          5. ${CROSS}ld-Tint.ldsstart.o-oint.elf
          6. #${CROSS}ld-Ttext-segment0x30000000start.o-oint.elf
          7. ${CROSS}objcopy-Obinary-Sint.elfint.bin
          8. #rm-f*.o
          9. clean:
          10. rm-f*.elf*.o
          11. rm-fint.bin

          該程序實現(xiàn)的流水燈,然后四個按鍵可以實現(xiàn)外部中斷.

          代碼中值得注意的地方有幾點:

          1、lds文件中的地址配為0x00000000,因為程序是download到nandflash中運行的.最開始這里寫的是0x30000000,那在異常向量表中:

          @b irq
          ldr pc, _irq

          就出現(xiàn)了一個問題:只能用b irq跳轉,無法用ldr pc, _irq跳轉.當時就覺得奇怪,找了半天原因.后來才知道b跳轉和用ldr偽指令只有區(qū)別的:

          b是位置無關的,ldr不是位置無關的

          b的范圍只能是前后16M,總共32M,而ldr是4G

          ldr的跳轉是根據(jù)_irq: .word irq的值,這個值是鏈接的時候確定的,也就是與鏈接地址相關.

          所以在lds中鏈接地址改為0x00000000后,b和ldr都是正確的.

          具體可以用dump看一下實際效果:

          當lds中是0x30000000時,arm-linux-objdump -d int.elf結果如下:

          30000000 <_start>:
          30000000: ea00000e b 30000040
          30000004: e59ff014 ldr pc, [pc, #20] ; 30000020 <_undefined_instruction>
          30000008: e59ff014 ldr pc, [pc, #20] ; 30000024 <_software_interrupt>
          3000000c: e59ff014 ldr pc, [pc, #20] ; 30000028 <_prefetch_abort>
          30000010: e59ff014 ldr pc, [pc, #20] ; 3000002c <_data_abort>
          30000014: e59ff014 ldr pc, [pc, #20] ; 30000030 <_not_used>
          30000018: e59ff014 ldr pc, [pc, #20] ; 30000034 <_irq>
          3000001c: e59ff014 ldr pc, [pc, #20] ; 30000038 <_fiq>

          而lds中是0x00000000時,dump的結果如下:

          00000000 <_start>:
          0: ea00000e b 40
          4: e59ff014 ldr pc, [pc, #20] ; 20 <_undefined_instruction>
          8: e59ff014 ldr pc, [pc, #20] ; 24 <_software_interrupt>
          c: e59ff014 ldr pc, [pc, #20] ; 28 <_prefetch_abort>
          10: e59ff014 ldr pc, [pc, #20] ; 2c <_data_abort>
          14: e59ff014 ldr pc, [pc, #20] ; 30 <_not_used>
          18: e59ff014 ldr pc, [pc, #20] ; 34 <_irq>
          1c: e59ff014 ldr pc, [pc, #20] ; 38 <_fiq>

          解決了這第一個問題,總算可以用ldr跳入中斷向量了.

          2、中斷處理程序的寫法:

          [cpp]view plaincopy
          1. irq:
          2. sublr,lr,#4
          3. stmfdsp!,{r0-r12,lr}
          4. blirq_isr
          5. ldmfdsp!,{r0-r12,pc}^
          值得注意的是ldmfd sp!,{r0-r12,pc}^ 會自動的從spsr_irq中恢復到cpsr中.

          stmfd等價于stmdb,ldmfd等價于ldmia.因為arm使用FD(向低地址整長的滿棧),所以堆棧處理都用fd的后綴即可.

          3、記得在中斷處理程序中清除中斷,不然的話會一直響應那個中斷.


          上一頁 1 2 下一頁

          關鍵詞: ARM匯編中斷匯編中斷處

          評論


          相關推薦

          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();