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

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

RE: [avr-gcc-list] Bizarre string problem, part 3


From: Bernard Fouché
Subject: RE: [avr-gcc-list] Bizarre string problem, part 3
Date: Thu, 9 Sep 2004 09:26:45 +0200

Hi.

I've tested the code of André on a ATMEGA162 with avrgcc 3.4.1 on Linux. I
just see the '1st led message'!

This is the dev system I use everyday. However I myself never use local
variables initialized this way...

-----Message d'origine-----
De : address@hidden
[mailto:address@hidden la part de Ian Caddy
Envoyé : jeudi 9 septembre 2004 05:11
À : André - BOL
Cc : address@hidden
Objet : Re: [avr-gcc-list] Bizarre string problem, part 3


Hi Andre,

It sounds to me like your data area is not being initialised at startup.
    There are 3 main segments in your code.  These are:

text - where your code is stored
data - where the initialised data is stored
bss - where the non-initialised data is stored.

Now the data and bss segments are in RAM, and the text segment is in
flash.  The initialisation data for the data area is also stored in
flash, generally after the text section.

The startup code has to copy this init data into the data section before
the c code starts for the data area to be valid.

If you have a look at your map file, it will show how big the text and
data areas are and where they are located.

The download file that you load into your processor (how ever you do
this?) should contain the text section and the initialisation data for
the data section.  Please check that the srec or file that you download
is bigger than just your text area.

Then, the library startup code should copy this initialisation data into
your data area.  If your system generates a .lss file, it will show you
everything you need.  At the top, there will be the vector table, the
reset vector is first.  It should jump to the startup code, in your
example I compiled, it was __ctors_end:  It will then fall into
__do_copy_data.

This function is the one that will copy the initialisation data out of
flash and put it into ram at the data section and it should do this for
the length of the data section.

Now, getting down to details.  You indicated before that the data looked
like it was 0xFF.  This indicates that the flash with the initialisation
data is not being programmed into the flash and it is blank flash that
is copied into the data area.  This is why the only function that worked
for you was the one that didn't use initialised data, but copied it in
during program execution.

Please let us know how you are downloading your code, and when the size
of the srec or binary file that you are downloading, and that it should
be the size of the text area and the data areas combined.

In the lss file the top will show you the size of the text and data
sections.  There is also 2 locations called VMA and LMA.  One is the
execution address and the other is the load address.  You will notice
for the data section the load address SHOULD be in flash and the
execution address SHOULD be in ram.

The other option would be to post your makefile and the output files for
us to have a look through if you still can't find the problem.

I hope this helps.

regards,

Ian Caddy


André - BOL wrote:

> Hi!
>
> First, I'd like to thank everybody for the tips, but they haven't
> worked. I formulated a new very simple example to demonstrate the
> problem I'm facing.
>
> Suppose I "initialize" a variable in some different and equivalent ways:
>     char a[10]  = {'T', 'T', 'T', 'T', 'T' };
>     char b[]      = "TTTTTTT";
>     char c[10];      c[0]='T';    c[1]='T';     c[2]='T';      c[3]='T';
> //i think this can't be called an initialization!!!
>     char *d      = "TTTTTTT"
>
>     now, I perform the test
>
>     if ( x[2] == 'T' ) printf("hi");    // x = a, b, c or d
>
>     All examples are LEGAL STANDARD PURE C. I chose size 10 and the 3rd
> ( [2] ! ) element to avoid avoid any doubts that I had enougth space
> reserved, and that I took the correct character. All tests should return
> true and print "hi". My example ttest.c is to be run on Pc and shows
> exactly that with printf's
>
>     PROBLEM: when using the very same code on the ATMEGA, changing the
> printf's for "turn on led 1", "turn on led 2", etc., only the third char
> sequence (C) causes correct evaluation of the if expression (i can see
> that, because I have the leds correctly connected and only the 3rd one
> lights)
>
>     I tryed this under WINDOWS AND UNDER LINUX, using avr-gcc.
>
>     Compilation and downloading commands:
>
> avr-gcc -g -mmcu=atmega32 -Wall -o t.o t.c
> avr-objcopy -j .text -O ihex t.o t.hex
> uisp -dprog=dapa --erase
> uisp -dprog=dapa --upload if=t.hex -dno-poll -v=3 --hash=32
>
>
>
> ------------------------------------------------------------------------
>
> #include <avr/io.h>
> #include <string.h>
>
>
> void xisa() {
>       // doesn't work
>       char aux[10] = {'A', 'A', 'A', 'A', 'A'} ;
>       if ('A' == aux[2]) PORTB |= 0X01;   // 1st led
> }
>
>
> void xisb() {
>       // doesn't work
>       char aux[] = "BBBBBBB";
>       if ('B' == aux[2]) PORTB |= 0X02;   // 2nd led
> }
>
> void xisc() {
>       // WORKS !!!!
>       char aux[10];
>
>       aux[0] = 'C';
>       aux[1] = 'C';
>       aux[2] = 'C';
>       aux[3] = 'C';
>       aux[4] = 'C';
>       aux[0] = '\0';
>
>       if ('C' == aux[2]) PORTB |= 0X04; // 3rd led
> }
>
>
> void xisd() {
>       // doesn't work
>       char aux[10];
>       aux[0] = '\0';
>       strcat(aux, "DDDDDDDD");
>       if ('D' == aux[2]) PORTB |= 0X08;   //4th led
> }
>
>
>
> void main(){
>       /***************************************************
>       *  I/O
>       ***************************************************/
>       outp(0xff,DDRB);   // PORT B = OUTPUT
>       outp(0xff,PORTB);  // WRITE PORT
>       PORTB = 0x00;      // BLANKS PORT
>
>       // TRY EACH OF THESE COMMANDS ALONE,
>       // and the problem persists
>       xisa();
>       xisb();
>       xisc();
>       xisd();
>
>
>
> }
>
>
>
> ------------------------------------------------------------------------
>
> #include <string.h>
> #include <stdio.h>
>
>
> void xisa() {
>       // doesn't work
>       char aux[10] = {'A', 'A', 'A', 'A', 'A'} ;
>       if ('A' == aux[2]) printf("\n1st led");
> }
>
>
> void xisb() {
>       // doesn't work
>       char aux[] = "BBBBBBB";
>       if ('B' == aux[2]) printf("\n2ndt led"); // 2nd led
> }
>
> void xisc() {
>       // WORKS !!!!
>       char aux[10];
>
>       aux[0] = 'C';
>       aux[1] = 'C';
>       aux[2] = 'C';
>       aux[3] = 'C';
>       aux[4] = 'C';
>       aux[0] = '\0';
>
>       if ('C' == aux[2]) printf("\n3rd led"); // 3rd led
> }
>
>
> void xisd() {
>       // doesn't work
>       char aux[10];
>       aux[0] = '\0';
>       strcat(aux, "DDDDDDDD");
>       if ('D' == aux[2]) printf("\n4th led");  //4th led
> }
>
>
>
> void main(){
>       /***************************************************
>       *  I/O
>       ***************************************************/
>       //outp(0xff,DDRB);   // PORT B = OUTPUT
>       //outp(0xff,PORTB);  // WRITE PORT
>       //PORTB = 0x00;      // BLANKS PORT
>
>
>       xisa();
>       xisb();
>       xisc();
>       xisd();
>
>
>
> }
>
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> avr-gcc-list mailing list
> address@hidden
> http://www.avr1.org/mailman/listinfo/avr-gcc-list

_______________________________________________
avr-gcc-list mailing list
address@hidden
http://www.avr1.org/mailman/listinfo/avr-gcc-list



reply via email to

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