c - AVR-GCC 链接器 : "Data"-Section overflows

标签 c gcc linker avr

我正在使用 Atmel AVR-GCC 编译一个基于 Atmel 的 Zigbee Bitcloud 的项目。在Atmega256rfr2( 256k Flash, 32k RAM)

添加更多代码后,我接近内存的限制(似乎是这样)。

我发现,如果链接器向“数据部分”添加了太多内容,就会导致程序出现不可预测的行为。问题是链接器没有帮助我找到这一点。所以我正在努力寻找一个稳定的解决方案。

我正在使用 Atmel 提供的以下链接器文件:

OUTPUT_FORMAT("elf32-avr")
OUTPUT_ARCH(avr:6)

MEMORY
{
    text   (rx)   : ORIGIN = 0x00000000, LENGTH = 256K
    boot   (rx)   : ORIGIN = 0x0003F000, LENGTH = 4K
    access (rx)   : ORIGIN = 0x0003FFF0, LENGTH = 16
    data   (rw!x) : ORIGIN = 0x00800200, LENGTH = 32K - 500  /* leave 500 bytes for stack */
    eeprom (rw!x) : ORIGIN = 0x00810000, LENGTH = 8K
}

SECTIONS
{  
.text :
  {
    PROVIDE(__text_start = .);

    *(.vectors)
    KEEP(*(.vectors))
    . = ALIGN(0x400);

    /* PDS NV memory section */
    PROVIDE(__d_nv_mem_start = .);
    . = ALIGN(0x4400);
    PROVIDE(__d_nv_mem_end = .);

    /* Non-volatile file system PDS_FF section */
    PROVIDE(__pds_ff_start = .);
    KEEP(*(.pds_ff))
    PROVIDE(__pds_ff_end = .);

    /* Non-volatile file system PDS_FD section */
    PROVIDE(__pds_fd_start = .);
    KEEP(*(.pds_fd))
    PROVIDE(__pds_fd_end = .);

    *(.progmem.gcc*)
    *(.progmem*)
    . = ALIGN(2);

    *(.trampolines*)
    *(.jumptables*)
    *(.lowtext*)

    *(.init0)
    KEEP (*(.init0))
    *(.init1)
    KEEP (*(.init1))
    *(.init2)
    KEEP (*(.init2))
    *(.init3)
    KEEP (*(.init3))
    *(.init4)
    KEEP (*(.init4))
    *(.init5)
    KEEP (*(.init5))
    *(.init6)
    KEEP (*(.init6))
    *(.init7)
    KEEP (*(.init7))
    *(.init8)
    KEEP (*(.init8))

    *(.text.main)
    KEEP (*(.text*main))
    *(.text)
    *(.text.*)

    PROVIDE(__text_end = .);
  } > text

  .data : AT (ADDR(.text) + SIZEOF(.text))
  {
    PROVIDE(__data_start = .);
    *(.data*)
    *(.rodata*)
    *(.gnu.linkonce.d*)
    . = ALIGN(2);
    PROVIDE(__data_end = .);
  } > data

  .bss __data_end :
  {
    PROVIDE(__bss_start = .);
    *(.bss*)
    *(COMMON)
    PROVIDE(__bss_end = .);
  } > data

  .noinit __bss_end :
  {
    *(.noinit*)
    PROVIDE(__heap_start = .);
  } > data

  __stack_start = .;

  __data_load_start = LOADADDR(.data);
  __data_load_end = __data_load_start + SIZEOF(.data);

  .access_section :
  {
    KEEP(*(.access_section*))
    *(.access_section*)
  } > access

  .boot_section :
  {
    *(.boot_section*)
  } > boot

  .eeprom :
  {
    FILL(0xff)
    BYTE(0xff)
    . = . + LENGTH(eeprom)-1;
  } > eeprom

  /DISCARD/ :
  {
    *(.init9)
    *(.fini9)
  }

}

我设法弄清楚代码在多大的数据量下肯定不再工作,以及在多大的数据量之前我没有明显的故障。 该程序适用于大小输出:

text       data     bss     dec     hex filename
210260    10914   25427  246601   3c349 (TOTALS)

avr-gcc-size -A:

    section              size      addr
    .data                2722   8389120
    .text              209468         0
    .bss                25426   8391842
    .noinit                 1   8417268
    .access_section         4    262128
    .boot_section         798    258048
    .eeprom              8192   8454144
    .debug_info        538541         0
    .debug_abbrev       46706         0
    .debug_loc          73227         0
    .debug_aranges       5704         0
    .debug_ranges        6032         0
    .debug_line        108276         0
    .debug_str          89073         0
    .comment               92         0
    .debug_frame        14252         0
    Total             1128514

我的尺寸有明显故障:

210260    10918   25427  246605   3c34d (TOTALS)

只增加文本,不增加数据,不会导致任何问题:

210270    10914   25427  246611   3c353 (TOTALS)

有没有人知道,为什么程序此时会失败?当这种情况可能发生时,我如何预测 future 的限制或让链接器向我发出警告?

我没有收到任何链接器错误消息或警告。程序就在此时崩溃了。

最佳答案

.data 部分中的所有内容都会占用闪存 RAM。 Flash 中的部分用于初始化RAM 中的部分。您的 RAM 可能用完了。所以我的建议是尽可能标记为const。执行该操作将移至 .text 段,它只占用 Flash,而将 RAM 留给更好的东西。

关于c - AVR-GCC 链接器 : "Data"-Section overflows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46706076/

相关文章:

c++ - 是否有 GCC __PRETTY_FUNCTION__ 等同于它所提供的文字参数?

c - 是否可以将命令行参数传递给 GNU LD 以创建一个部分、定义大小并将其放置在特定内存中?

c++ - 无法解释的链接器错误

c++ - "Undefined reference to class::function..."- 我链接不正确吗?

c++ - C/C++ 中有哪些不同的调用约定,每个约定是什么意思?

c - 在 C 中,无符号和有符号字符指针之间的转换何时变得不安全?

c++ - OpenGL 旋转 2D 纹理

c - 如何通过指令读取二进制可执行文件?

xcode/clang : clang: warning: argument unused during compilation: '-fcheck-new'

c - GNU 中 _TRACE 宏在哪里定义?