0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一段有关MPU配置代码的几个小疑问

茶话MCU 来源:茶话MCU 作者:茶话MCU 2022-12-05 10:33 次阅读

当我们阅读一些STM32F7或STM32H7系列芯片例程,或者基于这两类芯片通过cubeMx进行配置并用到MPU功能时,往往会在代码里看到下面这段MPU配置。

ab382200-73bf-11ed-8abf-dac502259ad0.png

对这段代码可能有人有些疑问,这里重点一起聊聊其中的3个,供参考。

第一个疑问,那行做赋值0x87的代码是什么意思?

第二个疑问,这段代码的注释【绿色】是说将未定义的区域配置为StronglyOrdered存储属性,这个未定义到底如何理解?从代码看,这里清晰地对从0开始的整个4G空间做了配置,未定义区域到底指的哪里?

第三个疑问,这段代码往往并不是开发者自己配置的。如果使用CubeMx进行配置它会自动给我们加上这段,为什么要加这段?很多时候经测试,即使没这段代码似乎也没有什么问题。

这几个问题,涉及到MPU和CortexM7内核芯片试探性访问的知识。我尽量通俗地加以介绍,知晓怎么回事即可。

我们知道,通过MPU可以配置特定地址空间的存储属性,给CPU约定访问权限。我们在对某块地址空间做MPU配置时,通常需要设置起始地址、空间大小、Cacheable、Bufferable、Shareable、子区属性、区块编号等。这里的地址空间,英文用Region来特指,后面都使用该词。

实际应用中我们往往会针对不同的Region做MPU配置,在做不同Region的MPU设置时,可能出现地址空间重叠的情况。比方像下面64KB空间内做了3个不同Region的MPU配置,而且发生了不同Region的地址重叠。

ab702c86-73bf-11ed-8abf-dac502259ad0.png

这个时候,对于地址重叠空间的MPU属性由Region编号大的决定。结合上图,N+2编号Region的MPU属性优先级最高,Region N的最低。

刚才我在前面提到了子区,它是什么意思呢?

子区也是个特定概念,英文用SubRegion。所谓Subregion,当我们对某地址空间不小于256B的Region进行MPU配置时,可以把该Region等分为8个子区【Subregion】,并把当前Region的MPU属性针对部分子区进行排除性或说例外性设置。啥意思呢?比方说,本来当前Region经MPU配置后为WriteThough支持共享的存储属性,同时呢,又将其中的2个子区做排除性设置,即这2个子区不适用当前的MPU配置。好比当前举国抗疫防新冠,要求全面强制核酸,但同时又可以做例外说明,那些基本足不出户的老人或小孩不适用该要求。

在MPU配置寄存器MPU_RASR里有个8位字段SRD专门用来配置子区的排除属性。每1位对应一个子区,高位对应高地址子区,低位对应低地址子区。某位为0表示该子区使用当前MPU配置,为1表示该子区不适用当前配置,即被排除在外。【更多细节可以参考下图】

ab85f160-73bf-11ed-8abf-dac502259ad0.png

不妨举例说一下,假设我们选择了某64KB区域进行MPU设置,其中有2个SubRegion被做了MPU排除处理,即其中2个8KB空间不适用当前的MPU配置。如下图所示:

aba3363a-73bf-11ed-8abf-dac502259ad0.png

此时,对应到MPU配置寄存器MPU_RASR里的SRD字段的内容就是0x48。

聊到这里,我们就可以回答开篇的部分疑问了。

ab382200-73bf-11ed-8abf-dac502259ad0.png

从上面这段代码不难看出,首先将从0开始的4GB空间做了MPU配置,Region编号为0,最终被配置为Strongly Ordered存储属性。那句赋值0x87的代码则是进一步针对当前Region里的SubRegion做属性排除设置。这里的0x87就是给前面提到的给SRD字段的赋值。【这里每个子区空间大小为512MB】

abdfde78-73bf-11ed-8abf-dac502259ad0.png

也就是说,这4GB空间中有4个子区不适用目前配置的MPU属性,即下图中几个红色方框内区域。

abf4c16c-73bf-11ed-8abf-dac502259ad0.png

换句话说,这里并没有真正针对整个4GB空间做MPU配置,实际上只对上图中的绿色区域做了StronglyOrder的存储属性设置。然而,代码的注释又说是针对未定义区域做MPU配置,怎么理解未定义区域呢?

这里说的未定义区域到底是上图中红色区域还是绿色区域呢?

显然不是指红色区域,因为这里特意对红色区域做了MPU属性排除处理,即当前MPU配置根本就不适用它。那是指绿色区域?似乎也不对!因为绿色区域的MPU配置不是很清晰吗?Region编号、地址空间、访问属性等一应俱全。何来未定义呢?

我们可以进一步了解到,上图中绿色区域对应的是外部存储设备的地址空间。如果我们需要用到外部存储设备的话,往往还会针对外扩的存储单元再做MPU配置。比方我们基于STM32H7芯片外扩了一个32MB的SDRAM,然后做了如下的MPU配置。

ac12dcec-73bf-11ed-8abf-dac502259ad0.png

照样,先对整个4GB空间做了MPU初始配置,即前面一直在解说的内容。然后针对外扩的32MB的SDRAM做了特定MPU配置,此时的Region标号为1,访问属性为Write Through。此块Region空间属于前面初始配置中外部存储空间的一部分,即出现不同Region地址重叠,所以这块SDRAM所在Region的MPU访问属性就是Write Through,而不再是一开始配置的Strongly Ordered属性了。见下图中绿色区域中那部分黄色方块。

ac4f7c10-73bf-11ed-8abf-dac502259ad0.png

当然,如果说你还外扩了其它的存储单元,比方扩个QSPI什么的,如果MPU属性依然不同于Strongly Ordered、且Region编号大于0,更多绿色区域将被新的黄色区域替换。比方变成下面图示的样子。

ac7a9fd0-73bf-11ed-8abf-dac502259ad0.png

也就是说,注释代码里提到的未定义区域,是指初始定义出来的绿色区域中没有被用户的实际外部存储器所占用的剩余空间。即上面图中抠除黄色区域以后剩下的绿色区域。

这里又衍生个问题,为什么要这样做呢?

这个问题又涉及到M7内核芯片的试探性访问特性。试探性访问可以提升芯片的性能,但有时可能也会导致些问题。比方,由于试探性访问,在CPU访问外部存储器时,可能发生越界访问。如果说它访问到一个本不存在存储设备的地址时,可能发生锁死异常。结合上面图形,黄色地址区域是实实在在的外部存储器件所占用的空间,如果因为试探性访问可能越界访问不存在物理存储单元的绿色区域而导致麻烦。

不过,由于CPU不会针对配置为Device 或Strongly Ordered存储属性的地址空间进行试探性访问。为了防止上面提到的问题,于是就有了前面谈到的一上来就把所有用于外部访问的存储空间配置为StronglyOrdered属性,显然这个配置是个粗框架性的。用户具体使用时根据实际存储器的特性、容量等再配置特定的MPU属性并覆盖原来初始设置,其它未用区域依然保持StronglyOrdered属性,正是为了防止在没有放置实际存储器的地方发生试探性访问。

最后一个问题,有人发现即使不要那段针对4GB空间的MPU初始代码,似乎也没遇到啥问题。

这也正常。因为你即使外扩了存储单元,并非一定会因为试探性访问导致异常。比方你外扩了32MB的存储单元,未必就一定会要用到最后一个位置,说不定还剩余很多,远不至于读到最后边界而让CPU试探到不存在存储器的空间。但是事先做那段初始配置,对系统是一个很好的未雨绸缪。就好像河边安置防护栏一样,没有,也不至于天天怎么样;有,肯定要安全保险得多。

几个小疑问,本以为可以很快写完,不禁啰嗦了这么久,就此打住。祝君好运!

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10816

    浏览量

    210994
  • MPU
    MPU
    +关注

    关注

    0

    文章

    342

    浏览量

    48712
  • STM32F7
    +关注

    关注

    1

    文章

    48

    浏览量

    8936
  • CubeMx
    +关注

    关注

    0

    文章

    30

    浏览量

    1312

原文标题:一段有关MPU配置代码的几个小疑问

文章出处:【微信号:stmcu832,微信公众号:茶话MCU】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    一段C代码关联的知识点

    之前有位网友在交流群里发了一段代码的截图,我觉得很有意思,在此分享下。
    发表于 08-30 10:42 415次阅读
    <b class='flag-5'>一段</b>C<b class='flag-5'>代码</b>关联的知识点

    MPU6050匀速转动一段时间后,偏航角不变怎么解决?

    显示之前的数据(看着像数据滞后),然后最后恢复正常,所以目前问题就是机器人匀速转动一段时间后就会偏航角输出不变,请问各位有遇到过吗,怎么解决的。
    发表于 04-09 08:24

    一段人体红外感应设计代码

    我是初学者,对着方面不太懂,之前自己写了一段,自己感觉没问题,结果下载到单片机上九出问题了,谢谢大家的帮助,最好是写一段用人体红外感应模块控制个LED的代码!谢谢了!
    发表于 03-09 15:19

    敲了一段verilog代码,找到了努力的方向。

    的日子,被考研逼着去学习泰勒柯西了,之前上课就没好好听,看个视频理解的都很费劲。敲了一段verilog代码,立刻有种找回自我的感觉,很提神,这几天看各种考研视频看得昏昏欲睡。推荐各位烧友们在人生迷茫的时候敲一段
    发表于 02-28 21:18

    labview 如何调用HTML中的一段JS代码

    labview 如何调用HTML中的一段JS代码,红色字体怎么转成labview代码?CComQIPtr spDoc = m_web.get_Document
    发表于 04-01 15:21

    检测一段文本是否为全中文

    易语言是门以中文作为程序代码编程语言学习例程:易语言-检测一段文本是否为全中文
    发表于 06-06 17:01 4次下载

    基于8051的Proteus仿真-播放一段音乐

    基于8051的Proteus仿真-播放一段音乐
    发表于 09-01 23:32 8次下载

    基于8051的Proteus仿真-演奏一段音阶

    基于8051的Proteus仿真-演奏一段音阶
    发表于 09-01 23:37 33次下载

    瑟瑟发抖:深度学习可以通过一段代码找出代码作者

    最近又有两个人,Caliskan和Greenstadt(名字不重要,姑且就称大C和大G)突然站出来说代码也类似!每个人都有自己的代码风格,深度学习是可以追踪出一段代码的原作者的。
    的头像 发表于 08-14 17:45 4477次阅读

    Arduino 接MPU6050 9250使用IIC通讯,输出数据一段时间后死机卡死的问题解决

    Arduino 接MPU6050 9250使用IIC通讯,输出数据一段时间后死机卡死的问题解决
    发表于 12-06 15:06 24次下载
    Arduino 接<b class='flag-5'>MPU</b>6050 9250使用IIC通讯,输出数据<b class='flag-5'>一段</b>时间后死机卡死的问题解决

    STM32之FreeRTOS:() 中断配置和临界的使用

    STM32之FreeRTOS:() 中断配置和临界的使用文章目录STM32之FreeRTOS:() 中断配置和临界
    发表于 01-14 15:43 3次下载
    STM32之FreeRTOS:(<b class='flag-5'>一</b>) 中断<b class='flag-5'>配置</b>和临界<b class='flag-5'>段</b>的使用

    真是一段漫长的旅程:从阿基米德到可重新配置仪表板

    真是一段漫长的旅程:从阿基米德到可重新配置仪表板
    发表于 11-03 08:04 0次下载
    真是<b class='flag-5'>一段</b>漫长的旅程:从阿基米德到可重新<b class='flag-5'>配置</b>仪表板

    基于AT89C51单片机播放一段音乐仿真及代码

    基于AT89C51单片机播放一段音乐仿真及代码
    发表于 05-05 10:33 1次下载

    基于AT89C51单片机演奏一段音阶仿真及代码

    基于AT89C51单片机演奏一段音阶仿真及代码
    发表于 05-05 10:09 0次下载

    devc怎么注释掉一段代码

    在DevC中,要注释掉一段代码,你可以使用注释符号来标记这段代码。注释符号的作用是告诉编译器不要编译这些代码,而是将其视为注释,这样可以方便开发人员在
    的头像 发表于 11-22 10:23 2354次阅读