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.

[参考译文] MSP430G2553:GCC 与 TLV 数据

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1077422/msp430g2553-gcc-vs-tlv-data

部件号:MSP430G2553

GCC 已开始警告阵列访问超出范围(如果不应该)。 看来编译器作者很难就此问题发出警告,但却在搞砸。 我从9.2版升级到9.3版,但结果是一样的。 我的问题是此代码:

/*
  Compute a checksum on the TLV data area and compare it to the value
  stored there. If they match, return true. Checked before using
  the ADC calibration data and DCO settings stored there.
 */
int tlv_good(void)
{
  int *p, chk, i;

  chk = 0;
  p = (int *)(&TLV_CHECKSUM + 1);
  for(i = 0; i < 31; i++)
    chk ^= *p++;

  chk += TLV_CHECKSUM;
  return ~chk;
}


/*
  Use factory calibration data to correct ADC readings.

  Starts with filtered Q4 fixed point numbers but just throws away the
  fractional bits.

  Remembers if the TLV structure checksum has checked out previously.
 */

uint16_t corrected(int val)
{

  int32_t tmp;
  static int *p = 0;

  if(p || tlv_good())
    {
      p = (int *)&TLV_ADC10_1_TAG;
      tmp = val >> 3;
      tmp *= *(p + CAL_ADC_25VREF_FACTOR/2);
      tmp >>= 16;      
      tmp *= *(p+CAL_ADC_GAIN_FACTOR/2);
      tmp >>= 16;
      tmp += *(p+CAL_ADC_OFFSET/2);
      return tmp;
    }
  else 
    return val >> 4;
  
}

第一个函数(tlv_bine())正常,但第二个函数会导致多个警告:

beeper.c: In function 'corrected':
beeper.c:86:14: warning: array subscript 6 is outside array bounds of 'volatile unsigned char[1]' [-Warray-bounds]
   86 |       tmp *= *(p + CAL_ADC_25VREF_FACTOR/2);
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/ti/gcc/include/msp430g2553.h:65,
                 from /usr/ti/gcc/include/msp430.h:1423,
                 from beeper.c:1:
/usr/ti/gcc/include/msp430g2553.h:904:1: note: while referencing 'TLV_ADC10_1_TAG'
  904 | sfr_b(TLV_ADC10_1_TAG);                       /* TLV ADC10_1 TAG */
      | ^~~~~

请注意,即使我正在使用整数的指针,编译器也在抱怨我使用的地址的来源和字符数组。 它没有对 tlv_Good ()中的指针引用提出任何此类投诉。 唯一的区别是所引用项目的大小。 一个定义为单词(Sfr_W),另一个定义为字符。 (SFR_b)。

更糟糕的是,当我查看代码时,它已经非常糟糕了。 尽管我使用整数的指针,但编译器一次提取一个字节的数据。 在将字节合并为整数之前,对一个字节执行缓慢而痛苦的八位偏移。

问题可能始于存储在内存中的这些数据结构在设备报头文件中被标记为特殊函数寄存器,但传播这些属性的编译器却导致了最大的麻烦。 没有禁用阵列边界警告,我没有找到解决该警告的方法。 无法使其生成 sane 代码。

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

    大卫,你好。

    我想指出的第一件事是,MSP430G2553在典型的 TLV 结构中没有像许多其他 MSP430器件那样的结构。 它将校准数据存储在内存段 INFOA 中,因此只需确保您指向正确的内存部分。

    至于警告,大小不匹配很可能是导致这种情况的原因,因为您正在尝试将一个单词(2个字符)转换为一个字符数组。  

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

    这几乎就像你没有读过我写的。

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

    我测试了一个解决此问题的方法。 它要求将指针声明和赋值移到函数之外,这不是我想要的。 指针仅在这一个函数中使用,因此不需要或建议使用全局范围。 但至少它导致编译器警告无效。

    它还将 fetch 整数消除为不一致的胡说八道。 (如果使用 SWPB 指令而不是八个班次,那就不会那么糟糕了。)

    我可以理解编译器设计人员希望尝试并减少数组索引问题,但这些问题自一开始就存在于 C 中,需要程序员的努力,而不是更聪明的编译器。 如果我想要编译器的智能,我会使用其他的东西。

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

    有关信息,我可以在 CCS 11.1中使用您的示例代码重新创建问题,方法是使用 随 CCS 一起安装的 MSP430-gcc-9.3.0.31 (Mitto Systems Limited)编译器为 MSP430G2553创建一个项目。

    我已附加项目,但不确定如何获得有关该问题的缺陷。 有两种构建配置,它们在优化级别上有所不同。

    警告对所用的优化级别敏感。 O1无警告:

    **** Build of configuration GCC_O1 for project MSP430G2553_TLV ****
    
    /home/mr_halfword/ti/ccs1110/ccs/utils/bin/gmake -k -j 12 all -O 
     
    Building file: "../main.c"
    Invoking: GNU Compiler
    "/home/mr_halfword/ti/ccs1110/ccs/tools/compiler/msp430-gcc-9.3.0.31_linux64/bin/msp430-elf-gcc-9.3.0" -c -mmcu=msp430g2553 -mhwmult=none -I"/home/mr_halfword/ti/ccs1110/ccs/ccs_base/msp430/include_gcc" -I"/home/mr_halfword/E2E_example_projects/MSP430G2553_TLV" -I"/home/mr_halfword/ti/ccs1110/ccs/tools/compiler/msp430-gcc-9.3.0.31_linux64/msp430-elf/include" -O1 -g -gdwarf-3 -gstrict-dwarf -Wall --save-temps -MMD -MP -MF"main.d_raw" -MT"main.o"   -o"main.o" "../main.c"
    Finished building: "../main.c"
     
    Building target: "MSP430G2553_TLV.out"
    Invoking: GNU Linker
    "/home/mr_halfword/ti/ccs1110/ccs/tools/compiler/msp430-gcc-9.3.0.31_linux64/bin/msp430-elf-gcc-9.3.0" -mhwmult=none -O1 -g -gdwarf-3 -gstrict-dwarf -Wall --save-temps -mmcu=msp430g2553 -Wl,-Map,"MSP430G2553_TLV.map" -Wl,--gc-sections -L"/home/mr_halfword/ti/ccs1110/ccs/ccs_base/msp430/include_gcc" -mmcu=msp430g2553 -o"MSP430G2553_TLV.out" "./main.o" -T"../msp430g2553.ld"  -Wl,--start-group -lgcc -lc -Wl,--end-group 
    Finished building target: "MSP430G2553_TLV.out"
     
    
    **** Build Finished ****

    在 O2处有警告:

    **** Build of configuration GCC_O2 for project MSP430G2553_TLV ****
    
    /home/mr_halfword/ti/ccs1110/ccs/utils/bin/gmake -k -j 12 all -O 
     
    Building file: "../main.c"
    Invoking: GNU Compiler
    "/home/mr_halfword/ti/ccs1110/ccs/tools/compiler/msp430-gcc-9.3.0.31_linux64/bin/msp430-elf-gcc-9.3.0" -c -mmcu=msp430g2553 -mhwmult=none -I"/home/mr_halfword/ti/ccs1110/ccs/ccs_base/msp430/include_gcc" -I"/home/mr_halfword/E2E_example_projects/MSP430G2553_TLV" -I"/home/mr_halfword/ti/ccs1110/ccs/tools/compiler/msp430-gcc-9.3.0.31_linux64/msp430-elf/include" -O2 -g -gdwarf-3 -gstrict-dwarf -Wall --save-temps -MMD -MP -MF"main.d_raw" -MT"main.o"   -o"main.o" "../main.c"
    ../main.c: In function 'corrected':
    ../main.c:42:16: warning: array subscript 6 is outside array bounds of 'volatile unsigned char[1]' [-Warray-bounds]
       42 |         tmp *= *(p + CAL_ADC_25VREF_FACTOR/2);
          |                ^~~~~~~~~~~~~~~~~
    In file included from /home/mr_halfword/ti/ccs1110/ccs/ccs_base/msp430/include_gcc/msp430.h:1423,
                     from ../main.c:1:
    /home/mr_halfword/ti/ccs1110/ccs/ccs_base/msp430/include_gcc/msp430g2553.h:904:31: note: while referencing 'TLV_ADC10_1_TAG'
      904 | sfr_b(TLV_ADC10_1_TAG);                       /* TLV ADC10_1 TAG */
          |                               ^~~~~~~~~~~~~~~
    ../main.c:44:16: warning: array subscript 1 is outside array bounds of 'volatile unsigned char[1]' [-Warray-bounds]
       44 |         tmp *= *(p+CAL_ADC_GAIN_FACTOR/2);
          |                ^~~~~~~~~~~~~~~
    In file included from /home/mr_halfword/ti/ccs1110/ccs/ccs_base/msp430/include_gcc/msp430.h:1423,
                     from ../main.c:1:
    /home/mr_halfword/ti/ccs1110/ccs/ccs_base/msp430/include_gcc/msp430g2553.h:904:31: note: while referencing 'TLV_ADC10_1_TAG'
      904 | sfr_b(TLV_ADC10_1_TAG);                       /* TLV ADC10_1 TAG */
          |                               ^~~~~~~~~~~~~~~
    ../main.c:46:16: warning: array subscript 2 is outside array bounds of 'volatile unsigned char[1]' [-Warray-bounds]
       46 |         tmp += *(p+CAL_ADC_OFFSET/2);
          |                ^~~~~~~~~~~~~~~
    In file included from /home/mr_halfword/ti/ccs1110/ccs/ccs_base/msp430/include_gcc/msp430.h:1423,
                     from ../main.c:1:
    /home/mr_halfword/ti/ccs1110/ccs/ccs_base/msp430/include_gcc/msp430g2553.h:904:31: note: while referencing 'TLV_ADC10_1_TAG'
      904 | sfr_b(TLV_ADC10_1_TAG);                       /* TLV ADC10_1 TAG */
          |                               ^~~~~~~~~~~~~~~
    Finished building: "../main.c"
     
    Building target: "MSP430G2553_TLV.out"
    Invoking: GNU Linker
    "/home/mr_halfword/ti/ccs1110/ccs/tools/compiler/msp430-gcc-9.3.0.31_linux64/bin/msp430-elf-gcc-9.3.0" -mhwmult=none -O2 -g -gdwarf-3 -gstrict-dwarf -Wall --save-temps -mmcu=msp430g2553 -Wl,-Map,"MSP430G2553_TLV.map" -Wl,--gc-sections -L"/home/mr_halfword/ti/ccs1110/ccs/ccs_base/msp430/include_gcc" -mmcu=msp430g2553 -o"MSP430G2553_TLV.out" "./main.o" -T"../msp430g2553.ld"  -Wl,--start-group -lgcc -lc -Wl,--end-group 
    Finished building target: "MSP430G2553_TLV.out"
     
    
    **** Build Finished ****
    

    [引用 userid="215629" url="~ë/support/microcontroller/MSP-low-Power-microcontroller-group/MSP430/f/MSP-low-Power-microcontroller-forum/1077422/msp430g2553-gcc-vs -tlv-data"]请注意,即使我使用整数的指针,编译器仍在抱怨字符和字符数组的来源。]

    对于所附示例, 使用--save-temps 选项获取编译器以保存生成的汇编器。

    C 源代码中的第42行是以下语句:

            tmp *= *(p + CAL_ADC_25VREF_FACTOR/2);

     在 GCC_O2/main.s 文件中,第42行显示了以下汇编程序:

    .LVL6:
    	.loc 1 42 9 is_stmt 1
    	.loc 1 42 16 is_stmt 0
    	MOV.B	&TLV_ADC10_1_TAG+13, R13
    	RLA.W	R13
    	RLA.W	R13
    	RLA.W	R13
    	RLA.W	R13
    	RLA.W	R13
    	RLA.W	R13
    	RLA.W	R13
    	RLA.W	R13
    	MOV.B	&TLV_ADC10_1_TAG+12, R14
    	BIS.W	R14, R13
    	.loc 1 42 13
    	MOV.W	R12, R14 { BIT.W	#0x8000, R14 { SUBC.W	R15, R15 { INV.W	R15, R15
    .LVL7:
    	MOV.W	R13, R12 { BIT.W	#0x8000, R12 { SUBC.W	R13, R13 { INV.W	R13, R13
    	CALL	#__mspabi_mpyl
    .LVL8:
    	MOV.W	R13, R14
    

    源代码语句使用 p 指针时,编译器优化程序似乎已用 &TLV_ADC10_1_tag 的偏移替换了对指针的引用。 我认为这解释了编译器随后发出警告的原因。

    e2e.ti.com/.../MSP430G2553_5F00_TLV.zip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="215629" url="~ë/support/microsofts/MSP-low-Power-microcontroller-group/MSP430/f/MSP-low-Power-microcontroller-forum/1077422/msp430g2553-gcc-vs -tlv-data/3992503#3992503]I 测试了解决此问题的方法。 它要求将指针声明和赋值移到函数之外,这不是我想要的。 指针仅在这一个函数中使用,因此不需要或建议使用全局范围。 但至少它导致编译器警告无效。

    在优化级别2删除编译器警告的另一个变通方法是声明 p 指针不稳定。 例如,通过从以下位置更改:

        static int *p = 0;

    至:

        static int *volatile p = 0;

    [引用 userid="215629" url="~ë/support/microcontroller/MSP-low-Power-microcontroller-group/MSP430/f/MSP-low-Power-microcontroller-forum/1077422/msp430g2553-gcc-vs -tlv-data/3992503#3992503]It 也消除了无效的取整数。 [/引用]

    上述变通方法也有同样的效果。

     第42行在 GCC_O2/main.s 中生成的代码现在为:

    .LVL6:
    	.loc 1 42 9 is_stmt 1
    	.loc 1 42 20 is_stmt 0
    	MOV.W	&p.1566, R13
    	.loc 1 42 13
    	MOV.W	R12, R14 { BIT.W	#0x8000, R14 { SUBC.W	R15, R15 { INV.W	R15, R15
    .LVL7:
    	MOV.W	12(R13), R13
    	MOV.W	R13, R12 { BIT.W	#0x8000, R12 { SUBC.W	R13, R13 { INV.W	R13, R13
    	CALL	#__mspabi_mpyl
    .LVL8:
    	MOV.W	R13, R14

    附带有变通方案的项目。

    e2e.ti.com/.../2352.MSP430G2553_5F00_TLV.zip