Forum: Compiler & IDEs AVR-GCC Starthilfe


von Christian Schuster (Gast)


Lesenswert?

Hallo zusammen
Als Umsteiger von Win nach Linux schaffe ich so manche Hürde nicht. Es
geht um eine Applikation mit einem AVR. Um die die
"Entwicklungsumgebung" zu testen habe ich erst mal versucht ein vom
Netz geladenes Miniprogramm zu übersetzen und bin daran schon
gescheitert.

Randbedingungen:
Debian;
binutils-avr, gcc-avr, avr-libc, gdb-avr und uisp habe ich mir via
apt-get install xxx... vom Netz gesaugt, dabei wurden die
Verzeichnisse
/usr/avr/bin mit ar, as, ld, nm, ranlib, strip
/usr/avr/include mit den header files (ctype.h, stdio.h, ...)
/usr/avr/include/avr mit den MCU spezifischen header files (ioxx.h,
boot.h, ..)
/usr/avr/lib mit crtxxx.o, libc.a, ...
angelegt.
Die env Variable PATH ist in /etc/profile auf /usr/avr gesetzt.
mit echo $PATH erhalte ich:
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/usr/avr/

Erstes Testprogramm:
/*********************************************
* Chip type           : AT90S4433
* Clock frequency     : 4,000000 MHz
*********************************************/
#include <io.h>
//#include "/usr/avr/include/avr/io.h"

void delay_ms(unsigned short ms)
/* delay for a minimum of <ms> */
/* with a 4Mhz crystal, the resolution is 1 ms */
{
   unsigned short outer1, outer2;
      outer1 = 200;

      while (outer1) {
      outer2 = 1000;
      while (outer2) {
         while ( ms ) ms--;
         outer2--;
      }
      outer1--;
   }
}

void main(void)
{
   /* enable  PD5 as output */
   sbi(DDRD,PD5);
   while (1) {
      /* led on, pin=0 */
      cbi(PORTD,PD5);
      delay_ms(500);
      /* set output to 5V, LED off */
      sbi(PORTD,PD5);
      delay_ms(500);
   }
}

Dazugehöriges Makefile:
# makefile, written by guido socher
MCU=at90s4433
CC=avr-gcc
OBJCOPY=avr-objcopy
# optimize for size:
CFLAGS=-g -mmcu=$(MCU) -Wall -Wstrict-prototypes -Os -mcall-prologues
#-------------------
all: avrledtest.hex
#-------------------
avrledtest.hex : avrledtest.out
   $(OBJCOPY) -R .eeprom -O ihex avrledtest.out avrledtest.hex
avrledtest.out : avrledtest.o
   $(CC) $(CFLAGS) -o avrledtest.out -Wl,-Map,avrledtest.map
avrledtest.o
avrledtest.o : avrledtest.c
   $(CC) $(CFLAGS) -Os -c avrledtest.c
# you need to erase first before loading the program.
# load (program) the software into the eeprom:
load: avrledtest.hex
   uisp -dlpt=/dev/parport0 --erase  -dprog=dapa
   uisp -dlpt=/dev/parport0 --upload if=avrledtest.hex -dprog=dapa
-v=3
--hash=32
# here is a pre-compiled version in case you have trouble with
# your development environment
#load_pre: avrledtest_pre.hex
#  uisp -dlpt=/dev/parport0 --erase  -dprog=dapa
#  uisp -dlpt=/dev/parport0 --upload if=avrledtest_pre.hex -dprog=dapa
-dno-poll
-v=3 --hash=32
#-------------------
clean:
   rm -f *.o *.map *.out
#-------------------

das ergibt nach dem Aufruf von make:
avr-gcc -g -mmcu=at90s4433 -Wall -Wstrict-prototypes -Os
-mcall-prologues -Os -c
avrledtest.c
avrledtest.c:11:16: io.h: No such file or directory
avrledtest.c:32: warning: return type of 'main' is not `int'
avrledtest.c: In function `main':
avrledtest.c:34: warning: implicit declaration of function `sbi'
avrledtest.c:34: error: `DDRD' undeclared (first use in this
function)
avrledtest.c:34: error: (Each undeclared identifier is reported only
once
avrledtest.c:34: error: for each function it appears in.)
avrledtest.c:34: error: `PD5' undeclared (first use in this function)
avrledtest.c:37: warning: implicit declaration of function `cbi'
avrledtest.c:37: error: `PORTD' undeclared (first use in this
function)
make: *** [avrledtest.o] Error 1

das heißt doch schon mal <io.h> wird nicht gefunden.

Ersetze ich im Quellcode
//#include <io.h>
#include "/usr/avr/include/avr/io.h"
dann findet er zwar die header Dateien, aber nicht die Makros "sbi,
cbi".

avr-gcc -g -mmcu=at90s4433 -Wall -Wstrict-prototypes -Os
-mcall-prologues -Os -c
avrledtest.c
avrledtest.c:32: warning: return type of 'main' is not `int'
avrledtest.c: In function `main':
avrledtest.c:34: warning: implicit declaration of function `sbi'
avrledtest.c:37: warning: implicit declaration of function `cbi'
avr-gcc -g -mmcu=at90s4433 -Wall -Wstrict-prototypes -Os
-mcall-prologues -o
avrledtest.out -Wl,-Map,avrledtest.map avrledtest.o
avrledtest.o(.text+0x2e): In function `main':
/home/putzi/avr/avrledtest-0.1/avrledtest.c:34: undefined reference to
`sbi'
avrledtest.o(.text+0x38):/home/putzi/avr/avrledtest-0.1/avrledtest.c:37:
undefined reference to `cbi'
avrledtest.o(.text+0x48):/home/putzi/avr/avrledtest-0.1/avrledtest.c:40:
undefined reference to `sbi'
make: *** [avrledtest.out] Error 1

Die Warnung mit dem return value vom main stört mich zunächst nicht
weiter.
Irgendwo hab' ich gelesen daß neuere avr-libs Makros wie sbi, cbi
nicht mehr unterstützen.
Gibt's da Ersatz oder fügt man die dann selbst in die header ein?
Wo muß ich drehen damit die header auch mit #include <io.h> im
Quellcode gefunden werden?

Und für später wenn das alles mal laufen sollte, mit welcher Prog-SW
krieg ich das am einfachsten auf ein STK500 Board.

Ich freue mich auf eine aussagefähige Unterstützung und sag schon mal
danke.
Die ersten grauen Haare hab ich schon. Hoffentlich werden das mit dem
AVR und Linux nicht noch mehr;-))

Christian

von +-0 (Gast)


Lesenswert?

als macro aus meinen quellen (flag = uint8_t): ---------------------

#define set_bit(flag, bit) ((flag) |= (uint8_t) (1<<(bit)))
#define clear_bit(flag, bit) ((flag) &= (uint8_t) ~(1<<(bit)))



beispiel aus avr-libc/faq.html: ------------------------------------

#include <inttypes.h>
#include <avr/io.h>

void
set_bits_func_wrong (volatile uint8_t port, uint8_t mask)
{
    port |= mask;
}

void
set_bits_func_correct (volatile uint8_t *port, uint8_t mask)
{
    *port |= mask;
}

#define set_bits_macro(port,mask) ((port) |= (mask))

int main (void)
{
    set_bits_func_wrong (PORTB, 0xaa);
    set_bits_func_correct (&PORTB, 0x55);
    set_bits_macro (PORTB, 0xf0);

    return (0);
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Wenn io.h nicht gefunden wird, sollte der Pfad auf die Include-Dateien
in die Environmentvariable INCLUDE eingetragen werden.

  void main(void)

ist nicht standardkonform und wird zu recht bemängelt.

Betr. cbi etc. hilft vielleicht das hier:

http://www.mikrocontroller.net/forum/read-2-196924.html#196999

von Christian Schuster (Gast)


Lesenswert?

Hallo Rufus,
die Makros in deinem angegebenen link laufen. void main() ersetzt mit
int main(){...return 0;} auch klar. Nur die env var INCLUDE die jetzt:
/usr/avr/include/avr enthält (in diesem directory ist neben vielen
anderen header files auch io.h) bringt nichts wenn im Quellcode
#include <io.h> steht. Wenn ich aber direkt den Pfad mit #include
"/usr/avr/include/avr/io.h" hinschreibe, dann werden die defines wie
"DDRD, PD5, ..." referenziert. Mach ich da noch was verkehrt?
Trotzdem danke für die Hilfe. Auch den beiden anderen.
 Christian

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

Jo, das sollte ja auch...
1
#include <avr/io.h>

...sein!

Btw: int main() ist ebenfalls nicht konform, es muss dann schon int
main(void) sein...

von Christian Schuster (Gast)


Lesenswert?

Ja Patrick das war's auch. ...und natürlich steht int main(void), hab'
das zuvor bloß nicht hingeschrieben. C ist nicht sosehr das Problem,
aber sich mit Linux erst mal zurecht zu finden schon!
Herzlichen Dank.
Christian

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.