你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

Ubuntu下开发STM32---4.SRAM中运行程序

[复制链接]
qianfan 发布时间:2015-10-26 11:03
本帖最后由 QianFan 于 2015-10-28 19:50 编辑
2 u' F9 H4 j2 `" W8 o( ]9 T
7 M2 {! G" J% v+ h/ I
st-flash能够将代码下载至STM32的任何位置。甚至是SRAM。在下载完毕之后,不用我们手动设置,他自动的设置pc至你下载代码的位置,并从pc处开始运行。
- z, o9 Q; ]2 y; R
1 u0 ]( B3 _; D8 m5 i6 w
反汇编:5 U5 `9 t( `5 `/ K4 G
  先来反汇编我们点亮ledhttps://www.stmcu.org.cn/module/forum/thread-603787-1-1.html的代码。使用arm-none-eabi-objdump -d blink.elf生成反汇编代码,如下图所示:
) n5 k. Z, X" y- }" K' D' k: ?' D Screenshot from 2015-10-25 21:11:15.png : ?9 P+ @" f8 E5 @- C
  等等,为什么第一条指令的地址是0x0800_0188?我们的代码不是应该从0x0800_0000开始吗?可能看到这样的代码会有这样的疑惑。那就要来看看ARMCM4的架构了。规定“0”地址(STM32当使用FLASH启动的时候,0x0800_0000会被映射为0地址。SRAM启动的时候,0x2000_0000映射为0地址)的第一个数据为sp(栈指针)。以后连续的地址用来存放中断向量表。向量表之后的地址用来存放实际的代码。( Y  U7 L" E, p* j/ k- O1 k/ m
4 M) ^' I% c; Z0 {1 Y# \
  打开启动文件数一下共有多少个中断向量:
/ V0 l% O. L+ E Screenshot from 2015-10-25 21:18:56.png Screenshot from 2015-10-25 21:19:06.png * [/ e: U, I6 z2 r
  从139行开始到235行,共97个中断向量。外加0地址的sp的值,共98个数据,每一个数据占用4个字节,合计98×4=392=0x188。从0地址开始存放的话,存放到0x187位置结束。所以0x188作为第一条指令的起点。- |0 O' R. m& a( |- i6 d( D

/ P( ^: B. B; _! X" k" _  I  由于ARM中,很多指令是与地址紧密相关的。虽然可以将这份程序强制下载到ARM中,但是因为地址的原因并不能运行。
, `7 U8 e9 U; Q# p( d9 j% @0 a0 f' {2 N) m0 P: h
分析flash.ld
( B% F' d" ?' y! ] Screenshot from 2015-10-26 09:54:54.png
0 y" f. R4 z" u+ [/ y. b: l  在flash.ld链接文件中定义了_estack。这个值在汇编文件中使用,作为0地址下的sp的值。一般来说,栈的初始值是可以随便设定的。只要在RAM中就可以。但是为了避免内存碎片化,会将sp的初始值放置RAM中的最后一个地址。照这样来算,64K的RAM最后一个地址为0x2001_0000。这也就是将_estack设置为这个值的原因。
* W9 o$ T2 ]; G4 W8 V  在MEMORY{}中设置了RAM,FLASH的起始地址和大小。如果你更换了其他的芯片,根据不同的FLASH,RAM的大小,只需要更改ORIGIN和LENGTH就行了(当然,也不要忘记更改_estack)。: ?# G% F& Y# g% D2 s

; n7 o" F4 U/ L2 h7 L3 k( ^/ n  |1 J  在我看来,这里的_Min_Heap_Size和_Min_Stack_Size并没有什么用。只是用来保证你程序中bss段不至于过大而已。比如你在程序中申请了一个比较大的数组,char buf[64*1024]。这样你的bss段至少占用了64K的内存。在加上_Min_Heap_Size和_Min_Stack_Size的大小,已经超出了RAM的实际大小了。这样在链接的时候便会给你报错。
( n( Y7 d/ Q; t- D9 O) M  不同于MDK,MDK的汇编文件中有一个数值,可以设置heap的大小,用于malloc等内存分配。但是在gcc中,即使你将链接文件中的_Min_Heap_Size更改为0,arm gcc的malloc函数一样能够分配到内存。因为他使用不一样的机制。他的内存分配是malloc和sbrk共同作用的。sbrk这个系统调用需要你自己来实现。% W! u. {+ t5 }5 i: G, o
5 v0 ^% I0 |1 t' q4 H9 J6 l
Screenshot from 2015-10-26 10:28:25.png Screenshot from 2015-10-26 10:28:38.png + J5 X7 j0 m# @9 R
5 w# |' m" x1 W7 P$ X

8 \* w. e* H$ m; d' y0 N8 u! L9 }更改FLASH的地址:
. g) T. p, W  _! G   要想让程序在RAM中能够运行,只需要更改FLASH的地址为RAM中的地址就可以了。因为Nucleo303有64K的内存,所以分配20K内存给RAM,分配40K内存当作FLASH使用。更改如下:/ V# K& g- R. z2 k' ~6 I. v
Screenshot from 2015-10-26 10:45:10.png 8 k3 r$ q7 d5 v1 @
; c( U6 {, \6 S! ~& l: U
修改Makefile:
% l$ t. @; _! t* t9 ]8 w. F# G   在Makefile中添加make sram用于生成在SRAM中运行的代码。添加make burns使用st-flash将代码烧写到SRAM中运行。
- {: b0 p. z) f Screenshot from 2015-10-26 10:52:03.png
2 b' w  s. G, M2 q; W6 e) Z
  C8 h( [9 p; O: {# ~% Q7 I& Q& p5 G8 O修改main函数:6 w# V! G' R' }2 u% j
   将原先代码的延时时间缩短,由之前的720000改为72000。
  y' k  W3 K# H7 h2 u0 X4 e Screenshot from 2015-10-26 10:54:12.png
& d$ v3 i+ t& r& x4 W" O* |   到目前位置,一切更改完毕。只需要使用make clean,make sram生成用于在sram中运行的程序。生成之后使用sudo make burns下载到SRAM中运行即可。如果你的flash中的程序还是上一个led灯的程序,未下载之前可以看到闪烁很慢,大约1s一次。当使用make burns下载成功之后,闪烁明显加快。在按一下复位键之后,再次运行存放在FLASH中的程序。闪烁较慢。
1 [( `# X! Y7 r( q1 ^* ?
/ r9 q: M0 I$ d  B, F9 f/ ?! `
- t! p7 z) [7 F0 R---------------------------------------------------------------
. Z! `5 r. h* Q9 ^
+ ^; \( p- [/ j0 T( n. [, E7 m
下载到SRAM中的时候,相比FLASH的下载,少了擦除那一项:, F0 ^0 \* u( X- p: g9 J" ]. w' i! h& Y
Screenshot from 2015-10-26 10:59:25.png
) d4 o9 k+ Q+ d5 T" Y) s: C9 n$ ?, I6 F1 l4 M
对程序进行反汇编,可以看到第一条指令是在0x2000_5188这个地址。, T% N! k: p' S2 k4 M* y5 n) N
Screenshot from 2015-10-26 11:00:55.png ( B( b/ P7 v1 Y  R. R

* c: c1 }8 u1 _: X) _* f完了吗?当然没完
* T. m: c* y! Q  g# E9 n看到流水灯能够闪烁,你可能觉得使用st-link将程序下载到SRAM中运行很简单。从表面上看,这个程序确实奏效了。但是其中隐藏这巨大的bug。那就是中断向量表的问题。因为这个程序并没有使用中断,表面上看起来是好的。但一旦使用中断的时候,这个Makefile产生的程序必然无法运行。我们将在下一节使用串口的时候进行修正。6 p; X$ p& K1 q* e5 i! B6 B% o" ~
提前提示一下,问题是SCB->VTOR的原因。
8 ]2 [( ]! I3 H" @6 ~

code_in_sram.zip

下载

412.38 KB, 下载次数: 66

赞 收藏 2 评论12 发布时间:2015-10-26 11:03

举报

12个回答
湛无双 回答时间:2015-10-26 11:09:22
楼主真牛逼,在Ubuntu中开发,学习了。
foxglove 回答时间:2015-10-26 11:14:22
Ubuntu下开发STM32
wamcncn 回答时间:2015-10-26 11:15:01
用Ubuntu的人多吗
qianfan 回答时间:2015-10-26 11:16:04
wambob 发表于 2015-10-26 11:15
& }( b' g/ v4 P# R) ~' c1 Z2 x6 u% M* i用Ubuntu的人多吗

5 u6 L& e6 e* ]3 i估计不多。。。
埃斯提爱慕 回答时间:2015-10-26 11:19:47
提示: 作者被禁止或删除 内容自动屏蔽
moyanming2013 回答时间:2015-10-26 11:34:29
想问下,在ubuntu的CLI在编写代码、调试等方面是否比较方便或者效率较高呢?
qianfan 回答时间:2015-10-26 12:42:38
moyanming2013 发表于 2015-10-26 11:34
  h* q& u9 f- u% G* ^3 v: d想问下,在ubuntu的CLI在编写代码、调试等方面是否比较方便或者效率较高呢? ...
, g5 `5 W% G$ |/ {  b
和IDE相比,肯定是差点。; F# p  p3 ~" e+ R! v+ W, C1 I
熟悉了之后,也差不了很多。
moyanming2013 回答时间:2015-10-26 15:39:30
QianFan 发表于 2015-10-26 12:421 k0 @! T# {( Y4 u4 {' `6 T; Q+ R; Z' ?
和IDE相比,肯定是差点。" ]" h9 F. I  _* @! L; g; [
熟悉了之后,也差不了很多。

  C4 q- I! i2 v; }0 K, N3 b: r我只开始试过,真是效率极低,感觉找其它方案了。+ B' n% I$ T9 S' g3 Z
现在是vs+visualgdb
小小笼包 回答时间:2015-10-28 20:52:01
swapkernel1111 回答时间:2018-6-29 17:27:27
sunnysun-47416 回答时间:2018-10-7 14:06:58
拜读了楼主的帖子,感觉很牛! 我最近也在linux下编译stm32f042k6的程序, 现在网上找了一些链接脚本,启动文件和makefile, 但是不行, 其他的源代码是正常的,在keil MDK正常工作, 不知道楼主有没有这些文件,无论有无,都感谢!
linuxfor 回答时间:2018-12-13 10:39:51
跟着学习了额
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版