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.

Bug in gcc version of stdlib for MSP430, atoi causes reboot

Other Parts Discussed in Thread: MSP430F5529, MSP430FR5959, MSP430FR6989

Hi!

I'd like to report a serious bug in the GCC stdlib implementation.

atoi() calls a function __mulsi2(), which seems to mess around with the PMM registers (for a reason unclear for me), even with reserved addresses above PM5CTL0 (0x0138 and 0x0134) The PMM being locked previously by the password, (I use driverlib for reising the vcore voltage), this operation causes the processor to reboot. A workaround would be of course to temporarily unlock the PMM, what else can I do...

__mulsi2():

015990: 1202 PUSH SR
015992: C232 DINT
015994: 4303 NOP
015996: 4C82 0130 MOV.W R12,&PMM__Power_Management_System_PM5CTL0
01599a: 4E82 0138 MOV.W R14,&0x0138
01599e: 4C82 0134 MOV.W R12,&0x0134
0159a2: 421C 013A MOV.W &0x013a,R12
0159a6: 4292 013C 013A MOV.W &0x013c,&0x013a
0159ac: 4F82 0138 MOV.W R15,&0x0138
0159b0: 4D82 0134 MOV.W R13,&0x0134
0159b4: 4E82 0138 MOV.W R14,&0x0138
0159b8: 421D 013A MOV.W &0x013a,R13
0159bc: 4132 POP.W SR
0159be: 0110 RETA

I am using GCC version 4.9.1., and large memory model.

  • This function tries to use the hardware multiplier, which is at different addresses in different MSP430 families. Which model did you compile this for?
  • I compiled for the MSP430F5529 (Launchpad). I used CCS for the build which adds the correct -mmcu flag. I noticed that the compiler successfully uses the mpy32 module in different situations (e.g. simple multiplication with the * operator), so I don't think that the model specification is incorrect. What else could be the cause of the issue?

  • The correct function to do 32-bit multiplications on F5 family MCUs is not __mulsi2 but __mulsi2_f5.

    I compiled gcc 4.9.2 with newlib 2.2.0 myself, and that atoi() does not do any multiplications directly. (And the compiler correctly calls __mulsi2_f5 for 32-bit multiplications.)

  • Moving this to the (DO NOT USE) TI C/C++ Compiler - Forum for visibility.
    -Katie
  • Please check the version on your compiler.  It should be at least the following ...

    % msp430-elf-gcc --version
    msp430-elf-gcc (GCC) 4.9.1 20140707 (prerelease (msp430-14r1-167)) (GNUPro 14r1)
     (Based on: GCC 4.8 GDB 7.7 Binutils 2.24 Newlib 2.1)
    Copyright (C) 2014 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    

    The 167 on line 2 is the important part.  This patch is the first to contain a fix to a problem which caused the compiler to call the wrong HW multiply routine.

    Thanks and regards,

    -George

  • My version is: 

    c:\ti\gcc\bin>msp430-elf-gcc --version

    msp430-elf-gcc (GCC) 4.9.1 20140707 (prerelease (msp430-14r1-10)) (GNUPro 14r1)
    (Based on: GCC 4.8 GDB 7.7 Binutils 2.24 Newlib 2.1)
    Copyright (C) 2014 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    This seems older so now at least I know the cause of the bug :)

    I already implemented my own atoi anyway..

    Thanks for the help :)

  • I' using TI CCS v6.1.0 which contains:
    msp430-elf-gcc (GCC) 4.9.1 20140707 (prerelease (msp430-14r1-167)) (GNUPro 14r1) (Based on: GCC 4.8 GDB 7.7 Binutils 2.24 Newlib 2.1).

    When I compile the following code:

    int main(void)
    {
    	volatile unsigned long a=1, b=2, c;
    	volatile int x;
    
    	c = a * b;
    	x = atoi("1");
    }
    

    GCC generates the following code:

    00008d5a <main>:
    int main(void)
    {
        8d5a:	2a 15       	pushm	#3,	r10	;16-bit words
        8d5c:	31 80 10 00 	sub	#16,	r1	;#0x0010
    	volatile unsigned long a=1, b=2, c;
        8d60:	91 43 04 00 	mov	#1,	4(r1)	;r3 As==01
        8d64:	81 43 06 00 	mov	#0,	6(r1)	;r3 As==00
        8d68:	a1 43 08 00 	mov	#2,	8(r1)	;r3 As==10
        8d6c:	81 43 0a 00 	mov	#0,	10(r1)	;r3 As==00, 0x000a
    	volatile int x;
    
    	c = a * b;
        8d70:	1e 41 04 00 	mov	4(r1),	r14	;
        8d74:	1f 41 06 00 	mov	6(r1),	r15	;
        8d78:	1c 41 08 00 	mov	8(r1),	r12	;
        8d7c:	1d 41 0a 00 	mov	10(r1),	r13	;0x0000a
        8d80:	b0 12 64 ad 	call	#44388		;#0xad64
        8d84:	81 4c 0c 00 	mov	r12,	12(r1)	; 0x000c
        8d88:	81 4d 0e 00 	mov	r13,	14(r1)	; 0x000e
    	x = atoi("1");
        8d8c:	3c 40 f0 82 	mov	#33520,	r12	;#0x82f0
        8d90:	b0 12 ee 92 	call	#37614		;#0x92ee
    

    The function at address 0xad64 is

    0000ad64 <__mulsi2_f5>:
        ad64:	02 12       	push	r2		;
        ad66:	32 c2       	dint			
        ad68:	03 43       	nop			
        ad6a:	82 4c d0 04 	mov	r12,	&0x04d0	;
        ad6e:	82 4d d2 04 	mov	r13,	&0x04d2	;
        ad72:	82 4e e0 04 	mov	r14,	&0x04e0	;
        ad76:	82 4f e2 04 	mov	r15,	&0x04e2	;
        ad7a:	1c 42 e4 04 	mov	&0x04e4,r12	;0x04e4
        ad7e:	1d 42 e6 04 	mov	&0x04e6,r13	;0x04e6
        ad82:	00 13       	reti

    So that's great, BUT when I trace the call of atoi(), we end up at:

    0000ad34 <__mulsi2>:
        ad34:	02 12       	push	r2		;
        ad36:	32 c2       	dint			
        ad38:	03 43       	nop			
        ad3a:	82 4c 30 01 	mov	r12,	&0x0130	;
        ad3e:	82 4e 38 01 	mov	r14,	&0x0138	;
        ad42:	82 4c 34 01 	mov	r12,	&0x0134	;
        ad46:	1c 42 3a 01 	mov	&0x013a,r12	;0x013a
        ad4a:	92 42 3c 01 	mov	&0x013c,&0x013a	;0x013c
        ad4e:	3a 01 
        ad50:	82 4f 38 01 	mov	r15,	&0x0138	;
        ad54:	82 4d 34 01 	mov	r13,	&0x0134	;
        ad58:	82 4e 38 01 	mov	r14,	&0x0138	;
        ad5c:	1d 42 3a 01 	mov	&0x013a,r13	;0x013a
        ad60:	00 13       	reti			
    

    Could it be that the precompiled library supplied by TI was compiled with the wrong compiler version?

  • Which device are you executing on?  Please show exactly how the compiler is invoked.

    Thanks and regards,

    -George

  • This is the output from the build console:


    **** Build of configuration Debug for project mul-atoi-test **** /home/USER/ti-ccs-v6.1/ccsv6/utils/bin/gmake -k all Building file: ../main.c Invoking: GNU Compiler "/home/USER/ti-ccs-v6.1/ccsv6/tools/compiler/gcc_msp430_4.9.14r1_167/bin/msp430-elf-gcc" -c -mmcu=msp430f5172 -DDEBUG -D__GNUC__=4 -D__MSP430F5172__=1 -I"/home/USER/ti-ccs-v6.1/ccsv6/tools/compiler/gcc_msp430_4.9.14r1_167/msp430-elf/include" -I"/home/USER/ti-ccs-v6.1/ccsv6/ccs_base/msp430/include_gcc" -Os -g -gdwarf-3 -gstrict-dwarf -Wall -std=gnu11 -minrt -MMD -MP -MF"main.d" -MT"main.d" -o"main.o" "../main.c" Finished building: ../main.c Building target: mul-atoi-test.out Invoking: GNU Linker "/home/USER/ti-ccs-v6.1/ccsv6/tools/compiler/gcc_msp430_4.9.14r1_167/bin/msp430-elf-gcc" -mmcu=msp430f5172 -DDEBUG -D__GNUC__=4 -D__MSP430F5172__=1 -Os -g -gdwarf-3 -gstrict-dwarf -Wall -Wl,-Map,"mul-atoi-test.map" -Wl,--gc-sections -o"mul-atoi-test.out" "./main.o" -T"../msp430f5172.ld" -Wl,--start-group -l"c" -l"gcc" -Wl,--end-group Finished building target: mul-atoi-test.out

    Below you should find an attachment containing a project which you can import into CCS v6.1.0.

    When compiling with GCC you will get a .lss file in the Debug folder where you will see that both "__mulsi2" and "__mulsi2_f5" are being included into the compilation.

    mul-atoi-test.zip

  • Even when adding "-mhwmult=none" to the project settings CCS Build -> GNU Compiler -> Miscellaneous, the "__mulsi2" won't disappear.

    The "__mulsi2_f5" vanishes in this case. This must really come from the precompiled library then.

  • When I copy "strtol.c" from TI MSP430 GCC (msp430-14r1-167) newlib to my project only "__mulsi2_f5" is left and faulty code from the library is not linked anymore.

    Below you'll find the "fixed" sample project.

    mul-atoi-test-fixed.zip

  • Someone from @Texas Instruments, can you please confirm that the library has been compiled with the wrong "-mhwmult=" option which is not suitable for the F5xx type MSP430!
  • I apologize for the delay.

    friedl said:
    can you please confirm that the library has been compiled with the wrong "-mhwmult=" option which is not suitable for the F5xx type MSP430!

    While I cannot confirm it, I think it is highly likely that this analysis is correct.  Thank you for the test case.  I see the same results you do.  I used the test case to file an issue with the Redhat development team to have this problem investigated.  Expect to hear something back on this issue in a few days.

    Thanks and regards,

    -George

  • It has been a few days. Has there been a resolution to this?

  • Hi Guys,

    Yes this is a real bug. The C library has been compiled with the
    default hardware multiply support enabled, ie for 32-bit, non
    F5-series hardware.

    This problem will be fixed in a new release of the toolchain
    which will be available from TI shortly. The fix chosen is to
    create multiple versions of the C library, each compiled with
    different versions of the hardware multiply support enabled.
    IE to use gcc's multilib facility to select the C library that
    matches the hardware that is being used.

    The patch has also been contributed upstream to the mainline
    FSF GCC development sources, so you can try it out from there
    if you prefer. The patch has not been back-ported to the gcc 5
    branch however.

    There is one small problem with the patch. If the user does
    not specify -mhwmult=XXX explicitly on the command line but
    instead uses -mmcu=XXX then gcc has to infer the type of
    hardware multiply support to use. GCC does not have the
    ability to read a devices.csv file however, so instead it
    contains a built-in list of MCU names and their hardware
    multiply types. This will work for now, but if TI releases
    new MCUs which do not use the default 32-bit non-F5 series
    hardware multiply, then the mechanism will break.

    Cheers
    Nick
  • Is this the patch?

    gcc.gnu.org/.../msg02734.html

    I looked at that list of changes and thought, "Of course, the only chip not in the list is the one I'm using .. the msp430fr5959" ...

    I wonder how many other ones are missing.  What about all the msp430fr69xx?

    -rick

  • Hi Rick,

    > Is this the patch?
    > gcc.gnu.org/.../msg02734.html

    Yes it is.

    > I looked at that list of changes and thought, "Of course, the only chip not in the list is the one I'm using .. the msp430fr5959" ...

    Darn. My suggestion, for now, is to explicitly select the hardware multiply to use by adding -mhwmult=f5series to your command line.

    > I wonder how many other ones are missing.

    I based the patch upon a devices.csv file that I received from TI a while ago. It does not contain a datestamp so I cannot say when it was produced, but obviously it is out of date.

    You can easily add more MCU names to the list that gcc will recognise by editing the gcc/config/msp430/t-msp430 file. Just go to the end of the file and then look back a few lines, to see examples of how it is done for other MCUs. (Note there are actually two places where gcc checks the MCU name and deduces the type of hardware multiply to use. The other is in gcc/config/msp430/msp430.c:msp430_use_f5_series_hwmult(), but fortunately you do not have to update this one. It uses pattern matching to accept any MCU name starting with msp430fr5).

    > What about all the msp430fr69xx?

    Ah, that is slightly more difficult as both places (t-msp430 and msp430.c) will need to be updated.

    If only I had an up to date devices.csv file, then I could generate an up to date patch.

    Cheers
    Nick

    PS. Please don't ask why a better mechanism to map MCU names to hardware multiply support was not used. I suggested it, but it was not to be. :-(
  • Hi Nick!

    Nick Clifton said:

    This problem will be fixed in a new release of the toolchain
    which will be available from TI shortly.

    Any time frame when this will be available for TI CCS v6.1 users?
    Currently it hasn't even made into to the stand-alone MSP430 gcc release.
     

  • Hello,


    The next msp gcc compiler release including above fix will be released on the ti.com gcc page in mid September.

    click on "get software" in below page:

    Thanks,

    Greg

  • Hello Greg!

    GregM said:
    The next msp gcc compiler release including above fix will be released on the ti.com gcc page in mid September.

    Thanks, but that's just half of what I've wanted to know.

    When will the updated GCC become available for TI CCS v6.1's online update mechanism?

  • Friedl,

    We will push out the CCS updates on the same day as when the ti.com gcc page is updated. Should be 9/14 or 9/15.
    At that point, the new release will show up the in CCS Apps center.

    Thanks
    Greg
  • Greg, thanks for the update!

  • So I grabbed the 3.05.00.00 binaries and it seems like the issues I raised didn't get addressed. Some of the msp430fr59xx chips work properly with libc. However, the msp430fr6xxx chips and the chips missing from the list still have issues. I downloaded the source and it is just the patch I referenced before.

    Can someone at TI get Nick Clifton an up to date devices.csv and get the t-msp430 and msp430.c patched to address the missing architectures?

    Thanks,
    -rick

  • Rick,

    Sorry for the inconvenience and issues with this and yes we are working on a better longer term solution.
    Thanks
    Greg
  • Nick Clifton said:
    Darn. My suggestion, for now, is to explicitly select the hardware multiply to use by adding -mhwmult=f5series to your command line.

    When using CCS 6.1.2.00014 with gcc_msp430_4.9.14r1_364 using a MSP430FR6989 I encountered the problem of the compiler calling __mulsi2 and thus generating incorrect results (when porting the OutOfBox_MSP430FR6989 example from the TI to GNU compiler).

    Adding -mhwmult=f5series fixed the problem.

    i.e. the problem still exists for msp430fr69xx devices.

  • All,

    The latest msp gcc release is the new beta for 5.2 which includes latest device list along with additional features like persistent (for FRAM devices) and smaller library size. Nick also added extra diagnostics as related to -mmcu to indicate when the compiler cannot determine device hw mpy settings.

    The release can be obtained at this ti.com gcc page:

    http://www.ti.com/tool/msp430-gcc-opensource

    Thanks
    Greg