C++ 微控制器的第一次gcc链接器脚本编译,但不';跑不动

C++ 微控制器的第一次gcc链接器脚本编译,但不';跑不动,c++,gcc,embedded,atmel,linker-scripts,C++,Gcc,Embedded,Atmel,Linker Scripts,我通过atmel studio为SAMD51J19微控制器创建了我的第一个gcc链接器脚本,它编译得非常好,没有问题,但当加载到设备中时,会发生奇怪的错误 有时是硬故障,有时不是,有时中断没有发送给处理程序,有时是。有时函数在运行时不会发生任何事情,有时也不会。调试器到处都是,我对旧的股票链接器代码没有任何问题,我也不知道为什么会发生这种情况 大部分都是从原始文件中重新使用的。我所做的主要是在区域之间添加一些间距或更好的对齐,并移动一些非强制放置的部分。例如,只读数据位于rom组0的末尾,而不是

我通过atmel studio为SAMD51J19微控制器创建了我的第一个gcc链接器脚本,它编译得非常好,没有问题,但当加载到设备中时,会发生奇怪的错误

有时是硬故障,有时不是,有时中断没有发送给处理程序,有时是。有时函数在运行时不会发生任何事情,有时也不会。调试器到处都是,我对旧的股票链接器代码没有任何问题,我也不知道为什么会发生这种情况

大部分都是从原始文件中重新使用的。我所做的主要是在区域之间添加一些间距或更好的对齐,并移动一些非强制放置的部分。例如,只读数据位于rom组0的末尾,而不是中间。所以我真的不明白为什么会这样

下面是我的链接器脚本

OUTPUT_格式(“elf32 littleram”、“elf32 littleram”、“elf32 littleram”)
输出拱(臂)
搜索目录()
/*
*NVM=2个存储组(512KB)(可用352KB)(为SEEPROM保留160KB)
*1组=32个区块(256K)和16个区域
*气缸组1(主)=32个区块(256K)和16个区域
*气缸组2(辅助)=12个块(96KB)和6个区域
*1个区域=2个块(16KB)(保护对齐)
*1块=16页(8KB)(分区对齐)
*1页=32个QWords(512B)(剖面对齐)
*1 QWord=16字节(分段对齐)
*1 DWord=8字节
*1字=4字节(默认对齐方式)
*
*路线:
*4字节:新片段
*16字节:新的小节
*512字节:新节
*8192字节:新分区
*16384字节:新的保护区域
*/
/*内存空间定义*/
记忆
{
Rom 0(rx):原点=0x00000000,长度=0x0003F800/*Rom列组0:主列组(用于代码)*/
lnl(rx):原点=0x0003F800,长度=0x0000800/*加载-N-锁定0-等待状态速度:2KB*/
Rom 1(rx):原点=0x00040000,长度=0x00018000/*Rom第1列:辅助列(用于数据)*/
qspi(rx):原点=0x04000000,长度=0x01000000/*外部NVM:(单独芯片上的附加辅助数据)*/
ram(rwx):原点=0x20000000,长度=0x00030000/*ram(默认ram)*/
seeprom(rx):原点=0x44000000,长度=0x00010000/*seeprom:运行时永久数据*/
bkupram(rwx):源代码=0x47000000,长度=0x000020000/*备份Ram:程序数据*/
}
/*应用程序使用的堆栈大小*/
堆栈大小=0xC000;
/*章节定义*/
部分
{
/*
程序代码
文本输出部分的游戏计划
不支持异常或展开表
向量从一开始就走
程序代码放在下一个QWord上
拇指/手臂粘合代码放置在下一个QWord上
只读数据放在它自己的页面中
重新定位数据被放置在它自己的页面中
*/
.案文:
{
/*从顶部开始*/
.=0x00000000;
_stext=。;
_sfixed=。;
/*向量表*/
/*根据需要将矢量放置在rom0的开始位置*/
保持(*(.vectors.vectors.*))
/*程序代码*/
.=对齐(16);/*新的小节*/
*(.text.text.*.gnu.linkonce.t.*))
/c+C++特殊生成代码,部分程序代码*//
/*C++安装程序代码*/
.=对齐(4);/*新件*/
保持(*.init))
.=对齐(4);/*新件*/
__preinit_数组_start=。;
保留(*.preinit_数组))
__preinit_数组_end=。;
.=对齐(4);/*新件*/
__init_数组_start=。;
KEEP(*(排序(.init_数组。*)))
保留(*.init_数组))
__init_数组_end=。;
/*C++构造函数代码*/
.=对齐(4);/*新件*/
保留(*crtbegin.o(.ctors))
保留(*(排除_文件(*crtend.o).ctors))
保留(*(排序(.ctors.*))
保持(*crtend.o(.ctors))
/*C++拆卸代码*/
.=对齐(4);/*新件*/
保持(*.fini))
.=对齐(4);/*新件*/
__fini_数组_start=。;
保留(*.fini_数组))
保留(*(排序(.fini_数组。*)))
__fini_数组_end=。;
/*C++解构器代码*/
.=对齐(4);/*新件*/
保留(*crtbegin.o(.dtors))
保留(*(排除_文件(*crtend.o).dtors))
保留(*(排序(.dtors.*))
保持(*crtend.o(.dtors))
/*拇指臂代码翻译胶*/
.=对齐(16);/*新的小节*/
*(.glue_7t)*(.glue_7)
/*只读/常量数据,放入新页面*/
.=对齐(512);/*新页*/
*(.rodata.rodata*.gnu.linkonce.r.*))
/*这是为了重新定位数据,请将其放在自己的页面中*/
.=对齐(512);/*新页*/
_地点重新定位=。;
_efix=。;
_etext=。;
}>rom0/*这些当然放在主rom库中*/
/*
Rom 0自定义代码
.rom0输出部分的游戏计划
这是一种与生成的代码无关的程序特定用法的工作区
代码。它需要进入它自己的区块。
*/
.rom0(空载):
{
.=对齐(8192);/*新块*/
_srom0=。;
*(.rom0*)
_erom0=。;
}>rom0
/*
Load-N-Lock 0-等待状态速度
.lnl输出部分的游戏计划
LNL被放置在它自己的保留内存区域中,该区域在rom0中具有特定的大小
非常拥挤,每个字节都计数。不会进行对齐。
*/
.lnl(空载):
{
_slnl=。;
*(.lnl*)
_elnl=。;
}>lnl/*进入它自己的特定区域*/
/*
Rom 1自定义代码
.rom1输出部分的游戏计划
Rom库1更为宽松,因为整个库用于程序使用。
这需要放在第一页之后。第一页是保留的
用于程序特定的标题数据和工作区。
*/
.rom1(空载):
{
.=512;/*从开始到第二页*/
_srom1=。;
*(.rom1*)
_erom1=。;
}>rom 1/*进入rom组1*/
/*
QSPI自定义代码
.qspi输出部分的游戏计划
QSPI类似于ROM1,因为它只是一个可以使用的区域
用于定制用途或工作区域。
*/
.qspi(空载):
{
.=对齐(4);/*新件*/
_sqspi=。;
*(.qspi*)