MSP430F1232: GCC MSP430 compiler uses wrong address for variable

Part Number: MSP430F1232

The GNU ld (Mitto Systems Limited - msp430-gcc 9.3.1.11) 2.34  compiler appears to generate incorrect assembly code that writes to the wrong memory address for the sluft_value_ member variable in certain conditional branches.
I have this simplified if construct. That produces the same result as the real implementation.

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

That depending on the ID sets two variables and then print the result. This is the variable definition in the class.

private:
uint16_t sluft_value_;
uint16_t sluft_connected_;


  
  

When I look at the print it does not look right.

Exprected:

When tmp_ven_id == 5sluft_value_ should be set to 0

When tmp_ven_id == 3sluft_value_ should be set to 1

Actual Behavior

he sluft_value_ member variable always reads as 1, regardless of which conditional branch executes.

ID    | Connected | Value
00005 | 00001     | 00001  (expected: 00000)
00003 | 00001     | 00001  (expected: 00001)
00005 | 00001     | 00001  (expected: 00000)
00003 | 00001     | 00001  (expected: 00001)

When looking into the asembler code the problem is esily visible. The wirte of the 0 value in case 5 happen to another address then it is passed to the function that prints the value. I spend some time debuggign this, but can't find the real cause of this issue. Just a bunch of changes I can make to seemingly "solve" this issue. 

// 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;
  }

For option 1 the text size as expected increases by 2 and the code works. Chainging from "else if" to only "ifs" has no effect.

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

text    data     bss     dec     hex filename
  29556    1338    1292   32186    7dba -> broken
  29558    1338    1292   32188    7dbc  ->working
  29534    1340    1292   32166    7da6 -> if
  29534    1340    1292   32166    7da6 -> else if

This is the resulting assembler code. Of the 3 differen implementations. In the broken example the mov 0 appears to a address that is far away. 

ti_error.png

I am using all options to reduce code size as well as ink-time optimization.

Compiler flags used:  -g3 -Os -fno-rtti -fno-exceptions -std=gnu++11 -Wl, -mcpu=430 -mhwmult=16bit -mno-warn-mcu

Ihave the suspiccion that there is a bug in the memory alignment that causes this. I disabled the LTO and changed the size of the rom section in the .ld file and the assembler code still had the faulty adress.

  • I am confused. This thread is tagged as being about the F1232 but the code shown can't possibly fit. That and the problem being with indexing on r12 and the index being much bigger than the 512 byte SRAM of this part. What device is this really for?

    And the code displayed is of limited utility as it can't be associated with the source. I use objdump -S for that. 

  • What are you missing from the src code? The assembler was generated using "./msp430-elf-objdump.exe -d -S" it only shows the function in question to keep this post as condensed as possible. My device is a open mps430 build into an ASIC. It has 32k of ram.

  • So a bespoke MSP430 of unknown configuration, a missing linker script, and an incomplete code fragment that can't be compiled.

    No chance of anyone replicating the error with that.

    When I use objdump -S (no -d) I get source intermingled with the disassembled code:

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

  • As this error only accures when the Class is as it is I unfortunatly can't provide the whole sorce code. A miminal implementation is not possible as there the problem does not accure. I uploaded the linker script to https://pastes.io/default-l and a bigger snipped of the disasebly https://pastes.io/disasemly , but there is no src code included even without the -d option.


**Attention** This is a public forum