[转载]2017年12月4日14:48:29

先描述下这几天碰到的一个奇怪的问题:

一个基于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中关于NVIC_SetVectorTable函数使用的疑惑与理解的更多相关文章

  1. STM32 中的 assert_param 函数

    在学STM32的时候函数assert_param出现的几率非常大,上网搜索一下,网上一般解释断言机制,做为程序开发调试阶段时使用. 断言机制函数assert_param我们在分析库函数的时候,几乎每一 ...

  2. stm32中的延时函数

    //粗延时函数,微秒 void delay_nus(u16 time) { u16 i=0; while(time--) { i=10;  //自己定义 while(i--) ; } } //毫秒级的 ...

  3. 简单理解ECMAScript2015中的箭头函数新特性

    箭头函数(Arrow functions),是ECMAScript2015中新加的特性,它的产生,主要有以下两个原因:一是使得函数表达式(匿名函数)有更简洁的语法,二是它拥有词法作用域的this值,也 ...

  4. STM32中如何对printf函数重定向

    通过USART1向计算机的串口调试助手打印数据,或者接收计算机串口调试助手的数据,接下来我们现STM32工程上的printf()函数,方便用于程序开发中调试信息的打印. 方法一:使用MicroLIB库 ...

  5. 如果简化stm32中printf函数的使用——首先重定向

    STM32单片机极简方法 使用宏定义 代替复杂的重定向printf()函数,实现串口打印.(HAL库例程)https://blog.csdn.net/wu10188/article/details/9 ...

  6. (二)STM32中中断优先级理解

    很多人在配置STM32中断时对固件库中的这个函数NVIC_PriorityGroupConfig()——配置优先级分组方式,会很不理解,尤其是看中文翻译版的,因为中文翻译版里把这里翻译成“先占优先级和 ...

  7. C语言学习及应用笔记之七:C语言中的回调函数及使用方式

    我们在使用C语言实现相对复杂的软件开发时,经常会碰到使用回调函数的问题.但是回调函数的理解和使用却不是一件简单的事,在本篇我们根据我们个人的理解和应用经验对回调函数做简要的分析. 1.什么是回调函数 ...

  8. 初识STM32中的USMART组件

    今天看了usmart那部分的模块,感觉使我们stm32的学习变更加方便,你可以通过串口查看和检验你所注册过的函数. USMART配步骤1.将USMART包添加到工程中,头文件要包括path2.添加所需 ...

  9. stm32中assert_param的用法说明

    stm32中assert_param的用法说明   首先是要知道条件判断语句 这个运算符分成三部分: (条件) ? (条件成立执行部分) :(条件不成立执行部分) 就这么简单 例如:a=(x>y ...

随机推荐

  1. Java(195-214)【final、权限、内部类】

    1.final关键字的概念与四种方法 今天是基础学习的最后一天!~ 2.final关键字用来修饰一个类 3.final关键字来修饰成员方法 4.final用于修饰局部变量 package cn.itc ...

  2. Centos下搭建DNS域名解析服务器

    Centos下搭建DNS域名解析服务器 DNS  即Domain Name System(域名系统)的缩写,它是一种将ip地址转换成对应的主机名或将主机名转换成与之相对应ip地址的一种机制.其中通过域 ...

  3. Kubernetes删除一直处于Terminating状态的namespace

    问题现象: 删除namespace,一直处于Terminating,并且用--force --grace-period=0 也删除不了 develop Terminating 4d9h Error f ...

  4. 什么?女神发了朋友圈,快来围观之Java设计模式:观察者模式

    目录 观察者模式 示例 定义 设计原则 意图 主要解决问题 何时使用 优缺点 女神和追求者的故事 Java中的实现 观察者模式 示例 微信公众号,关注就可以收到推送的消息,取消关注就不会收到 定义 定 ...

  5. 玉帝传美猴王上天,大闹天宫之Java设计模式:命令模式

    目录 示例 改进代码 命令模式 定义 意图 主要解决问题 何时使用 优缺点 玉帝传美猴王上天 命令模式和策略模式的区别 示例 系统需要设计一个命令行界面,用户可输入命令来执行某项功能,系统的功能会不断 ...

  6. Android APK程序的smali动态调试

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/71250622 一.Apktool的下载和安装 Apktool是Android逆向分 ...

  7. PhpMyWind储存型XSS漏洞练习(CVE-2017-12984)

    0x01 介绍 又是一款开源CMS内容管理系统PhpMyWind,在小于等于5.4版本中存在储存型XSS漏洞.如下图所示,这个就是发生储存型XSS漏洞的代码 0x02 演示 1.第一张图是客户留言时, ...

  8. [转帖]大家分析分析C++ X64X86通用驱动读写API源码教程

    //#include  <windows.h>//#include <algorithm>  //#include <string.h>//#include < ...

  9. 13.PHP_ThinkPHP

    ThinkPHP 先把百度百科上对这个框架的介绍粘贴过来: ThinkPHP是为了简化企业级应用开发和敏捷WEB应用开发而诞生的.最早诞生于2006年初,2007年元旦正式更名为ThinkPHP,并且 ...

  10. 你注意到了吗?修改API文档也需要规范!

    关于API接口文档的内容和格式规范的文章,之前也有写过,网上也有不少写的比我还好的,就不赘述了,今天想说的是一个很容易被忽略的点,修改API文档的规范:版本控制. 示例 拿Eolinker来演示一下流 ...