新聞中心

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

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

        作者: 時(shí)間:2016-11-26 來(lái)源:網(wǎng)絡(luò) 收藏
      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.104case.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

        該程序?qū)崿F(xiàn)的流水燈,然后四個(gè)按鍵可以實(shí)現(xiàn)外部中斷.

        代碼中值得注意的地方有幾點(diǎn):

        1、lds文件中的地址配為0x00000000,因?yàn)槌绦蚴莇ownload到nandflash中運(yùn)行的.最開(kāi)始這里寫(xiě)的是0x30000000,那在異常向量表中:

        @b irq
        ldr pc, _irq

        就出現(xiàn)了一個(gè)問(wèn)題:只能用b irq跳轉(zhuǎn),無(wú)法用ldr pc, _irq跳轉(zhuǎn).當(dāng)時(shí)就覺(jué)得奇怪,找了半天原因.后來(lái)才知道b跳轉(zhuǎn)和用ldr偽指令只有區(qū)別的:

        b是位置無(wú)關(guān)的,ldr不是位置無(wú)關(guān)的

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

        ldr的跳轉(zhuǎn)是根據(jù)_irq: .word irq的值,這個(gè)值是鏈接的時(shí)候確定的,也就是與鏈接地址相關(guān).

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

        具體可以用dump看一下實(shí)際效果:

        當(dāng)lds中是0x30000000時(shí),arm-linux-objdump -d int.elf結(jié)果如下:

        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時(shí),dump的結(jié)果如下:

        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>

        解決了這第一個(gè)問(wèn)題,總算可以用ldr跳入中斷向量了.

        2、中斷處理程序的寫(xiě)法:

        [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}^ 會(huì)自動(dòng)的從spsr_irq中恢復(fù)到cpsr中.

        stmfd等價(jià)于stmdb,ldmfd等價(jià)于ldmia.因?yàn)閍rm使用FD(向低地址整長(zhǎng)的滿(mǎn)棧),所以堆棧處理都用fd的后綴即可.

        3、記得在中斷處理程序中清除中斷,不然的話(huà)會(huì)一直響應(yīng)那個(gè)中斷.


        上一頁(yè) 1 2 下一頁(yè)

        關(guān)鍵詞: ARM匯編中斷匯編中斷處

        評(píng)論


        相關(guān)推薦

        技術(shù)專(zhuān)區(qū)

        關(guān)閉
        主站蜘蛛池模板: 榕江县| 武清区| 大新县| 额尔古纳市| 高要市| 凌海市| 昌江| 黎川县| 华安县| 吴川市| 资源县| 衡东县| 宣威市| 昌都县| 沐川县| 郓城县| 大石桥市| 台北市| 若尔盖县| 沙洋县| 二手房| 龙里县| 凤台县| 克拉玛依市| 平邑县| 凉山| 承德市| 扶绥县| 应用必备| 青川县| 沽源县| 上蔡县| 丘北县| 青龙| 吕梁市| 长丰县| 额济纳旗| 牙克石市| 汉中市| 永胜县| 阳朔县|