avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] Possible avr-gcc or binutils problem


From: Nick Downing
Subject: [avr-gcc-list] Possible avr-gcc or binutils problem
Date: 30 May 2003 18:25:06 +1000

dear List,

Please can someone provide a bit of newby help?  I am trying to get
started with avr-gcc but I found a number of rather strange problems. 
First I will include my code and makefiles so that others can duplicate
the problem I found.  I'll paste directly into here.  Here goes:

---- cut here ----
/* hello.h by Nick for Hytech AVR */

int my_putc(char c);
int my_getc(void);
int main(void);

---- cut here ----
/* hello.c by Nick for Hytech AVR */

#include <stdio.h>
#include <avr/io.h>
#include "hello.h"

int my_putc(char c)
        {
        while (bit_is_set(UCSRA, UDRE) == 0)
                ;
        UDR = c;
        return 0;
        }

int my_getc(void)
        {
        if (bit_is_set(UCSRA, RXC) == 0)
                return -1;
        return UDR;
        }

int main(void)
        {
        /* initialise the AVR's built-in UART for 9600 bps */
        UCSRA = _BV(TXC);
        UCSRB = _BV(TXEN) | _BV(RXEN);
        UBRR = 71;
        /* UBRRH = 0; */ /* = (11059200 / (9600 * 16)) - 1 */

#if 1
        /* send a demo message to ISPD via the AVR's UART */
        my_putc('h');
        my_putc('e');
        my_putc('l');
        my_putc('l');
        my_putc('o');
#else
        /* setup the standard input, output and error streams */
        fdevopen(my_putc, my_getc, 0);

        /* send a demo message to ISPD via the AVR's UART */
        printf("hello, world\r\n");
#endif

        /* enter an infinite loop as we can never exit */
        while (1)
                ;
        }

---- cut here ----

My compiler is installed from the following set of rpm's:

avr-binutils-2.13.90.030512-1.i386.rpm
avr-gcc-3.2.90.20030512-1.i386.rpm
avr-libc-20030512cvs-1.i386.rpm
avr-libc-docs-20030512cvs-1.i386.rpm

The code seems to compile properly, using my "bash" script as follows:

---- cut here ----
#!/bin/sh
avr-gcc -mmcu=at90s4433 -Wl,--oformat,ihex hello.c -o hello.hex
---- cut here ----

As you can see, I selected an output format of "Intel Hex" since this is
the needed format for our programmer tool.  Does anyone know whether the
switch "--oformat ihex" to "avr-ld" works properly?  Perhaps I should be
building an "elf" binary and then extracting the code segment as "hex"??

Anyway, when I run the program the results are rather strange.  It often
seems to crash and output endless garbage to the UART.  The behaviour is
affected by seemingly insignificant changes (for example, un-commenting
the line which says "UBRRH = 0;" makes it go crazy).  A few times I was
able to get a character or several to come out, but most often not.

That's when I started looking more closely at the generated files, and I
think I found a rather bizarre problem.  I searched all the mailing list
archives that I could find, and as many FAQs as I could find, looking
for anyone else who might have encountered this problem.  I didn't find
anything looking remotely like it, so maybe I am doing something wrong?

I found this anomaly by running the "revava" program on my generated
"hello.hex" output.  Here is an excerpt showing the start of the Flash:

---- cut here ----
#arch AT90S8515
#include "avr.inc"

        seg abs=0x0 flash.code0

        rjmp    28              ; 0000, Dest: 001E
        rjmp    76              ; 0002, Dest: 0050
        rjmp    74              ; 0004, Dest: 0050
        rjmp    72              ; 0006, Dest: 0050
        rjmp    70              ; 0008, Dest: 0050
        rjmp    68              ; 000A, Dest: 0050
        rjmp    66              ; 000C, Dest: 0050
        rjmp    64              ; 000E, Dest: 0050
        rjmp    62              ; 0010, Dest: 0050
        rjmp    60              ; 0012, Dest: 0050
        rjmp    58              ; 0014, Dest: 0050
        rjmp    56              ; 0016, Dest: 0050
        rjmp    54              ; 0018, Dest: 0050
        rjmp    52              ; 001A, Dest: 0050

        clr     r1              ; 001C
        ;eor    r1, r1          ; 001C

        out     0x3F, r1        ; 001E
        ldi     r28, 0xDF       ; 0020
        out     0x3D, r28       ; 0022
---- cut here ----

As far as I can see, the initial RJMP instruction (in the reset vector)
is jumping one location too far.  See the line saying "Dest: 001E".  I
think the program should begin execution at address "001C".  These are
all "byte" addresses, the corresponding "word" addresses are "000F" and
"000E".  The program starts with an instruction "C00E" which is a jump
foward 000E words, ie. to "word" location 000F.  The "hex" begins with:

:100000000EC026C025C024C023C022C021C020C0ED
:0C0010001FC01EC01DC01CC01BC01AC0B9
:08001C0011241FBECFEDCDBF82
:10002400106000E1B06028E2F1E003C0C8953196A9

So, if my understanding of the disassembly output is correct, it means
the program starts with "OUT SREG, R1" where the R1 contents are not
defined.  This could cause extremely strange behaviour (especially if
some interrupt sources are enabled).  I know the AVR initialises some
locations on reset, but I still don't know what the effects of this code
would be.  I would much prefer to begin my program with "CLR R1" which
seems to be the intention.  I tried compiling the appropriate avr-libc
modules (gcrt1.S, etc) with my setup, but this didn't change anything.  

I tried WinAVR (versions from 2002 and 2003) and it still produced the
same .hex output as my Linux system.  So that's not the problem.  At a
guess it's probably my use of "--oformat ihex" that's causing a problem?

Thanks in advance,
cheers,
Nick

ps.  Does anyone know of an AVR resources page where I could download a
program similar to the above?  Preferably a working one, unlike mine. 
:)  I found something, but it won't compile because of "__outw_atomic"
which seems to be deprecated in this version of avr-gcc??  Does anyone
know why this symbol is now broken?  I want to use it to read the timer!

pps.  I am unsure of how to instruct avr-gcc to put strings and/or
constants into Flash.  Can someone please advise?  By default, they seem
to go into SRAM.  I have been unable to verify that they really get
copied from Flash to SRAM but I would assume this is the reason for the
"__do_copy_data()" symbol.  Do I have to call this myself?  I was going
to check this by looking at the "revava" output but it's too confusing.

ppps.  Once a string has been defined in Flash (or a constant array),
how do I set up a pointer into Flash so I can read it?  I would assume
that any pointer variables (for example "char *p;") would have to be
declared differently in this case.  Can someone please advise??  Thanks!





reply via email to

[Prev in Thread] Current Thread [Next in Thread]