【问题标题】:How can I bind a variable to an unused AVR I/O register using avr-gcc?如何使用 avr-gcc 将变量绑定到未使用的 AVR I/O 寄存器?
【发布时间】:2012-04-26 21:30:02
【问题描述】:

我想使用 avr-gcc 将全局变量绑定到未使用的 I/O 寄存器(例如 PORTB),以减少代码大小。我在 AVR 的应用笔记AVR035(第 14 页)中学到了这个技巧。

在应用笔记中,他们使用 IAR 编译器并将变量绑定到 I/O 寄存器,如下所示:

__no_init volatile uint8_t counter@0x35;

使用 avr-gcc,我可以使用以下行将变量绑定到标准寄存器(在本例中为 r3):

register uint8_t counter asm("r3");

这不适用于 I/O 寄存器。有没有办法对 I/O 寄存器执行此操作?

【问题讨论】:

  • 哇,这是个好技巧。但有一个问题:当您考虑使用 IN 和 OUT 而不是 STS 和 LDS 获得的代码大小时,为什么不首先在汇编中编写整个代码?跨度>
  • Assembly 可能是这个级别的代码调整的好主意 :-) 我希望通过将一些全局变量移动到 i/o 寄存器来“快速”获得收益。原来这并不容易。

标签: avr avr-gcc


【解决方案1】:

由于这仅适用于全局变量,因此仅使用类似的东西来使用怎么样,例如 Uart 波特率寄存器:

#define myGlobalVariable UBRR

还要注意,这种优化只有在进行大量位测试时才值得,因为大多数 IO 寄存器都有直接位测试指令。 哦,我忘了,不是所有的 AVR 都有 LDS 和 STS 指令以及一些仅通过 Z 寄存器访问 SRAM,与简单的 IN 和 OUT 相比,这在代码大小和速度上都有很大的不同......

【讨论】:

  • 是的,这就是我现在正在做的事情。但是我注意到与 SRAM var 相比,使用 UBRR 实际上增加了代码大小。使用例如PORTB 虽然节省了几个字节。可能我需要更仔细地看看编译器在这里做了什么。
  • @henning77 IO 寄存器通常为volatile,这意味着编译器必须为源代码中的每个读取或写入生成IO 操作。使用(非易失性)变量,编译器可以通过在寄存器中缓存值来优化访问。示例:i = 5; i = i + 1; i = i * 2; 需要对别名为 i 的 IO 寄存器进行 3 次写入和 2 次读取,但只需要对全局非易失性变量 i 进行一次写入。
猜你喜欢
  • 2012-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-24
  • 1970-01-01
相关资源
最近更新 更多