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

STM32F1系列之使用链接脚本链接代码

[复制链接]
STMCU小助手 发布时间:2022-8-27 13:59
一、链接脚本的作用
链接脚本的作用就是用来指定程序的链接方式的,一个程序中包含各种文件,例如start.o、main.o、led.o等,每个文件有包含如代码段、数据段等各种段,而链接脚本的作用就是用来指定各种文件各种段的链接方式。前面我们都没有使用链接文件,只使用了-Ttext参数来指明代码段的链接地址,其他都是按照默认链接的,使用之前曾强调要将start.o文件放在最前面。

二、编写链接文件
将Makefile中的链接命令改为如下所示

  1. $(LD) -g $(OBJECTS) -T stm32f103zet6.ld -o $@
复制代码

接着编写一个最简单的链接文件stm32f103zet6.ld如下所示,其实这个和之前的-Ttext 0x80100000参数效果是一样的。首先SECTIONS {}是链接文件的语法,表示程序的所有段都在其中;然后. = 0x80100000表示当前地址设置为0x80100000,亦即链接的起始地址为0x80100000;. = ALIGN(4)表示当前地址按4字节对齐;.text表示段名,*(.text)表示将所有文件的代码段都存放在此。

  1. SECTIONS {
  2.     . = 0X8000000;

  3.     . = ALIGN(4);
  4.     .text      :
  5.     {
  6.       *(.text)
  7.     }
  8. }
复制代码

我们打开反汇编文件,可以看到段名为.text的段,同时其链接地址也是从0X8000000开始的

20210124230324612.png

三、指定内存区域
因为对于在STM32F103这类资源紧缺的单片机芯片中:
代码段保存在Flash上,直接在Flash上运行(当然也可以重定位到内存里)
数据段暂时先保存在Flash上,然后在使用前被复制到内存里(只读数据段不复制)
所以我们要给予代码段和数据段不同的保存地址,在链接文件中添加如下内存区域指定说明,分别定义RAM和FLASH两个内存区域,分别对应stm32芯片上的ram和flash区域,其中Flash区域可读可执行,开始地址为0x08000000,长度为512K,Ram区域可读可写可执行,开始地址为0x20000000,长度为 64K

  1. MEMORY
  2. {
  3. RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 64K
  4. FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 512K
  5. }
复制代码

然后添加只读数据段、数据段、BSS段并指定其内存区域,修改完的链接文件如下

  1. /* 指定内存区域 */
  2. MEMORY
  3. {
  4.     FLASH (rx)  : ORIGIN = 0x08000000, LENGTH = 512K
  5.     RAM (xrw)   : ORIGIN = 0x20000000, LENGTH = 64K
  6. }

  7. SECTIONS {

  8.     .text      :
  9.     {
  10.         . = ALIGN(4);
  11.         *start.o (.text)
  12.         *main.o (.text)
  13.         *(.text)
  14.     } > FLASH

  15.     .rodata :
  16.     {
  17.         . = ALIGN(4);
  18.         *(.rodata)         /* .rodata sections (constants, strings, etc.) */
  19.         *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
  20.         . = ALIGN(4);
  21.     } >FLASH

  22.     .data :
  23.     {
  24.         . = ALIGN(4);
  25.         _sdata = .;        /* create a global symbol at data start */
  26.         *(.data)           /* .data sections */
  27.         *(.data*)          /* .data* sections */
  28.         . = ALIGN(4);
  29.         _edata = .;        /* define a global symbol at data end */
  30.     } >RAM

  31.     . = ALIGN(4);
  32.     .bss :
  33.     {
  34.         /* This is used by the startup in order to initialize the .bss secion */
  35.         _sbss = .;         /* define a global symbol at bss start */
  36.         __bss_start__ = _sbss;
  37.         *(.bss)
  38.         *(.bss*)
  39.         *(COMMON)

  40.         . = ALIGN(4);
  41.         _ebss = .;         /* define a global symbol at bss end */
  42.         __bss_end__ = _ebss;
  43.     } >RAM
  44. }
复制代码

然后修改main程序添加如下全局变量

20210104000036956.png

使用make编译,打开反汇编文件,找到如下所示,可以看到这三个段分别存放着刚刚定义的C语言中的全局变量。
首先,只读数据段.rodata中放置加const修饰的变量myconst,其存放在Flash区域;
然后,数据段data中已初始化的全局变量mydata,其存放在Ram区域;
最后,bss段放置未初始化或初始化为零的全局变量,同样也存放在Ram区域。

20210124233334501.png

四、验证
修改mian.c如下所示,添加各个变量地址的打印

  1. #include "uart.h"
  2. #include "led.h"

  3. int mydata = 0x12315;
  4. const int myconst = 0x22315;
  5. int myzero = 0;
  6. int my;

  7. int main(void)
  8. {
  9.     uart_init();
  10.     led_init();
  11.     putstring("stm32f103zet6\r\n");
  12.         putstring("mydata\t:");
  13.     puthex((unsigned int)&mydata);
  14.     putstring("\r\nmyconst\t:");
  15.     puthex((unsigned int)&myconst);
  16.         putstring("\r\nmyzero\t:");
  17.     puthex((unsigned int)&myzero);
  18.     putstring("\r\nmy\t:");
  19.     puthex((unsigned int)&my);
  20.     putstring("\r\n");

  21.     while(1)
  22.     {
  23.                 putstring("led on\r\n");
  24.         led_on();
  25.         delay(1000000);

  26.                 putstring("led off\r\n");
  27.         led_off();
  28.         delay(1000000);
  29.     }
  30. }
复制代码

编译烧录运行,并于反汇编文件做对比,可以看到,其地址完全符合:

20210124234104593.png

————————————————
Willliam_william


收藏 评论0 发布时间:2022-8-27 13:59

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版