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.

[参考译文] MSPM0G3505:使用 TICLANG 时出现编译器错误?

Guru**** 2811295 points

Other Parts Discussed in Thread: MSPM0G3505

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1624323/mspm0g3505-compiler-error-with-ticlang

器件型号: MSPM0G3505

我正在实施无效的回路、但失败了。

请参阅调试屏幕截图。  

当我逐步浏览 for 循环时、我会观察-  

for (i = 0;i < 8;i++){...}
我看到 它从 0 增加到超过 8。  I = 20、在屏幕截图中。  这是怎么一回事?
 
MSPM0G3505、CCS 版本:20.4.1.4__1.10.1 TI Clang 4.0.4 LTS
 
调试屏幕截图图像无法上传、代码如下:
 
void SetDisp(volatile uint8_t mask){
	volatile unsigned char i;
	for(i = 0; i < 8; i++){
  		DL_GPIO_clearPins(DISP_GRP_PORT,DISP_GRP_SHFT_PIN);
		if((mask & (0x80 >> i))==0){
			DL_GPIO_clearPins(DISP_GRP_PORT,DISP_GRP_DOUT_PIN);
		}
		else{
			DL_GPIO_setPins(DISP_GRP_PORT,DISP_GRP_DOUT_PIN);
		}
  		DL_GPIO_setPins(DISP_GRP_PORT,DISP_GRP_SHFT_PIN);
	}
}

.
 
调试窗口信息:

CORTEX_M0P
 
已停止
  
SetDisp () 0x00000494display.c32:23
DispSplash () 0x0000047ADDISPLAY.C46:3
main () 0x00000348main.c0:5
  
当地人
 
I:20    0x20203FE0
 
 
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Dan:

    您能尝试使用优化级别 0、再试一次相同的代码吗、我想确保函数没有被编译器优化。

     当您观察到变量“i"时“时、您在循环执行过程中观察到了吗?

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

    在 for 循环之外、I 还可以用于其他用途。

    调试器在哪里中断?

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

    感谢您的快速答复...

    我打破了循环 — 线 “ DL_GPIO_setPins(DISP_GRP_PORT,DISP_GRP_SHFT_PIN);"  

    我还有一个刚刚经过循环但从未到达的断点。

    从优化上的 2 更改为 0 确实可以解决问题、但这似乎是一个相当弱的修复。

    另外,我尝试了一种不同形式的循环(见下文),它也失败了 — x 到达 0 但循环从未退出。  

    除了观看调试中的变量外、我还使用示波器在外部监控引脚、并发现代码滞留在循环中、这肯定是现实世界中的问题、而不是一些奇怪的调试卤化问题。

    void SetDisp (uint8_t mask){

      Volatile unsigned char x;
      X = 0x80
      执行
        DL_GPIO_clearPins (DISP_GRP_PORT、DISP_GRP_SHFT_PIN);
        IF(掩码和 x)
          DL_GPIO_setPins (DISP_GRP_PORT、DISP_GRP_DOUT_PIN);
        暴露
          DL_GPIO_clearPins (DISP_GRP_PORT、DISP_GRP_DOUT_PIN);
        DL_GPIO_setPins (DISP_GRP_PORT、DISP_GRP_SHFT_PIN);
        x = x >> 1
      } while (x!= 0);

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

    你是否在没有“波动“的情况下尝试过它不是真的在这里做任何事情。

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

    相反,“易失性“允许我在行为中捕捉代码。  我最初没有使用它,我的变量(x 或 i 取决于循环版本)被优化了,所以我看不到它。 但当我开始怀疑循环行为不正确时、我用 volatile 标记了索引、迫使编译器保持可见、以便我可以观察它通过测试条件后的增量。

    所以、是的、循环在有和没有“volatile “表示法的情况下都失败。

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

    FYI 将优化设置为 1、2、3 或“快速“"z"或“或"g"“"g"(“(这些“这些非(这些非数值优化是什么)会导致循环无限执行。

    设置为“S"(“(这(这是什么?) 让我陷入故障陷阱:

    /*这是处理器收到意外消息时调用的代码 */
    /*中断。  这只需进入一个无限循环、保持系统状态*/
    /*以供调试器检查。                        */
    void Default_Handler (void)
      /*输入一个无限循环。 */
      while (1){
      }
    }
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Dan:

    我对这个问题的怀疑之一是、“x"定义“定义为“unsigned char“、这是实际的 8 位类型。 它可以在较高 24 位具有通过编译器优化定义的其他变量的地址中定义。 当您访问“x"时“时、它可能会从地址中获取整个 32 位数据。

    您可以尝试使用 uint32_t 类型定义 x、或尝试在访问“x"时“时使用 ((uint8_t) x) 替换 (x)、并尝试用它来解决问题。

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

    通过反汇编、编译器似乎优化了测试。 我在任何地方都看不到比较分支或条件分支。
    当 I break on 时、PC 处于 0x0BFE

    对于 (I = 0;I < 8;I++)



      0x00000BF2  06C2         lsls  R2、r0、#0x1b
      0x00000BF4  600A         STR   R2、[R1]
      0x00000BF6  6020         STR   r0、[R4]
      0x00000BF8  200A         MOV  r0、#0xA
      0x00000BFA  F9B8F000       BL   0xf6e
      0x00000BFE  9802         LDR   r0、[sp、#0x8]
      0x00000C00  1C40         增加了  r0、r0、#0x1
      0x00000C02  9002         STR   r0、[sp、#0x8]
      0x00000C04  9802         LDR   r0、[sp、#0x8]
      0x00000C06  2001         MOV  r0、#0x1
      0x00000C08  6120         STR   r0、[R4、#0x10]
      0x00000C0A  9903         LDR   R1、[sp、#0xc]
      0x00000C0C  9A02         LDR   R2、[sp、#0x8]
      0x00000C0E  4091         lsls  R1、r2
      0x00000C10  0609         lsls  R1、R1、#0x18
      0x00000C12  D4ED         BMI   0xbf0
      0x00000C14  4621         MOV   R1、R4
      0x00000C16  3110         增加了  R1 #0x10
      0x00000C18  E7EB         b    0xbf2
      0x00000C1A  B004         新增   sp #0x10
      0x00000C1C  BD10         弹出   {R4、PC}
      0x00000C1E  46C0         MOV   R8、R8
      0x00000C20  400A1290       .word   0x400A1290
      0x00000C24  00000FAF       .word   0x00000FAF

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

    我把这个函数(两个版本)打包了一个简单的主体 (),它用不同的掩码值来称呼它,我看不到你描述过的任何症状。 我尝试了[-O2、-O3、-OS]波形看起来正确、甚至看到了正确的“i"值“值(我通常只相信调试器告诉我的这些东西。) 在第二个版本中、调试器报告“x"和“和“Mask"都“都已被优化掉。

    我怀疑您发布的代码之外会有什么问题。 给定您看到的一系列症状、即栈溢出(可能是由于杂散中断引起的?) 似乎是一种可能性。 如果您可以再次生成该(假定)硬故障、则从那里向后工作可能会告诉您一些事情。

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

    有趣的建议 但似乎仍然归结为编译器生成的代码是一个无限循环。

    请解释我在拆卸中看到的内容:

    如果我正确地读取汇编代码,我看到在 0xC12 有一个条件分支 (BMI) 到 0xBF0(一条指令高于我粘贴的内容 — 0xBF0: MOV   r1, r4 ),或者你得到 0xC18,在那里你遇到一个无条件分支到 0xBF2。  因此、无论什么、这个代码在 0xBF0 和 0xC18 之间无限保持 — 我是否误读了这个?  无论 ISR、栈等发生什么情况、这段代码中的指令似乎都是根本错误的。

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

    你发布的函数没有调用 delay_cycles (),所以我怀疑整个函数已经被归入调用方 ( inline-d )。 在这种情况下--只是猜测调用方做了什么--可能没有任何理由退出循环。 这在我的实验中没有发生,但所有这意味着你的呼叫者是不同的我。

    这可能是一个编译器错误;发生了这些错误、但它们非常罕见。 更常见的幻想是由优化器和/或调试器造成的。

    如果您要报告它、编译器首先要求的是一个完整的、最小的、自包含的工程、它会显示症状。 您可以通过构建来深入了解所看到的内容。

    【编辑:轻微澄清。】