我正在尝试使用 AVR 风格的 gcc 专门提供的变量属性(https://gcc.gnu.org/onlinedocs/gcc/AVR-Variable-Attributes.html#AVR-Variable-Attributes)。
手册说这些特殊属性应该允许我强制将变量放置在预定的内存地址处。他们甚至举了一个例子:
volatile int porta __attribute__((address (0x600)));
但是,当我从上述文档编译和调试此代码示例时,使用此类属性声明的变量被放置到编译器和链接器确定的 SRAM 中的位置,而不是按要求放置在地址 0x600 处。实际上,如果我从声明中完全删除该属性,最终结果不会改变 - 变量被放置在相同的“无论”地址。当我使用“io”和“io_low”属性而不是“address”时,也会发生同样的情况。
我正在使用针对 8 位 MCU (ATMega64) 的最新版本 Atmel Studio 7.0.19.31 中打包的 gcc 工具链。
因此问题:有没有人尝试使用这些特殊的 AVR 特定属性并取得成功?
重要提示:
*(volatile int*)0x600 = your_data_here;
但这对我来说也不是一个选择,我需要声明一个实际的变量(因为我想将其映射到按位结构上,以便在不显式使用掩码和逻辑运算的情况下访问各个位。所以我真的在寻找一种方法来使提供的属性发挥作用,而不是寻找解决方法。我错过了什么?
手册说这些特殊属性应该允许我强制将变量放置在预定的内存地址。
不,不是。 它明确指出“没有分配内存”。因此,您不能使用它来将变量放置在特定地址。
使用此类属性声明的变量被放置到编译器和链接器确定的 SRAM 中的位置,而不是按要求放置在地址 0x600 处。
也许您遇到了PR112952中报告的问题:属性
io
、io_low
、address
无法正常工作,具体取决于-f[no-]data-sections
和-f[no-]common
。 请注意,-fcommon
默认值在 v10 中发生了更改,请参阅 GCC v10 发行说明。
我需要声明一个实际的变量
那么你就不能使用这些属性中的任何一个,因为它们不分配内存。 这些属性基本上相当于
(*(volatile Type*) 0x???)
模式,但其地址仅在链接时评估;而对于常量地址的转换,该地址必须在编译时已知。
** 对于位于固定地址的对象,您需要将其放在自己的部分中并使用自定义链接描述文件。**
因为我想将其映射到按位结构上,以便在不显式使用掩码和逻辑运算的情况下访问各个位。
你在这里失去了我。您能举例说明您想要实现的目标吗?
typedef struct {
uint8_t rx:4;
uint8_t tx:4;
} Pio_TXRXMUX_t;
#define Pio_TXRXMUX (*(volatile Pio_TXRXMUX_t *)(0x22)) //PORTA on ATMEGA1280