stm32中的程序是在RAM里还是flash里执行?

光明磊 2016-09-18 08:25:34
stm32中的Code在程序运行时要不要拷贝到RAM里执行呢?还是直接从Flash中取程序指令执行?
不是nand flash不能运行程序吗?难道32里用的是nor flash?
...全文
11090 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
lr2131 2020-01-15
  • 打赏
  • 举报
回复 5
引用 9 楼 weixin_38632329 的回复:
[quote=引用 4 楼 lr2131 的回复:]
[quote=引用 楼主 happygaohualei 的回复:]
stm32中的Code在程序运行时要不要拷贝到RAM里执行呢?还是直接从Flash中取程序指令执行?
不是nand flash不能运行程序吗?难道32里用的是nor flash?


如果你有研究过单片机编程的分散加载机制,在编程中写过分散加载脚本。你问的第一个问题就解决了。
如果你有写过nand flash的驱动程序,你问的第二个问题就解决了。

STM32中的code可以不用拷贝到RAM中运行,也可拷贝到RAM中运行,这些不是技术问题,而是要看这段code
有没有加载到RAM中运行的必要。后面再解释。

nand flash不支持片上执行,不能在nand flash中执行程序,但nor flash支持。
但不能因此就断定STM32用的外置flash都是nor的。只要STM32带nand flash的控制器,就可以把nand中的code加载到RAM中运行。至于能不能用IO模拟nand 的接口协议,我没搞过不清楚。

首先,应该所有的单片机都是片内集成RAM和ROM(在加载域和运行域的角度看,Flash就是ROM)。
一般容量小的单片机,RAM和ROM都小,不会把flash中的代码加载到RAM中。
但有时确实需要加载,怎么办呢。就把code中比较关键的,调用很频繁的,对响应速度有要求的,就会加载到RAM中。
例如高频率中断的定时器中断ISR,就可以在分散加载脚本中修改这段code的运行域到RAM中。程序在刚上电后会在main函数之前加载这段code到RAM中。这样做的好处就是,这段code的执行速度快,我们知道ROM和RAM执行代码的速度比差距是很大的。RAM比ROM中执行速度快得多!
当然,如果你的RAM很大,你甚至可以把全部的Code加载到RAM中运行。

nand flash不是直接接到CPU的三总线上的,所以CPU不能直接从nand中取得可执行的指令,而是通过nand的控制器!
而nor是在总线上的,所以nor中的code可以直接执行。(nor的这个观点仅是我个人看法,仅供参考)。

再说外置RAM的问题,单片机在带SDRAM的控制器之后,就可以支持SDRAM了。
SDRAM在初始化好之后,SDRAM的使用方法和内置的SRAM没有差别。

如果你的单片机支持SDRAM和Nand flash,你可以把nand flash中的code加载到SDRAM中运行。
如果你知道怎么写分散加载脚本,这个功能分分钟就能实现。

[/quote]


一般容量小的单片机,RAM和ROM都小,不会把flash中的代码加载到RAM中
请教一下大神,如果是代码中的全局变量,静态变量,也不会把flash中的代码加载到RAM中吗,那如果需要修改这些变量,flash中可以直接修改吗,另外感觉大神这一块研究很深,但是还是没给出答案,stm32内部既不是nor flash,也不是nandflash吗,最近我也是在用这个突然想到的,我觉得应该算是nor flash,因为总线可以直接访问到,我的一点疑惑 和大神探讨一下[/quote]

其实我也不是大神,真正的大神似乎都很少来论坛。。。。。。

“一般容量小的单片机,RAM和ROM都小,不会把flash中的代码加载到RAM中”
不好意思,我这句话有些背景概念没有交代清楚,看来已经误导了人。但是要说清楚,也不是一两句就说的清楚的。还是先直接回答你的问题吧。

1.flash中的代码,怎么加载到RAM中,有两种做法
A.编写或改写分散加载脚本,编译出来的程序,在启动时,也就是在进入你的main函数之前,会按照分散加载脚本的要求,
把全部或部分代码加载到RAM中。这个比较通用,也还算是比较简单。
B.自己编写加载代码,自己将自己的某个部分或全部加载到RAM中,如果没有特殊需要,建议用A方法。
什么是特殊需要呢,我一下展开不了,你看看嵌入式的bootloader,就是这么干的,非常普遍。

一般A的做法,是为了让某些被调用得非常频繁的函数,运行速度更快,这个你也知道单片机内的flash,执行速度比片内RAM慢。
你可以试试。如果是为了让某些函数被运行得更快,建议你用A方法,例如中断频率非常高的定时器ISR,把代码直接加载到RAM中,
以后就直接在RAM中运行这段代码了,而不去flash中拿这段代码了。
不过这些都已经优化的高级阶段了,实际产品开发中你知道这个优化方法,但也可能不会用得很多。

如果单片机本身的RAM就很小,你自然不能把太多的代码加载到里面,不然就没有足够的RAM给程序的其他代码用了,对不对。
你的代码中有没有用到静态变量(全局变量和静态变量),和代码要不要加载到RAM没有什么关系。
请注意,静态变量不是代码。静态变量属于数据段,定义时无初始化值的静态变量在ZI区,定义时有初始化值的在RW区,不过我有一点也很模糊,我不知道定义时有初始化值的,但初始值是0的,是不是也在ZI区。对应到嵌入式Linux的说法,叫ZI->BSS,RW->DATA,RO->text
建议你关注以下概念:
加载域,运行域。数据段,代码段,堆栈段。RO,RW,ZI. text,data,bss
书籍推荐杜春雷的《ARM体系结构与编程》 ,王宇行的《ARM程序分析与设计》,高阶的可以看《程序员的自我修养:链接、装载与库》 ,这几本书中都有上面这些概念的相关章节,可以挑着看。

2.怎么修改这些静态变量。
如果这些静态变量,不需要做到断电保存,那就没什么要说的。
如果你要做成断电保存,那你一定得要知道它在flash中的地址,对不对。
做法,我还是不写了,你上网找找资料吧,这个很多,做法也有几种。

3.STM32内部的flash是nor还是nand,其实我也不知道,说不定还有第三种答案呢。
但是没所谓,这几种flash的特点你都知道,这几种你都会用,就好了。硬要说是哪种,我觉得似乎更接近nor的特性。










weixin_38632329 2020-01-15
  • 打赏
  • 举报
回复 1
引用 4 楼 lr2131 的回复:
[quote=引用 楼主 happygaohualei 的回复:] stm32中的Code在程序运行时要不要拷贝到RAM里执行呢?还是直接从Flash中取程序指令执行? 不是nand flash不能运行程序吗?难道32里用的是nor flash?
如果你有研究过单片机编程的分散加载机制,在编程中写过分散加载脚本。你问的第一个问题就解决了。 如果你有写过nand flash的驱动程序,你问的第二个问题就解决了。 STM32中的code可以不用拷贝到RAM中运行,也可拷贝到RAM中运行,这些不是技术问题,而是要看这段code 有没有加载到RAM中运行的必要。后面再解释。 nand flash不支持片上执行,不能在nand flash中执行程序,但nor flash支持。 但不能因此就断定STM32用的外置flash都是nor的。只要STM32带nand flash的控制器,就可以把nand中的code加载到RAM中运行。至于能不能用IO模拟nand 的接口协议,我没搞过不清楚。 首先,应该所有的单片机都是片内集成RAM和ROM(在加载域和运行域的角度看,Flash就是ROM)。 一般容量小的单片机,RAM和ROM都小,不会把flash中的代码加载到RAM中。 但有时确实需要加载,怎么办呢。就把code中比较关键的,调用很频繁的,对响应速度有要求的,就会加载到RAM中。 例如高频率中断的定时器中断ISR,就可以在分散加载脚本中修改这段code的运行域到RAM中。程序在刚上电后会在main函数之前加载这段code到RAM中。这样做的好处就是,这段code的执行速度快,我们知道ROM和RAM执行代码的速度比差距是很大的。RAM比ROM中执行速度快得多! 当然,如果你的RAM很大,你甚至可以把全部的Code加载到RAM中运行。 nand flash不是直接接到CPU的三总线上的,所以CPU不能直接从nand中取得可执行的指令,而是通过nand的控制器! 而nor是在总线上的,所以nor中的code可以直接执行。(nor的这个观点仅是我个人看法,仅供参考)。 再说外置RAM的问题,单片机在带SDRAM的控制器之后,就可以支持SDRAM了。 SDRAM在初始化好之后,SDRAM的使用方法和内置的SRAM没有差别。 如果你的单片机支持SDRAM和Nand flash,你可以把nand flash中的code加载到SDRAM中运行。 如果你知道怎么写分散加载脚本,这个功能分分钟就能实现。 [/quote] 一般容量小的单片机,RAM和ROM都小,不会把flash中的代码加载到RAM中 请教一下大神,如果是代码中的全局变量,静态变量,也不会把flash中的代码加载到RAM中吗,那如果需要修改这些变量,flash中可以直接修改吗,另外感觉大神这一块研究很深,但是还是没给出答案,stm32内部既不是nor flash,也不是nandflash吗,最近我也是在用这个突然想到的,我觉得应该算是nor flash,因为总线可以直接访问到,我的一点疑惑 和大神探讨一下
cc-15015401 2020-01-14
  • 打赏
  • 举报
回复
phangbob 2016-09-30
  • 打赏
  • 举报
回复
引用 5 楼 qq_20553613 的回复:
[quote=引用 2 楼 phangbob 的回复:] STM32里有ROM和RAM,ROM就是flash,程序是下载到里面。 当STM32执行程序时,是把ROM中的数据,程序“搬运”到RAM中然后再执行的,一般的指令存储在ROM。 就比如电脑,RAM是运行内存,ROM是硬盘,cpu不是直接执行在硬盘上的程序,而是将硬盘的程序拷贝到运行内存里面,然后在运行内存中执行。 互相学习,有错误望指出,虚心受教,希望能帮到你。
stm32内部是nor flash,直接执行代码。[/quote] 楼上各位大侠的留言都看完了,学习了,感谢感谢。
Acuity. 2016-09-29
  • 打赏
  • 举报
回复
引用 2 楼 phangbob 的回复:
STM32里有ROM和RAM,ROM就是flash,程序是下载到里面。 当STM32执行程序时,是把ROM中的数据,程序“搬运”到RAM中然后再执行的,一般的指令存储在ROM。 就比如电脑,RAM是运行内存,ROM是硬盘,cpu不是直接执行在硬盘上的程序,而是将硬盘的程序拷贝到运行内存里面,然后在运行内存中执行。 互相学习,有错误望指出,虚心受教,希望能帮到你。
stm32内部是nor flash,直接执行代码。
lr2131 2016-09-28
  • 打赏
  • 举报
回复
引用 楼主 happygaohualei 的回复:
stm32中的Code在程序运行时要不要拷贝到RAM里执行呢?还是直接从Flash中取程序指令执行? 不是nand flash不能运行程序吗?难道32里用的是nor flash?
如果你有研究过单片机编程的分散加载机制,在编程中写过分散加载脚本。你问的第一个问题就解决了。 如果你有写过nand flash的驱动程序,你问的第二个问题就解决了。 STM32中的code可以不用拷贝到RAM中运行,也可拷贝到RAM中运行,这些不是技术问题,而是要看这段code 有没有加载到RAM中运行的必要。后面再解释。 nand flash不支持片上执行,不能在nand flash中执行程序,但nor flash支持。 但不能因此就断定STM32用的外置flash都是nor的。只要STM32带nand flash的控制器,就可以把nand中的code加载到RAM中运行。至于能不能用IO模拟nand 的接口协议,我没搞过不清楚。 首先,应该所有的单片机都是片内集成RAM和ROM(在加载域和运行域的角度看,Flash就是ROM)。 一般容量小的单片机,RAM和ROM都小,不会把flash中的代码加载到RAM中。 但有时确实需要加载,怎么办呢。就把code中比较关键的,调用很频繁的,对响应速度有要求的,就会加载到RAM中。 例如高频率中断的定时器中断ISR,就可以在分散加载脚本中修改这段code的运行域到RAM中。程序在刚上电后会在main函数之前加载这段code到RAM中。这样做的好处就是,这段code的执行速度快,我们知道ROM和RAM执行代码的速度比差距是很大的。RAM比ROM中执行速度快得多! 当然,如果你的RAM很大,你甚至可以把全部的Code加载到RAM中运行。 nand flash不是直接接到CPU的三总线上的,所以CPU不能直接从nand中取得可执行的指令,而是通过nand的控制器! 而nor是在总线上的,所以nor中的code可以直接执行。(nor的这个观点仅是我个人看法,仅供参考)。 再说外置RAM的问题,单片机在带SDRAM的控制器之后,就可以支持SDRAM了。 SDRAM在初始化好之后,SDRAM的使用方法和内置的SRAM没有差别。 如果你的单片机支持SDRAM和Nand flash,你可以把nand flash中的code加载到SDRAM中运行。 如果你知道怎么写分散加载脚本,这个功能分分钟就能实现。
maxwell11 2016-09-27
  • 打赏
  • 举报
回复
代码不一定要在RAM中才能执行,CPU从一个存储器件中读取指令并执行,主要看的是该存储器能否实现随机读取(访问任意地址)。基于这个原理很多flash被修改成可以直接执行程序。STM是如何修改的,没有研究过。见过一种做法是,做一个缓冲区(只用来缓冲执行代码)将FLASH的代码读到该区中,有点类似MPU的感觉。 对于RAM,最初设计是用来存放变量的,可以说是栈空间,由CPU的SP指针指向。 以PC机为例(主流操作系统也是这样),将代码从硬盘从读取,存放到内存中(DDR),系统则会将该内存定义为READ ONLY也就是ROM的意思。对CPU来说,该区域并不是什么DDR或者RAM,只是一个可以随机读取代码的存储器,当然CPU也不关心这个是ROM,DDR,还是FLASH。
phangbob 2016-09-27
  • 打赏
  • 举报
回复
STM32里有ROM和RAM,ROM就是flash,程序是下载到里面。 当STM32执行程序时,是把ROM中的数据,程序“搬运”到RAM中然后再执行的,一般的指令存储在ROM。 就比如电脑,RAM是运行内存,ROM是硬盘,cpu不是直接执行在硬盘上的程序,而是将硬盘的程序拷贝到运行内存里面,然后在运行内存中执行。 互相学习,有错误望指出,虚心受教,希望能帮到你。
Quan略略略 2016-09-19
  • 打赏
  • 举报
回复
是norflash,不能直接从ram中运行,选项中有一个init区域可以选成ram。你直接把程序运行指针指向ram的话会出错。

27,375

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧