【发布时间】:2015-04-01 04:10:29
【问题描述】:
我对 Arduino 之外的嵌入式 c++ 相当陌生,但到目前为止,我已经能够解决我遇到的所有问题,除了这个问题。 我在 Atmega 1284P 上使用 Atmel Studio,用 C++ 编码。我正在使用以下变量与 TTL 串行输入进行比较(串行输入在 0 到 255 之间以单个无符号字符字节传输):
const unsigned char STEER_DEADZONE_MIN = 120;
const unsigned char STEER_DEADZONE_MAX = 120;
const unsigned char THROTTLE_DEADZONE_MIN = 136;
const unsigned char THROTTLE_DEADZONE_MAX = 136;
当我尝试使用 STEER_DEADZONE_MIN 或任何列出的无符号字符时,它们显示为 12。我已确认我的程序使用 Atmel Studio 模拟器监视工具并将其打印到 LCD 上的显示为 12嵌入式设备。实际上,我已经为 unsigned char 提出了一个修复方法,即删除 const,但我有 const 是有原因的,因为我不希望更改值。声明为:
unsigned char TEST = 120;
unsigned char TEST1 = 136;
这会导致该值正确地为 120 或 136,但随后可能会意外更改该值。似乎如果我在主循环中执行分配:
const unsigned char TEST = 120;
这也修复了该值,但引入了其他问题,此后我的任何函数都无法访问它。
当涉及到 const unsigned int 时,我也遇到了一个看似相关的问题。当我在主循环之外声明它时:
const unsigned int SERVO_ESC_SPEED = 200;
const unsigned int SERVO_STEER_SPEED = 200;
const unsigned int SERVO_DISTANCE_SENSOR_SPEED = 200;
该值为 37900,但是,我尝试在我的主循环中将其声明为:
const unsigned int TEST = 200;
这更正了该值,但如上所述,由于我的函数不再可以访问它,因此无济于事。在这种情况下,在主循环之外删除 const 并不能修复该值。在这一点上,我真的很茫然。在这一点上,我唯一能想到的尝试的另一件事是创建一个包含所有这些 const 变量的设置类,看看是否可以更正这些值。我将在接下来尝试并更新结果。
【问题讨论】:
-
也许您的代码中某处存在一个错误,它破坏了存储
const变量的区域;或者,链接器或程序加载器可能有问题,并且它没有首先正确设置const变量区域。尝试制作一个最小的程序来测试,即一个只包含main()(或任何你的入口点)和一个const全局变量以及检查该变量值所需的绝对最少代码量。 -
好的,所以我能够通过使用 atmega1284P 模板创建一个新的 Atmel Studio 项目来确认同样的问题,然后构建一个只定义了这些变量和一个 main() 的完全准系统 main.cpp只将它们直接打印到 LCD 上。在这一点上,我只能假设这是 avr-gcc、atmel studio 或工具链/链接器模板中的错误。无论如何,我找到了一种解决方法,方法是在 Settings.h 文件中构建一个 Settings 类并在该类中声明所有这些常量。
-
我不会相信任何进一步的代码,只要你描述的一些基本问题的解决方法是必需的。
-
你是对的。这更像是一个测试和一个临时的解决方法。在通宵工作之后,我终于找到了解决方法而不是解决方法。我的电路板制造商提供的模板启用了以下编译器优化:fdata-sections 和 ffunctions-sections。关闭这两个优化,完全解决了这个问题。 fdata-sections 导致了无符号字符的问题,而 ffunctions-sections 导致了无符号整数的问题。我现在已经将我的常量移回了所属的位置,并且一切正常。
-
您可能应该进一步调查。看看您是否可以查看链接器映射以查看这些变量的位置(通常它们位于 .text 或 .rodata 中)。您的程序代码通常在 .text 中。也许您可以尝试检查是否正在加载 .rodata(如果这是这些常量所在的位置);或者可能将常量放入 .text 而不是 .rodata 。
标签: c++ constants avr-gcc atmelstudio