首页 > 其他分享 >Cortex-M7中断向量表的重定向

Cortex-M7中断向量表的重定向

时间:2024-04-02 13:31:28浏览次数:19  
标签:__ 中断向量 地址 SCB VTOR M7 Cortex interrupt 向量

1 前言

        系统上电后,PC会指向复位向量,即向量表中的Reset_Handler,而系统就是通过Vector Table Offset Register (VTOR)的值加上4字节来找到复位向量的入口的。

        因为地址 0 处应该存储引导代码,所以它通常映射到 Flash 或者是 ROM 器件,并且它们的值不得在运行时改变。然而,为了支持动态重分发中断, CM3 允许向量表重定位——从其它地址处开始定位各异常向量。这些地址对应的区域可以是代码区,但更多是在 RAM 区。在 RAM 区就可以修改向量的入口地址了。为了实现这个功能, NVIC 中有一个寄存器,称为“向量表偏移量寄存器”(在地址 0xE000_ED08 处),通过修改它的值就能重定位向量表。            ---引自《Cortex-M3权威指南》

        简单来说,系统上电后默认中断向量表在地址0,通过VTOR将向量表重定向到RAM中,就可以对其进行操作了,可以在运行时更改其中的中断服务函数。 在Cortex-M7中,支持重定向的偏移地址范围为0x00000000-0xFFFFFF80;此外,如果重定位后的向量表位域可缓存(cacheable)区域,则在使用STR或LDR指令时需要用DSB,ISB等同步隔离指令来清洗流水线。

2 中断向量表偏移寄存器(VTOR)

        Vector Table Offset Register,VTOR的值表示中断向量表相对于地址0x00000000的偏移量。该寄存器在特权级下可读写,其地址为0xE000ED08,复位后为不确定值。

  图1 Vector Table Offset Register

        如图1所示,该寄存器的bit0~bit6为预留位,这些bit默认为0,bit7~bit31记录了偏移量。在设置向量表偏移地址时,必须按照向量表中的异常数制定对齐规则,即将向量表的向量个数向上圆整成2的k次方幂,然后计算处所需要的大小,并按该大小进行字节对齐。例如当有16个系统中断和21个外部中断时,总计37个异常,将向量表的向量个数向上圆整成2的6次方幂64,每个向量大小为4字节,所以向量表的偏移值必须按4*64 = 256 = 0x100字节进行对齐。

        低7位默认为0,也就意味着偏移量至少是按128 = 32*4字节对齐的,这样意味着CPU至少需要支持32个异常(包括16个系统异常和16个外部中断)。

        至于为什么这么做呢?应该是与中断向量的硬件机制有关。有一种猜测,是该机制取了对齐地址的全0位的个数作为向量表的大小(向量个数),以便于取向量时使用或运算,而不是加法运算。

3 VTOR的相关示例

3.1 VTOR的初始化

        在系统上电后,通常需要对VTOR进行初始化。例如,可以在选择在SystemInit函数关中断后,随即进行VTOR的初始化,而这个函数在Reset_Handler中调用。

/*----------------------------------------------------------------------------
  System initialization function
 *----------------------------------------------------------------------------*/
void SystemInit (void)
{
	__disable_irq();							// disable interrupts

#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
  SCB->VTOR = (uint32_t) &__VECTOR_TABLE;       // init the VTOR
#endif

#if defined (__FPU_USED) && (__FPU_USED == 1U)
  SCB->CPACR |= ((3U << 10U*2U) |           /* enable CP10 Full Access */
                 (3U << 11U*2U)  );         /* enable CP11 Full Access */
#endif

#ifdef UNALIGNED_SUPPORT_DISABLE
  SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk;
#endif

// MPU CONFIG and ENABLE
#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
  MPUInit();
#endif

// CACHE ENABLE
#if defined (__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U)
  SCB_InvalidateICache();
  SCB_EnableICache();
#endif
#if defined (__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
  SCB_InvalidateDCache();
//  SCB_EnableDCache();
#endif

  SystemCoreClockUpdate();

  __enable_irq();							// enable interrupts
}

3.2 VTOR的访问  

         VTOR初始化完成后,软件就可以在特权级模式下访问该寄存器,从而找到中断向量表的位置。 例如,freeRTOS的函数prvPortStartFirstTask中,就是通过地址0xE000ED08找到向量表首地址,然后读取向量表的第一个向量的值(MSP的栈顶地址,起始地址),然后将MSP复位为该初始值(主堆栈的栈顶地址):

/*-----------------------------------------------------------*/

static void prvPortStartFirstTask( void )
{
    /* Start the first task.  This also clears the bit that indicates the FPU is
     * in use in case the FPU was used before the scheduler was started - which
     * would otherwise result in the unnecessary leaving of space in the SVC stack
     * for lazy saving of FPU registers. */
    __asm volatile (
        " ldr r0, =0xE000ED08 	\n"/* Use the NVIC offset register to locate the stack. */
        " ldr r0, [r0] 			\n"
        " ldr r0, [r0] 			\n"
        " msr msp, r0			\n"/* Set the msp back to the start of the stack. */
        " mov r0, #0			\n"/* Clear the bit that indicates the FPU is in use, see comment above. */
        " msr control, r0		\n"
        " cpsie i				\n"/* Globally enable interrupts. */
        " cpsie f				\n"
        " dsb					\n"
        " isb					\n"
        " svc 0					\n"/* System call to start first task. */
        " nop					\n"
        " .ltorg				\n"
        );
}
/*-----------------------------------------------------------*/

        cmsis中也提供了VTOR相关的标准接口,从中实现也可以清晰的看到中断向量表的实现就是一个一维数组:

/**
  \brief   Set Interrupt Vector
  \details Sets an interrupt vector in SRAM based interrupt vector table.
           The interrupt number can be positive to specify a device specific interrupt,
           or negative to specify a processor exception.
           VTOR must been relocated to SRAM before.
  \param [in]   IRQn      Interrupt number
  \param [in]   vector    Address of interrupt handler function
 */
__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
{
  uint32_t vectors = (uint32_t )SCB->VTOR;
  (* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4)) = vector;
  __DSB();
}

/**
  \brief   Get Interrupt Vector
  \details Reads an interrupt vector from interrupt vector table.
           The interrupt number can be positive to specify a device specific interrupt,
           or negative to specify a processor exception.
  \param [in]   IRQn      Interrupt number.
  \return                 Address of interrupt handler function
 */
__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn)
{
  uint32_t vectors = (uint32_t )SCB->VTOR;
  return (uint32_t)(* (int *) (vectors + ((int32_t)IRQn + NVIC_USER_IRQ_OFFSET) * 4));
}

标签:__,中断向量,地址,SCB,VTOR,M7,Cortex,interrupt,向量
From: https://blog.csdn.net/m0_47462420/article/details/137125855

相关文章

  • RTOS--异常向量和中断向量
    目录1异常向量2中断向量3示例说明RTOS(实时操作系统)中的异常和中断向量是操作系统处理异常事件和中断请求的关键机制。这些向量是预定义的内存地址,当特定事件发生时,处理器会跳转到这些地址执行相应的处理程序。下面将详细介绍RTOS中的异常和中断向量,并通过示例来说明它......
  • Bootloader/IAP零基础入门(1.1) —— 设计一个Bootloader引导进入APP的程序,包含中断向量
    前言(1)如果有嵌入式企业需要招聘湖南区域日常实习生,任何区域的暑假Linux驱动/单片机/RTOS的实习岗位,可C站直接私聊,或者邮件:[email protected],此消息至2025年1月1日前均有效(2)在上一章节中,我们详细介绍了如何让Bootloader引导进入APP程序。但是上一章节的工程是无法使用......
  • 嵌入式笔记1.2 ARM Cortex-M3M4汇编指令集
    目录Cortex-M处理器的指令集Cortex-M处理器支持的指令集Cortex-M处理器指令集的选择寄存器组详解1.通用寄存器R0~R122.栈指针3.连接寄存器4.程序计数寄存器5.程序状态字寄存器(xPSR)6.特殊功能寄存器7.浮点控制寄存器指令集详解(Cortex-M3和Cortex-M4都支持的)1.处理......
  • 嵌入式笔记1.1 ARM Cortex-M3M4简介
    目录微型计算机的硬件共性结构及基本性能指标关于存储器的介绍微型计算机的基本性能指标1.字长2.主频3.存储容量4.外设扩展能力5.软件配置情况ArmCortex系列微处理器系列概述ArmCortex-A系列处理器ArmCortex-R系列处理器ArmCortex-M系列处理器Cortex-M3和Cortex-M......
  • 上海安川机器人SGM7G-30APK-YR11电机维修让你放心
    一、安川机器人SGM7G-30APK-YR11电机常见电机故障·绕组短路:电机长时间运行或过载可能导致绕组绝缘层损坏,进而引发短路。·轴承磨损:轴承是安川机器人SGM7G-30APK-YR11电机转动的关键部件,长时间使用或缺乏维护会导致磨损,影响电机精度和稳定性。·编码器故障:编码器用于提供......
  • cortex-A处理器
    ARM在cortex-A系列处理器在性能上大致为排序为:A77、A75、A73、A57、A53、A15、A9、A7、A5等A7内核的工作模式、寄存器组织、程序状态寄存器、存储系统、流水线、异常处理、以及汇编指令、汇编编程、C混合编程等 ARM产品线和产品介绍: ARM的含义:ARM一般有两个含义:1、ARM公......
  • 过年相亲 别开问界M7
    文|AUTO芯球作者|王晓不瞒你们因为相亲我和我发下差点打起来了这不年底了,我那个从小一起长大的兄弟要去相亲去乡下之前,我就劝他,不要开问界M7去没有牌面他偏不信说顶配M7也要三十多万也是高端品牌结果他和女孩子聊了90分钟其中80分钟都在解释,他这台M7这是什么车什么科技配置......
  • (2A)ADM7172ACPZ-2.5低压差线性稳压器 (LDO),AD5684BRUZ内置SPI接口的四通道、12位DAC
    一、ADM71726.5V、2A、超低噪声、高PSRR、快速瞬态响应CMOSLDOADM7172ACPZ-2.5超低噪声、高PSRR、快速瞬变响应CMOS低压差线性调节器采用2.3V到6.5V电压提供高达500mA的输出电流。这些高输出电流LDO适用于调节6V至1.2V供电轨的高性能模拟和混合信号电路。该......
  • JVM7(GC 分代收集算法 VS 分区收集算法)
    1.分代收集算法当前主流VM垃圾收集都采用”分代收集”(GenerationalCollection)算法,这种算法会根据对象存活周期的不同将内存划分为几块,如JVM中的新生代、老年代、永久代,这样就可以根据各年代特点分别采用最适当的GC算法1.1.在新生代-复制算法每次垃圾收集都能发......
  • DM7_SQL语言使用手册_第 1 章 结构化查询语言 DM_SQL 简介
    第1章结构化查询语言DM_SQL简介结构化查询语言SQL(StructuredQueryLanguage)是在1974年提出的一种关系数据库语言。由于SQL语言接近英语的语句结构,方便简洁、使用灵活、功能强大,倍受用户及计算机工业界的欢迎,被众多计算机公司和数据库厂商所采用,经各公司的不断修改......