This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430F1232:GCC MSP430 编译器对变量使用错误的地址

Guru**** 2794765 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1618492/msp430f1232-gcc-msp430-compiler-uses-wrong-address-for-variable

器件型号: MSP430F1232

GNU ld (Mitto Systems Limited - MSP430-gcc 9.3.1.11) 2.34 编译器似乎会生成不正确的汇编代码、这些代码会sluft_value_在某些条件分支中写入成员变量的错误内存地址。
我得到了这个简化的 IF 结构。 这将产生与实际实现相同的结果。

uint8_t AppVtux_Slave::dummyID() {
  static uint32_t counter = 0;
  uint8_t values[] = {0x03, 0x05};
  uint8_t index = counter % 2;
  counter++;
  return values[index];
}

#pragma GCC push_options
#pragma GCC optimize("O0")
void AppVtux_Slave::SLuftDetection() {
  valve_flash_.iot_cs_number_ = 1;
  uint16_t tmp_ven_id = dummyID();

  sluft_connected_ = 3;

  if (tmp_ven_id == 5) {
    sluft_connected_ = 1;
    sluft_value_ = 0;
  } else if (tmp_ven_id == 3) {
    sluft_connected_ = 1;
    sluft_value_ = 1;
  }


  SendUInt16(tmp_ven_id);
  SendStringNoLen("|");
  SendUInt16(sluft_connected_);
  SendStringNoLen("|");
  SendUInt16(sluft_value_);
  SendStringNoLen("\n");
}
#pragma GCC pop_options

根据 ID 设置两个变量、然后打印结果。 这是类中的变量定义。

private:
uint16_t sluft_value_;
uint16_t sluft_connected_;


  
  

当我查看打印时、它看起来不正确。

已缓存:

tmp_ven_id == 5sluft_value_ 应设置为  0

tmp_ven_id == 3sluft_value_ 应设置为  1

实际行为

 sluft_value_  1无论执行哪个条件分支、成员变量始终读取为。

ID  |已连接|值
00005 | 00001  | 00001 (预期值:00000)
00003 | 00001  | 00001 (预计:00001)
00005 | 00001  | 00001 (预期值:00000)
00003 | 00001  | 00001 (预计:00001)

查看沉降器代码时、问题明显可见。 在第 5 种情况下、0 值的 wirte 发生在另一个地址、然后将其传递给打印该值的函数。 我花了一些时间进行调试、但无法找到导致此问题的真正原因。 只是一堆变化,我可以做似乎“解决“这个问题.  

// Option 1:
//add Dummy variable.

 private:
  uint16_t dummy = 0xFFFF;
  uint16_t sluft_value_;
  uint16_t sluft_connected_;


// Option 2:
//Change the else if to if

  if (tmp_ven_id == 5) {
    sluft_connected_ = 1;
    sluft_value_ = 0;
  }
  if (tmp_ven_id == 3) {
    sluft_connected_ = 1;
    sluft_value_ = 1;
  }

对于选项 1、文本大小按预期增加 2、代码正常工作。 从“Else if“链接到“IFS “不起作用。

GNU ld (Mitto Systems Limited - MSP430-gcc 9.3.1.11) 2.34  

文本  数据  BSS  十进  制文件名
 29556  1338  1292 32186  7dba ->已断开
 29558  1338  1292 32188  7dbc ->正在工作
 29534  1340  1292 32166  7da6 -> IF
 29534  1340  1292 32166  7da6 ->否则

生成的汇编器代码如下。 3 种不同实现方案中的每一种。 在 BROKEN 示例中、mov 0 显示为一个距离很远的地址。  

ti_error.png

我正在使用所有选项来减小代码大小并优化链接时。

使用的编译器标志: -g3 -os -fno-rtti -fno-exceptions -std=GNU+11 -wl、-mcpu=430 -mhwmult=16 位-mno-warn-mcu

我怀疑内存对齐中存在导致这种情况的错误。 我禁用了 LTO 并更改了.ld 文件中 ROM 段的大小、汇编器代码仍然具有错误地址。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我很困惑。 这个线程被标记为是关于 F1232 的,但所示的代码不可能适合。 这就导致了在 R12 上建立索引、并且索引远大于该器件的 512 字节 SRAM 的问题。 这款器件真正适用于哪个器件?

    显示的代码是有限的实用程序、因为它不能与源代码关联。 我使用 objdump -S 来实现这一点。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    src 代码中缺少哪些内容? 汇编器是使用“./msp430-elf-objdump.exe -d -S“生成的、它仅显示相关函数以尽可能精简此 POST。 我的器件是一款集成在 ASIC 中的开放式 mps430。 它具有 32k 的 ram。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    因此、一个未知配置的定制 MSP430、一个缺少链接器脚本的 MSP430 和一个无法编译的不完整代码片段。

    任何人都不可能复制该错误。

    当我使用 objdump -S (no -d) 时、会使源代码与不汇编的代码混合:

    // Timer A CCR0 interrupt
    void __attribute__ ((interrupt(TIMER0_B0_VECTOR))) Timer_A(void)
    {
      tick++;
        442c:       92 53 00 1c     inc     &0x1c00         ;
    
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    因为这个错误只有当类是因为它是我不幸地不能提供整个排序代码时才会出现。 由于问题无法解决、因此无法实现间接实现。 我将链接器脚本上传到  了 pastes.io/default-l、并对 https://pastes.io/disasemly 进行了更详细的搜索、但即使没有-d 选项、也没有包含 src 代码。


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    从“else if“链接到只有“IFS “不起作用。

    根据汇编代码、更改为“if"看起来“看起来变量地址与添加虚拟变量相同、是否也不起作用?

    这看起来像编译器问题、但我建议您调整所有寄存器 R12、R4 配置、以查看加载的值是否不同并导致汇编语言差异。

    同时、我已经转发给编译器团队以查看是否有一些评论、不确定此编译器工具 (GNU ld (Mitto Systems Limited - MSP430-gcc 9.3.1.11) 2.34) 是否由 TI 维护。 如果有更新、我会回来的。

    B.R.

    Sal

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    TI 自 2020 年以来未提供 GCC 包的更新。 虽然 GCC 继续操作、但没有。

    任何人都可以构建当前版本的 GCC 并将 MSP430 作为目标。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢 David。

    是的、我还会从编译器团队那里收到这样的评论:TI 不会维护该工具。

    B.R.

    Sal

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    没有影响的目标是代码大小。 它不变。 但错误地址的问题确实得到了解决。
    感谢您发送编修。 我将检查 我是否发现 R4 或 R12 有点奇怪

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这就是我目前正在尝试的内容、我使用当前 GCC 版本构建 MSP430 编译器。 在实际构建目标时仍然存在一些问题。 如果有任何影响、我会进行更新。