6681如何重映射向量表到RAM

wangbing · 27次点击 · 3天前
在标准配置下,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()第一句话即可。

vectors_ram-202502256538.zip
被收藏 0  ∙  0 赞  
加入收藏
点赞
0 回复  
善言善语 (您需要 登录 后才能回复 没有账号 ?)

请先登录网站