OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 19532|回复: 24

关于程序是怎样在STM32里运行的,有点困惑。

[复制链接]

38

主题

527

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1424
金钱
1424
注册时间
2011-11-27
在线时间
122 小时
发表于 2012-5-22 10:13:55 | 显示全部楼层 |阅读模式
用习惯了集成开发环境,有很多基本的问题没有搞明白,现请教大家。
STM32里有ROM和RAM,ROM就是flash,我们的程序就是下载到里面了,但是执行启动STM32的时候,需要搬运ROM里的数据变量到RAM里。
(1) 是不是我们定义的数据变量(全局变量和局部变量)的大小不能超过ram?
(2)执行程序的过程:cpu从rom里取出指令,去操作ram里的数据,然后再存到ram里。这样理解不知恰当否?
永远保持一颗学习的心态。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-5-22 10:56:04 | 显示全部楼层
回复【楼主位】科科1987:
---------------------------------
1,是的.
2,给你个51执行过程(转载的):
单片机执行程序的过程,实际上就是执行我们所编制程序的过程。即逐条指令的过程。计算机每执行一条指令都可分为三个阶段进行。即取指令-----分析指令-----执行指令。

取指令的任务是:根据程序计数器PC中的值从程序存储器读出现行指令,送到指令寄存器。

分析指令阶段的任务是:将指令寄存器中的指令操作码取出后进行译码,分析其指令性质。如指令要求操作数,则寻找操作数地址。 
计算机执行程序的过程实际上就是逐条指令地重复上述操作过程,直至遇到停机指令可循环等待指令。

一般计算机进行工作时,首先要通过外部设备把程序和数据通过输入接口电路和数据总线送入到存储器,然后逐条取出执行。但单片机中的程序一般事先我们都已通过写入器固化在片内或片外程序存储器中。因而一开机即可执行指令。

下面我们将举个实例来说明指令的执行过程: 

开机时,程序计算器PC变为0000H。然后单片机在时序电路作用下自动进入执行程序过程。执行过程实际上就是取出指令(取

出存储器中事先存放的指令阶段)和执行指令(分析和执行指令)的循环过程。

例如执行指令:MOV A,#0E0H,其机器码为“74H E0H”,该指令的功能是把操作数E0H送入累加器,

0000H单元中已存放74H,0001H单元中已存放E0H。当单片机开始运行时,首先是进入取指阶段,其次序是: 
1 程序计数器的内容(这时是0000H)送到地址寄存器;

2 程序计数器的内容自动加1(变为0001H);

3 地址寄存器的内容(0000H)通过内部地址总线送到存储器,以存储器中地址译码电跟,使地址为0000H的单元被选中;

4 CPU使读控制线有效;

5 在读命令控制下被选中存储器单元的内容(此时应为74H)送到内部数据总线上,因为是取指阶段,所以该内容通过数据总线被送到指令寄存器。

至此,取指阶段完成,进入译码分析和执行指令阶段。 
由于本次进入指令寄存器中的内容是74H(操作码),以译码器译码后单片机就会知道该指令是要将一个数送到A累加器,而该数是在这个代码的下一个存储单元。所以,执行该指令还必须把数据(E0H)从存储器中取出送到CPU,即还要在存储器中取第二个字节。其过程与取指阶段很相似,只是此时PC已为0001H。指令译码器结合时序部件,产生74H操作码的微操作系列,使数字E0H从0001H单元取出。因为指令是要求把取得的数送到A累加器,所以取出的数字经内部数据总线进入A累加器,而不是进入指令寄存器。至此,一条指令的执行完毕。单片机中PC=0002H,PC在CPU每次向存储器取指或取数时自动加1,单片机又进入下一取指阶段。这一过程一直重复下去,直至收到暂停指令或循环等待指令暂停。CPU就是这样一条一条地执行指令,完成所有规定的功能。

 
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

14

主题

173

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2011-10-14
在线时间
2 小时
发表于 2012-5-22 13:46:54 | 显示全部楼层
学习了
回复 支持 反对

使用道具 举报

14

主题

173

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2011-10-14
在线时间
2 小时
发表于 2012-5-22 13:59:44 | 显示全部楼层
函数体内的局部变量(堆空间)也应该是在RAM里分配吧?
局部变量是运行时再申请的吧?
在编译生成的目标文件里并不知道局部变量需要多大ram吧?
回复 支持 反对

使用道具 举报

38

主题

527

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1424
金钱
1424
注册时间
2011-11-27
在线时间
122 小时
 楼主| 发表于 2012-5-22 16:38:18 | 显示全部楼层
回复【2楼】正点原子:
回复【楼主位】科科1987:
---------------------------------
1,是的.
2,给你个51执行过程(转载的):
单片机执行程序的过程,实际上就是执行我们所编制程序的过程。即逐条指令的过程。计算机每执行一条指令都可分为三个阶段进行。即取指令-----分析指令-----执行指令。
取指令的任务是:根据程序计数器PC中的值从程序存储器读出现行指令,送到指令寄存器。
分析指令阶段的任务是:将指令寄存器中的指令操作码取出后进行译码,分析其指令性质。如指令要求操作数,则寻找操作数地址。 
计算机执行程序的过程实际上就是逐条指令地重复上述操作过程,直至遇到停机指令可循环等待指令。
一般计算机进行工作时,首先要通过外部设备把程序和数据通过输入接口电路和数据总线送入到存储器,然后逐条取出执行。但单片机中的程序一般事先我们都已通过写入器固化在片内或片外程序存储器中。因而一开机即可执行指令。
下面我们将举个实例来说明指令的执行过程: 
开机时,程序计算器PC变为0000H。然后单片机在时序电路作用下自动进入执行程序过程。执行过程实际上就是取出指令(取
出存储器中事先存放
......
---------------------------------
谢谢原子哥!
永远保持一颗学习的心态。
回复 支持 反对

使用道具 举报

38

主题

527

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1424
金钱
1424
注册时间
2011-11-27
在线时间
122 小时
 楼主| 发表于 2012-5-22 16:57:09 | 显示全部楼层
回复【4楼】smithlin:
函数体内的局部变量(堆空间)也应该是在RAM里分配吧?
局部变量是运行时再申请的吧?
在编译生成的目标文件里并不知道局部变量需要多大ram吧?
---------------------------------
转载一个帖子。

单片机编译器中局部变量和全局变量的深入解析
      通常我们都是学了标准c语言教程后从事单片机c语言的编写的, 那就先要明白一点, 标准c语言实际上是起源于pc平台上的一种语言, 标准c语言肯定是不会照顾到单片机的特殊性的. 因此单片机c编译器中的c语言是一种基于标准c,但是又有相应修改扩充的扩展c语言.  所以在单片机c编译器里写程序时一定要了解单片机编译器扩展c语言的不同之处, 绝不能死板地照搬标准c.

      在标准c里, 局部变量是函数在调用的时候才临时分配存储空间的,全局变量是程序整个生命周期都一直存在的.  不过要知道,临时分配存储空间是需要操作系统内存管理程序支持的, 单片机中通常都没有操作系统,也就不能实现像pc平台中那样的局部变量的空间分配.  这里就需要深入了解一下单片机的c编译器究竟是如何处理局部变量的,如果对此没有概念,碰到调试过程中的一些奇异现象恐怕只能觉匪夷所思了.
      另外需要知道的一点是, 不同的编译器对于局部变量的处理方法也不一样, 不能学了一个就到处照搬. 这里拿KEIL C ,IARAVR, ICCAVR这个三个编译器做分析比较.
       首先说 Keil C51 , 它的局部变量并不是在堆栈中, C51 为了提高代码的效率, 根据 51 处理器的特性. 编译器对函数局部变量的安排进行了处理.局部变量如果不能分配到 寄存器里, 就放在 RAM 中了.编译器通过覆盖分析, 可以共享局部变量的地址空间.。 最终的DATA使用量取决于调用链中那个使用DATA最多的链。所以,在程序中增加一个局部变量,如果不是位于那个使用DATA最多的链中,需要的DATA数量是有可能不会增加的。

      如:main()->f11()->f12()->f13().... // 链1
              |----->f21()->f22()->f23().... // 链2

      因为f11(),f21()不在同一个调用链上,显然,f11()中使用的局部变量,可以和f21()中的局部变量,使用同一个存储单元。因为它们中的任何一个处在生命期内的话,另一个必然已经离开它的生命周期,同时它的局部变量也离开了它的生命周期,这些局部变量所占用的存储单元当然可以另做它用了。
      假设链1目前的局部变量需要50个存储单元,链2需要40个存储单元。那么你在链2中加入不多于10个单元的局部变量的话,程序最终需要的存储单元数量是不会增加的。

       再说ICCAVR ,  它把局部变量存放在软件堆栈空间中.  ICCAVR使用两个堆栈:一个用于子程序调用和中断操作的硬件堆栈,一个用于传递参数、临时变量和局部变量的软件堆栈。硬件堆栈是从数据内存的顶部开始分配的,在硬件堆栈下面再分配一定数量的字节作为软件堆栈。
       IARAVR对于局部变量的处理方法与ICCAVR一样. 它也有两个堆栈,一个是data stack ,一个是return address stack.  分别用于存放临时变量,局部变量,传递参数, 和函数返回地址.
       这里需要注意的是, 局部变量存放在堆栈中的处理方式一定要保证堆栈足够大, 特别是定义了局部数组变量的情况下,一旦数组过大,超过了堆栈大小就会发生堆栈溢出,  如果只是读取数据还好, 一旦写入数据,就会破坏堆栈空间以外的数据, 导致程序时常.
永远保持一颗学习的心态。
回复 支持 反对

使用道具 举报

38

主题

527

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1424
金钱
1424
注册时间
2011-11-27
在线时间
122 小时
 楼主| 发表于 2012-5-22 17:01:58 | 显示全部楼层


通过仿真可以看出,局部变量分配到了寄存器里或太大就分配到堆里了。
永远保持一颗学习的心态。
回复 支持 反对

使用道具 举报

48

主题

177

帖子

0

精华

高级会员

Rank: 4

积分
782
金钱
782
注册时间
2013-4-23
在线时间
166 小时
发表于 2013-5-10 19:41:12 | 显示全部楼层
回复【楼主位】科科1987:
---------------------------------
执行启动STM32的时候,需要搬运ROM里的数据变量到RAM里?如果有nor flash的话,是不是就不需要RAM了
努力做,耐心等
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2256
金钱
2256
注册时间
2010-12-16
在线时间
206 小时
发表于 2013-5-11 00:50:18 | 显示全部楼层
回复【8楼】chenweigang:
---------------------------------
1.是.
2.NOR_FLASH只是实现了内存总线,但擦写寿命有限,不能完全替代RAM.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

48

主题

177

帖子

0

精华

高级会员

Rank: 4

积分
782
金钱
782
注册时间
2013-4-23
在线时间
166 小时
发表于 2013-5-11 20:08:02 | 显示全部楼层
回复【9楼】shihantu:
---------------------------------
在stm32的启动代码里有实现ROM的数据变量搬到RAM?
努力做,耐心等
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2256
金钱
2256
注册时间
2010-12-16
在线时间
206 小时
发表于 2013-5-11 20:20:25 | 显示全部楼层
当然了,难道直接对FLASH操作啊..for一个16位循环就超标了.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

48

主题

177

帖子

0

精华

高级会员

Rank: 4

积分
782
金钱
782
注册时间
2013-4-23
在线时间
166 小时
发表于 2013-5-12 13:30:14 | 显示全部楼层
回复【11楼】shihantu:
---------------------------------
内部FLASH应该和RAM读写方式一样的吧?STM32启动代码能贴出来吗在哪里
努力做,耐心等
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2256
金钱
2256
注册时间
2010-12-16
在线时间
206 小时
发表于 2013-5-12 15:16:04 | 显示全部楼层
https://www.google.com/#hl=en&gs_rn=12&gs_ri=psy-ab&tok=h3a0X39WjcsARwCrYUhYEA&cp=21&gs_id=3&xhr=t&q=%E5%86%85%E9%83%A8FLASH%E5%BA%94%E8%AF%A5%E5%92%8CRAM%E8%AF%BB%E5%86%99%E6%96%B9%E5%BC%8F%E4%B8%80%E6%A0%B7%E7%9A%84%E5%90%A7&es_nrs=true&pf=p&newwindow=1&output=search&sclient=psy-ab&oq=%E5%86%85%E9%83%A8FLASH%E5%BA%94%E8%AF%A5%E5%92%8CRAM%E8%AF%BB%E5%86%99%E6%96%B9%E5%BC%8F%E4%B8%80%E6%A0%B7%E7%9A%84%E5%90%A7&gs_l=&pbx=1&bav=on.2,or.r_qf.&bvm=bv.46340616,d.aGc&fp=1e04ab1166102392&biw=1292&bih=652

关于启动代码,随便下载一个程序,然后汇编跟踪就可以了.本身是不开源,我也没有.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

头像被屏蔽

6168

主题

7036

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
19705
金钱
19705
注册时间
2012-12-27
在线时间
25 小时
发表于 2013-5-13 17:15:10 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

9

主题

41

帖子

0

精华

初级会员

Rank: 2

积分
99
金钱
99
注册时间
2012-12-25
在线时间
0 小时
发表于 2013-9-29 21:49:03 | 显示全部楼层
不错不错,学习了。
不忘初心,才能始终。
回复 支持 反对

使用道具 举报

3

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
52
金钱
52
注册时间
2014-4-25
在线时间
1 小时
发表于 2014-8-20 15:39:01 | 显示全部楼层
准备将程序放到W25Q64中,因为程序太大了,然后从W25Q64中执行程序,不知道可以吗?正在学习中...
回复 支持 反对

使用道具 举报

38

主题

527

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1424
金钱
1424
注册时间
2011-11-27
在线时间
122 小时
 楼主| 发表于 2014-8-20 16:50:54 | 显示全部楼层
回复【16楼】multisensor:
---------------------------------
把W25Q64作为外部Flash,搞明白了指导一下我们。
永远保持一颗学习的心态。
回复 支持 反对

使用道具 举报

28

主题

1489

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1656
金钱
1656
注册时间
2013-7-24
在线时间
1 小时
发表于 2014-8-20 17:10:40 | 显示全部楼层
回复【16楼】multisensor:
---------------------------------
就是需要你这样能打破枷锁的人才!
于20150522停用该账号:http://www.microstar.club
回复 支持 反对

使用道具 举报

13

主题

123

帖子

0

精华

初级会员

Rank: 2

积分
197
金钱
197
注册时间
2013-8-3
在线时间
0 小时
发表于 2014-8-28 20:22:20 | 显示全部楼层
回复【16楼】multisensor:
---------------------------------
不可以。。
回复 支持 反对

使用道具 举报

9

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2012-3-30
在线时间
5 小时
发表于 2014-12-3 13:39:36 | 显示全部楼层
标记一下,太有用了
回复 支持 反对

使用道具 举报

15

主题

786

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3223
金钱
3223
注册时间
2015-7-26
在线时间
811 小时
发表于 2015-7-31 19:02:58 | 显示全部楼层
标记一下!!!!!
我的博客:http://blog.csdn.net/itdo_just
回复 支持 反对

使用道具 举报

0

主题

0

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2020-6-17
在线时间
18 小时
发表于 2015-9-25 10:44:07 | 显示全部楼层
MARK
回复 支持 反对

使用道具 举报

4

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
59
金钱
59
注册时间
2016-3-16
在线时间
7 小时
发表于 2016-3-22 19:31:57 | 显示全部楼层
科科1987 发表于 2012-5-22 17:01
通过仿真可以看出,局部变量分配到了寄存器里或太大就分配到堆里了。

这个是用什么仿真的?
回复 支持 反对

使用道具 举报

38

主题

527

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1424
金钱
1424
注册时间
2011-11-27
在线时间
122 小时
 楼主| 发表于 2016-3-23 07:11:08 | 显示全部楼层
rongshuxia 发表于 2016-3-22 19:31
这个是用什么仿真的?

keil的软件仿真
永远保持一颗学习的心态。
回复 支持 反对

使用道具 举报

0

主题

0

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2018-4-24
在线时间
8 小时
发表于 2017-1-16 11:45:02 | 显示全部楼层
MARK
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-23 20:32

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表