完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
相关的关键寄存器
VTOR(Vector Table Offset Register)寄存器 其中保存了中断向量表(Vector Table)的首地址,此地址必须是4*(2^n)的倍数,(2^n)需要大于(不能等于)处理器支持的中断数量。 比如STM32支持的中断一共有68(for interrupts)+16(for system exception)=84个,那么最小的(2^n)等于128,128*4=512(十六进制为0x200),所以STM32处理器的中断向量表的地址必须为512的倍数。 系统复位后该寄存器可以根据一些硬件管脚的配置输入信号初始化成不同的值。比如STM32一般都是初始化成0x08000000。 SP(Stack Pointer)寄存器 保存栈顶地址。 PC(Program Counter)寄存器 保存下一条要执行的指令地址。 bootloader的启动 1、处理器上电或者复位后,VTOR被初始化成一个固定的值,硬件电路自动将VTOR所指向的中断向量表的的第1个WORD(4字节)值装载到SP中, 将第2个WORD值装载到PC中,然后执行第一条指令,即VTOR所指向的中断向量表的第2个WORD值指向的指令。 该指令所在的函数一般叫做Reset_Handler,该函数一般先调用SystemInit,然后调用__main函数,__main函数中调用我们熟知的程序入口函数:main。 一般在SystemInit中会修改VTOR寄存器的值为bootloader的中断向量表首地址。 2、判断是否需要跳转到app,如果需要并且app是有效的,将app的中断向量表的第1个WORD装载到SP中(MDK-ARM toolchain对应的示例代码:__set_MSP(*(__IO uint32_t *)APP_START_ADDRESS);), 然后将app的中断向量表的第2个WORD的值作为函数指针进行调用。 app的启动 app自己的Reset_Handler被调用,该函数也是先调用SystemInit,然后调用__main函数。 SystemInit中会修改VTOR寄存器的值为app的中断向量表首地址,这样app中的中断就都由app的中断向量表指向的中断处理函数来处理了。 中断向量表 中断向量表的格式以及和中断号的对应关系如下图: eset_Handler。 |
|
|
|
相关的关键寄存器
VTOR(Vector Table Offset Register)寄存器 其中保存了中断向量表(Vector Table)的首地址,此地址必须是4*(2^n)的倍数,(2^n)需要大于(不能等于)处理器支持的中断数量。 比如STM32支持的中断一共有68(for interrupts)+16(for system exception)=84个,那么最小的(2^n)等于128,128*4=512(十六进制为0x200),所以STM32处理器的中断向量表的地址必须为512的倍数。 系统复位后该寄存器可以根据一些硬件管脚的配置输入信号初始化成不同的值。比如STM32一般都是初始化成0x08000000。 SP(Stack Pointer)寄存器 保存栈顶地址。 PC(Program Counter)寄存器 保存下一条要执行的指令地址。 bootloader的启动 1、处理器上电或者复位后,VTOR被初始化成一个固定的值,硬件电路自动将VTOR所指向的中断向量表的的第1个WORD(4字节)值装载到SP中, 将第2个WORD值装载到PC中,然后执行第一条指令,即VTOR所指向的中断向量表的第2个WORD值指向的指令。 该指令所在的函数一般叫做Reset_Handler,该函数一般先调用SystemInit,然后调用__main函数,__main函数中调用我们熟知的程序入口函数:main。 一般在SystemInit中会修改VTOR寄存器的值为bootloader的中断向量表首地址。 2、判断是否需要跳转到app,如果需要并且app是有效的,将app的中断向量表的第1个WORD装载到SP中(MDK-ARM toolchain对应的示例代码:__set_MSP(*(__IO uint32_t *)APP_START_ADDRESS);), 然后将app的中断向量表的第2个WORD的值作为函数指针进行调用。 app的启动 app自己的Reset_Handler被调用,该函数也是先调用SystemInit,然后调用__main函数。 SystemInit中会修改VTOR寄存器的值为app的中断向量表首地址,这样app中的中断就都由app的中断向量表指向的中断处理函数来处理了。 中断向量表 中断向量表的格式以及和中断号的对应关系如下图: eset_Handler。 |
|
|
|
中断向量表在代码中如何构造出来
一般通过汇编语言编写: ; MDK-ARM toolchain的汇编代码 Stack_Size EQU 0x1000 AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size ;告诉编译器开辟一段空间,用作栈内存 __initial_sp Heap_Size EQU 0x2000 AREA HEAP, NOINIT, READWRITE, ALIGN=3 __heap_base Heap_Mem SPACE Heap_Size ;告诉编译器开辟一段空间,用作堆内存 __heap_limit PRESERVE8 THUMB ; 下面是构造中断向量表的汇编语句 ; Vector Table Mapped to Address 0 at Reset AREA RESET, DATA, READONLY EXPORT __Vectors EXPORT __Vectors_End EXPORT __Vectors_Size __Vectors DCD __initial_sp ; Top of Stack, flash上分配4字节内存,并初始化为栈顶的地址 DCD Reset_Handler ; Reset Handler, flash上分配4字节内存,并初始化为Reset_Handler函数的地址 DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU Fault Handler DCD BusFault_Handler ; Bus Fault Handler DCD UsageFault_Handler ; Usage Fault Handler DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD SVC_Handler ; SVCall Handler DCD DebugMon_Handler ; Debug Monitor Handler DCD 0 ; Reserved DCD PendSV_Handler ; PendSV Handler DCD SysTick_Handler ; SysTick Handler ; External Interrupts DCD WWDG_IRQHandler ; Window WatchDog DCD PVD_IRQHandler ; PVD through EXTI Line detection DCD TAMP_STAMP_IRQHandler ; Tamper and TimeStamps through the EXTI line DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line DCD FLASH_IRQHandler ; FLASH DCD RCC_IRQHandler ; RCC DCD EXTI0_IRQHandler ; EXTI Line0 DCD EXTI1_IRQHandler ; EXTI Line1 DCD EXTI2_IRQHandler ; EXTI Line2 DCD EXTI3_IRQHandler ; EXTI Line3 DCD EXTI4_IRQHandler ; EXTI Line4 DCD DMA1_Stream0_IRQHandler ; DMA1 Stream 0 DCD DMA1_Stream1_IRQHandler ; DMA1 Stream 1 DCD DMA1_Stream2_IRQHandler ; DMA1 Stream 2 DCD DMA1_Stream3_IRQHandler ; DMA1 Stream 3 DCD DMA1_Stream4_IRQHandler ; DMA1 Stream 4 DCD DMA1_Stream5_IRQHandler ; DMA1 Stream 5 DCD DMA1_Stream6_IRQHandler ; DMA1 Stream 6 DCD ADC_IRQHandler ; ADC1, ADC2 and ADC3s DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD EXTI9_5_IRQHandler ; External Line[9:5]s DCD TIM1_BRK_TIM9_IRQHandler ; TIM1 Break and TIM9 DCD TIM1_UP_TIM10_IRQHandler ; TIM1 Update and TIM10 DCD TIM1_TRG_COM_TIM11_IRQHandler ; TIM1 Trigger and Commutation and TIM11 DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare DCD TIM2_IRQHandler ; TIM2 DCD TIM3_IRQHandler ; TIM3 DCD TIM4_IRQHandler ; TIM4 DCD I2C1_EV_IRQHandler ; I2C1 Event DCD I2C1_ER_IRQHandler ; I2C1 Error DCD I2C2_EV_IRQHandler ; I2C2 Event DCD I2C2_ER_IRQHandler ; I2C2 Error DCD SPI1_IRQHandler ; SPI1 DCD SPI2_IRQHandler ; SPI2 DCD USART1_IRQHandler ; USART1 DCD USART2_IRQHandler ; USART2 DCD 0 ; Reserved DCD EXTI15_10_IRQHandler ; External Line[15:10]s DCD RTC_Alarm_IRQHandler ; RTC Alarm (A and B) through EXTI Line DCD OTG_FS_WKUP_IRQHandler ; USB OTG FS Wakeup through EXTI line DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD DMA1_Stream7_IRQHandler ; DMA1 Stream7 DCD 0 ; Reserved DCD SDIO_IRQHandler ; SDIO DCD TIM5_IRQHandler ; TIM5 DCD SPI3_IRQHandler ; SPI3 DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD DMA2_Stream0_IRQHandler ; DMA2 Stream 0 DCD DMA2_Stream1_IRQHandler ; DMA2 Stream 1 DCD DMA2_Stream2_IRQHandler ; DMA2 Stream 2 DCD DMA2_Stream3_IRQHandler ; DMA2 Stream 3 DCD DMA2_Stream4_IRQHandler ; DMA2 Stream 4 DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD OTG_FS_IRQHandler ; USB OTG FS DCD DMA2_Stream5_IRQHandler ; DMA2 Stream 5 DCD DMA2_Stream6_IRQHandler ; DMA2 Stream 6 DCD DMA2_Stream7_IRQHandler ; DMA2 Stream 7 DCD USART6_IRQHandler ; USART6 DCD I2C3_EV_IRQHandler ; I2C3 event DCD I2C3_ER_IRQHandler ; I2C3 error DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved DCD FPU_IRQHandler ; FPU DCD 0 ; Reserved DCD 0 ; Reserved DCD SPI4_IRQHandler ; SPI4 DCD SPI5_IRQHandler ; SPI5 __Vectors_End __Vectors_Size EQU __Vectors_End - __Vectors AREA |.text|, CODE, READONLY ; Reset handler Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main LDR R0, =SystemInit ;调用SystemInit函数 BLX R0 LDR R0, =__main ;调用__main函数 BX R0 ENDP 总结 bootloader和app都有自己的中断向量表,可以通过改变VTOR中的值来启用哪个中断向量表。中断向量表的第1个字保存的是栈顶地址。 如果要执行存储在外部SD卡上程序,可以先将中断向量表拷贝到RAM中,然后变更VTOR的值为RAM中的向量表,最后跳转到向量表中的R |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1771 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1070 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1936浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
729浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
569浏览 3评论
594浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
552浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 16:59 , Processed in 0.880532 second(s), Total 79, Slave 64 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号