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.

MSP430FR4133: Transfer project from cl430 to gcc430-elf-gcc

Part Number: MSP430FR4133

Hello everyone,

I want to transfer a legacy MSP430 (FR4133) project that runs with the cl430 version (v18.12.4.LTS) under the Code Composer 9.3.0 to the latest available TI MSP 430 GCC and a CMAKE setup under Linux Ubuntu.

In case you ask why: having a GCC-based, relatively future proof and IDE independent solution that allows for easy use and integration of things like clang-format and clang-tidy.

However, I still have the problem that the built hex file seems to be faulty and I had to make some adjustments that I am not 100% sure about. I wanted to flash the hex via the MSPFlasher to proof it works as before.

The code is based on a TI RTOS for msp430 that is not maintained anymore: downloads.ti.com/.../tirtos_msp43x_setuplinux_2_20_00_06.bin

To get the code to compile and link I had to replace/update the msp430_driverlib to 2.91.13.01, which I downloaded from the TI website.

I also took the latest msp430 gcc compiler that I could obtain from the TI website:msp430-gcc 9.3.1.11

Furthermore, I had to replace a POP.A assembler instruction with POPX.A to get the extract of the 20-bit address within the PREP_STACK_FOR_RETI function assembling again. As seen in here: Diapositivo 1 (roboticsclub.org). Is my understanding correct here?

I have set the following compiler flags for GCC

 -mlarge (use large model addressing for 20-bit pointers, 20 bit size_t)

-O2 -ffunction-sections -fdata-sections -mhwmult=none -g

The -mlarge-flag seems to be the equivalent for  cl430's --code_model=large

The code requires per #ifndef check that __LARGE_CODE_MODEL__ is set, but the marcro is not available in gcc-msp430 and I have had to set the definition manually.

Adjusting the code and data region parameter was of no help either.

GCC Linker flags

  -mmcu=${MSP_MCU}

  -T/usr/bin/msp430-gcc/include/msp430fr4133.ld

  -nostdlib

  -Wl,-Map=${EXE_FLOWMETER}.map

  -Wl,--gc-sections

 

Other cl430 compiler flags that I do not see a direct equivalent for:

--heap_size=160 – how does it relate to the objcopy parameter when converting to ihex?

--stack_size=160 – how does it relate to the objcopy parameter?

 --silicon_version=mspx  - also required for cl430 20-bit pointers according to the documentation.

 Has somebody a hint what it could be and if the settings regarding the code model are sufficient? I have checked the code and am quite sure not to have missed including parts of the code in the CMAKE setup. 

TI compiler doc: MSP430 Optimizing C/C++ Compiler v18.1.0.LTS User's Guide (Rev. R)

GCC compiler doc: MSP430 GCC User's Guide (Rev. F) (ti.com)

 

  • Linking with "-nostdlib" is certain to cause trouble because there will be no C startup code. All that stuff that initializes variables and then calls main().

    Heap and stack size aren't of much use anyway so no great loss. The heap starts at the end of the bss and grows up. The stack starts at the end of memory and grows down. If they meet, there will be trouble. But dynamic allocation is usually not a good thing to be using in an embedded application.

    Other things:

    hwmult - the compiler knows what to do here given the MCU.

    Include "-Wall" for lint like nitpicking of your code

    linker script - the compiler knows which one to use given the MCU

    Not sure why you are messing with popx unless this is in the RTOS state save/restore code. In which case popm is the better choice.

  • Hi David, thanks alot! I All your points are valid and work as described. I took the -nostdlib flag from another CMAKE compiler setup, but that one had a custom linker applied. My mistake was to assume that, as functions like ltoa are not available, it would solve discrepancies between the TI lib and the compiler lib, when, in fact, the non-C-standard functions simply had to be replaced by the GCC newlib signatures in the code.

    The assembler code is within the RTOS code to prepare the stack for return from interrupt. It is pretty much aligned with the RTOS code in the discontinued RTOS lib I mentioned above, code from there below. If I replace the POP.A (or POPX.A) with POPM.A #4, it works, too. Is POPM simply better because it is more explicit? I reckon it should cover the all 20 bits?

     

            POP.A   R14
            PUSH.W  R14
    
            RRAM.A  #4, R14         ; merge upper 4 bits of RA into
            AND.W   #0xf000, R14    ; upper 4 bits of SR
            BIS.W   SR, R14
    
            PUSH.W  R14     
            PUSHM.A #7, R10
            MOV.W   SP, 0(OLD)      ; small data pointer
            MOV.W   0(NEW), SP
            POPM.A  #7, R10
            RETI
    

  • popm (and pushm) move multiple registers so save space.

    That is strange looking code. I have only ever used FreeRTOS so have no clue what the TI RTOS is doing here.

**Attention** This is a public forum