Author Topic: Why "Undefined Reference To" Errors  (Read 10216 times)

0 Members and 1 Guest are viewing this topic.

Offline ChrisMcCTopic starter

  • Jr. Member
  • **
  • Posts: 11
  • Helpful? 0
Why "Undefined Reference To" Errors
« on: January 28, 2012, 02:16:43 PM »
As a newbie working on understanding timers and interrupts, I'm trying to write a simple program.  It would set a timer running, run a continuous loop in main(), and toggle an LED every time the timer overflowed a number of times.

Unfortunately I keep getting "undefined reference to" errors for the three functions that I've called from timerx8.h.

The code is:

/*
 * LED.c
 *
 * Created: 15/09/2011 19:50:32
 *  Author: Chris
 */

#include <avr/io.h>
#include <avr/interrupt.h>
#include <timerx8.h>
#include "SoR_Utils.h"

int Overflow_Count = 0;
int LED_Status = 0;

void Timer_Overflow_Action ( void )
   {
   if ( Overflow_Count == 3000 )
      {
      if ( LED_Status == 0 )
         {
         PORT_OFF(PORTD, 7);//turn LED on
         LED_Status = 1;
         }
      else
         {
         PORT_ON(PORTD, 7);//turn LED off
         LED_Status = 0;
         }
      Overflow_Count = 0;
      }
   }


int main(void)
{
   timer0Init();
   timer0SetPrescaler( TIMER_CLK_DIV1 );

   configure_ports();
   LED_Status = 1;
   timerAttach( TIMER0OVERFLOW_INT, Timer_Overflow_Action );

   while(1)
    {
    }
}

Now, I don't get any errors about the timerx8.h file, so its seeing that.  Also, I've added the path to the directory where timerx8.h AND timerx8.c sit, into the Libraries Search Path section of the AVR/GNU C Linker options, in the Project Properties.  I'm using AVR Studio 5.

From what I know about C compiling, which is very little, the errors mean that it can't find the timerx8.c file.  Is that correct?  If it is, how do I point it to the location?

I know that the code probably doesn't look too pretty but I'm learning.  I'm happy to deal with my syntax and logic errors when they arise, so for now, I just want the thing to build as it is.

Thanks for reading, and any help will be greatly appreciated.

Chris

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: Why "Undefined Reference To" Errors
« Reply #1 on: January 28, 2012, 02:44:41 PM »
Generally "undefined reference to ..." errors are from the linker. I suspect you have a library or .o file somewhere that needs to be linked in, but I can't help more than that without seeing the makefile. Can you post that?

Joe

Edit: Sorry I missed the fact that you're using AS5. I don't use AVR Studio and I'm not familiar with its project files. If it produces a makefile you could post I'd be happy to take a look at that.

BTW, AS5 is spoken of badly on the AVRFreaks forum. Mostly people there recommend you to stay with AS4 for till they get the bugs worked out of 5.
« Last Edit: January 28, 2012, 02:47:28 PM by joe61 »

Offline ChrisMcCTopic starter

  • Jr. Member
  • **
  • Posts: 11
  • Helpful? 0
Re: Why "Undefined Reference To" Errors
« Reply #2 on: January 28, 2012, 03:23:36 PM »
Joe

Thanks for the heads-up on AS5.  I'm going to download and install v4 and see how the code runs in that, before I ask you, or anyone, to try debugging makefiles and the like.

I'll post back with whatever happens.

Thanks again.

Chris

Offline Gertlex

  • Supreme Robot
  • *****
  • Posts: 742
  • Helpful? 23
  • Nuclear Engineer Roboticist
Re: Why "Undefined Reference To" Errors
« Reply #3 on: January 28, 2012, 03:58:13 PM »
If you put function prototypes in timerx8.h, that might fix the problem.

This stuff is definitely confusing :)
I

Offline ChrisMcCTopic starter

  • Jr. Member
  • **
  • Posts: 11
  • Helpful? 0
Re: Why "Undefined Reference To" Errors
« Reply #4 on: January 29, 2012, 07:10:40 AM »
Well I've trying to get past this through various means, and getting nowhere.

I uninstalled AS5 and installed AS4 plus the toolchain.  Then I started a new project with the original LED.c file.  When I try to build it I get the same three 'undefined reference to..' errors.

I've been adding folders to the library search paths like a mad thing, and telling it to link with every available object.  No joy there either, except that at one point I lost the error for the timerAttach function.  Wierd.  Anyway, I'm back with the original three.

I tried adding timerx8.c as a source file and got a different error.

    make: *** No rule to make target `..//D/Applications/Robotics/avrlib/timerx8.c', needed by `timerx8.o'.  Stop.

I tried adding timerx8.c in the 'Other Files' section and got the three original errors again.

It looks like the issue is with the makefile but I don't know enough about them to debug it.  Shouldn't it be the case that AVR Studio populates the makefile itself from what you code and the options that you choose in the GUI?

I'll put the makefile contents in the next post, to try to keep things tidy.  If anyone can help I will be in your debt.

Thanks

Chris

EDIT
Just noticed that there are TWO makefiles!  Is this right?  One is in the top level project directory, where the LED.c file is.  The other is in the /default  directory.
« Last Edit: January 29, 2012, 07:14:03 AM by ChrisMcC »

Offline ChrisMcCTopic starter

  • Jr. Member
  • **
  • Posts: 11
  • Helpful? 0
Re: Why "Undefined Reference To" Errors
« Reply #5 on: January 29, 2012, 07:19:13 AM »
Both makefiles seem to be identical at least, so here's what's in them.

###############################################################################
# Makefile for the project LED
###############################################################################

## General Flags
PROJECT = LED
MCU = atmega168
TARGET = LED.elf
CC = avr-gcc

CPP = avr-g++

## Options common to compile, link and assembly rules
COMMON = -mmcu=$(MCU)

## Compile options common for all C compilation units.
CFLAGS = $(COMMON)
CFLAGS += -Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d

## Assembly specific flags
ASMFLAGS = $(COMMON)
ASMFLAGS += $(CFLAGS)
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2

## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS +=  -Wl,-Map=LED.map


## Intel Hex file production flags
HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature

HEX_EEPROM_FLAGS = -j .eeprom
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings


## Include Directories
INCLUDES = -I"D:\Applications\Robotics\avrlib" -I"D:\Applications\Robotics\WinAVR-20100110" -I"D:\Applications\Robotics\Atmel\AVR Tools\AVR Toolchain\include" -I"D:\Applications\Robotics\Atmel\AVR Tools"

## Library Directories
LIBDIRS = -L"D:\Applications\Robotics\Atmel\AVR Tools\AvrStudio4" -L"D:\Applications\Robotics\Atmel\AVR Tools\AVR Toolchain" -L"D:\Applications\Robotics\Atmel\AVR Tools\AVR Toolchain\lib" -L"D:\Applications\Robotics\avrlib\conf" -L"D:\Applications\Robotics\WinAVR-20100110" -L"D:\Applications\Robotics\avrlib"

## Libraries
LIBS = -lc -lm -lprintf_flt -lprintf_min -lscanf_flt -lscanf_min -lavr-sim -lbfd -lgmp -liberty -lmpc -lmpfr -lavr-sim -lbfd -lgmp -liberty -lmpc -lmpfr

## Objects that must be built in order to link
OBJECTS = LED.o

## Objects explicitly added by the user
LINKONLYOBJECTS =

## Build
all: $(TARGET) LED.hex LED.eep LED.lss size

## Compile
LED.o: ../LED/LED.c
   $(CC) $(INCLUDES) $(CFLAGS) -c  $<

##Link
$(TARGET): $(OBJECTS)
    $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)

%.hex: $(TARGET)
   avr-objcopy -O ihex $(HEX_FLASH_FLAGS)  $< $@

%.eep: $(TARGET)
   -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0

%.lss: $(TARGET)
   avr-objdump -h -S $< > $@

size: ${TARGET}
   @echo
   @avr-size -C --mcu=${MCU} ${TARGET}

## Clean target
.PHONY: clean
clean:
   -rm -rf $(OBJECTS) LED.elf dep/* LED.hex LED.eep LED.lss LED.map


## Other dependencies
-include $(shell mkdir dep 2>NUL) $(wildcard dep/*)


Anything jump out at anyone?

Thanks

Chris

Offline ChrisMcCTopic starter

  • Jr. Member
  • **
  • Posts: 11
  • Helpful? 0
Re: Why "Undefined Reference To" Errors
« Reply #6 on: January 29, 2012, 08:35:23 AM »
Another update.

After doing more searching I came across references to AVR Studio putting flags in the wrong order in the makefiles.  So I canged the Linker Flags section from

## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS +=  -Wl,-Map=LED.map

to

## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS +=  -Map=LED.map,-WI

When I rebuilt the project I only had two errors.  The undefined reference to timerAttach was gone!  I rebuilt yet again and I was back to three errors!

This just seems bizarre.

You can imagine that when I had a free weekend and had planned on working on coding, to have spent a day trying to sort out this has been incredibly frustrating.

Do I now have to learn all about makefiles and how to write them myself, just to be able to produce new projects?

Chris

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: Why "Undefined Reference To" Errors
« Reply #7 on: January 29, 2012, 10:04:09 AM »
I booted Windows and tried building a small LED blinking program. The makefile I wound up with differs from yours in several respects. I'm guessing that Windows didn't really clean things out when you uninstalled AS5. If it was me I'd uninstall again, manually remove all the directories that got left behind, and maybe take a look at the registry to be sure there aren't any bad memories from the previous install (This is one reason I don't like working with Windows).

In particular, the rule
Code: [Select]
## Compile
LED.o: ../LED/LED.c
   $(CC) $(INCLUDES) $(CFLAGS) -c  $<

Is different than the makefile I got. Mine was

Code: [Select]
## Compile
led.o: ../led.c
$(CC) $(INCLUDES) $(CFLAGS) -c  $<

Which makes me think it's looking in the wrong directory. Or maybe you just set your project up differently, again I'm not familiar with AS. But it looks like it defaults to the makefile being in a subdirectory under the source. Yours has it in another subdirectory under the source.

I don't think you need all the libraries you added (although I'm not sure AS isn't my bag). Try adding a rule  like the following somewhere in the file (with other similar rules).

Code: [Select]
%.o: %.c
        $(CC) $(INCLUDES) $(CFLAGS) -c $<

This is a general rule that tells make how to turn a .c file into a .o file. That really should be built into make, not sure what the problem is there. If you copy and paste that, be sure to change the leading spaces on the second line to a tab character.

I'm guessing that you're the victim of Windows' no-cleanup-when-uninstalling policy though.

Hope this helps, if not, try asking about this at http://www.avrfreaks.net in the "AVR GCC" forum. Someone there will be able to help.

Joe

Offline ChrisMcCTopic starter

  • Jr. Member
  • **
  • Posts: 11
  • Helpful? 0
Re: Why "Undefined Reference To" Errors
« Reply #8 on: January 29, 2012, 10:38:50 AM »
Many thanks for your efforts and advice Joe.  I'll give it a try, as well as embarking on trying to understand makefiles!

After trying a squillion and one other things I followed Gertlex's advice, and copied the functions from timerx8.c to timerx8.h.  Then there was a long process of copying in other functions and variables in them that weren't recognised, until the program built successfully.  We'll see where that takes me but it's not an approach that I'd want to take all the time.

If anyone else has any ideas, please let me know.

Thanks again.

Chris

Offline Gertlex

  • Supreme Robot
  • *****
  • Posts: 742
  • Helpful? 23
  • Nuclear Engineer Roboticist
Re: Why "Undefined Reference To" Errors
« Reply #9 on: January 29, 2012, 10:59:04 AM »
You just need to copy the function prototype, not the function itself... or that was my guess, anyways. (But you do have to make sure all the variables being used are accessible)  Basically, the compiler compiles each C file individually, and only sees the included .h files in that .c file, not other .c file, generally.

Webbot describes this really nicely in this thread: http://www.societyofrobots.com/robotforum/index.php?topic=14907
I

Offline joe61

  • Supreme Robot
  • *****
  • Posts: 417
  • Helpful? 16
Re: Why "Undefined Reference To" Errors
« Reply #10 on: January 29, 2012, 11:54:13 AM »
After trying a squillion and one other things I followed Gertlex's advice, and copied the functions from timerx8.c to timerx8.h.  Then there was a long process of copying in other functions and variables in them that weren't recognised, until the program built successfully.  We'll see where that takes me but it's not an approach that I'd want to take all the time.

Yeah, that's not the way it should go. The link to Webbot's explanation gives a good description of why. I think it's the makefile. I'm still leaning towards leftover cruft from AS5 being in the way.

For whatever it's worth, I wrote a couple test files, led.c and targetx8.c. led.c is a copy of the code you posted. My targetx8.c is just a bunch of stub functions to give the linker something to be happy with. There's also a targetx8.h file. This makefile compiles them all happily and produces a hex file:

Code: [Select]
DEVICE = atmega168
AVRDUDE_DEVICE = m168

PROG = -c usbtiny -P usb

CFLAGS=-g -Wall -mcall-prologues -mmcu=$(DEVICE) -Os
CC=avr-gcc
OBJ2HEX=avr-objcopy
LDFLAGS=-Wl,-gc-sections -Wl,-relax

AVRDUDE=avrdude
TARGET=led
OBJECT_FILES=led.o timerx8.o
SRC_FILES=$(OBJECT_FILES:%.o=%.c)

all: $(TARGET).hex

clean:
        rm -f *.o *.hex *.obj *.hex

%.hex: %.obj
        $(OBJ2HEX) -R .eeprom -O ihex $< $@

%.obj: $(OBJECT_FILES)
        $(CC) $(CFLAGS) $(OBJECT_FILES) $(LDFLAGS) -o $@

program: $(TARGET).hex
        $(AVRDUDE) -p $(AVRDUDE_DEVICE) $(PROG) -U flash:w:$(TARGET).hex

That's using a command line programmer called avrdude, but that makes no difference for building it. The important parts are below the all: target

I believe you can setup AS4 to use an external makefile, try this makefile (you'll probably have to modify it a bit to add project specific information).

And take a look at the AVRFreaks gcc forum.

Joe

Offline ChrisMcCTopic starter

  • Jr. Member
  • **
  • Posts: 11
  • Helpful? 0
Re: Why "Undefined Reference To" Errors
« Reply #11 on: January 29, 2012, 02:09:06 PM »
Joe

I'll have a look at your file, thanks.  It should help me in understanding makefiles.  I have been on the AVRFreaks forums as well as here.  It's not a complaint to say that there and here there are an embarrasment of riches, so to speak, with so much information.

As things stand I've managed to get my LED blinking so I know that I've programmed a timer and hung an interrupt off it successfully.  That means I can relax abit and spend more time reading and learning, so I will be making use of the forums on  both sites.

Gertlex, that's what was confusing me.  The functions that were causing errors were prototyped in the header file.  So there was a line saying

void timer0Init( void );

The other two problem functions were there too.  It wasn't until I copied the functions into the header file that the program built.

Thanks again to both of you.  With your help I've managed to accomplish the goal I'd set myself this weekend.  That, in my book, is a result.

Chris

 


Get Your Ad Here

data_list