Perhaps this has already been found, but I've come across what looks
like an array indexing bug in msp430-gcc 4.5.3.  My platform is Ubuntu
Natty, and I built this from source, using the directions at
https://github.com/sergiocampama/Launchpad/blob/master/README.md

I've tried to make a minimal example that demonstrates the bug.  This
code was originally a program to do SPI with an LCD panel, but I've
trimmed almost everything.  The functions write_ones() and
write_zeros() are essentially identical, except that the array in
write_ones() is marked volatile while the array in write_zeros() is
not.  It is the write_zeros() function that shows the error, and I've
indicated it in the assembly that follows.

#include <msp430g2211.h>

#define RED BIT0
#define GRN BIT6

void spi_IO( unsigned char data[] ) {
    if( data[0] == 5) {  // show red light when called by ones() and
grn for zeros()
        P1OUT |= RED;
        P1OUT &= ~GRN;
    } else {
        P1OUT |= GRN;
        P1OUT &= ~RED;
    }
}

void write_zeros( void ) {
    unsigned char zeros[17];
    int j, page;

    for( page = 0; page < 2; page++ ) {
        zeros[0] = 6;
        spi_IO( zeros );

        for( j = 0; j < 17; j++ ) zeros[j] = 0x00;

        spi_IO( zeros );
    }
}

void write_ones( void ) {
    volatile unsigned char ones[17];
    int j, page;

    for( page = 0; page < 2; page++ ) {
        ones[0] = 5;
        spi_IO( ones );

        for( j = 0; j < 17; j++ ) ones[j] = 0xFF;

        spi_IO( ones );
    }
}

void main( void ) {
    int i;
    // Stop the watchdog timer so it doesn't reset our chip
    WDTCTL = WDTPW + WDTHOLD;

    // These are the pins we need to drive.
    P1DIR |= RED + GRN;

    P1OUT |= RED + GRN;
    for( i = 0; i < 20; i++ ) {
        __delay_cycles( 30000 );
    }
    P1OUT &= ~(RED + GRN);

    write_ones();
    write_zeros();

    P1OUT &= ~(RED + GRN);

    for( ;; ) {
        __bis_SR_register( LPM3_bits + GIE );
    }
}

I built it and sent it to a Launchpad with these commands:

$ /usr/local/bin/msp430-gcc -S -O2 -mmcu=msp430g2211 -o minimal.s minimal.c
$ /usr/local/bin/msp430-gcc -O2 -mmcu=msp430g2211 -o minimal.elf minimal.s
$ mspdebug rf2500 "prog minimal.elf"

The bug is in the write_zeros() function.  In the assembly code, the
array bound is set to 17 instead of 17+base pointer.

        .file   "minimal.c"
        .arch msp430g2211
        .cpu 430
        .mpy none

        .text
        .p2align 1,0
.global spi_IO
        .type   spi_IO,@function
/***********************
 * Function `spi_IO'
 ***********************/
spi_IO:
        cmp.b   #5, @r15
        jeq     .L5
        bis.b   #64, &__P1OUT
        and.b   #llo(-2), &__P1OUT
        ret
.L5:
        bis.b   #1, &__P1OUT
        and.b   #llo(-65), &__P1OUT
        ret
.Lfe1:
        .size   spi_IO,.Lfe1-spi_IO
;; End of function

        .p2align 1,0
.global write_zeros
        .type   write_zeros,@function
/***********************
 * Function `write_zeros'
 ***********************/
write_zeros:
        push    r11
        push    r10
        push    r9
        add     #llo(-18), r1
        mov     #2, r9
        mov     r1, r11
        mov     #17, r10         ;<------------ right here.  Needs another
instruction: add r11, r10
.L8:
        mov.b   #6, @r1
        mov     r11, r15
        call    #spi_IO
        mov     r11, r15
.L7:
        mov.b   #0, @r15
        add     #1, r15
        cmp     r10, r15           ;<------------- because here we compare the
index pointer to it
        jne     .L7
        mov     r11, r15
        call    #spi_IO
        add     #llo(-1), r9
        jne     .L8
        add     #18, r1
        pop     r9
        pop     r10
        pop     r11
        ret
.Lfe2:
        .size   write_zeros,.Lfe2-write_zeros
;; End of function

        .p2align 1,0
.global write_ones
        .type   write_ones,@function
/***********************
 * Function `write_ones'
 ***********************/
write_ones:
        push    r11
        add     #llo(-18), r1
        mov     #2, r11
.L13:
        mov.b   #5, @r1
        mov     r1, r15
        call    #spi_IO
        mov     #0, r15
.L12:
        mov     r1, r14
        add     r15, r14
        mov.b   #llo(-1), @r14
        add     #1, r15
        cmp     #17, r15
        jne     .L12
        mov     r1, r15
        call    #spi_IO
        add     #llo(-1), r11
        jne     .L13
        add     #18, r1
        pop     r11
        ret
.Lfe3:
        .size   write_ones,.Lfe3-write_ones
;; End of function

        .section        .init9,"ax",@progbits
        .p2align 1,0
.global main
        .type   main,@function
/***********************
 * Function `main'
 ***********************/
main:
        mov     #23168, &__WDTCTL
        bis.b   #65, &__P1DIR
        bis.b   #65, &__P1OUT
        mov     #20, r15
.L17:
        nop
        mov     #9999, r14
.L__delay__111:
        dec     r14
        jnz     .L__delay__111
        add     #llo(-1), r15
        jne     .L17
        and.b   #llo(-66), &__P1OUT
        call    #write_ones
        call    #write_zeros
        and.b   #llo(-66), &__P1OUT
.L18:
        bis     #216, r2
        jmp     .L18
.Lfe4:
        .size   main,.Lfe4-main
;; End of function

------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing 
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
Mspgcc-users mailing list
Mspgcc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mspgcc-users

Reply via email to