历史上的今天
今天是:2025年01月07日(星期二)
2019年01月07日 | stm32中关于NVIC_SetVectorTable函数使用的疑惑与理解
2019-01-07 来源:eefocus
先描述下这几天碰到的一个奇怪的问题:
一个基于stm32的工程中使用到了IAP编程,其中boot空间预留长度为0x6100,实际boot的bin文件大小为21.1KB,具体为21633Byte.我在最开始调试时对于IAP编程的app程序直接下载到单片机中,程序工作一切正常,但是在通过boot将app更新到单片机中后程序可以进入到app中,但是程序工作不正常。
最后经过查找原因,最后在代码注释中找到了问题所在:

途中划红线的部分可以看出,NVIC_SetVectorTable函数参数中的Offset必须是0x200的倍数,但是~但是我刚刚说的那个IAP中的boot空间大小为0x6100,这个值并不是0x200的整数倍,这也就是问题所在了。
=============================分割线==============================
上面找到了问题所在,那么是不是就结束了呢?很明显没有,NVIC_SetVectorTable的函数注释中知识轻描淡写的说Offset必须是0x200的倍数,但是为什么要这样它并没有进行解释。着就是目前的新问题了。
首先查看NVIC_SetVectorTable函数的实现代码,非常简单,首先是对参数进行正确性判断,然后就是对一个寄存器进行赋值。在判断参数正确性的代码中并没有找到有关于0x200的代码,那么问题肯定就在这个寄存器赋值上了。具体代码如下:
SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80);
我们关注Offset部分,它与0x1FFFFF80进行与运算,奇怪的是这个与运算的结果只能使得Offset能够0x80的整数倍,并不是0x200。如果要是0x200,那么倒推回来那么这个地方应该是0x1FFFFE00才对,难道是stm32官方的库函数有问题?!这个真是让我有点小兴奋。我隐约感觉到问题没有这么简单,决定先看看这个寄存器相关的资料在做结论,经过查看,在周立功的《CM3技术参考手册》中的讲解NVIC章节(第90页)中发现了如下的讲解:

这个地方说明VTOR寄存器的第7到28位是用来存储偏移量的,这也就能解释为什么刚才代码里面进行与运算的是0x1FFFFF80了。
但是问题还是没有解决,为什么Offset要是0x200的整数倍呢?
对于这种与CM3系统架构相关的内容,一般都是去看《Cortex-M3权威指南》,果然,最后找到了如下解释(中文版第113页):

途中划红线的部分是关键,按照它说的方法,我打开工程的启动文件,发现其中有60个普通中断,另外有16个系统中断,一起是74个中断,由于74大于2的6次方(也就是64,),所以幂向上加1也就是2的7次方,即128,然后一个地址占用四个字节,所以得出128*4=512,也就是我苦苦寻觅的0x200。
至此最初的疑问已经解决,但是在读上面划红线的文字时,一个疑问在我脑海环绕:为什么要一定为2的整数次幂,按着划红线的示例,我在flash中就花费48*4个字节给中断向量表不就挺好么。对于这个问题目前还没有发现比较好的答案,根据我个人的理解,我觉得可能是出于以下两点原因:
1 方便扩从中断向量表
解释:比如现在需要48个中断向量那我就分配它48*4个字节空间,但是以后需要49个捏?考虑到拓展性所以还是多留空间的好
2 方便编程时的FLASH擦写
解释:给出一个Offset的相对固定的值,方便程序员在编程时提高效率,试想如果设置一个非常复杂的boot长度地址,每次修改都会浪费不少时间
下一篇:STM32串口空闲中断问题
史海拾趣
|
补充一些内容 (仅针对工包,行货不管这些)一:输出滤波元件 (看不懂的可以不管这一部分)功率稍微大点(250W)的电源,输出的滤波线圈就是2个.再大点(400W以上)的一般都是3个.输出滤波电感通常位于电源的那一大堆出线附近. ...… 查看全部问答> |
|
硬件工程师在硬件开发中要注意的事项 [ 2010-7-5 2:47:00 | By: szdiscuz ] 1 启动一个硬件开发项目 原始的推动力会来自于很多方面,比如市场的需要,基于整个系统架构的 ...… 查看全部问答> |
|
WINCE下怎么诊断一个驱动有没存在资源锁死的问题?就是多个线程对同一个资源的访问同步互斥没做好。 WINCE下怎么诊断一个驱动有没存在资源锁死的问题?就是多个线程对同一个资源的访问同步互斥没做好。… 查看全部问答> |
|
======WINCE6.0下这些异常怎么定位解决---Exception 'Undefined Instruction'++++Exception 'Pref ======WINCE6.0下这些异常怎么定位解决---Exception \'Undefined Instruction\'++++Exception \'Prefetch Abort\' ======… 查看全部问答> |
|
Xilinx Spartan-6 FPGA SP605 Embedded Development Kit 试用报告 v1.0 Spartan-6 FPGA 嵌入式套件已试用完成,现已传递给下一位使用者,现在上报告!O(∩_∩)O~Xilinx Spartan-6 FPGA SP605 Embedded Development Kit试用报告 v1.0,目录如下: 报告前三节已基本完成,后三节将在v1.1中更新,谢谢!下载报告,请右击 ...… 查看全部问答> |
|
交流电流过负载时,加在该负载上的交流电压与通过该负载的交流电流产生相位差,人们便从中引出功率因数这一概念。人们生产、生活用电来自电网,电网提供频率为50Hz或60Hz的交流电。作为交流电的负载有电阻、电感、电容三种类型: 1、当交流电通过 ...… 查看全部问答> |
|
请问各位,怎么实现5438和电脑进行网口通信?我用的开发板是BW-DK5438的,上边的网口芯片是ENC28J60,怎么进行连接呢?用网络调试助手还是其他手段呢?在连接的时候,430的端口号和IP地址如何设定呢?谢谢了… 查看全部问答> |




