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

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

[复制链接]
qianfan 发布时间:2015-10-26 11:03
本帖最后由 QianFan 于 2015-10-28 19:50 编辑

st-flash能够将代码下载至STM32的任何位置。甚至是SRAM。在下载完毕之后,不用我们手动设置,他自动的设置pc至你下载代码的位置,并从pc处开始运行。

反汇编:
  先来反汇编我们点亮ledhttps://www.stmcu.org.cn/module/forum/thread-603787-1-1.html的代码。使用arm-none-eabi-objdump -d blink.elf生成反汇编代码,如下图所示:
Screenshot from 2015-10-25 21:11:15.png
  等等,为什么第一条指令的地址是0x0800_0188?我们的代码不是应该从0x0800_0000开始吗?可能看到这样的代码会有这样的疑惑。那就要来看看ARMCM4的架构了。规定“0”地址(STM32当使用FLASH启动的时候,0x0800_0000会被映射为0地址。SRAM启动的时候,0x2000_0000映射为0地址)的第一个数据为sp(栈指针)。以后连续的地址用来存放中断向量表。向量表之后的地址用来存放实际的代码。

  打开启动文件数一下共有多少个中断向量:
Screenshot from 2015-10-25 21:18:56.png Screenshot from 2015-10-25 21:19:06.png
  从139行开始到235行,共97个中断向量。外加0地址的sp的值,共98个数据,每一个数据占用4个字节,合计98×4=392=0x188。从0地址开始存放的话,存放到0x187位置结束。所以0x188作为第一条指令的起点。

  由于ARM中,很多指令是与地址紧密相关的。虽然可以将这份程序强制下载到ARM中,但是因为地址的原因并不能运行。

分析flash.ld
Screenshot from 2015-10-26 09:54:54.png
  在flash.ld链接文件中定义了_estack。这个值在汇编文件中使用,作为0地址下的sp的值。一般来说,栈的初始值是可以随便设定的。只要在RAM中就可以。但是为了避免内存碎片化,会将sp的初始值放置RAM中的最后一个地址。照这样来算,64K的RAM最后一个地址为0x2001_0000。这也就是将_estack设置为这个值的原因。
  在MEMORY{}中设置了RAM,FLASH的起始地址和大小。如果你更换了其他的芯片,根据不同的FLASH,RAM的大小,只需要更改ORIGIN和LENGTH就行了(当然,也不要忘记更改_estack)。

  在我看来,这里的_Min_Heap_Size和_Min_Stack_Size并没有什么用。只是用来保证你程序中bss段不至于过大而已。比如你在程序中申请了一个比较大的数组,char buf[64*1024]。这样你的bss段至少占用了64K的内存。在加上_Min_Heap_Size和_Min_Stack_Size的大小,已经超出了RAM的实际大小了。这样在链接的时候便会给你报错。
  不同于MDK,MDK的汇编文件中有一个数值,可以设置heap的大小,用于malloc等内存分配。但是在gcc中,即使你将链接文件中的_Min_Heap_Size更改为0,arm gcc的malloc函数一样能够分配到内存。因为他使用不一样的机制。他的内存分配是malloc和sbrk共同作用的。sbrk这个系统调用需要你自己来实现。

Screenshot from 2015-10-26 10:28:25.png Screenshot from 2015-10-26 10:28:38.png


更改FLASH的地址:
   要想让程序在RAM中能够运行,只需要更改FLASH的地址为RAM中的地址就可以了。因为Nucleo303有64K的内存,所以分配20K内存给RAM,分配40K内存当作FLASH使用。更改如下:
Screenshot from 2015-10-26 10:45:10.png

修改Makefile:
   在Makefile中添加make sram用于生成在SRAM中运行的代码。添加make burns使用st-flash将代码烧写到SRAM中运行。
Screenshot from 2015-10-26 10:52:03.png

修改main函数:
   将原先代码的延时时间缩短,由之前的720000改为72000。
Screenshot from 2015-10-26 10:54:12.png
   到目前位置,一切更改完毕。只需要使用make clean,make sram生成用于在sram中运行的程序。生成之后使用sudo make burns下载到SRAM中运行即可。如果你的flash中的程序还是上一个led灯的程序,未下载之前可以看到闪烁很慢,大约1s一次。当使用make burns下载成功之后,闪烁明显加快。在按一下复位键之后,再次运行存放在FLASH中的程序。闪烁较慢。


---------------------------------------------------------------

下载到SRAM中的时候,相比FLASH的下载,少了擦除那一项:
Screenshot from 2015-10-26 10:59:25.png

对程序进行反汇编,可以看到第一条指令是在0x2000_5188这个地址。
Screenshot from 2015-10-26 11:00:55.png

完了吗?当然没完
看到流水灯能够闪烁,你可能觉得使用st-link将程序下载到SRAM中运行很简单。从表面上看,这个程序确实奏效了。但是其中隐藏这巨大的bug。那就是中断向量表的问题。因为这个程序并没有使用中断,表面上看起来是好的。但一旦使用中断的时候,这个Makefile产生的程序必然无法运行。我们将在下一节使用串口的时候进行修正。
提前提示一下,问题是SCB->VTOR的原因。

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
用Ubuntu的人多吗

估计不多。。。
埃斯提爱慕 回答时间: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
想问下,在ubuntu的CLI在编写代码、调试等方面是否比较方便或者效率较高呢? ...

和IDE相比,肯定是差点。
熟悉了之后,也差不了很多。
moyanming2013 回答时间:2015-10-26 15:39:30
QianFan 发表于 2015-10-26 12:42
和IDE相比,肯定是差点。
熟悉了之后,也差不了很多。

我只开始试过,真是效率极低,感觉找其它方案了。
现在是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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版