如何在SAMD21嵌入式项目中链接静态库中的向量表
SAMD21固件拆分项目中断向量表符号丢失问题排查与解决请求
项目背景
- 参考RepRapFirmware架构搭建SAMD21固件,拆分为核心静态库和主项目:
- 核心库:包含ASF库、自定义驱动等底层代码,具备跨处理器可移植性;定义了基础向量表、
Reset_Handler和Dummy_Handler,其余中断handler以弱属性声明并别名至Dummy_Handler,需在主项目中按需实现 - 主项目:处理器无关的高层代码
- 核心库:包含ASF库、自定义驱动等底层代码,具备跨处理器可移植性;定义了基础向量表、
问题现象
- 核心静态库编译完成后,归档文件中包含所有向量表符号
- 链接主项目与核心库后,生成的
.elf和.map文件仅保留Reset_Handler,其余向量表符号全部丢失 - 单项目编译时所有符号正常,固件运行无异常
- 调试栈信息:
??@0xfffffffe (Unknown Source:0) <signal handler called>@0xfffffff9 (Unknown Source:0) _sfixed@0x00000000 (Unknown Source:0)
已尝试的解决方法
- 移除编译选项中的
-ffunction-sections -fdata-sections - 在库中为handler添加
__attribute__((weak, alias("Dummy_Handler"), used))属性 - 使用Copilot建议的引用向量表符号的代码
疑问与需求
推测丢失的handler是问题根源,也可能存在其他诱因。若确为此问题,如何强制链接完整的向量表?
附链接脚本
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) MEMORY { rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 } STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > rom PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > rom PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; } > ram .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _stack = .; } > ram . = ALIGN(4); _end = . ; }
内容的提问来源于stack exchange,提问作者Artem Plyusnin
相关产品推荐
相关产品推荐

