我的应用程序有许多模块,每个模块都需要将一些变量存储在片外非易失性存储器中。为了使读取和写入更容易,我试图将它们收集到一个连续的 RAM 区域中,以便 NVM 驱动程序在与 NVM 设备通信时可以寻址单个内存块。
为此,我创建了一个自定义链接器脚本,其中包含以下部分定义。
.nvm_fram :
{
/* Include the "nvm_header" input section first. */
*(.nvm_header)
/* Include all other input sections prefixed with "nvm_" from all modules. */
*(.nvm_*)
/* Allocate a 16 bit variable at the end of the section to hold the CRC. */
. = ALIGN(2);
_gld_NvmFramCrc = .;
LONG(0);
} > data
_GLD_NVM_FRAM_SIZE = SIZEOF(.nvm_fram);
该data
区域使用 Microchip 为目标器件提供的标准定义在 MEMORY 部分中定义。
data (a!xr) : ORIGIN = 0x1000, LENGTH = 0xD000
NVM 驱动程序本身就是试图将其变量放在本节中的 C 源文件的一个示例。驱动程序在 NVM 部分的开头保存一个简短的标头结构,以便它可以在将 NVM 设备加载到 RAM 之前验证它的内容。未报告此变量的链接器错误。
// Locate the NVM configuration in the non-volatile RAM section.
nvm_header_t _nvmHeader __attribute__((section(".nvm_header")));
另一个具有要存储在 .nvm_fram 部分中的变量的模块是通信 (CANopen) 堆栈。这会将模块 ID 和比特率保存在 NVM 中。
// Locate LSS Slave configuration in the non-volatile RAM section.
LSS_slave_config_t _slaveConfig __attribute__((section(".nvm_canopen"))) =
{ .BitRate = DEFAULT_BITRATE, .ModuleId = DEFAULT_MODULEID };
一切都编译得很好,但是当链接器运行时,以下错误会停止构建。
elf-ld.exe: Link Error: attributes for input section '.nvm_canopen' conflict with
output section '.nvm_fram'
重要的是,可以通过 crt 启动使用值初始化变量,如上面的_slaveConfig
声明所示,以防 NVM 驱动程序无法从 NVM 设备加载它们(它是空白的,或者软件版本已更改等)。这是导致属性不匹配的原因吗?
这里和 Microchip 论坛上有几个问题,这些问题与从 C 访问链接描述文件中定义的符号有关。其中大部分涉及闪存程序中的值以及如何从 C 访问它们;我知道该怎么做。有一个类似的问题,但这似乎没有解决属性问题,并且由于特定于不同目标处理器的链接器而有点令人困惑。
我已经在线阅读了 Microchip 链接器手册和各种 GCC 链接器文档,但找不到相关部分,因为我并不真正理解错误的含义以及它与我的代码的关系。什么是“输入和输出部分属性”,它们在我的代码中指定的位置,以及如何让它们相互匹配?