Petrus K.
Petrus K.

Reputation: 840

undefined reference to ... - linking issues?

I don't know what I'm getting the following error:

proc1.o: In function `procEx1':
/cygdrive/c/armprojects/projekt/motor/proc1.c:45: undefined reference to `motorTest_test'
collect2: ld returned 1 exit status
make: *** [main.hex] Error 1

I've checked the following threads on this issue:

This is my output:

13:46:46 **** Build of configuration Default for project motor ****
make all 
make[1]: Entering directory `/cygdrive/c/armprojects/projekt/motor/startup'
rm -f .depend 
arm-elf-gcc -c -mcpu=arm7tdmi  -I . -DEL -DGCC   -mthumb-interwork -DLPC2148  -Os -    gdwarf-2 -Wall -Wcast-align -Wcast-qual -Wimplicit -Wnested-externs -Wpointer-arith -Wswitch     -Wreturn-type  -Wa,-ahlms=consol.lst -o consol.o consol.c
arm-elf-gcc -c -mcpu=arm7tdmi  -I . -DEL -DGCC   -mthumb-interwork -DLPC2148  -Os -    gdwarf-2 -Wall -Wcast-align -Wcast-qual -Wimplicit -Wnested-externs -Wpointer-arith -Wswitch -Wreturn-type  -Wa,-ahlms=framework.lst -o framework.o framework.c
framework.c: In function 'exceptionHandlerInit':
framework.c:201: warning: pointer targets in assignment differ in signedness
arm-elf-gcc -c -mcpu=arm7tdmi  -I . -DEL -DGCC   -mthumb-interwork -DLPC2148  -x           assembler-with-cpp -gstabs -Wa,-alhms=startup.lst -o startup.o startup.S
arm-elf-ar cr libea_startup_thumb.a consol.o framework.o startup.o
arm-elf-ranlib libea_startup_thumb.a
make[1]: Leaving directory `/cygdrive/c/armprojects/projekt/motor/startup'
make[1]: Entering directory `/cygdrive/c/armprojects/projekt/motor/LCD'
rm -f .depend 
arm-elf-gcc -c -mcpu=arm7tdmi  -I . -DEL -DGCC   -mthumb-interwork -DLPC2148  -O0 -    gdwarf-2 -Wall -Wcast-align -Wcast-qual -Wimplicit -Wnested-externs -Wpointer-arith -Wswitch     -Wreturn-type  -Wa,-ahlms=LCD.lst -o LCD.o LCD.c
arm-elf-ar cr lib_LCD.a LCD.o 
arm-elf-ranlib lib_LCD.a
make[1]: Leaving directory `/cygdrive/c/armprojects/projekt/motor/LCD'
make[1]: Entering directory `/cygdrive/c/armprojects/projekt/motor/interrupt'
rm -f .depend 
arm-elf-gcc -c -mcpu=arm7tdmi  -I . -DEL -DGCC   -mthumb-interwork -DLPC2148  -Os -    gdwarf-2 -Wall -Wcast-align -Wcast-qual -Wimplicit -Wnested-externs -Wpointer-arith -Wswitch     -Wreturn-type  -Wa,-ahlms=interrupt_timer.lst -o interrupt_timer.o interrupt_timer.c
arm-elf-gcc -c -mcpu=arm7tdmi  -I . -DEL -DGCC   -mthumb-interwork -DLPC2148  -Os -    gdwarf-2 -Wall -Wcast-align -Wcast-qual -Wimplicit -Wnested-externs -Wpointer-arith -Wswitch     -Wreturn-type  -Wa,-ahlms=interrupt_tacho.lst -o interrupt_tacho.o interrupt_tacho.c
arm-elf-ar cr lib_interrupt.a interrupt_timer.o interrupt_tacho.o 
arm-elf-ranlib lib_interrupt.a
make[1]: Leaving directory `/cygdrive/c/armprojects/projekt/motor/interrupt'
rm -f .depend 
arm-elf-gcc -c -mcpu=arm7tdmi -mthumb-interwork -I./startup -DEL -DGCC -mthumb-interwork     -mthumb -DTHUMB_CSTART -DTHUMB_INTERWORK -mthumb-interwork -DLPC2148  -O0 -gdwarf-2 -Wall -    Wcast-align -Wcast-qual -Wimplicit -Wnested-externs -Wpointer-arith -Wswitch -Wreturn-type      -Wa,-ahlms=main.lst -o main.o main.c
arm-elf-gcc -c -mcpu=arm7tdmi -mthumb-interwork -I./startup -DEL -DGCC -mthumb-interwork     -mthumb -DTHUMB_CSTART -DTHUMB_INTERWORK -mthumb-interwork -DLPC2148  -O0 -gdwarf-2 -Wall -    Wcast-align -Wcast-qual -Wimplicit -Wnested-externs -Wpointer-arith -Wswitch -Wreturn-type      -Wa,-ahlms=proc1.lst -o proc1.o proc1.c
motor/motor_test.h:18: warning: 'duty1' defined but not used
motor/motor_test.h:19: warning: 'duty2' defined but not used
arm-elf-gcc -c -mcpu=arm7tdmi -mthumb-interwork -I./startup -DEL -DGCC -mthumb-interwork     -mthumb -DTHUMB_CSTART -DTHUMB_INTERWORK -mthumb-interwork -DLPC2148  -O0 -gdwarf-2 -Wall -    Wcast-align -Wcast-qual -Wimplicit -Wnested-externs -Wpointer-arith -Wswitch -Wreturn-type      -Wa,-ahlms=proc2.lst -o proc2.o proc2.c
arm-elf-gcc -c -mcpu=arm7tdmi -mthumb-interwork -I./startup -DEL -DGCC -mthumb-interwork     -mthumb -DTHUMB_CSTART -DTHUMB_INTERWORK -mthumb-interwork -DLPC2148  -O0 -gdwarf-2 -Wall -    Wcast-align -Wcast-qual -Wimplicit -Wnested-externs -Wpointer-arith -Wswitch -Wreturn-type      -Wa,-ahlms=proc3.lst -o proc3.o proc3.c
arm-elf-gcc main.o proc1.o proc2.o proc3.o  startup/libea_startup_thumb.a     pre_emptive_os/pre_emptive_os.a LCD/lib_LCD.a interrupt/lib_interrupt.a -I./startup -    mcpu=arm7tdmi -mthumb-interwork -mthumb-interwork -nostartfiles -T     build_files/link_32k_512k_rom.ld -o main.elf -Wl,-Map=main.map,--cref
proc1.o: In function `procEx1':
/cygdrive/c/armprojects/projekt/motor/proc1.c:45: undefined reference to     `motorTest_test'
collect2: ld returned 1 exit status
make: *** [main.hex] Error 1

13:46:52 Build Finished (took 6s.46ms)

If you want to you could checkout my repository at: http://dt3-robotlego-2012ht-white.googlecode.com/svn/branches/motor/Project12/

Here's some of my code (the relevant parts):
proc1.c

/*
 * proc1.c
 *
 *  Created on: 31 okt 2011
 *      Author: Tommy
 */

/*****************************************************************************
 * Process 1
 ****************************************************************************/
#include "pre_emptive_os/api/osapi.h"
#include "general.h"
#include "startup/lpc2xxx.h"
#include "startup/printf_P.h"
#include "startup/ea_init.h"
#include "startup/consol.h"
#include "startup/config.h"
#include "startup/framework.h"
#include "utils/utils.h"
#include "LCD/LCD.h"
#include "motor/motor_test.h"

extern long const delayshort;
extern long const delaylong;

extern tCntSem mutexLCD;

/*****************************************************************************
 * Function prototypes
 ****************************************************************************/
void LCD_clearDisplay(void);

/****************************************************************************/

void
procEx1(void* arg)
{
  tU8 error;

    for (;;) {  // QUESTION: why use for-loop?

        osSemTake(&mutexLCD, 0, &error);

        // REMARK: doesn't work at the moment... issues including runPwm()
        motorTest_test();

        osSemGive(&mutexLCD, &error);

        osSleep(100);
    }

}

void LCD_clearDisplay(void) {
    delay(delayshort);
    send_instruction(1);    //clears the display
    delay(delaylong);
    send_instruction(2);    //the cursor is moved to the first position
}

motor_test.h

/******************************************************************************
 * Includes
 *****************************************************************************/
#include "motor.h"

/******************************************************************************
 * Defines
 *****************************************************************************/
#define TASK                9       // task 1 - use circulary loop
                                    // task 2 - use constant PWM signal
                                    // ...
#define RUN_SETPWM_IN_LOOP  1       // dictates whether setPwmDutyPercentx(tU32) should be run outside the "TASK conditional statement"

/*****************************************************************************
 * Global variables
 ****************************************************************************/
static tU32 duty1;
static tU32 duty2;


/******************************************************************************
 * Prototypes
 *****************************************************************************/
void motorTest_test();
void dev_run(tU32 duty1, tU32 duty2);
void pwm_motor_init();
void pwm_motor_run(tU32 duty1, tU32 duty2);
void change_mode(short mode);

motor_test.c

#include "motor_test.h"

/******************************************************************************
 * Functions
 *****************************************************************************/
void motorTest_test() {
    init();
    dev_run(duty1, duty2);
}



// dev function - not used in release
// COMMENT: PWM signal is continuously generated when the setPwmDutyPercent(tU32) function is called, no need to endlessly iterate the calls
// EDIT:    seems like you need to iterate over the setPwmDutyPercent(tU32) functions afterall...
// COMMENT: the duty sets the speed of the motor driver
//          the value that can be set is 0-10000
//          a higher value means a lower speed, conversely a low value means a higher speed
void dev_run(tU32 duty1, tU32 duty2) {
    //wait 10 ms
    //delayMs(10);

    //wait 100 ms
    //delayMs(100);

    // COMMENT: try running without delays
    //          seems to work fine..

    while (1) {

        //set frequency value
        if (RUN_SETPWM_IN_LOOP == 1) {
            setPwmDutyPercent1(duty1);
            setPwmDutyPercent2(duty2);
        }

        //  delayMs(10);

        switch (TASK) {
        case 1: {
            //update duty cycle (0.00 - 100.00%, in steps of 0.10%)
            duty1 += 10;
            if (duty1 > 10000)
                duty1 = 0;
            break;
        }
        case 2: {
            duty1 = 0;
            duty2 = 8500;
            // COMMENT: slowest speed = 8500 duty
            //          fastest speed = 0    duty
            break;
        }
        case 3: { // left
            duty1 = 6000;
            duty2 = 8000;
            break;
        }
        case 4: { // right
            duty1 = 8000;
            duty2 = 6000;
            break;
        }
        case 5: {
            duty1 = 6000;
            duty2 = 6000;
            break;
        }

        case 6: {
            short delay = 1;
            short duty_vals = 6000;
            short section[3] = { 1, 0, 0 };

            if (section[0] == 1) {
                setMode1(MODE_FORWARD);
                setMode2(MODE_FORWARD);
                duty1 = duty_vals;
                duty2 = duty_vals;
                setPwmDutyPercent1(duty1);
                setPwmDutyPercent2(duty2);
                //delayMs(0);
                delay_millis(delay);
            }

            if (section[1] == 1) {
                setMode1(MODE_BRAKE);
                setMode2(MODE_BRAKE);
                setPwmDutyPercent1(duty1);
                setPwmDutyPercent2(duty2);
                delay_millis(delay);
            }

            if (section[2] == 1) {
                setMode1(MODE_REVERSE);
                setMode2(MODE_REVERSE);
                duty1 = duty_vals;
                duty2 = duty_vals;
                setPwmDutyPercent1(duty1);
                setPwmDutyPercent2(duty2);
                delay_millis(delay);
            }
            break;
        }
        case 7: {
            pwm_motor_init();
            duty1 = 6000;
            duty2 = 6000;

            //delayMs(10);
            delay_millis(10);

            pwm_motor_run(duty1, duty2);
            break;
        }
        case 8: {


            setMode1(MODE_FORWARD);
            setMode2(MODE_FORWARD);

            delay_millis(700);

            duty1 = 7000;
            duty2 = 7000;


            setMode1(MODE_REVERSE);
            setMode2(MODE_REVERSE);

            delay_millis(700);

            duty1 = 1000;
            duty2 = 1000;

            break;
        }

        case 9: {
            duty1 = 0;
            duty2 = 0;
            break;
        }

        }
    }
}

/*****************************************************************************
 * Temporary developer functions
 ****************************************************************************/
void pwm_motor_init() {
    setMode1(MODE_FORWARD);
    setMode2(MODE_FORWARD);

    delay_millis(10);
}

void pwm_motor_run(tU32 duty1, tU32 duty2) {
    setPwmDutyPercent1(duty1);
    setPwmDutyPercent2(duty2);

    while(1) {
        change_mode(MODE_FORWARD);
        change_mode(MODE_BRAKE);
        change_mode(MODE_REVERSE);
        change_mode(MODE_BRAKE);
    }
}

void change_mode(short mode) {
    setMode1(mode);
    setMode2(mode);
    delay_millis(10);
}

Upvotes: 0

Views: 3632

Answers (1)

MvG
MvG

Reputation: 61027

Make sure to include all C sources into the CSRCS variable of your makefile. Then the build system will know it has to compile that file as well, and include the resulting object into the link.

Upvotes: 2

Related Questions