STM32F gcc编译后续

本文介绍如何使用GCC链接文件自定义程序的Flash空间分配,并解决在链接过程中遇到的找不到特定对象文件的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

后话之定制链接分散文件
在通常应用中,需要将程序的Flash空间进行自定义的划分,如下图所示。

为此,在gcc的链接文件*.ld文件中根据上图来进行编写。
MEMORY
{
  FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 64K
  RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 8K
}
 
/* Define output sections */
SECTIONS
{
/* 第一段中断向量区 */
  .vector :               
  {
    . =ALIGN(4);
   KEEP(*(.isr_vector)) /* Startup code */
    . =ALIGN(4);
   *_start_gcc.o(.text*)
  } >FLASH
 
/* 应用程序1空间 */
.app1 0x08001000 :
  {
    . = ALIGN(4);
    app1.o(.text*)
    . = ALIGN(4);
  } >FLASH
 
/* 应用程序2空间 */
  .app2 0x08002000 :
  {
    . = ALIGN(4);
    app2.o(.text*)
    . = ALIGN(4);
  } >FLASH
 
/* 其他应用程序空间,下面并不是完整的链接文件,其中还有数据段,bss段堆栈段等没有列出 */
 .text 0x08003000:
  {
    . = ALIGN(4);
    *(.text.startup.main)
    *(.text)           /* .text sections (code) */
 
    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end ofcode */
  } >FLASH
 
在编写好上面文件,进行重新链接的时候,提示错误信息如下:
c:/programfiles/gnu tools arm embedded/4.7 2013q1/bin/../lib/gcc/arm-none-eabi/4.7.3/../../../../arm-none-eabi/bin/ld.exe:cannot find app1.o
collect2.exe: error: ld returned 1 exitstatus
找不到app1.o,于是将app1.o包含暂时屏蔽处理,然后从*.map文件中可以找到如下字段
LOAD app1.o
这个时候有点犯迷糊了,怎么明明都正确装载了,却找不到呢?
经过多番试验,仍然不然找到问题原因。那么在map文件里肯定可以找到app1.o对应的函数定义信息,不看不知道,问题原因竟在这里
.text.app1_test1
               0x08002e74       0x24d:\Tmp\ccKPCaS8.ltrans1.ltrans.o
.text.app1_test2
               0x08002f74       0x24d:\Tmp\ccKPCaS8.ltrans1.ltrans.o
原来在链接的时候,链接器都从*.ltrans.o文件中来获得,这到底是什么原因呢,后来经过仔细对比Make的编译选项,发现有一个编译选项是–flto,它的目的是用于提高链接速度的,刚开始在试验的时候有怀疑过这个选项,但是它的作用是提高链接速度,所以当初并没有更加深入去分析这个选项。原文如下:
-flto
This option runs the standard link-time optimizer. When invoked withsource
code, it generates GIMPLE (one of GCC’s internal representations)and writes
it to special ELF sections in the object file. When the object filesare linked
together, all the function bodies are read from these ELF sectionsand instan-tiated as if they had been part of the same translation unit.
于是在链接选项中将 –flto去掉,结果编译和验证顺利通过。
 
### STM32串口重定向与ARMGCC编译教程 #### 使用ARMGCC编译器配置STM32项目 为了使STM32能够通过串口输出调试信息,在开发环境中设置好ARMGCC工具链至关重要。通常情况下,开发者会利用GNU ARM Embedded Toolchain来完成这一过程。 当尝试运行经过简化处理后的二进制文件时,可能会遇到缺少调试符号的情况[^1]。因此建议确保编译选项中启用了调试信息生成(如`-g`),以便于后续可能需要借助GDB等工具进行更深入的分析工作。 #### 实现串口重定向功能 对于嵌入式系统而言,将标准输入/输出流映射到物理设备上的特定接口是非常常见的需求之一。针对STM32平台来说,可以考虑如下方法: 1. **修改启动代码**:调整C库初始化部分,使得程序开始执行前就完成了对USART外设的相关配置; 2. **自定义I/O函数**:编写专门用于读写操作的新版本`_write()`和`_read()`函数,并告知链接器优先采用这些替代方案; 下面给出一段简单的示例代码片段展示如何实现上述第二种方式中的`_write()`函数: ```c #include "stm32f4xx_hal.h" int _write(int file, char *ptr, int len){ HAL_UART_Transmit(&huart1,(uint8_t *) ptr,len,HAL_MAX_DELAY); return len; } ``` 此段代码假设已经正确设置了UART句柄变量`huart1`,并且调用了相应的硬件抽象层API来进行实际的数据发送动作。 #### 编译命令样例 最后附上一条完整的编译指令供参考: ```bash arm-none-eabi-gcc -mcpu=cortex-m4 -mfpu=fpv4-sp-dted -mfloat-abi=hard \ -specs=nano.specs -T<your_linker_script.ld> main.c startup_stm32f407vg.s \ -o output.elf -O0 -ggdb3 -Wall -Wextra -pedantic-errors ``` 这条命令指定了目标架构、浮点单元特性以及其他必要的参数,同时还包含了优化级别设定以及启用全面警告的功能开关。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值