EmbDev.net

Forum: ARM programming with GCC/GNU tools GCC weirdness (I think)


Author: jm (Guest)
Posted on:

Rate this post
0 useful
not useful
I'm using a recently downloaded install of MinGW and Eclipse to test 
some functions by using the debugger...so anyway, I have defined a 
struct and instantiated one as a global by doing something like this:

struct foo_t
{
    signed int num;
};

struct foo_t foo;

This statement is outside of main(), and outside of all functions.

The real struct contains mostly signed ints.

In main(), I do something like this:

int main(void)
{
foo.num = 300;
afunc();
}


Now for the weird part: when I step past where it sets it to 300, I can 
see that struct member is 300.  As soon as I enter afunc(), foo.num is 
zero!  I don't even modify foo in afunc().  Once it exits afunc(), the 
value of 300 is restored.

I've done lots of C programming, so either I'm having a brain fart or 
come across some bug.

Author: Norbert (Guest)
Posted on:

Rate this post
0 useful
not useful
Hmmm, don't know which version you're using but it compiles and runs 
fine here.


GNU C (Debian 4.4.5-8) version 4.4.5 (x86_64-linux-gnu)
  compiled by GNU C version 4.4.5, GMP version 4.3.2, MPFR version 
3.0.0-p3.
#include <stdio.h>

struct foo_t
{
    signed int num;
};

struct foo_t foo;

void afunc(void)
{
    printf("%d\n", foo.num);
}

int main(void)
{
    foo.num = 300;
    printf("%d\n", foo.num);
    afunc();
    printf("%d\n", foo.num);
    return 0;
}


Result:
300
300
300

Author: Alexander F. (alexf91)
Posted on:

Rate this post
0 useful
not useful
It compiles and runs fine at my system too.

gcc (Debian 4.7.2-5) 4.7.2 and
GNU gdb (GDB) 7.6-debian

Author: jm (Guest)
Posted on:

Rate this post
0 useful
not useful
Definite brain fart.  I had the struct defined in main() AND globally. 
I had to start stripping large sections of code out to see it.

I guess I'll never stop making dumb mistakes.

Author: Clarence Roopnarine (croopnarine)
Posted on:

Rate this post
0 useful
not useful
Hi, I’ve tried to compile a drivre for a UART on the TMS470R1B1M part of 
the driver ( the write function is shown below):

static int uart_write( struct _file_descriptor* fd, const void* 
write_buf, int num_bytes )
{
       volatile int bytes_written = -1;
       volatile SCI_TypeDef* SCIx;
       if( ( is_valid_handle( fd ) ) &&
           ( write_buf != NULL )     &&
           ( num_bytes > 0 ) )
       {
             SCIx = ( ( SCI_TypeDef* )( fd->fd_priv_data ) );
             if( ( fd->mode & O_RDONLY ) != O_RDONLY )
             {
                    bytes_written = 0;
                    while( bytes_written < num_bytes )
                    {
                       /* Determine if the transmitter is ready to
                          transmit a byte */
                           while( ( SCIx->CTL2 & SCI_TXRDY ) != 0 )
                               asm("nop;");
                           SCIx->TXBUF =
                              ( ( char* )( write_buf ) 
)[bytes_written++];
                    }
             }
       }
       return bytes_written;
}

When complied with gcc arm-elf 4.2.0 I’ve got the following output:

static int uart_write( struct _file_descriptor* fd,
                       const void* write_buf,
                       int num_bytes )
{
    uart_wri:mov     r12,r13
    stmdb   r13!,{r11-r12,r14,pc}
    sub     r11,r12,#0x4
    sub     r13,r13,#0x14
    str     r0,[r11,#-0x18]
    str     r1,[r11,#-0x1C]
    str     r2,[r11,#-0x20]
    volatile int bytes_written = -1;
    mvn     r3,#0x0
    str     r3,[r11,#-0x14]
    volatile SCI_TypeDef* SCIx;
    if( ( is_valid_handle( fd ) ) &&
        ( write_buf != NULL )     &&
        ( num_bytes > 0 ) )
    ldr     r0,[r11,#-0x18]
    bl      0x11180          ; is_valid_handle
    mov     r3,r0
    cmp     r3,#0x0
    beq     0x11540
    ldr     r3,[r11,#-0x1C]
    cmp     r3,#0x0
    beq     0x11540
    ldr     r3,[r11,#-0x20]
    cmp     r3,#0x0
    ble     0x11540
{
    SCIx = ( ( SCI_TypeDef* )( fd->fd_priv_data ) );
    ldr     r3,[r11,#-0x18]
    ldr     r3,[r3,#0x1C]
    str     r3,[r11,#-0x10]

    while( bytes_written < num_bytes )
    {
        /* Determine if the transmitter is ready to transmit a byte */
        while( ( SCIx->CTL2 & SCI_TXRDY ) != 0 ) asm("nop;");
        SCIx->TXBUF = ( ( char* )( write_buf ) )[bytes_written++];
     }

}
    return bytes_written;
    ldr     r3,[r11,#-0x14]
    mov     r0,r3
    sub     r13,r11,#0x0C
    ldmia   r13,{r11,r13,pc}
}

As can be seen no assembly code is generated for the while loop. These 
are the flags used for gcc

CFLAGS += -mbig-endian  -mcpu=arm7tdmi -mapcs-frame -gdwarf-2 
-I$(PROJECTROOT)

AFLAGS = -mcpu=arm7tdmi  --warn -EB -mfpu=softfpa -mapcs-32 --gdwarf2

LDFLAGS = --script=$(TMS470R1B1MDIR)ldscript -EB 
-Map=$(OUTPUTDIR)/main.map --cref --gc-sections

ODFLAGS = --wide --source --all-headers --reloc --syms --disassemble -t

LDFLAGS += -L /cygdrive/c/GNUARM/arm-elf/lib/be/

LIBS = $(SYSTEMLIBSDIR)libgcc.a
LIBS += /cygdrive/c/GNUARM/arm-elf/lib/be/libc.a
LIBS += /cygdrive/c/GNUARM/arm-elf/lib/be/libg.a
LIBS += /cygdrive/c/GNUARM/arm-elf/lib/be/libm.a


Any suggestion I can try to get the complier to generate the assembly 
code for the while loop?

Thanks

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.