在标准配置下,6681 SDK 提供的向量表默认存储于Flash中,具体地址为0x08003000(在BOOT模式下除外),并由SystemInit函数负责初始化。相关代码如下所示。 voidSystemInit(void) { //... #if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) SCB->VTOR =(uint32_t)&(__VECTOR_TABLE[0]); #endif //... } 向量表的定义为__VECTOR_TABLE,如下所示。 #ifndef __VECTOR_TABLE #define __VECTOR_TABLE __Vectors #endif 向量表__Vectors通常定义于启动文件中,位于应用程序二进制文件的起始偏移位置。 以下是启动文件中关于__Vectors定义的详细内容。 __Vectors: .long __INITIAL_SP /* Top of Stack */ .long Reset_Handler /* Reset Handler */ .long NMI_Handler /* -14 NMI Handler */ .long HardFault_Handler /* -13 Hard Fault Handler */ .long MemManage_Handler /* -12 MPU Fault Handler */ .long BusFault_Handler /* -11 Bus Fault Handler */ .long UsageFault_Handler /* -10 Usage Fault Handler */ .long SecureFault_Handler /* -9 Secure Fault Handler */ #if 1 .long __CHIP_ID /* Reserved */ #else .long 0 /* Reserved */ #endif .long 0 /* Reserved */ .long 0 /* Reserved */ .long SVC_Handler /* -5 SVCall Handler */ .long DebugMon_Handler /* -4 Debug Monitor Handler */ .long 0 /* Reserved */ .long PendSV_Handler /* -2 PendSV Handler */ .long SysTick_Handler /* -1 SysTick Handler */ /* Interrupts */ .long QDEC0_IRQHandler /* 0 QDEC0 */ .long QDEC1_IRQHandler /* 1 QDEC1 */ .long QDEC2_IRQHandler /* 2 QDEC2 */ ... .long USB_BUS_ACTIVE_IRQHandler /* 57 USB BUS */ .long USB_DMA_IRQHandler /* 58 USB DMA */ .long SDHC_IRQHandler /* 59 SD_HOST */ .long SDHC_WAKEUP_IRQHandler /* 60 SDHC wakeup */ .long Interrupt61_Handler /* 61 Interrupt 61 */ .long Interrupt62_Handler /* 62 Interrupt 62 */ .long Interrupt63_Handler /* 63 Interrupt 63 */ __Vectors_End: .equ __Vectors_Size, __Vectors_End - __Vectors .size __Vectors, . - __Vectors __Vectors 的结构包括,首字存储了上电初始化的主堆栈指针(MSP)值,紧接着是Reset_Handler,之后直至Systick共计16个字。随后,从下一个位置开始,64个字分别存储了6681的各种中断向量。因此,在准备RAM空间时,必须预留出16+64=80个字,即320字节的空间,以存储向量表。 在某些特定需求下,有必要将上述向量表复制到RAM中。例如,为了提升中断响应速度,或在擦除内部Flash时,确保某些中断能够继续响应(例如,在擦除内部Flash期间,串口可能需要继续将数据接收至RAM中)。 // 使用extern将startup_om6681a_core0.S中向量表起始符合导入 extern volatile uint32_t __Vectors[]; extern volatile uint32_t __Vectors_End[]; // 定义保存向量表的数组,这里使用__RAM_DATA_NON_CACHED标记,前面对对齐必须到512字节 static volatile __ALIGNED(512) __RAM_DATA_NON_CACHED uint32_t vector_ram_arr[80]; __RAM_CODE void vectors_ram_init(void) { OM_ASSERT(sizeof(vector_ram_arr) >= \ (size_t)(__Vectors_End - __Vectors) * sizeof(uint32_t)); uint32_t i; uint32_t vector_size = (size_t)(__Vectors_End - __Vectors); __disable_irq(); for (i = 0; i < vector_size; i++) { vector_ram_arr[i] = __Vectors[i]; } // Set VTOR to point to the new vector table in RAM SCB->VTOR = (uint32_t)vector_ram_arr; __enable_irq(); } vectors_ram_init函数可以在系统启动的早期阶段被调用。 int main(void) { vectors_ram_init(); hal_app_init(); //... } 调用vectors_ram_init函数后,处理器将从vector_ram_arr所指向的内存区域获取中断向量。 可以通过gdb脚本irq.gdb进行验证,其中num参数代表中断向量编号,En表示中断是否启用,Pend表示中断是否处于挂起状态等待响应,而Act表示中断当前是否正在执行。 (gdb) source ../../../../tools/gdb/irq.gdb VTOR reg = 0x2000b400, vector table base = 0x2000b400 Num En Pend Prio Act Type 00 0 0 00 0 QDEC0_IRQn 01 0 0 00 0 QDEC1_IRQn 02 0 0 00 0 QDEC2_IRQn 03 1 0 32 0 USART1_IRQn 04 0 0 00 0 TIM_IRQn 05 0 0 00 0 ECDSA_IRQn 06 0 0 00 0 AES256_IRQn 07 0 0 00 0 PMU_TIMER0_IRQn 08 0 0 00 0 USART0_IRQn 09 0 0 00 0 ETC2DEC_IRQn 10 0 0 00 0 I2C0_IRQn 11 0 0 64 0 PIN_WAKEUP_IRQn 12 0 0 00 0 GPADC_IRQn 13 0 0 00 0 SPI0_IRQn 14 0 0 00 0 SHA256_IRQn 15 0 0 00 0 GP_COMP_IRQn 16 0 0 00 0 GPDMA_IRQn 17 1 0 96 0 EFUSE_IRQn 18 0 0 00 0 REV18_IRQn 19 0 0 00 0 REV19_IRQn 20 0 0 00 0 RTC_AF_IRQn 21 0 0 00 0 RTC_1HZ_IRQn 22 0 0 00 0 REV22_IRQn 23 0 0 00 0 REV23_IRQn 24 0 0 00 0 XTAL32M_INT_IRQn 25 0 0 00 0 OSPI1_IRQn 26 0 0 00 0 GPIO0_IRQn 27 0 0 00 0 GRAPH2D_IRQn 28 0 0 00 0 TIM0_IRQn 29 0 0 00 0 TIM1_IRQn 30 0 0 00 0 GPIO2_IRQn 31 0 0 00 0 CPM_IRQn 32 0 0 00 0 CRY32K_IRQn 33 1 0 48 0 OSPI0_IRQn 34 0 0 00 0 CTOUCH_IRQn 35 0 0 00 0 I2S1_TX_IRQn 36 0 0 00 0 I2S0_TX_IRQn 37 0 0 00 0 I2S2_RX_IRQn 38 0 0 00 0 ICACHE_IRQn 39 0 0 00 0 DCACHE_IRQn 40 0 0 00 0 SOFT0_IRQn 41 0 0 00 0 SOFT1_IRQn 42 0 0 00 0 SOFT2_IRQn 43 0 0 00 0 SOFT3_IRQn 44 0 0 00 0 SOFT4_IRQn 45 0 0 00 0 SOFT5_IRQn 46 0 0 00 0 SOFT6_IRQn 47 0 0 00 0 SOFT7_IRQn 48 0 0 00 0 AUDIO_IRQn 49 0 0 00 0 REV49_IRQn 50 0 0 00 0 PMU_TIMER1_IRQn 51 0 0 00 0 GSPI_IRQn 52 0 0 00 0 CLOCK_CHECK_IRQn 53 0 0 00 0 OSPI2_IRQn 54 1 0 96 0 IPC_IRQn 55 1 0 64 0 CHARGER_STATE_CHANGE_IRQn 56 0 0 00 0 USB_IRQn 57 0 0 00 0 USB_BUS_ACTIVE_IRQn 58 0 0 00 0 USB_DMA_IRQn 59 0 0 00 0 SD_HOST_IRQn 60 0 0 00 0 SD_HOST_WAKEUP_IRQn 61 0 0 00 0 EXTERNAL_IRQn_Num 62 0 0 00 0 62 63 0 0 00 0 63 完整代码如附件,下载后放到SDK,放到大核core0的main()第一句话即可。 |
