NVIC的向量表偏移寄存器设置问题(已解决)

2019-07-20 23:51发布

void MY_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset) 
{
   //检查参数合法性
 assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));
 assert_param(IS_NVIC_OFFSET(Offset));   
 SCB->VTOR = NVIC_VectTab|(Offset & (u32)0x1FFFFF80);//设置NVIC的向量表偏移寄存器
 //用于标识向量表是在CODE区还是在RAM区
}

问个问题,为什么(Offset & (u32)0x1FFFFF80)  为什么使用0x1FFFFF80,0x1FFFFF80是怎样得来的呢?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
38条回答
guama
1楼-- · 2019-07-24 20:27
看了上边的回复,我理解的意思是:
向量表偏移量寄存器,也就是SCB->VTOR:31位,30位保留,它的第29位,用来标识向量表是在CODE区还是RAM区,从而0X1,就是最高3位不去动,0-6位为保留位需要清零,所以要同0x1FFFFF80(0001 1111 1111 1111 1111 1111 1000 0000)与(&),保证最高3位,和低7位为0;中间7-28位是地址偏移,这个地址有个要求:(必须先求出系统中共有多少个向量,再把这个数字向上增大到是2 的整次幂,而起始地址必须对齐到后者的边界上。如:STM32自己有60个中断,加上CM3的16个,总共有76个中断,扩大到2的整次幂,那就是128,然后再乘以4,得到512,也就是0X200.根据这样计算,合法的偏移地址应该是0X0,0X200,0X400,0X600... )。

PS:
1.地址偏移的要求是用户在设定时需要另外考虑的(比如上例中,设定的地址需要是0X200的倍数),跟&0x1FFFFF80没有关系;
2.关于为什么乘以4,应该是每个32位的地址占四个字节吧。
3.要保证整除0x200就要去掉小于0x200的余数,所以&0X1FFF FE00后就能保证得出的数可以整除0x200。

楼主帮忙看看你们要表达的是不是这个意思。
zhanminlove
2楼-- · 2019-07-25 01:35
刘飞月 发表于 2016-10-24 17:31
在第一百零四页,有这么一段话:
    NVIC 中有一个寄存器,称为“向量表偏移量寄存器”(在地址0xE000_ED08 ...

权威指南里说每个向量占4个字节
mxiaotao
3楼-- · 2019-07-25 05:07
 精彩回答 2  元偷偷看……
森海有眼泉
4楼-- · 2019-07-25 07:29
我把各位大神的回帖 整理总结了一下.
https://blog.csdn.net/justsure91/article/details/80852623
不知道对不对.有误请指正.
Kinglkf2R
5楼-- · 2019-07-25 10:47
正点原子 发表于 2015-4-29 23:16
回复【25楼】哈根斯坦:
---------------------------------
看《CM3权威指南》

在学习IAP编程时候对于APP程序执行中断时候有一点疑问
在图中的圈4步骤     APP程序发生中断时候调到原始中断表




点我在看M3权威指南时候有个关于建立新中断向量表的内容




我的理解是  对于一个APP程序  它的中断服务函数的入口地址在编译之后是固定的      不一样的是要将这个入口地址填入到中断向量表的对应位置   

既然是APP程序  那么它的中断向量表位置相对BootLoader程序有一个偏移地址    称之为新中断向量表    那么现在的问题就是将APP的中断服务函数入口地址填入的新中断向量表中  

这个时候  就需要更具中断向量表的偏移地址来计算      首先算出新表的起始地址    在计算新表中的第几项   确定之后将地址填入   

按照这个过程  APP程序发生中断时候要找中断向量只能去新表中找   而在旧表中是找不到的     所以图中的圈4应该直线灰 {MOD}的新中断表   


如果去旧表中去找  那移位着BootLoader程序的中断向量被APP程序覆盖    那么BootLoader程序只能执行一次   下册执行会出错

henu321
6楼-- · 2019-07-25 10:58
 精彩回答 2  元偷偷看……

一周热门 更多>