请选择 进入手机版 | 继续访问电脑版

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

工程师笔记|关于STM32CubeIDE链接脚本的小问题

[复制链接]
STMCU-管管 发布时间:2021-11-29 14:28
越来越多的客户在使用STM32CubeIDE作为集成开发工具。STM32CubeIDE在编译代码的时候,用到了链接脚本。通常情况下,STM32CubeIDE会自动生成默认的链接脚本。但是有些情况下,例如,用户程序需要定义一些特别的段来放置代码或者数据的时候,我们就需要修改链接脚本文件。
; u7 u7 h9 V/ Z1 D/ S! D. X) D/ t. [* }

; `0 A( k* t. }最近有客户在修改链接脚本后,编译没有出现问题。但是编译之后生成的BIN文件很大,导致无法烧录到Flash中。结合这个问题,本文详细分析一下它的原因以及解决办法。
* Z4 t4 y% k2 }0 |; h) w8 ]6 `6 p" Z3 w5 k6 S9 O: S* K% B3 y8 F& o
问题描述
; D. z. `1 y  k/ p: o$ o4 W: e1 r
% u- t6 _+ Z9 H8 x
" T: p+ l3 H$ O8 H! c- m
使用STM32CubeIDE创建工程的时候,在项目工程目录文件夹下生成后缀为ld的链接脚本文件,程序的编译和链接都会依赖链接脚本文件。如下图所示,STM32H743VIT6的RAM空间被包含6块,每块RAM的起始地址是独立的,如果客户需要把指定特定的RAM区域放置数据或者代码的时候,需要手动修改链接脚本文件。6 a' `( r' v( @9 M" r0 P' J+ V
14.png
Figure 1 Memory Mapping for STM32H43
, |& J+ X4 J) {1 K4 U6 h
! o& @7 n: G, s* P客户在使用STM32H743VIT6进行应用开发的时候,需要在0x24000000 以及0x30000000的RAM空间定义两个未初始化的数组。所以客户修改了ld链接脚本文件,添加两个SECTIONS分别定位在0x24000000和0x30000000位置,同时在代码中使用__attribute__关键字指定数组在对应的SECTIONS中。5 W8 n5 |+ }% F7 q* H2 j

9 D# l" K. L4 p1 h( w4 n  d依照客户的问题描述,我们首先修改链接脚本,添加两个SECTIONS分别为ram_at_0x24000000和ram_at_0x30000000,参考如下。
$ c7 F/ @- t6 i
15.png
Figure 2 Id链接脚本文件+ l. a* u; W4 I& z$ P: k8 ?

( u0 b/ {+ p3 a8 O7 U% X2 }同时在源代码中添加两个数组,分别定位在添加的SECTIONS中,参考如下。$ v6 |$ b7 g, i2 Y3 O  O) f# R
16.png
Figure 3 定义数组参考代码% G/ ?6 b; A0 N: a5 j1 L7 d9 L
9 _2 N3 f! k+ t, U3 F

9 s; B& h& i7 `. R% s( P6 {5 X编译修改之后的工程,是可以正常运行的,但是我们发现当把ELF目标文件转为BIN文件之后,产生的BIN文件非常的大。这就导致如果使用BIN文件进行下载的话,是无法下载成功的,因为BIN文件的大小以及超出了Flash的存储空间。由下图BIN文件属性我们可以看到BIN文件的大小为650M。
) ~; h! [( a1 j% g' p# w
17.png
Figure 4 BIN文件大小) X# n& |$ ]# h& u' S; Q& L5 u

! W7 I+ L4 W$ H' h那么是什么原因导致产生的BIN文件这么大呢?文件就出在ld链接脚本文件这里。
, A7 Y8 k+ Y0 |& o1 p2 W! R6 n- S- w6 K
问题分析
3 G) H9 [% b4 O6 k: N6 J% v6 ~+ d4 K

0 i% g; I  E2 Z0 d: K* ^BIN文件是最纯粹的二进制机器代码, 或者说是"顺序格式"。按照assembly code顺序翻译成binary machine code,内部没有地址标记。BIN是直接的内存映象表示,二进制文件大小即为文件所包含的数据的实际大小。BIN文件就是直接的二进制文件,一般用编程器烧写时从00开始,而如果下载运行,则下载到编译时的地址即可。' N# ~5 j- k3 N5 M5 [7 p

: O4 E7 T4 U7 lSTM32CubeIDE依赖链接脚本文件生成目标ELF文件,生成ELF目标文件之后,STM32CubeIDE会依赖GNU Objcopy工具把ELF文件转为BIN文件。这个过程简单一点来说,就是提取ELF文件中的代码段以及可加载数据段按照地址信息顺序生成BIN文件。
& y* e* n/ r. o% ?& Q$ v  G. x* [; T
所以,如果BIN文件很大,那说明可加载的代码段和数据段很大。在我们的测试项目中,代码段是固定的;现在BIN文件很大,说明是数据段过大导致的。8 S7 Z# b  V7 E. ]- T9 r  k, b; o

) S: X. N/ J, M+ B' {6 h( h) N& ]# r

- ?. M$ {: g! ?9 V. t7 m( E3 V2 r通过查看编译产生的list文件,我们可以清楚的看到每个段的大小。- R( R4 I6 Z+ \5 B  M! c2 m
18.png
Figure 5 Sections Map. a' u' A; A- q; @" L* R5 `
1 O$ l; D6 y1 T8 ]7 ^0 p( d) w
从上图的Sections Map中,每个Section会有几个关键的参数和类型。Size为每个Section的大小,VMA是指Section在程序运行时候的地址,LMA是指Section在Flash中的加载地址。通常情况下从Flash执行的程序,Code段VMA和LMA是一样的。Data段的VMA会放在RAM中,LMA会放在Flash中,所以Data段的VMA和LMA通常不一样。在每个段的类型中,还有一个关键的属性是LOAD,如果定义了LOAD属性,那说明这个段是需要写入Flash中的。
2 W, B0 e! g* r/ E8 O  J  u9 i- L5 s" d% r8 C
GNU Objcopy工具生成BIN文件的过程,实际上就是把ELF文件中各个定义了LOAD属性的SECTION按照LMA的先后顺序提取出来,写入BIN文件中。SECTION的地址如果不是连续的,间隔部分则会填充DUMMY或指定的数据。所以BIN文件的大小为最大LMA加上对应的SECTION的Size。
; Y* Y+ k, {* q+ I% `& @/ W5 G6 f0 H# r1 e, k. f
结合上图,该工程最终生成的BIN文件大小为 0x30000000+0x4000 -0x8000000 =  671105024 和图4的文件属性显示的大小是一致的。
4 ]$ R% y" q7 B4 C5 j( D
9 {' R: U2 ^, w# ?4 s' X8 o问题已分析
( ~; U  Y! {& Z1 w- R5 c$ m- z+ T* N
问题解决, r: h* _8 Y2 P) e: }4 {) D

. j  ^% B* A  o
* P; p* o; J2 @- f/ }
▼查收解决方法▼

, `+ P# V  p7 I8 ]1 Z  M$ _1 O
0 v: R$ g( j* Y% E" y' `8 r" h
根据上面章节分析的原因,BIN文件过大是新增加的两个SECTIONS导致的。如图5所示,ram_at_0x24000000 段和ram_at_0x30000000段都具有LOAD属性,所以GNU Objcopy工具认为该段是需要加载到Flash中的。如果修改该段的属性为NOLOAD,则可解决这个问题。% j; x( D- e& u4 K: J3 }5 E

& _8 O! c! b0 {; \+ o

/ s3 Q5 e/ W. _! V# O参考 The GNU Linker 文档第73页,指定SECTION的类型为NOLOAD。最终修改后的链接脚本文件如下所示。
# t* a: @" Z7 a5 o5 x+ R
19.png
Figure 6 更新后的链接脚本* V/ ~' k% y! S' f( d3 d2 @. [8 z  H
; |) A  @% [: o
依赖修改后的链接脚本编译得到的目标ELF文件,查看其段描述,可以知道新添加的段的属性不再为LOAD。GNU Objcopy工具在进行BIN文件生成的时候,也不会加载这两个段。所以,最终得到的BIN文件只包含有效的代码段和数据段,大小为24428字节。
2 F9 a) _- w* A9 N% j
20.png
Figure 7 更新后的段描述- G" I' F9 `; m: E

! D9 w) b  C/ j  F+ s, P问题总结* V0 n0 k$ P7 x5 m1 z* i3 z  ?

4 V& m" z8 Z( q) n1 v

9 x% U7 K4 Z4 {4 h! b! F% B本文通过一个具体的问题阐述了BIN文件的产生过程,同时对链接脚本的格式做了一个简单的介绍。STM32用户后期如果遇到变量无需加载却导致BIN文件过大的问题,可依照该方法进行处理。
& F2 i) ?; m1 T) m
$ x) X% E" R: s/ O( s$ K
收藏 2 评论0 发布时间:2021-11-29 14:28

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版