Undefined reference when linking in Eclipse?

I’m trying to get some things that work in Linux (Ubuntu 16) set up to work under Windows 7, using Eclipse IDE and targetting the 3pi robot. My sample project to print to the 3pi’s screen and turn the motors compiles, builds to a hex and loads onto the robot. All great.

However, when I try to add functionality to read the calibrated sensors (I’m specifically using the function read_line_sensors_calibrated()) , I get a linking error related to PololuQTRSensors.cpp. The build output is below:

make all
Building file: …/assign1_3pi.cpp
Invoking: AVR C++ Compiler
avr-g++ -Wall -Os -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -funsigned-char -funsigned-bitfields -fno-exceptions -mmcu=atmega328p -DF_CPU=2000000UL -MMD -MP -MF"assign1_3pi.d" -MT"assign1_3pi.o" -c -o “assign1_3pi.o” “…/assign1_3pi.cpp”
…/assign1_3pi.cpp: In function ‘void calibrateLineSensors()’:
…/assign1_3pi.cpp:64: warning: comparison between signed and unsigned integer expressions
…/assign1_3pi.cpp:81: warning: unused variable ‘position’
…/assign1_3pi.cpp: At global scope:
…/assign1_3pi.cpp:30: warning: ‘void displayGraph(const unsigned int*)’ defined but not used
Finished building: …/assign1_3pi.cpp

Building target: lab1.elf
Invoking: AVR C++ Linker
avr-g++ -Wl,-Map,lab1.map,–cref -mrelax -Wl,–gc-sections -L"C:\libpololu-avr" -mmcu=atmega328p -o “lab1.elf” ./assign1_3pi.o -lpololu_atmega328p
C:\libpololu-avr\libpololu_atmega328p.a(PololuQTRSensors.o): In function PololuQTRSensors::~PololuQTRSensors()': /home/david/libpololu-avr/devices/atmega328p/../../src/PololuQTRSensors/../../src/PololuQTRSensors/PololuQTRSensors.cpp:780: undefined reference to__muluhisi3’
make: *** [lab1.elf] Error 1

14:12:30 Build Failed. 2 errors, 3 warnings. (took 342ms)

I’ve installed Eclipse, WinAVR, Pololu AVR Development Bundle and used this page(https://www.instructables.com/id/How-to-get-started-with-Eclipse-and-AVR/) as a guide for setup.

Any suggestions on how to resolve this error?

Hello.

I suspect you are missing a linker option, such as -lm to link the math library, but I am not sure how to change your settings in Eclipse to add that flag. If you know how to do that (or can find how to add linker options in Eclipse), could you give it a try? Also, can you post your main code here?

- Amanda

Hello! I can actually use terminal through Eclipse and ran the following (added the -lm)

avr-gcc -Wl,-Map,lab1.map,–cref -mrelax -Wl,–gc-sections -mmcu=atmega328p -o “lab1.elf” ./assign1_3pi.o -lpololu_atmega328p -lm

but got the same result. The code in question is below. We have a main function that’s pretty simple:

int main() {

	clear();
	print("Calibrate");
	lcd_goto_xy(0,1);
	print("Now");
	delay_ms(5000);
	calibrateLineSensors();
	while (true); // prevent exit from main
	return 0; // dead code
}

and this works fine without the call to calibrateLineSensors(), which is also defined within the file…

void calibrateLineSensors()
{
	// Initialize sensors.
	pololu_3pi_init(2000);

	const int TURN_SPEED = 40; // motor speed for turning
	const int TURN_STEPS = 20; // number of samples in a half turn
	const int SAMPLE_DELAY = 20; // ms between samples
	unsigned char button; // which button is pressed at the end

	// We will want to turn a little to the left, a little to the right
	// and then back to centre.
	int speeds[][2] =
	{
			{ -TURN_SPEED, +TURN_SPEED },  // turn left
			{ +TURN_SPEED, -TURN_SPEED },  // turn right (back to centre)
			{ +TURN_SPEED, -TURN_SPEED },  // keep turning right
			{ -TURN_SPEED, +TURN_SPEED },  // turn back to centre
	};
	static const int TURNS = sizeof(speeds) / sizeof(speeds[0]);

	for (size_t i = 0; i < TURNS; i++)
	{
		set_motors(speeds[i][0], speeds[i][1]);

		for (int i = 0; i < TURN_STEPS; i++)
		{
			calibrate_line_sensors(IR_EMITTERS_ON);
			delay_ms(SAMPLE_DELAY);
		}
	}

	set_motors(0,0);
	unsigned int sensor[5];
	read_line_sensors_calibrated(sensor, IR_EMITTERS_ON); //    read the sensors
	delay_ms(200); // wait a bit more*/
}

THAT function also works fine if we don’t call read_line_sensors_calibrated().

Our includes within the code are:

#include <pololu/orangutan>
#include <pololu/Pololu3pi.h>
#include <pololu/PololuQTRSensors.h>
#include <pololu/PololuWheelEncoders.h>

and within the Eclipse project we have included header files from:
C:/WinAVR020100110/avr/include
C:/WinAVR020100110/lib/gcc/avr/4.3.3/include
C:/WinAVR020100110/lib/gcc/avr/4.3.3/include-fixed

We were able to reproduce your error in the Eclipse IDE, and then realized that someone on the forum had a similar issue with AVR Studio 4 which also uses WinAVR. You can see our response here.

By the way, we noticed that your compile command includes “-DF_CPU=2000000UL”, which seems to specify a frequency of 2 MHz instead of 20 MHz like I would expect for a 3pi. You should probably make sure it is the correct value so your programs run correctly.

- Amanda

Thanks tremendously, I did the same as your previous poster did and it worked! And thanks for catching the clock frequency problem, missed a 0.

1 Like