全球服饰网_打造最专业最全面服装资讯平台
您当前的位置 : 全球服饰网  >  企业
STM32在线升级中断向量重定向深度剖析!
2020-11-19 04:12:03 来源:互联网 阅读:

在做stm32 iap升级固件的时候通常需要多份中断向量表。比如bootloader的中断向量表在0x00000000位置,应用程序的中断向量表则会放在flash的另一个地方或者是放在RAM中运行。

要维护向量表位置就需要用VTOR这个东西,那么就要先从VTOR来聊聊, 先弄清这个东西又是干嘛的。

VTOR是arm内核的一个寄存器,叫做中断向量偏移量寄存器。当系统上电启动的时候CPU会从先找到中断向量表的位置,然后从表中找到复位中断Reset_Handler,而main函数的执行实际上就是在复位中断函数中的。如下汇编代码就是复位中断服务函数,该函数在启动文件中定义。在Reset_Handler 中会执行__main(),而main函数又是被__main()调用了。

Reset_Handler    PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP

前面复习一下ARM处理器启动到执行main的一个大概流程。再回归正题继续探讨这个VTOR。当来一个中断时,cpu就会从0x0000000+VTOR位置找到中断向量表,然后再查表跳转到对应的中断服务函数去执行。所以你代码里面存在多份中断向量表是可以的,只需要动态改变VTOR的值就可以了。

STM32在线升级中断向量重定向深度剖析

APP的中断向量放在flash中:

如下图所示,在运行bootloader的时候用的是他自己的bootloader,当从bootloader跳转到app以后就需要用app的向量表了。所以进入APP的首要任务就是设置VTOR值为0x0x8001000,再产生中断的时候让cpu去app的向量表里找中断服务函数入口。

STM32在线升级中断向量重定向深度剖析

所以从在app中重定义向量表是不是很简单。但是有个前提,就是要有VTOR寄存器。实际上,并不是所有stm32都带有VTOR的。准确的说是因为ARM-CORTEX-M0内核的芯片没有,所以stm32F0系列所采用M0内核的芯片就没有VTOR。但是还有需要注意的就是L0系列使用的M0+内核和M0内核又是不同的,是有VTOR的。

这就意味着stm32F0系列没有办法使用这种简单的修改VTOR的方式重新定位APP的中断向量表。那肯定还有其他思路,就是稍微麻烦一点。

中断向量放在RAM中:

那就是把中断向量表放在RAM中去,并且针对F0没有VTOR的还必须把中断向量表拷贝到RAM的起始地址。

为什么这样做,因为前面我们提到过CPU默认会认为0x00000000处放的就是向量表。那么我们换种思路可以把RAM的地址映射到0x00000000处。这个通过配置SYSCFG寄存器的MEM_MODE就可以把RAM地址映射到0x00000000处。

STM32在线升级中断向量重定向深度剖析

这时候再进入到APP以后首要任务就是把APP的中断向量表拷贝到RAM的起始地址,并且修改MEM_MODE位。

在代码里面比较简单的做法就是在ram起始地址处定义一个数组,上电以后把向量表拷贝到这个数组中。如下代码是在MDK中定义的方法,在IAR或者GCC定义的方式会有区别。

__IO uint32_t vector_t[48] __attribute__((at(0x20000000)));

但是要编译通过还需要在mdk配置里面把ram的起始地址设置为0x200000c0,前面的0xc0的空间腾出来存放定义的这个数组。

有VTOR的系列向量表放在RAM中

stm32F0系列内核决定了即便把向量表放在RAM中也只能放在RAM的起始位置而不能任意放。但是有VTOR的型号就可以随便放。这样分配存放向量表的数组也可以不用定位在0x20000000位置了。可以如下方式定义:

__align(256) uint32_t vector_t[48];

可以看到虽然没有了必须放在ram起始地址的限制,但是还是要遵守一定的规则。就是对齐有要求的。比如L0系列有48个中断向量,一共占用内存为48*4=192bytes。扩大为2的整次方为256:28=256。所以就要求向量存储的地址必须是256对齐的。存放在0x0或者0x20000100都可以满足要求。

另外这种方式虽然更灵活了一些,但是却造成了一定RAM空间的浪费。我在这样定义编译以后查看MAP文件如下,红色的区域空出来的一段内存空间就会被浪费掉:

STM32在线升级中断向量重定向深度剖析

关于0X00000000地址

前面说过默认cpu会从0x00000000地址来取向量表,那么stm32的flash都是从0x8000000地址开始的,这时候不设置VTOR偏移为什么也可以正常运行。实际上当从用户flash启动的时候,从0x8000000或者0x00000000访问的都是同一片区域。所以cpu从0x0取向量表相当于取的就是0x8000000地址处的数据。

更进一步理解,stm32通过配置boot脚(或者SYSCFG中MEM_MODE位)有三种启动模式选择,这三种模式的本质就是看把那个区域重映射为0x00000000地址。这样CPU取第一条指令就是从哪里取:

  1. 从用户flash区启动,用户flash起始地址被映射到0x00000000上
  2. 从系统flash区启动,系统flash起始地址被映射到0x00000000上,上电就执行内置的bootloader
  3. 从RAM区启动,RAM起始地址被映射到0x00000000上,这时候你再回过去看我刚才说的F0无VTOR寄存器实现IAP就是这样的思路。向量表放在了RAM区域的起始地址。

推荐阅读:中国财经时讯网

频道推荐
  • 日本很火的秋刀鱼在中国却不受待见?你知道吗?这才是主要原因
    日本很火的秋刀鱼在中国却不受待见?你知道吗?

    日本是一个岛国,水产资源丰富,所以他们的食物有很大一部都是海鲜,鱼对他们来说是最平常无奇的食物了,就像我们的大米饭一样,并且他们吃鱼的花样繁多。然而这些不是重点...

    2019-12-18
  • 那些看综艺被安利的美食,你吃了么?
    那些看综艺被安利的美食,你吃了么?

    那些#被综艺安利过的美食# :《中餐厅》四川辣子鸡《舌尖上的中国》过桥米线《天天向上》王一博吃的各种零食《拜托了冰箱》王嘉尔每一次吃东西《街头美食斗士》烤冷面《...

    2019-12-18
  • 老干妈换回原配方,销量依旧不乐观,你还愿意给它机会吗?
    老干妈换回原配方,销量依旧不乐观,你还愿意给

    老干妈想必大家都认识了,毕竟“国民女神”,谁家没有个吃不下饭的时候呢,老干妈拌米饭,或者卷饼,都是非常惬意的。老干妈在国内辣椒酱品牌里一直都是极具人气和知名度的...

    2019-12-18
  • 这些让狗狗馋到飞起的零食,看着都流口水
    这些让狗狗馋到飞起的零食,看着都流口水

    都说有什么样的主人就有什么样的宠物,一年的时间,我家狗子成功迈入了吃货的行列!现在好了,自己在吃零食的时候有狗陪了!你不要以为这就可以了,吃货也是有自己的尊严的...

    2019-12-18
  • 卖豆腐的大妈把豆腐这么卖,收入瞬间翻几倍,顾客却纷纷抱怨
    卖豆腐的大妈把豆腐这么卖,收入瞬间翻几倍,顾

    卖豆腐的大妈把豆腐这么卖,收入瞬间翻几倍,顾客却纷纷抱怨!豆腐是大家经常吃的食物,豆腐营养价值高,而且还非常便宜,一般一块豆腐也就几块钱,自从大妈把豆腐这样做后...

    2019-12-18
  • 测评!百元内适合女生喝的微醺果酒
    测评!百元内适合女生喝的微醺果酒

    Hi,小酒鬼又的上线了。【不喜欢太烈的就,会让人迷失方向。喜欢一点点微醺又好喝的高颜值小酒~】今天分享的小酒,有集盲盒的快感,第一眼就被5瓶摆在一起的海报吸引了...

    2019-12-18