Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

undefined reference to `initUsart' #19

Open
alkopop79 opened this issue May 17, 2016 · 11 comments
Open

undefined reference to `initUsart' #19

alkopop79 opened this issue May 17, 2016 · 11 comments

Comments

@alkopop79
Copy link

I'm trying to upload a serial example and when trying to compile I get these errors:

alkopop79$ avr-gcc -g -mmcu=atmega328p -o serial.elf serial.o
serial.o: In function main': /Users/alkopop79/Documents/AVR/serial/serial.c:9: undefined reference toinitUsart'
/Users/alkopop79/Documents/AVR/serial/serial.c:10: undefined reference to printString' /Users/alkopop79/Documents/AVR/serial/serial.c:13: undefined reference torecieveByte'
/Users/alkopop79/Documents/AVR/serial/serial.c:14: undefined reference to `transmitByte'
collect2: error: ld returned 1 exit status

I wonder what am I doing wrong? I'm using avrdude in Terminal (OS X) and an Arduino Nano board. So far I have managed to upload the Blink example successfully.

@rithma
Copy link

rithma commented May 17, 2016

I remember the same thing happening to me.
It looks like you are forgetting to include USART.c in your command line. Not sure what serial.c you're working with, but if it does an #include "USART.h", give this a try.

avr-gcc -g -mmcu=atmega328p -o serial.c USART.c serial.o

I'm still a beginner so if that doesnt work, ask the AVRFreaks forum. They usually respond within a couple hours....

/e

@alkopop79
Copy link
Author

Thank you! Do I need to add USART.h as well? I did this:

avr-gcc -g -Os -DF_CPU=16000000UL -mmcu=atmega328p -c serial.c USART.c USART.h

then

avr-gcc -g -mmcu=atmega328p -o serial.elf serial.o

Do I need to add USART.elf and USART.o?

@alkopop79
Copy link
Author

Scusi, here's the main file:

#include <avr/io.h>
#include <util/delay.h>
#include "pinDefines.h"
#include "USART.h"

int main(void){
char serialCharacter;

initUsart();
printString("test\r\n");

while(1){
    serialCharacter=recieveByte();
    transmitByte(serialCharacter);
    }
    return(0);
}

USART.h, USART.c and pinDefines.h are in the same directory.

@hexagon5un
Copy link
Owner

The code looks fine -- you're just having trouble with the compiling/linking.

If you want to do the compilation by hand, the easiest way to go is to make sure that all the files you need (.h and .c) are all in the same directory. This works great for small personal projects.

Then you can compile simply with avr-gcc -Os -Wall -DF_CPU=16000000UL -DBAUD=9600UL -mmcu=atmega328p *.c -o serial.o

where if you want to be explicit, you can list out all the something.c files in place of the *.c

Because I reuse the serial libraries all over the place, I kept them in one place and linked to them. That ends up being all sorts of hassle -- you need to use the -I flag to tell the compiler where the .h files are located, and you need to specify a full path to the corresponding source files.

That, plus the other compilation options that are nice to use on the AVR platform, lead me to write up a makefile and use make for the book. It's a bit opaque for the beginner, which I don't like, but it should work more easily.

If I were re-doing it, I would consider simply copying the pinDefines.h and the USART.c and .h files into every directory that uses them. (You can do that yourself.) It's a horrible duplication of code, that makes any changes difficult to manage, but it's more straightforward.

@alkopop79
Copy link
Author

Thank you for you reply, Elliot! I'm loving the book, thank you!!!

If I were re-doing it, I would consider simply copying the pinDefines.h and the USART.c and .h files into every directory that uses them.

Please don't do that. I like the way it is. Of course, it took me some time and research to figure out that I needed to add the files but this is how you learn. Again, I love the book, don't change a thing!

@alkopop79
Copy link
Author

I've been trying to compile this project for days with no success. I cannot progress in the book if I can't compile these files. I've been trying to find information about compiling multiple files or at least some AVR tutorials with project files and there's hardly anything. I've tried

avr-gcc -Os -Wall -DF_CPU=16000000UL -DBAUD=9600UL -mmcu=atmega328p *.c -o serial.o

and it yields tons of errors:

alkopop79$ avr-gcc -Os -Wall -DF_CPU=16000000UL -DBAUD=9600UL -mmcu=atmega328p *.c -o serial.o
serial2.c: In function 'main':
serial2.c:10:1: warning: implicit declaration of function 'initUsart' [-Wimplicit-function-declaration]
 initUsart();
 ^
serial2.c:14:2: warning: implicit declaration of function 'recieveByte' [-Wimplicit-function-declaration]
  serialCharacter=recieveByte();
  ^
/var/folders/gw/2wc3kcqn7msdklf1hxdbyl4w0000gn/T//ccv7O3QW.o: In function `main':
serial2.c:(.text.startup+0x0): undefined reference to `initUsart'
serial2.c:(.text.startup+0xc): undefined reference to `recieveByte'
collect2: error: ld returned 1 exit status

Could anyone explain properly how to compile multiple files?

@baldowl
Copy link

baldowl commented May 23, 2016

Fix those typos: initUSART(), not initUsart(); and receiveByte(), not recieveByte().

@alkopop79
Copy link
Author

How embarrassing, thank you!

@sametron90
Copy link

sametron90 commented Apr 6, 2017

Hi,

I am having a similar issue. Here is whats happening:

  • I am using USBasp
  • I am using ATMega 328p
  • I have been able to load blink examples usccesfully
  • USART.c, USART.h, pinDefines.h are all in the same folder where serialLoopback.c is in.
  • As we can see from the attached terminal screenshot, I am able to create *.o file, but error happens when trying to create *.elf file.

serialLoopback.c:

#include <avr/io.h>
#include <util/delay.h>
#include "pinDefines.h"
#include "USART.h"

int main(void) {
char serialCharacter;
LED_DDR = 0xff;
initUSART();
printString("Hello World!\r\n");
while (1) {
serialCharacter = receiveByte();
transmitByte(serialCharacter);
LED_PORT = serialCharacter;
}
return (0);
}

capture

@rithma
Copy link

rithma commented Apr 7, 2017

@sametron90 It looks like you need to point your linker to all the corresponding C files.
Try this:
avr-gcc -g -Os -mmcu=atmega328p -c serialLoopback.c USART.c serialLoopback.o

this will combine the code from serialLoopback.c and USART.c and spit it out into 1 object file.

also, before any of your #includes, write the line:

#define F_CPU 1000000UL

this will tell the chip how fast to run before calling any of the delay functions.

@sametron90
Copy link

@rithma Thanks for the input, I think I got what you are conveying. I will try to include all the associated files and do the command.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants