我正在使用 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/