前言 ARM的中断和51单片机的中断有不少不同的地方,这里梳理一下ARM外部中断的实现过程。
环境
- ARM单片机:公司设计的EM537单片机
- ARM指令集型号:V7-A
ARM中断可以分为以下几种类型:
文章图片
文章图片
ARM中断向量的地址和优先级表格
文章图片
ARM共有8种类型的中断,中断的数目可以扩展。
EM537中通过TZIC模块,将IRQ中断数目扩展至128。
FIQ的中断,优先级高,延迟低。常用于DMA类型的中断。二、中断触发-处理中断的过程(以外部中断为例) 2.1 中断的配置
我们平时使用最多的还是IRQ外部中断。
不同平台配置寄存器不同
- 打开想使用的中断允许位
- 配置中断优先级
- 打开总中断
满足中断触发条件后,由硬件进行触发。
作为开发者不需要关心硬件触发过程。
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进行配置。【嵌入式|ARM 外部中断的过程】然后解析一下其中一段程序的内容:
设置相应中断的中断号。如果此中断触发,就可以在HIPND(0-3) interrupt pending register这四个寄存器中查到。
@将中断挂起寄存器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关键字用来让一个符号对链接器可见,可以供其他链接对象模块使用。所以ini_table.s中的
.global _start 让_start符号成为可见的标示符,这样链接器就知道跳转到程序中的什么地方并开始执行。linux寻找这个 _start标签作为程序的默认进入点。
在汇编和C混合编程中,在GNU ARM编译环境下,汇编程序中要使用.global伪操作声明汇编程序为全局的函数,意即可被外部函数调用,同时C程序中要使用extern声明要调用的汇编语言程序。
.global UART1_ANDED_INT_ROUTINE
只是声明了一个符号,并没有相应的程序。在interrupt.h文件中
extern void ( *UART1_ANDED_INT_ROUTINE )(void);
使用extern关键字声明,以便在c里面进行调用。这里声明的
UART1_ANDED_INT_ROUTINE
是一个函数指针。这里引用参考文献4中的介绍:
文章图片
因此可以通过更改
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寄存器进行上电初始化。
初始化的主要功能是:
- 初始化Rn等常用寄存器的值为0;(理论上要使用的内存区域都要初始化,避免硬件初始化值不同造成错误。)
- 初始化各种处理器模式下的堆栈指针,否则堆栈指针可能会覆盖内存中的值,造成程序错误。
- 进入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;
参考文献
- ARM汇编–汇编中符号和变量
- ARM汇编.global和.extern
- ARM中C和汇编混合编程及示例
- 函数指针和指针函数用法和区别
- 《ARM体系与结构编程》
- ARM嵌入式系统开发软件设计与优化
推荐阅读
- linux技术成长|ARM中断向量表与响应流程
- Linux|Linux内核ARM架构异常中断向量表
- 嵌入式|ARM中断向量表与响应流程【转】
- 灵动微MM32F0144C6P单片机为汽车传感控制主控
- 51单片机笔记|(十五)51单片机——呼吸灯与直流电机调速(PWM)
- 51单片机笔记|(十六)51单片机——红外遥控
- 51单片机笔记|(十四)51单片机——LCD1602实现滚动效果
- 单片机|单片机 c语言 d,单片机89C51与A/D转换器MAX - 控制/MCU - 电子发烧友网
- 51单片机——My-Clock项目