嵌入式|ARM 外部中断的过程

前言 ARM的中断和51单片机的中断有不少不同的地方,这里梳理一下ARM外部中断的实现过程。
环境

  • ARM单片机:公司设计的EM537单片机
  • ARM指令集型号:V7-A
正文 一、ARM中断类型 首先参考《ARM体系结构与编程》第九章异常中断处理章节中的内容。
ARM中断可以分为以下几种类型:
嵌入式|ARM 外部中断的过程
文章图片

嵌入式|ARM 外部中断的过程
文章图片

ARM中断向量的地址和优先级表格
嵌入式|ARM 外部中断的过程
文章图片

ARM共有8种类型的中断,中断的数目可以扩展。
EM537中通过TZIC模块,将IRQ中断数目扩展至128。
FIQ的中断,优先级高,延迟低。常用于DMA类型的中断。
我们平时使用最多的还是IRQ外部中断。
二、中断触发-处理中断的过程(以外部中断为例) 2.1 中断的配置
不同平台配置寄存器不同
  1. 打开想使用的中断允许位
  2. 配置中断优先级
  3. 打开总中断
2.2 中断的触发
满足中断触发条件后,由硬件进行触发。
作为开发者不需要关心硬件触发过程。
2.3 中断的执行
首先参考一下EM537的中断向量表:
@vectable.s @-------------------------------- @ vector table @--------------------------------.global _start .global UNDEF_HLDR .global SWI_HLDR .global PREFETCH_HLDR .global ABORT_HLDR .global IRQ_HLDR .global FIQ_HLDR .global JUMP_CS0 .global JUMP_COMMON .armVECTORS: .ifdef BOOT_DENALI ldr pc, =JUMP_COMMON .else .ifdef ARM_EMBEDDED_MODE ldr pc, =_start .else ldr pc, =JUMP_CS0 .endif .endif ldr pc, =UNDEF_HLDR ldr pc, =SWI_HLDR ldr pc, =PREFETCH_HLDR ldr pc, =ABORT_HLDR nop ldr pc, =IRQ_HLDR ldr pc, =FIQ_HLDR nop nop

首先定义的是复位异常中断,此中断跳转地址是正常程序的起始地址**_start**。
然后按顺序定义其他的中断跳转地址。
硬件触发外部中断后,ARM会跳转到IRQ_HLDR。
然后来看看 IRQ_HLDR的汇编。
@crt0.s的部分内容 IRQ_HLDR: stmfdsp!, {r0-r12,lr}ldrr0,= TZIC_BASE_ADDR+0xD80 @; HIPND0 interrupt pending register ldrr0,[r0] mov r2, #0x0 cmp r0, #0 bne FIND_NUMBERldrr0,= TZIC_BASE_ADDR+0xD84 @; HIPND1 interrupt pending register ldrr0,[r0] mov r2, #32 cmp r0, #0 bne FIND_NUMBERldrr0,=TZIC_BASE_ADDR+0xD88 @; HIPND2 interrupt pending register ldrr0,[r0] mov r2, #64 cmp r0, #0 bne FIND_NUMBERldrr0,=TZIC_BASE_ADDR+0xD8C @; HIPND3 interrupt pending register ldrr0,[r0] mov r2, #96 cmp r0, #0 bne FIND_NUMBERFIND_NUMBER: mov r0, r0, lsr #1 cmp r0, #0 beq FOUND_NUMBER add r2, r2, #0x1 b FIND_NUMBERFOUND_NUMBER: mov r2, r2, lsl #2 mov r0, r2ldrlr,=INTERRUPT_0 ldrr0,[lr,r0] movlr,pc bxr0 mrsr0, cpsr bicr1, r0, #0x100 msrcpsr_cxsf, r1 ldmfdsp!, {r0-r12,lr} subspc,lr,#4

首先stmfd 压栈, 保护CPU状态。
接下来是4段比较相似的程序,用于查询触发的外部中断号。
TZIC 实现了128个外部中断,使用前需要先对TZIC进行配置。
设置相应中断的中断号。如果此中断触发,就可以在HIPND(0-3) interrupt pending register这四个寄存器中查到。
【嵌入式|ARM 外部中断的过程】然后解析一下其中一段程序的内容:
@将中断挂起寄存器0的地址,保存到r0 ldrr0,= TZIC_BASE_ADDR+0xD80 @; HIPND0 interrupt pending register@寄存器间接寻址,将r0寄存器的值看作地址,然后将地址对应的值传给r0 ldrr0,[r0]@r2 = 0 mov r2, #0x0@比较r0和0的大小,如果r0!=0,则跳转FIND_NUMBER cmp r0, #0 bne FIND_NUMBER@回顾这段代码,功能是检查中断挂起寄存器的值,如果全零就检查下一个,否则跳转FIND_NUMBER计算相应的中断号

FIND_NUMBER通过移位找出中断号,然后保存在r2中。
FOUND_NUMBER首先左移2,相当于*4,是为了计算相应的偏移地址。然后保存在r0中。
ldrlr,=INTERRUPT_0 ldrr0,[lr,r0]

这两句是相对寻址,最后r0=INTERRUPT_0的地址+r0。
结合下面的汇编代码,更容易理解
然后就可以跳转到对应的外部中断处理程序。
@int_table.s的部分 .global INTERRUPT_0 .global ESDHC1_INT_ROUTINE .global ESDHC2_INT_ROUTINE .global ESDHC3_INT_ROUTINE .global ESDHC4_INT_ROUTINE .global DAP_INT_ROUTINE .global SDMA_INT_ROUTINE .global IOMUX_INT_ROUTINE .global EMI1_INT_ROUTINE .global VPU1_INT_ROUTINE .global IPU_ERR_INT_ROUTINE .global IPU_FUNC_INT_ROUTINE .global GPU1_INT_ROUTINE .global UART4_ANDED_INT_ROUTINE .global USB_UH1_INT_ROUTINE .global EMI2_INT_ROUTINE .global USB_UH2_INT_ROUTINE .global USB_UH3_INT_ROUTINE .global USB_UOTG_INT_ROUTINE .global SAHARA_INT1_ROUTINE .global SAHARA_INT2_ROUTINE .global SCC_SMON_INT_ROUTINE .global SCC_SCTL_INT_ROUTINE .global SCC_SCTL_NS_INT_ROUTINE .global SRTC_INT_ROUTINE .global SRTC_SEC_INT_ROUTINE .global RTIC_INT_ROUTINE .global CSU_INT_ROUTINE .global SATA_INT_ROUTINE .global SSI1_INT_ROUTINE .global SSI2_INT_ROUTINE .global UART1_ANDED_INT_ROUTINE .global UART2_ANDED_INT_ROUTINE .global UART3_ANDED_INT_ROUTINE

2.4 代码中调用中断(动态设置中断函数)
首先引用一下,参考文献1,2关于global的说明
.global 修饰标号为全局的,用法 .global xxx 这个符号可以被当前源文件以外的其他文件使用也可以被连接脚本(连接器)使用,xxx仅仅是一个标号对应一个地址并不是C中的一个变量。
无法对他取地址,因为他本身代表一个地址,仅仅是一个对应到一个编译过程中的值的别名,类似C代码中的define 定义的一样,只是在链接时他的值是由连接器自动处理的。
汇编代码使用仅能使用ldr,Rx,=xxx;而不能使用ldr,Rx,xxx
.global关键字用来让一个符号对链接器可见,可以供其他链接对象模块使用。
.global _start 让_start符号成为可见的标示符,这样链接器就知道跳转到程序中的什么地方并开始执行。linux寻找这个 _start标签作为程序的默认进入点。
在汇编和C混合编程中,在GNU ARM编译环境下,汇编程序中要使用.global伪操作声明汇编程序为全局的函数,意即可被外部函数调用,同时C程序中要使用extern声明要调用的汇编语言程序。
所以ini_table.s中的.global UART1_ANDED_INT_ROUTINE只是声明了一个符号,并没有相应的程序。
在interrupt.h文件中extern void ( *UART1_ANDED_INT_ROUTINE )(void); 使用extern关键字声明,以便在c里面进行调用。
这里声明的UART1_ANDED_INT_ROUTINE是一个函数指针。
这里引用参考文献4中的介绍:
嵌入式|ARM 外部中断的过程
文章图片

因此可以通过更改UART1_ANDED_INT_ROUTINE中断函数指针指向的函数,实现动态更改中断函数。
EM537中使用下面里例子进行设置:
#define CAPTURE_INTERRUPT(handle,routine) handle = (void (*)(void)) routine __irq(intr_routin1) #pragma interrupt intr_routin1 void intr_routin1(void);void intr_routin1(void){ //用户自定义函数内容 }void main(){ CAPTURE INTERRUPT(UART1_ANDED_INT_ROUTINE, intr_routin1); }

三、ARM初始化配置 想要正确的执行中断,还需要对ARM寄存器进行上电初始化。
初始化的主要功能是:
  1. 初始化Rn等常用寄存器的值为0;(理论上要使用的内存区域都要初始化,避免硬件初始化值不同造成错误。)
  2. 初始化各种处理器模式下的堆栈指针,否则堆栈指针可能会覆盖内存中的值,造成程序错误。
  3. 进入SPVR 模式 打开程序状态寄存器(CPSR)中的IRQ和FIQ中断标志位。
附件2 crt0.s是初始化相关的汇编代码。
附件 1. interrupt.h
// These interrupts MUST be defined in the correct order.// IRQ INTERRUPT extern void ( *INTERRUPT_0 )(void); //RESERVED extern void ( *ESDHC1_INT_ROUTINE )(void); extern void ( *ESDHC2_INT_ROUTINE )(void); extern void ( *ESDHC3_INT_ROUTINE )(void); extern void ( *ESDHC4_INT_ROUTINE )(void); extern void ( *DAP_INT_ROUTINE )(void); extern void ( *SDMA_INT_ROUTINE )(void); extern void ( *IOMUX_INT_ROUTINE )(void); extern void ( *EMI1_INT_ROUTINE )(void); extern void ( *VPU1_INT_ROUTINE )(void); extern void ( *IPU_ERR_INT_ROUTINE )(void); extern void ( *IPU_FUNC_INT_ROUTINE )(void); extern void ( *GPU1_INT_ROUTINE )(void); extern void ( *UART4_ANDED_INT_ROUTINE )(void); extern void ( *USB_UH1_INT_ROUTINE )(void); extern void ( *EMI2_INT_ROUTINE )(void); extern void ( *USB_UH2_INT_ROUTINE )(void); extern void ( *USB_UH3_INT_ROUTINE )(void); extern void ( *USB_UOTG_INT_ROUTINE )(void); extern void ( *SAHARA_INT1_ROUTINE )(void); extern void ( *SAHARA_INT2_ROUTINE )(void); extern void ( *SCC_SMON_INT_ROUTINE )(void); extern void ( *SCC_SCTL_INT_ROUTINE )(void); extern void ( *SCC_SCTL_NS_INT_ROUTINE )(void); extern void ( *SRTC_INT_ROUTINE )(void); extern void ( *SRTC_SEC_INT_ROUTINE )(void); extern void ( *RTIC_INT_ROUTINE )(void); extern void ( *CSU_INT_ROUTINE )(void); extern void ( *SATA_INT_ROUTINE )(void); extern void ( *SSI1_INT_ROUTINE )(void); extern void ( *SSI2_INT_ROUTINE )(void); extern void ( *UART1_ANDED_INT_ROUTINE )(void); extern void ( *UART2_ANDED_INT_ROUTINE )(void); extern void ( *UART3_ANDED_INT_ROUTINE )(void); extern void ( *RTC_INT_ROUTINE )(void); extern void ( *PTP_INT_ROUTINE )(void); extern void ( *ECSPI1_INT_ROUTINE )(void); extern void ( *ECSPI2_INT_ROUTINE )(void); extern void ( *CSPI_INT_ROUTINE )(void); extern void ( *GPT_INT_ROUTINE )(void); extern void ( *EPIT1_INT_ROUTINE )(void); extern void ( *EPIT2_INT_ROUTINE )(void); extern void ( *GPIO1_INT7_ROUTINE )(void); extern void ( *GPIO1_INT6_ROUTINE )(void); extern void ( *GPIO1_INT5_ROUTINE )(void); extern void ( *GPIO1_INT4_ROUTINE )(void); extern void ( *GPIO1_INT3_ROUTINE )(void); extern void ( *GPIO1_INT2_ROUTINE )(void); extern void ( *GPIO1_INT1_ROUTINE )(void); extern void ( *GPIO1_INT0_ROUTINE )(void); extern void ( *GPIO1_INT15_0_ROUTINE )(void); extern void ( *GPIO1_INT31_16_ROUTINE )(void); extern void ( *GPIO2_INT15_0_ROUTINE )(void); extern void ( *GPIO2_INT31_16_ROUTINE )(void); extern void ( *GPIO3_INT15_0_ROUTINE )(void); extern void ( *GPIO3_INT31_16_ROUTINE )(void); extern void ( *GPIO4_INT15_0_ROUTINE )(void); extern void ( *GPIO4_INT31_16_ROUTINE )(void); extern void ( *WDOG1_INT_ROUTINE )(void); extern void ( *WDOG2_INT_ROUTINE )(void); extern void ( *KPP_INT_ROUTINE )(void); extern void ( *PWM1_INT_ROUTINE )(void); extern void ( *I2C1_INT_ROUTINE )(void); extern void ( *I2C2_INT_ROUTINE )(void); extern void ( *I2C3_INT_ROUTINE )(void); extern void ( *MLB_INT_ROUTINE )(void); extern void ( *ASRC_INT_ROUTINE )(void); extern void ( *SPDIF_INT_ROUTINE )(void); extern void ( *INTERRUPT_68 )(void); //RESERVED extern void ( *IIM_INT_ROUTINE )(void); extern void ( *PATA_INT_ROUTINE )(void); extern void ( *CCM_INT1_ROUTINE )(void); extern void ( *CCM_INT2_ROUTINE )(void); extern void ( *GPC_INT1_ROUTINE )(void); extern void ( *GPC_INT2_ROUTINE )(void); extern void ( *SRC_INT_ROUTINE )(void); extern void ( *TIGERP_PLATFORM_NE_32K_256K_NM_INT_ROUTINE )(void); extern void ( *TIGERP_PLATFORM_NE_32K_256K_PMU_INT_ROUTINE )(void); extern void ( *TIGERP_PLATFORM_NE_32K_256K_CTI_INT_ROUTINE )(void); extern void ( *TIGERP_PLATFORM_NE_32K_256K1_INT_ROUTINE )(void); extern void ( *TIGERP_PLATFORM_NE_32K_256K2_INT_ROUTINE )(void); extern void ( *ESAI1_INT_ROUTINE )(void); extern void ( *CAN1_INT_ROUTINE )(void); extern void ( *CAN2_INT_ROUTINE )(void); extern void ( *GPU2D_IRQ_INT_ROUTINE )(void); extern void ( *GPU2D_BUSY_INT_ROUTINE )(void); extern void ( *UART5_ANDED_INT_ROUTINE )(void); extern void ( *FEC_INT_ROUTINE )(void); extern void ( *OWIRE_INT_ROUTINE )(void); extern void ( *TIGERP_PLATFORM_NE_32K_256K3_INT_ROUTINE )(void); extern void ( *SJC_INT_ROUTINE )(void); extern void ( *INTERRUPT_91 )(void); //RESERVED extern void ( *TVOUT_INT_ROUTINE )(void); extern void ( *FIRI_INT_ROUTINE )(void); extern void ( *PWM2_INT_ROUTINE )(void); extern void ( *INTERRUPT_95 )(void); //RESERVED extern void ( *SSI3_INT_ROUTINE )(void); extern void ( *INTERRUPT_97 )(void); //RESERVED extern void ( *TIGERP_PLATFORM_NE_32K_256K4_INT_ROUTINE )(void); extern void ( *INTERRUPT_99 )(void); //RESERVED extern void ( *VPU2_INT_ROUTINE )(void); extern void ( *EMI_PROG_INT_ROUTINE )(void); extern void ( *GPU2_INT_ROUTINE )(void); extern void ( *GPIO5_INT15_0_ROUTINE )(void); extern void ( *GPIO5_INT31_16_ROUTINE )(void); extern void ( *GPIO6_INT15_0_ROUTINE )(void); extern void ( *GPIO6_INT31_16_ROUTINE )(void); extern void ( *GPIO7_INT15_0_ROUTINE )(void); extern void ( *GPIO7_INT31_16_ROUTINE )(void); extern void ( *INTERRUPT_109_128 )(void); //RESERVED// IRQ TZIC INTERRUPT NUMBER #define INTERRUPT_0_NUM0//RESERVED #define ESDHC1_INT_NUM1 #define ESDHC2_INT_NUM2 #define ESDHC3_INT_NUM3 #define ESDHC4_INT_NUM4 #define DAP_INT_NUM5 #define SDMA_INT_NUM6 #define IOMUX_INT_NUM7 #define EMI1_INT_NUM8 #define VPU1_INT_NUM9 #define IPU_ERR_INT_NUM10 #define IPU_FUNC_INT_NUM11 #define GPU1_INT_NUM12 #define UART4_ANDED_INT_NUM13 #define USB_UH1_INT_NUM14 #define EMI2_INT_NUM15 #define USB_UH2_INT_NUM16 #define USB_UH3_INT_NUM17 #define USB_UOTG_INT_NUM18 #define SAHARA_INT1_NUM19 #define SAHARA_INT2_NUM20 #define SCC_SMON_INT_NUM21 #define SCC_SCTL_INT_NUM22 #define SCC_SCTL_NS_INT_NUM23 #define SRTC_INT_NUM24 #define SRTC_SEC_INT_NUM25 #define RTIC_INT_NUM26 #define CSU_INT_NUM27 #define SATA_INT_NUM28 #define SSI1_INT_NUM29 #define SSI2_INT_NUM30 #define UART1_ANDED_INT_NUM31 #define UART2_ANDED_INT_NUM32 #define UART3_ANDED_INT_NUM33 #define RTC_INT_NUM34 #define PTP_INT_NUM35 #define ECSPI1_INT_NUM36 #define ECSPI2_INT_NUM37 #define CSPI_INT_NUM38 #define GPT_INT_NUM39 #define EPIT1_INT_NUM40 #define EPIT2_INT_NUM41 #define GPIO1_INT7_NUM42 #define GPIO1_INT6_NUM43 #define GPIO1_INT5_NUM44 #define GPIO1_INT4_NUM45 #define GPIO1_INT3_NUM46 #define GPIO1_INT2_NUM47 #define GPIO1_INT1_NUM48 #define GPIO1_INT0_NUM49 #define GPIO1_INT15_0_NUM50 #define GPIO1_INT31_16_NUM51 #define GPIO2_INT15_0_NUM52 #define GPIO2_INT31_16_NUM53 #define GPIO3_INT15_0_NUM54 #define GPIO3_INT31_16_NUM55 #define GPIO4_INT15_0_NUM56 #define GPIO4_INT31_16_NUM57 #define WDOG1_INT_NUM58 #define WDOG2_INT_NUM59 #define KPP_INT_NUM60 #define PWM1_INT_NUM61 #define I2C1_INT_NUM62 #define I2C2_INT_NUM63 #define I2C3_INT_NUM64 #define MLB_INT_NUM65 #define ASRC_INT_NUM66 #define SPDIF_INT_NUM67 #define INTERRUPT_68_NUM68//RESERVED #define IIM_INT_NUM69 #define PATA_INT_NUM70 #define CCM_INT1_NUM71 #define CCM_INT2_NUM72 #define GPC_INT1_NUM73 #define GPC_INT2_NUM74 #define SRC_INT_NUM75 #define TIGERP_PLATFORM_NE_32K_256K_NM_INT_NUM76 #define TIGERP_PLATFORM_NE_32K_256K_PMU_INT_NUM77 #define TIGERP_PLATFORM_NE_32K_256K_CTI_INT_NUM78 #define TIGERP_PLATFORM_NE_32K_256K1_INT_NUM79 #define TIGERP_PLATFORM_NE_32K_256K2_INT_NUM80 #define ESAI1_INT_NUM81 #define CAN1_INT_NUM82 #define CAN2_INT_NUM83 #define GPU2D_IRQ_INT_NUM84 #define GPU2D_BUSY_INT_NUM85 #define UART5_ANDED_INT_NUM86 #define FEC_INT_NUM87 #define OWIRE_INT_NUM88 #define TIGERP_PLATFORM_NE_32K_256K3_INT_NUM89 #define SJC_INT_NUM90 #define INTERRUPT_91_NUM91//RESERVED #define TVOUT_INT_NUM92 #define FIRI_INT_NUM93 #define PWM2_INT_NUM94 #define INTERRUPT_95_NUM95//RESERVED #define SSI3_INT_NUM96 #define INTERRUPT_97_NUM97//RESERVED #define TIGERP_PLATFORM_NE_32K_256K4_INT_NUM98 #define INTERRUPT_99_NUM99//RESERVED #define VPU2_INT_NUM100 #define EMI_PROG_INT_NUM101 #define GPU2_INT_NUM102 #define GPIO5_INT15_0_NUM103 #define GPIO5_INT31_16_NUM104 #define GPIO6_INT15_0_NUM105 #define GPIO6_INT31_16_NUM106 #define GPIO7_INT15_0_NUM107 #define GPIO7_INT31_16_NUM108 #define INTERRUPT_109_128_NUM109//RESERVED#ifdef ROC_TEST #define ROC_ABORT_INTERRUPT127 //abort interrupt for ROC test only!!! (shayg) #endif //ROC_TEST// FIQ INTERRUPT extern void ( *FIQ_INTERRUPT_0 )(void); //RESERVED extern void ( *FIQ_ESDHC1_INT_ROUTINE )(void); extern void ( *FIQ_ESDHC2_INT_ROUTINE )(void); extern void ( *FIQ_ESDHC3_INT_ROUTINE )(void); extern void ( *FIQ_ESDHC4_INT_ROUTINE )(void); extern void ( *FIQ_DAP_INT_ROUTINE )(void); extern void ( *FIQ_SDMA_INT_ROUTINE )(void); extern void ( *FIQ_IOMUX_INT_ROUTINE )(void); extern void ( *FIQ_EMI1_INT_ROUTINE )(void); extern void ( *FIQ_VPU1_INT_ROUTINE )(void); extern void ( *FIQ_IPU_ERR_INT_ROUTINE )(void); extern void ( *FIQ_IPU_FUNC_INT_ROUTINE )(void); extern void ( *FIQ_GPU1_INT_ROUTINE )(void); extern void ( *FIQ_UART4_ANDED_INT_ROUTINE )(void); extern void ( *FIQ_USB_UH1_INT_ROUTINE )(void); extern void ( *FIQ_EMI2_INT_ROUTINE )(void); extern void ( *FIQ_USB_UH2_INT_ROUTINE )(void); extern void ( *FIQ_USB_UH3_INT_ROUTINE )(void); extern void ( *FIQ_USB_UOTG_INT_ROUTINE )(void); extern void ( *FIQ_SAHARA_INT1_ROUTINE )(void); extern void ( *FIQ_SAHARA_INT2_ROUTINE )(void); extern void ( *FIQ_SCC_SMON_INT_ROUTINE )(void); extern void ( *FIQ_SCC_SCTL_INT_ROUTINE )(void); extern void ( *FIQ_SCC_SCTL_NS_INT_ROUTINE )(void); extern void ( *FIQ_SRTC_INT_ROUTINE )(void); extern void ( *FIQ_SRTC_SEC_INT_ROUTINE )(void); extern void ( *FIQ_RTIC_INT_ROUTINE )(void); extern void ( *FIQ_CSU_INT_ROUTINE )(void); extern void ( *FIQ_SATA_INT_ROUTINE )(void); extern void ( *FIQ_SSI1_INT_ROUTINE )(void); extern void ( *FIQ_SSI2_INT_ROUTINE )(void); extern void ( *FIQ_UART1_ANDED_INT_ROUTINE )(void); extern void ( *FIQ_UART2_ANDED_INT_ROUTINE )(void); extern void ( *FIQ_UART3_ANDED_INT_ROUTINE )(void); extern void ( *FIQ_RTC_INT_ROUTINE )(void); extern void ( *FIQ_PTP_INT_ROUTINE )(void); extern void ( *FIQ_ECSPI1_INT_ROUTINE )(void); extern void ( *FIQ_ECSPI2_INT_ROUTINE )(void); extern void ( *FIQ_CSPI_INT_ROUTINE )(void); extern void ( *FIQ_GPT_INT_ROUTINE )(void); extern void ( *FIQ_EPIT1_INT_ROUTINE )(void); extern void ( *FIQ_EPIT2_INT_ROUTINE )(void); extern void ( *FIQ_GPIO1_INT7_ROUTINE )(void); extern void ( *FIQ_GPIO1_INT6_ROUTINE )(void); extern void ( *FIQ_GPIO1_INT5_ROUTINE )(void); extern void ( *FIQ_GPIO1_INT4_ROUTINE )(void); extern void ( *FIQ_GPIO1_INT3_ROUTINE )(void); extern void ( *FIQ_GPIO1_INT2_ROUTINE )(void); extern void ( *FIQ_GPIO1_INT1_ROUTINE )(void); extern void ( *FIQ_GPIO1_INT0_ROUTINE )(void); extern void ( *FIQ_GPIO1_INT15_0_ROUTINE )(void); extern void ( *FIQ_GPIO1_INT31_16_ROUTINE )(void); extern void ( *FIQ_GPIO2_INT15_0_ROUTINE )(void); extern void ( *FIQ_GPIO2_INT31_16_ROUTINE )(void); extern void ( *FIQ_GPIO3_INT15_0_ROUTINE )(void); extern void ( *FIQ_GPIO3_INT31_16_ROUTINE )(void); extern void ( *FIQ_GPIO4_INT15_0_ROUTINE )(void); extern void ( *FIQ_GPIO4_INT31_16_ROUTINE )(void); extern void ( *FIQ_WDOG1_INT_ROUTINE )(void); extern void ( *FIQ_WDOG2_INT_ROUTINE )(void); extern void ( *FIQ_KPP_INT_ROUTINE )(void); extern void ( *FIQ_PWM1_INT_ROUTINE )(void); extern void ( *FIQ_I2C1_INT_ROUTINE )(void); extern void ( *FIQ_I2C2_INT_ROUTINE )(void); extern void ( *FIQ_I2C3_INT_ROUTINE )(void); extern void ( *FIQ_MLB_INT_ROUTINE )(void); extern void ( *FIQ_ASRC_INT_ROUTINE )(void); extern void ( *FIQ_SPDIF_INT_ROUTINE )(void); extern void ( *FIQ_INTERRUPT_68 )(void); //RESERVED extern void ( *FIQ_IIM_INT_ROUTINE )(void); extern void ( *FIQ_PATA_INT_ROUTINE )(void); extern void ( *FIQ_CCM_INT1_ROUTINE )(void); extern void ( *FIQ_CCM_INT2_ROUTINE )(void); extern void ( *FIQ_GPC_INT1_ROUTINE )(void); extern void ( *FIQ_GPC_INT2_ROUTINE )(void); extern void ( *FIQ_SRC_INT_ROUTINE )(void); extern void ( *FIQ_TIGERP_PLATFORM_NE_32K_256K_NM_INT_ROUTINE )(void); extern void ( *FIQ_TIGERP_PLATFORM_NE_32K_256K_PMU_INT_ROUTINE )(void); extern void ( *FIQ_TIGERP_PLATFORM_NE_32K_256K_CTI_INT_ROUTINE )(void); extern void ( *FIQ_TIGERP_PLATFORM_NE_32K_256K1_INT_ROUTINE )(void); extern void ( *FIQ_TIGERP_PLATFORM_NE_32K_256K2_INT_ROUTINE )(void); extern void ( *FIQ_ESAI1_INT_ROUTINE )(void); extern void ( *FIQ_CAN1_INT_ROUTINE )(void); extern void ( *FIQ_CAN2_INT_ROUTINE )(void); extern void ( *FIQ_GPU2D_IRQ_INT_ROUTINE )(void); extern void ( *FIQ_GPU2D_BUSY_INT_ROUTINE )(void); extern void ( *FIQ_UART5_ANDED_INT_ROUTINE )(void); extern void ( *FIQ_FEC_INT_ROUTINE )(void); extern void ( *FIQ_OWIRE_INT_ROUTINE )(void); extern void ( *FIQ_TIGERP_PLATFORM_NE_32K_256K3_INT_ROUTINE )(void); extern void ( *FIQ_SJC_INT_ROUTINE )(void); extern void ( *FIQ_INTERRUPT_91 )(void); //RESERVED extern void ( *FIQ_TVOUT_INT_ROUTINE )(void); extern void ( *FIQ_FIRI_INT_ROUTINE )(void); extern void ( *FIQ_PWM2_INT_ROUTINE )(void); extern void ( *FIQ_INTERRUPT_95 )(void); //RESERVED extern void ( *FIQ_SSI3_INT_ROUTINE )(void); extern void ( *FIQ_INTERRUPT_97 )(void); //RESERVED extern void ( *FIQ_TIGERP_PLATFORM_NE_32K_256K4_INT_ROUTINE )(void); extern void ( *FIQ_INTERRUPT_99 )(void); //RESERVED extern void ( *FIQ_VPU2_INT_ROUTINE )(void); extern void ( *FIQ_EMI_PROG_INT_ROUTINE )(void); extern void ( *FIQ_GPU2_INT_ROUTINE )(void); extern void ( *FIQ_GPIO5_INT15_0_ROUTINE )(void); extern void ( *FIQ_GPIO5_INT31_16_ROUTINE )(void); extern void ( *FIQ_GPIO6_INT15_0_ROUTINE )(void); extern void ( *FIQ_GPIO6_INT31_16_ROUTINE )(void); extern void ( *FIQ_GPIO7_INT15_0_ROUTINE )(void); extern void ( *FIQ_GPIO7_INT31_16_ROUTINE )(void); extern void ( *FIQ_INTERRUPT_109_128 )(void); //RESERVED// FIQ TZIC INTERRUPT NUMBER #define FIQ_INTERRUPT_0_NUM0//RESERVED #define FIQ_ESDHC1_INT_NUM1 #define FIQ_ESDHC2_INT_NUM2 #define FIQ_ESDHC3_INT_NUM3 #define FIQ_ESDHC4_INT_NUM4 #define FIQ_DAP_INT_NUM5 #define FIQ_SDMA_INT_NUM6 #define FIQ_IOMUX_INT_NUM7 #define FIQ_EMI1_INT_NUM8 #define FIQ_VPU1_INT_NUM9 #define FIQ_IPU_ERR_INT_NUM10 #define FIQ_IPU_FUNC_INT_NUM11 #define FIQ_GPU1_INT_NUM12 #define FIQ_UART4_ANDED_INT_NUM13 #define FIQ_USB_UH1_INT_NUM14 #define FIQ_EMI2_INT_NUM15 #define FIQ_USB_UH2_INT_NUM16 #define FIQ_USB_UH3_INT_NUM17 #define FIQ_USB_UOTG_INT_NUM18 #define FIQ_SAHARA_INT1_NUM19 #define FIQ_SAHARA_INT2_NUM20 #define FIQ_SCC_SMON_INT_NUM21 #define FIQ_SCC_SCTL_INT_NUM22 #define FIQ_SCC_SCTL_NS_INT_NUM23 #define FIQ_SRTC_INT_NUM24 #define FIQ_SRTC_SEC_INT_NUM25 #define FIQ_RTIC_INT_NUM26 #define FIQ_CSU_INT_NUM27 #define FIQ_SATA_INT_NUM28 #define FIQ_SSI1_INT_NUM29 #define FIQ_SSI2_INT_NUM30 #define FIQ_UART1_ANDED_INT_NUM31 #define FIQ_UART2_ANDED_INT_NUM32 #define FIQ_UART3_ANDED_INT_NUM33 #define FIQ_RTC_INT_NUM34 #define FIQ_PTP_INT_NUM35 #define FIQ_ECSPI1_INT_NUM36 #define FIQ_ECSPI2_INT_NUM37 #define FIQ_CSPI_INT_NUM38 #define FIQ_GPT_INT_NUM39 #define FIQ_EPIT1_INT_NUM40 #define FIQ_EPIT2_INT_NUM41 #define FIQ_GPIO1_INT7_NUM42 #define FIQ_GPIO1_INT6_NUM43 #define FIQ_GPIO1_INT5_NUM44 #define FIQ_GPIO1_INT4_NUM45 #define FIQ_GPIO1_INT3_NUM46 #define FIQ_GPIO1_INT2_NUM47 #define FIQ_GPIO1_INT1_NUM48 #define FIQ_GPIO1_INT0_NUM49 #define FIQ_GPIO1_INT15_0_NUM50 #define FIQ_GPIO1_INT31_16_NUM51 #define FIQ_GPIO2_INT15_0_NUM52 #define FIQ_GPIO2_INT31_16_NUM53 #define FIQ_GPIO3_INT15_0_NUM54 #define FIQ_GPIO3_INT31_16_NUM55 #define FIQ_GPIO4_INT15_0_NUM56 #define FIQ_GPIO4_INT31_16_NUM57 #define FIQ_WDOG1_INT_NUM58 #define FIQ_WDOG2_INT_NUM59 #define FIQ_KPP_INT_NUM60 #define FIQ_PWM1_INT_NUM61 #define FIQ_I2C1_INT_NUM62 #define FIQ_I2C2_INT_NUM63 #define FIQ_I2C3_INT_NUM64 #define FIQ_MLB_INT_NUM65 #define FIQ_ASRC_INT_NUM66 #define FIQ_SPDIF_INT_NUM67 #define FIQ_INTERRUPT_68_NUM68//RESERVED #define FIQ_IIM_INT_NUM69 #define FIQ_PATA_INT_NUM70 #define FIQ_CCM_INT1_NUM71 #define FIQ_CCM_INT2_NUM72 #define FIQ_GPC_INT1_NUM73 #define FIQ_GPC_INT2_NUM74 #define FIQ_SRC_INT_NUM75 #define FIQ_TIGERP_PLATFORM_NE_32K_256K_NM_INT_NUM76 #define FIQ_TIGERP_PLATFORM_NE_32K_256K_PMU_INT_NUM77 #define FIQ_TIGERP_PLATFORM_NE_32K_256K_CTI_INT_NUM78 #define FIQ_TIGERP_PLATFORM_NE_32K_256K1_INT_NUM79 #define FIQ_TIGERP_PLATFORM_NE_32K_256K2_INT_NUM80 #define FIQ_ESAI1_INT_NUM81 #define FIQ_CAN1_INT_NUM82 #define FIQ_CAN2_INT_NUM83 #define FIQ_GPU2D_IRQ_INT_NUM84 #define FIQ_GPU2D_BUSY_INT_NUM85 #define FIQ_UART5_ANDED_INT_NUM86 #define FIQ_FEC_INT_NUM87 #define FIQ_OWIRE_INT_NUM88 #define FIQ_TIGERP_PLATFORM_NE_32K_256K3_INT_NUM89 #define FIQ_SJC_INT_NUM90 #define FIQ_INTERRUPT_91_NUM91//RESERVED #define FIQ_TVOUT_INT_NUM92 #define FIQ_FIRI_INT_NUM93 #define FIQ_PWM2_INT_NUM94 #define FIQ_INTERRUPT_95_NUM95//RESERVED #define FIQ_SSI3_INT_NUM96 #define FIQ_INTERRUPT_97_NUM97 #define FIQ_TIGERP_PLATFORM_NE_32K_256K4_INT_NUM98 #define FIQ_INTERRUPT_99_NUM99//RESERVED #define FIQ_VPU2_INT_NUM100 #define FIQ_EMI_PROG_INT_NUM101 #define FIQ_GPU2_INT_NUM102 #define FIQ_GPIO5_INT15_0_NUM103 #define FIQ_GPIO5_INT31_16_NUM104 #define FIQ_GPIO6_INT15_0_NUM105 #define FIQ_GPIO6_INT31_16_NUM106 #define FIQ_GPIO7_INT15_0_NUM107 #define FIQ_GPIO7_INT31_16_NUM108 #define FIQ_INTERRUPT_109_128_NUM109//RESERVED

2. crt0.s
.globalRESET_HLDR .globalUNDEF_HLDR .globalSWI_HLDR .globalPREFETCH_HLDR .globalABORT_HLDR .globalIRQ_HLDR .globalFIQ_HLDR .globalSMI_HLDR.extern__init_main .externmain .externmain_section .externSMI_RANDOM.global_start.global undef_hdler .global swi_hdler .global prefetch_hdler .global abort_hdler .global irq_hdler .global fiq_hdler .global smi_hdler .extern rompatch_tbl_ptr.extern c_main .extern UNDEF_HLDR_EXCEPT .extern SWI_HLDR_EXCEPT .extern PREFETCH_HLDR_EXCEPT .extern ABORT_HLDR_EXCEPT .extern IRQ_HLDR_EXCEPT .extern FIQ_HLDR_EXCEPT .extern SMI_HLDR_EXCEPT.align4 .arm.section .start.macrowrite_reg addr, val ldr r0, =\addr ldr r1, =\val str r1, [r0] .endm.macroread_reg addr, reg ldr r0, =\addr ldr \reg, [r0] .endm.equ TZIC_BASE_ADDR,0x0FFFC000 .equ IRAM_BASE_ADDR,0xF8000000 .equ RAM_TEST_CODE_ADDR,IRAM_BASE_ADDR+0x1000@; F800_1000 - F800_FFFF (EFFF)Test code_start: nop CRT0_START:@; @@@@@@@@@@@@@@@@@NORMAL@@@@@@@@@@@@@@; initialize registers in USER modemovr0,#0 movr1,#0 movr2,#0 movr3,#0 movr4,#0 movr5,#0 movr6,#0 movr7,#0 movr8,#0 movr9,#0 movr10,#0 movr11,#0 movr12,#0@; ARM_EMBEDDED_MODEmrsr7,CPSR bicr7,r7,#0x0f@; clear mode bits addr6,r7,#0x01 msrCPSR,r6@; goto FIQ mode@; initialize registers in FIQ modemovr8,#0 movr9,#0 movr10,#0 movr11,#0 movr12,#0 ldrsp,=__SP_FIQ movlr,#0addr6,r7,#0x02 msrCPSR,r6@; goto IRQ mode@; initialize registers in IRQ modeldrsp,=__SP_IRQ movlr,#0addr6,r7,#0x03 msrCPSR,r6@; goto SVC mode@; initialize registers in SVC mode@; Read Secure or Nonsecure Vector Base Address Register mrcp15,0,r5,c12,c0,1 ldrr5,=vects1_start @; Write Secure or Nonsecure Vector Base Address Register mcrp15,0,r5,c12,c0,1ldrsp,=__SP_SVC movlr,#0addr6,r7,#0x06 msrCPSR,r6@; go to MON mode@; initialize registers in monitor mode ldrsp,=__SP_MON movlr,#0addr6,r7,#0x07 msrCPSR,r6@; goto ABORT mode@; initialize registers in ABORT modeldrsp,=__SP_ABORT movlr,#0addr6,r7,#0x0b msrCPSR,r6@; goto UNDEF mode@; initialize registers in UNDEF modeldrsp,=__SP_UNDEF movlr,#0addr6,r7,#0x0f msrCPSR,r6@; goto SYSTEM modemrs r0, cpsr bic r1,r0, #0x100@; @ try to clear the A bit msr cpsr_cxsf, r1 mrs r0, cpsr@; initialize registers in SYSTEM mode @; @; Note:SYSTEM mode does not share r13 and r14 (i.e. sp and lr) with USER modeldrsp,=__SP_SYSTEM movlr,#0@; Enable exceptions@; clean up and call the C 'main' function mrsr6,CPSR bicr7,r6,#0xc0@; enable exceptions msrCPSR,r7@; enable the coprocessors ldr r0,=0xffffffff mcr p15,0,r0,c1,c0,2@; ensure the return stack does not have x'swhich can cause core to hang BL rs_label0 rs_label0: BL rs_label1 rs_label1: BL rs_label2 rs_label2: BL rs_label3 rs_label3: BL rs_label4 rs_label4: BL rs_label5 rs_label5: BL rs_label6 rs_label6: BL rs_label7 rs_label7:@; ; edof27.8 @; ; MOV to spvr mode so test will start in SPVR mode with SP_svc and LR_svc mrs r0,CPSR@; ; Read CPSR bic r0,r0,#0x1f@; ; Clear Mode bits orr r0,r0,#0x13 @; ; Set the Mode bits to SPVR mode msr CPSR_c,r0 @; ; Update the control bits in the CPSR , now in SPVR mode@; Mapping the special handler UNDEF_HLDR,SWI_HLDR,PREFECH_HLDR,ABORT_HLDR,IRQ_HLDR,FIQ_HLDR. @; look in $DESIGN_DIR/project_settings/testbench/arm_gnu/src/vectable.s for the HDLR orderLDR r5, = 0x00000004 LDR r6, = 0xE59FF014@; op.code -> jump to the address in pc+0x1CLDR r1, = IRAM_BASE_ADDR+0x1FFBC@; ; RAM address,the ARM jump to this address when UNDEF occur. str r6, [r1]add r1,r1,r5@; RAM address,the ARM jump to this address when SWI occur. str r6, [r1]add r1,r1,r5@; RAM address,the ARM jump to this address when PREFECH occur. str r6, [r1]add r1,r1,r5@; RAM address,the ARM jump to this address when ABORT occur. str r6, [r1]add r1,r1,r5@; NOP - empty str r6, [r1]add r1,r1,r5@; RAM address,the ARM jump to this address when IRQ occur. str r6, [r1]add r1,r1,r5@; RAM address,the ARM jump to this address when FIQ occur. str r6, [r1]LDR r6, = RAM_TEST_CODE_ADDR@; ; UNDEF_HLDR place when running from RAMadd r1,r1,r5 str r6, [r1]@; ; UNDEF_HLDR placeadd r1,r1,r5 ldr r2,= 0x1c add r6,r6,r2@; addr=base+0x1c str r6, [r1]@; ; SWI_HLDR placeadd r1,r1,r5 ldr r2,= 0x38 add r6,r6,r2@; addr=base+0x54 str r6, [r1]@; ; PREFECH_HLDR placeadd r1,r1,r5 ldr r2,= 0x1c add r6,r6,r2@; addr=base+0x70 str r6, [r1]@; ; ABORT_HLDR placeadd r1,r1,r5 ldr r2,= 0x00 add r6,r6,r2@; str r6, [r1]@; ; NOP placeadd r1,r1,r5 ldr r2,= 0x3c add r6,r6,r2@; addr=base+0xac str r6, [r1]@; ; IRQ_HLDR placeadd r1,r1,r5 ldr r2,= 0x94 add r6,r6,r2@; addr=base+0x140 str r6, [r1]@; ; FIQ_HLDR placeldr r6,= 0x00001fff add r1,r1,r5 str r6, [r1]@; Data so we will not read xxxx (r1=SCC_RAM_BASE_ADDR+0x1FFF4) add r1,r1,r5 str r6, [r1]@; Data so we will not read xxxx (r1=SCC_RAM_BASE_ADDR+0x1FFF8) add r1,r1,r5 str r6, [r1]@; Data so we will not read xxxx (r1=SCC_RAM_BASE_ADDR+0x1FFFC)bc_mainUNDEF_HLDR: stmfdsp!, {r0,lr}@; push our temp reg, R0, since C seems to feel free to bash it anyway ldrlr,=undef_hdler@; load address of pointer to undef handler function using LR temporarily ldrr0,[lr]@; load the undef handler function pointer into R0 movlr,pc@; preserve PC in LR so that called code can return. bxr0@; this way of doing the call allows Thumb code to be called ldmfdsp!, {r0,lr}@; then, pull back preserved R0. movspc,lr@; return from the interrupt to wherever LR points.SWI_HLDR: stmfdsp!, {r0-r1,lr}@; push register onto SWI stack mrsr0, spsr@; get saved status register tstr0, #0x20@; check if call was in THUMB mode ldrnehr0, [lr,#-2]@; yes: load opcode half-word and bicner0, r0, #0xff00@; yes: extract THUMB comment ldreqr0, [lr,#-4]@; no: load opcode word and biceqr0, r0, #0xff000000@; no: extract ARM comment @; now r0 has comment field ldrlr,=swi_hdler@; >= 16: pointer to standard SWI ldrr1,[lr]@; handler movlr,pc@; >= 16: set link register bxr1@; >= 16: jump to standard SWI @; handler ldmfdsp!, {r0-r1,pc}^.ltorgPREFETCH_HLDR: stmfdsp!, {r0,lr}@; see UNDEF_HLDR for commentary @; as this only differs in return mechanism ldrlr,=prefetch_hdler ldrr0,[lr] movlr,pc bxr0 ldmfdsp!, {r0,lr} subspc,lr,#4ABORT_HLDR: stmfdsp!, {r0-r2,lr}@; see UNDEF_HLDR for commentary @; as this only differs in return mechanism ldrlr,=abort_hdler ldrr0,[lr] movlr,pc bxr0 mrcp15,0,r0,c5,c0,0 ldrr1,=0x40f andr0,r0,r1 ldrr2,=0x406 cmpr0,r2 bneNOT_IMPRECISE_ABORT ldmfdsp!, {r0-r2,lr} subspc,lr,#8 NOT_IMPRECISE_ABORT : ldmfdsp!, {r0-r2,lr} subspc,lr,#4IRQ_HLDR: stmfdsp!, {r0-r12,lr}ldrr0,= TZIC_BASE_ADDR+0xD80 @; HIPND0 interrupt pending register ldrr0,[r0] mov r2, #0x0 cmp r0, #0 bne FIND_NUMBERldrr0,= TZIC_BASE_ADDR+0xD84 @; HIPND1 interrupt pending register ldrr0,[r0] mov r2, #32 cmp r0, #0 bne FIND_NUMBERldrr0,=TZIC_BASE_ADDR+0xD88 @; HIPND2 interrupt pending register ldrr0,[r0] mov r2, #64 cmp r0, #0 bne FIND_NUMBERldrr0,=TZIC_BASE_ADDR+0xD8C @; HIPND3 interrupt pending register ldrr0,[r0] mov r2, #96 cmp r0, #0 bne FIND_NUMBERFIND_NUMBER: mov r0, r0, lsr #1 cmp r0, #0 beq FOUND_NUMBER add r2, r2, #0x1 b FIND_NUMBERFOUND_NUMBER: mov r2, r2, lsl #2 mov r0, r2ldrlr,=INTERRUPT_0 ldrr0,[lr,r0] movlr,pc bxr0 mrsr0, cpsr bicr1, r0, #0x100 msrcpsr_cxsf, r1 ldmfdsp!, {r0-r12,lr} subspc,lr,#4FIQ_HLDR: stmfdsp!, {r0-r12,lr}ldrr0,= TZIC_BASE_ADDR+0xD80 @; HIPND0 interrupt pending register ldrr0,[r0] mov r2, #0x0 cmp r0, #0 bne FIQ_FIND_NUMBERldrr0,= TZIC_BASE_ADDR+0xD84 @; HIPND1 interrupt pending register ldrr0,[r0] mov r2, #32 cmp r0, #0 bne FIQ_FIND_NUMBERldrr0,= TZIC_BASE_ADDR+0xD88 @; HIPND2 interrupt pending register ldrr0,[r0] mov r2, #64 cmp r0, #0 bne FIQ_FIND_NUMBERldrr0,= TZIC_BASE_ADDR+0xD8C @; HIPND3 interrupt pending register ldrr0,[r0] mov r2, #96 cmp r0, #0 bne FIQ_FIND_NUMBERFIQ_FIND_NUMBER: mov r0, r0, lsr #1 cmp r0, #0 beq FIQ_FOUND_NUMBER add r2, r2, #0x1 b FIQ_FIND_NUMBERFIQ_FOUND_NUMBER: mov r2, r2, lsl #2 mov r0, r2ldrlr,=FIQ_INTERRUPT_0 ldrr0,[lr,r0] movlr,pc bxr0 mrsr0, cpsr bicr1, r0, #0x100 msrcpsr_cxsf, r1 ldmfdsp!, {r0-r12,lr} subspc,lr,#4@; MODIFIED 26-May(IDC) .align 5 vects1_start:nop@; offset 0x00 nop@; offset 0x04 ldrpc, =SMI_HLDR@; offset 0x08 nop@; offset 0x0c nop@; offset 0x10 nop@; offset 0x14 nop@; offset 0x18 ldrpc, =FIQ_HLDR@; offset 0x1c nop@; offset 0x20 nop@; offset 0x24 nop@; offset 0x28 nop@; offset 0x2c nop@; offset 0x30 nop@; offset 0x34 nop@; offset 0x38 nop@; offset 0x3c nop@; offset 0x40 nop@; offset 0x44 nop@; offset 0x48 nop@; offset 0x4c nop@; offset 0x50 nop@; offset 0x54 nop@; offset 0x58 nop@; offset 0x5c nop@; offset 0x60 nop@; offset 0x64 nop@; offset 0x68 nop@; offset 0x6c nop@; offset 0x70 nop@; offset 0x74 nop@; offset 0x78 nop@; offset 0x7c nop@; offset 0x80 nop@; offset 0x84 nop@; offset 0x88 ldrpc, =SMI_HLDR@; offset 0x8c@; MODIFIED 11-May(IDC)SMI_HLDR: stmfdsp!, {r0-r1,lr}@; push register onto SMI stack ldrr1,=smi_hdler@; >= 16: pointer to standard SMI ldrr0,[r1]@; handler movlr,pc@; >= 16: set link register bxr0@; >= 16: jump to standard SMI @; handler ldmfdsp!, {r0-r1,pc}^@; Following is Exception Table undef_hdler: .longUNDEF_HLDR_EXCEPT swi_hdler: .longSWI_HLDR_EXCEPT prefetch_hdler: .longPREFETCH_HLDR_EXCEPT abort_hdler: .longABORT_HLDR_EXCEPT irq_hdler: .longIRQ_HLDR_EXCEPT fiq_hdler: .longFIQ_HLDR_EXCEPT smi_hdler: .longSMI_HLDR_EXCEPTCRT0_END: .ltorg@; literal dump

3. 链接脚本
MEMORY { rom:org = 0x00000000, len = 0x00008000 ram:org = 0xf8000000, len = 0x00020000 }/********************************************************* ** Define memory regions for secure ROM and BOOT *********************************************************/ __SEC_ROM_START= 0x00000000; __NORM_ROM_START = 0x00000000; SECTIONS { .rom: { vectors.o(.vectors); } > rom .rom: { crt0.o(.start)*(.text); } > rom .rom: { * (.text); *(.rodata); } > rom .ram: { *(.glue_7)*(.glue_7t) ; } > ram .data: { *(.data) ; } > ram .bss: { *(.bss)*(.sbss) ; } > ram .stack: { . += 0x1000; } > ram .mmu: { *(.mmu) ; } > ram .vfp11_veneer: { *(.vfp11_veneer) ; } > ram }/* ------------------------------------------------------------------------- */ /* Definitions of identifiers used by sbrk.c, init.c, and the different*/ /* crt0.s files. Their purpose is to control initialization and memory*/ /* allocation.*/ /**/ /* __HEAP_START : Start of memory used by malloc() etc.*/ /* __HEAP_END: End of heap memory*/ /* __SP_INIT: Initial address of stack pointer*/ /* __SP_END: Only used when stack probing*/ /* __DATA_ROM: Address of initialized data in ROM*/ /* __DATA_RAM: Address of initialized data in RAM*/ /* __DATA_END: End of allocated initialized data*/ /* __BSS_START: Start of uninitialized data*/ /* __BSS_END: End of data to be cleared*/ /* ------------------------------------------------------------------------- */__HEAP_START= ADDR(.bss)+SIZEOF(.bss); __SP_UNDEF= ADDR(.stack)+SIZEOF(.stack); __SP_ABORT= __SP_UNDEF - 0x0200; __SP_SVC= __SP_UNDEF - 0x0400; __SP_IRQ= __SP_UNDEF - 0x0600; __SP_FIQ= __SP_UNDEF - 0x0800; __SP_SYSTEM= __SP_UNDEF - 0x0a00; __SP_MON= __SP_UNDEF - 0x0c00; __HEAP_END= __SP_UNDEF - 0x8000; __SP_END= __HEAP_END; __DATA_ROM= ADDR(.data); __DATA_RAM= ADDR(.data); __DATA_END= ADDR(.data)+SIZEOF(.data); __BSS_START= ADDR(.bss); __BSS_END= ADDR(.bss)+SIZEOF(.bss); /* ------------------------------------------------------------------------- */ /* Some targets use an extra underscore in front of identifiers*/ /* ------------------------------------------------------------------------- */ ___HEAP_START= __HEAP_START; ___HEAP_END= __HEAP_END; ___SP_INIT= __SP_SYSTEM; ___SP_END= __SP_END; ___DATA_ROM= __DATA_ROM; ___DATA_RAM= __DATA_RAM; ___DATA_END= __DATA_END; ___BSS_START= __BSS_START; ___BSS_END= __BSS_END;

参考文献
  1. ARM汇编–汇编中符号和变量
  2. ARM汇编.global和.extern
  3. ARM中C和汇编混合编程及示例
  4. 函数指针和指针函数用法和区别
  5. 《ARM体系与结构编程》
  6. ARM嵌入式系统开发软件设计与优化

    推荐阅读