GNU ARM匯編--(四)中斷匯編之非嵌套中斷處理
lds文件:本文引用地址:http://m.butianyuan.cn/article/201611/321727.htm
- OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm","elf32-littlearm")
- OUTPUT_ARCH(arm)
- ENTRY(_start)
- SECTIONS{
- .=0x00000000;
- .text:{
- *(.text)
- *(.rodata)
- }
- .dataALIGN(4):{
- *(.data)
- }
- .bssALIGN(4):{
- *(.bss)
- }
- }
makefile:
- CROSS=arm-linux-
- CFLAGS=-nostdlib
- int.bin:start.S
- ${CROSS}gcc$(CFLAGS)-c-ostart.ostart.S
- ${CROSS}ld-Tint.ldsstart.o-oint.elf
- #${CROSS}ld-Ttext-segment0x30000000start.o-oint.elf
- ${CROSS}objcopy-Obinary-Sint.elfint.bin
- #rm-f*.o
- clean:
- rm-f*.elf*.o
- rm-fint.bin
該程序?qū)崿F(xiàn)的流水燈,然后四個(gè)按鍵可以實(shí)現(xiàn)外部中斷.
代碼中值得注意的地方有幾點(diǎn):
1、lds文件中的地址配為0x00000000,因?yàn)槌绦蚴莇ownload到nandflash中運(yùn)行的.最開始這里寫的是0x30000000,那在異常向量表中:
@b irq
ldr pc, _irq
就出現(xiàn)了一個(gè)問題:只能用b irq跳轉(zhuǎn),無法用ldr pc, _irq跳轉(zhuǎn).當(dāng)時(shí)就覺得奇怪,找了半天原因.后來才知道b跳轉(zhuǎn)和用ldr偽指令只有區(qū)別的:
b是位置無關(guān)的,ldr不是位置無關(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è)問題,總算可以用ldr跳入中斷向量了.
2、中斷處理程序的寫法:
- irq:
- sublr,lr,#4
- stmfdsp!,{r0-r12,lr}
- blirq_isr
- ldmfdsp!,{r0-r12,pc}^
stmfd等價(jià)于stmdb,ldmfd等價(jià)于ldmia.因?yàn)閍rm使用FD(向低地址整長的滿棧),所以堆棧處理都用fd的后綴即可.
3、記得在中斷處理程序中清除中斷,不然的話會(huì)一直響應(yīng)那個(gè)中斷.
評(píng)論