Defeated by undefined reference to ...

Go To Last Post
17 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello everyone,

 

I know there were many posts around the issue but i actually fought through all possible solutions and either i'm missing something obvious, or.. i have been defeated by avr freakness, but bare with me for a moment :)

 

Lets begin with small project for ATMega1284 in C with everything in one project folder. Everything works fine, chinese pcb carefully soldered comes to life spewing some data over usart and blinking leds - we are fine.

 

Then i wanted to include two libraries i was trying share across another project, and i got dreaded undefined reference to error - more specifically :

 

 

To my excuse - I'm mostly java programmer with bit of hardware hobby.. so I might miss some obvious for C people things.. - don't stone me right away if did so.

 

Right click menu - add as link - listed in project files - near main C file.

 

So we have following structure :

 

main file, Compass_IO_proto.c which includes GENET_HW_DEF.h and later on GENET_ISR_LIB.h and finally ds18b20_TIMER_DRIVER.h <- culprit ?

 

//
//  Compass_IO_proto.c
//
//  Created: 04/15/19 11:52:18
//  Author: byt3
//

#define LF 13
#define CR 10
#define etl 15
// etl[14] = 31 - input rs buffer overflow.
#define errtresh 3
#define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))

#include "GENET_HW_DEF.h" // include hardware definitions
#include <avr/io.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <util/delay.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "GENET_ISR_LIB.h"
#include "ds18b20_TIMER_DRIVER.h"

[...]

int main(void)
{
    hw_init_states();
    CMBset_out(WATER_D10);
    CMBset_out(WATER_D9);

    [...]

}

GENET_HW_DEF.h :

 

/*
* COMPASS_Hardware_Definitions

* Created: 2019-07-20 18:48:06
*  Author: Byt3
*/
#include <avr/io.h>

#ifndef GENET_HW_DEF
#define GENET_HW_DEF

#define sbi(port, pin) (port) |= (1<<pin)

[...]

#define ONE_WIRE
#ifdef ONE_WIRE
	#include "ds18b20_TIMER_DRIVER.h"
	#define ONE_WIRE_RX C,7
	#define ONE_WIRE_TX C,6
#endif

// define pins
#define STATUS_LED B,7
[...]
#define UART_TX1_BUFFER_SIZE GENET_USART_1
#endif

extern void hw_init_states();
#endif /* GENET_HW_DEF */
//
//  GENET_HW_DEF.c
//
//  Created: 2019-07-28 14:42:52
//   Author: Byt3
//

// runtime initialization
#include "GENET_HW_DEF.h"
#include "ds18b20_TIMER_DRIVER.h"

void hw_init_states(){

	DDRA=0x00;
	PORTA=0x00;
	DDRB=0x00;
	PORTB=0x00;
	[...]

	#ifdef ERROR_LED
	CMBset_out(ERROR_LED);
	#endif

	#ifdef GENET_USART_0
	CMBset_out(GENET_USART_0LINESW);
	CMBcbi(GENET_USART_0LINESW);
	#endif

	#ifdef GENET_USART_1
	CMBset_out(GENET_USART_1LINESW);
	CMBcbi(GENET_USART_1LINESW);
	#endif

	#ifdef ONE_WIRE
	  ds18b20_init();
	#endif

	// ADC section

[...]
	ADCSRA = 0b11110111;
	#endif
}
//
// ds18b20_TIMER_DRIVER.h
//

#ifndef DS18B20_H_
#define DS18B20_H_

#include <avr/io.h>

//commands
#define DS18B20_CMD_CONVERTTEMP 0x44
#define DS18B20_CMD_RSCRATCHPAD 0xbe
#define DS18B20_CMD_WSCRATCHPAD 0x4e
#define DS18B20_CMD_CPYSCRATCHPAD 0x48
#define DS18B20_CMD_RECEEPROM 0xb8
#define DS18B20_CMD_RPWRSUPPLY 0xb4
#define DS18B20_CMD_SEARCHROM 0xf0
#define DS18B20_CMD_READROM 0x33
#define DS18B20_CMD_MATCHROM 0x55
#define DS18B20_CMD_SKIPROM 0xcc
#define DS18B20_CMD_ALARMSEARCH 0xec

#define OW_NULL 0
#define OW_RESET 1
#define OW_WRITEBIT 2
#define OW_READBIT 3
#define OW_WRITEBYTE 4
#define OW_READBYTE 5
#define OW_READTEMP_WHATEVER 6

//functions
extern void ds18b20_gettemp();
extern void ds18b20_init();
extern uint8_t ds18b20_is_free();
extern uint8_t ds18b20_get_response_bit();
extern uint8_t ds18b20_get_response_byte();
extern uint16_t ds18b20_get_response_dbyte();

#endif
/*
ds18b20_TIMER_DRIVER.c
*/
#include "GENET_HW_DEF.h" // include hardware definitions <- I NEED TO IMPORT THIS AS PREVIOUS IMPORTS ARE NOT VISIBLE ON .c LEVEL!

#ifdef ONE_WIRE

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#include "ds18b20_TIMER_DRIVER.h"

static volatile uint8_t topfunc = OW_NULL;
static volatile uint8_t lastfunc =OW_NULL;
static volatile uint8_t function =OW_NULL;
[...]

// ds18b20_init
void ds18b20_init(){
	CMBset_in(ONE_WIRE_RX);
	CMBset_out(ONE_WIRE_TX);
	// Set the Timer1 Mode to CTC
	TCCR1A |= (1 << WGM11);
	OCR1A = 0xFFFF;
	TIMSK1 |= (1 << OCIE1A);    //Set the ISR COMPA vect
	// set prescaler to 64 - 312500Hz - 1 tick = 3.2 us
	TCCR1B |= (1 << CS11);
	TCCR1B |= (1 << CS10);
}

[...]

#endif

 

and the error is :

 

Severity    Code    Description    Project    File    Line
Error        undefined reference to `ds18b20_init'    Compass_IO_proto    D:\_SVN\Compass\AVR\Compass_IO_proto\Compass IO_proto\GENET_HW_DEF.c    58

 

which is exactly here :

 

#ifdef ONE_WIRE
	  ds18b20_init();
	#endif
	

    Invoking: AVR/GNU Linker : 5.4.0
        GENET_HW_DEF.o: In function `hw_init_states':
D:\_SVN\Compass\AVR\Compass_IO_proto\Compass IO_proto\GENET_HW_DEF.c(58,1): error: undefined reference to `ds18b20_init'
collect2.exe(0,0): error: ld returned 1 exit status
        make: *** [Compass_IO_proto.elf] Error 1
        "C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe" -o Compass_IO_proto.elf  ds18b20_TIMER_DRIVER.o GENET_ISR_LIB.o uart.o GENET_HW_DEF.o Compass_IO_proto.o   -Wl,-Map="Compass_IO_proto.map" -Wl,--start-group -Wl,-lm  -Wl,--end-group -Wl,-L"D:\_svn\asm\AVR\avrlib"  -Wl,--gc-sections -mrelax -mmcu=atmega1284p -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega1284p"  
D:\_SVN\Compass\AVR\Compass_IO_proto\Compass IO_proto\Debug\Makefile(154,1): error: recipe for target 'Compass_IO_proto.elf' failed
        The command exited with code 2.
    Done executing task "RunCompilerTask" -- FAILED.

 

Ideas ?

 

This topic has a solution.

Intelligence is not everything, wisdom is more than that.

Last Edited: Sat. Nov 2, 2019 - 01:42 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is ONE_WIRE defined when "ds18b20_TIMER_DRIVER.c" is compiled?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes - in GENET_HW_DEF.h as pictured :


#define ONE_WIRE
#ifdef ONE_WIRE
	#include "ds18b20_TIMER_DRIVER.h"
	#define ONE_WIRE_RX C,7
	#define ONE_WIRE_TX C,6
#endif

 

Intelligence is not everything, wisdom is more than that.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

bajtec wrote:

Yes - in GENET_HW_DEF.h as pictured :

 

Ok, but you didn't include this file in ds18b20_TIMER_DRIVER.c before the #ifdef, so it's not defined there.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

So even if I include it in main file that does not implicate having it in c file ? .H definitions/values are visible only in C file directly including them ?

[UPDATE]

 

Ok it did the trick = i'll face few other issues but at least it works. - i just learned something about C :)

 

Thanks!

Intelligence is not everything, wisdom is more than that.

Last Edited: Fri. Nov 1, 2019 - 09:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Now i'm getting

Warning        implicit declaration of function 'ds18b20_reset_step' [-Wimplicit-function-declaration]    Compass_IO_proto    D:\_SVN\Compass\AVR\GENET_ISR\ds18b20_TIMER_DRIVER.c    65

 

Hmm - why if I include header ?

 

[solved]

 

You need to define static functions ( not externalized )  inside declarations in C file (like variables) so those are not encountered as implicit declarations.

Intelligence is not everything, wisdom is more than that.

Last Edited: Fri. Nov 1, 2019 - 09:30 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In

ds18b20_TIMER_DRIVER.c

Change 

#ifdef ONE_WIRE

To: 

 

#ifndef ONE_WIRE

#define ONE_WIRE

If the facts don't fit the theory, change the facts. ALBERT EINSTEIN

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bajtec wrote:
.H definitions/values are visible only in C file directly including them ?

This is a standard 'C' question - nothing specific to AVR or Atmel Studio.

 

What a #define does is, effectively, just paste the entire content of the specified file, verbatim, at the point of that #include.

 

So stuff from a header is only visible in a compilation unit if it has been #included in that compilation unit - possibly via nested #includes.

 

To see the result of preprocessing - ie, what the compiler itself actually sees - use the --save-temps option.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bajtec wrote:
implicit declaration of function 'ds18b20_reset_step' [-Wimplicit-function-declaration] 

The 'C' programming language requires that everything must be declared before it is used - again, not specific to AVR or Atmel Studio.

 

If you don't explicitly provide a declaration (eg, a prototype), the compiler may provide a default - or "implicit" - declaration.

 

The warning just tells you that this has happened.

 

Note that the "[-Wimplicit-function-declaration]" at the end is the option which would disable this warning.

 

If you put "Wimplicit-function-declaration" (ie, without the hyphen prefix) into google, it will get you the documentation on that option:

 

https://www.google.com/search?q=Wimplicit-function-declaration  -->  https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

 

 

 

-Wimplicit-function-declaration (C and Objective-C only)

Give a warning whenever a function is used before being declared. In C99 mode (-std=c99 or -std=gnu99), this warning is enabled by default and it is made into an error by -pedantic-errors. This warning is also enabled by -Wall.

-Wimplicit 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

BoltSwith wrote:

In

ds18b20_TIMER_DRIVER.c

Change 

#ifdef ONE_WIRE

To: 

 

#ifndef ONE_WIRE

#define ONE_WIRE

 

but that defeats the point of defining modules as it will always be included ?

 

Anyway :)

 

Thanks - I think I'll be able to handle it from now on :) Thank you all for prompt and merit support :)

Intelligence is not everything, wisdom is more than that.

Last Edited: Fri. Nov 1, 2019 - 09:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A DS18B20 is an inexpensive three-terminal TO-90 temperature sensor.   The terminals are Vcc (+3.3--+5), gnd, and data.  Data has a 4.7K ohm pull-up resistor connected to Vcc.  Data is a bi-directional line that uses precise timing to primarily send temperature bits from the sensor to the CPU.    Each DS18b20 sensor is manufactured with a unique 64-bit ID number.

 

Does your device use one of these?  If not, then remove all references in the code to DS18B20.    If there is one present, you could use any of the many libraries around for DS18B20. 

 

This whole .h file business/madness in C programming is a left-over from the late-1960s when computer files had to have tiny sizes.  It causes endless grief.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

bajtec wrote:
but that defeats the point of defining modules as it will always be included ?

No, if doesn't.

 

Again, standard 'C' stuff - called "Include Guards" or "Header Guards".

 

Cliff explained it a couple of weeks ago:

 

https://www.avrfreaks.net/commen...

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Simonetta wrote:
This whole .h file business/madness in C programming is a left-over from the late-1960s when computer files had to have tiny sizes. 

Not really.

 

It's about making your code modular - which is an entirely up-to-date good practice.

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Simonetta wrote:
This whole .h file business/madness in C programming is a left-over from the late-1960s when computer files had to have tiny sizes.  It causes endless grief.
what utter nonsense. You could train chimps to understand C linkage. Anyone who can't grasp such trivial concepts should switch from programming to knitting (actually that could be beyond them too).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Knitting is complicated... but good modular design is worth doing, and with guard statements, there's no issue. Monolithic files are a pain in the fundement.

 

Neil

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Simonetta wrote:
This whole .h file business/madness in C programming is a left-over from the late-1960s when computer files had to have tiny sizes.  It causes endless grief.
what utter nonsense. You could train chimps to understand C linkage. Anyone who can't grasp such trivial concepts should switch from programming to knitting (actually that could be beyond them too).

Actually I can understand quite well that switching from Java or C# to C will be a little tricky in that respect. In Java and C# you just implement your class in the proper namespace and you're all set to reference it in other classes/modules. It would have been nice if C supported that. I never like creating redudant pieces of code and with header files that is partially what you do.

 

But sure, after a few years you do get used to it...

/Jakob Selbing

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jaksel wrote:
It would have been nice if C supported that.
Couldn't find anything like that in the forthcoming C2X.

In-lieu of, GObject?

jaksel wrote:
I never like creating redudant pieces of code and with header files that is partially what you do.
Then tools other than the compiler (conditional compilation?)

 


ISO/IEC JTC1/SC22/WG14 - C via ISO/IEC JTC1/SC22/WG14 - C: Approved standards

C Programming/GObject - Wikibooks, open books for an open world

Conditional Compilation Options | cmake-compile-features(7) — CMake 3.16.0-rc3 Documentation

MSBuild Conditional Constructs - Visual Studio 2015 | Microsoft Docs

 

"Dare to be naïve." - Buckminster Fuller