Undefined reference to Chip_I2C_Init()

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Undefined reference to Chip_I2C_Init()

1,929 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Hackscribble on Sun Sep 21 14:48:07 MST 2014
Hello

Attached cut-down sample code demonstrates the problem.  C++ program uses C++ library.  Member function of the library calls Chip_I2C_Init().  I get linker error "undefined reference to `Chip_I2C_Init'test-lib.cpp/test-lib/srcline 17C/C++ Problem".

If I remove the call to Chip_I2C_Init() from the library and include it in the main function of my program, it links OK.

Any ideas on how to avoid this workaround? 

In my full program, other I2C API and Chip_... calls work OK when called from the library functions.  Only Chip_I2C_Init() is giving an error.

I'm using v7.3.0 of the IDE and v2.06 of LPCOpen for 11u68.

Many thanks

Ray

// test-lib.h
#ifndef TEST_LIB_H_
#define TEST_LIB_H_

#include "board.h"
#include "cr_section_macros.h"

class testClass
{
public:
testClass();
void begin();
};

#endif /* TEST_LIB_H_ */


// test-lib.cpp
#include "test-lib.h"

testClass::testClass()
{

}

void testClass::begin()
{
Chip_I2C_Init(I2C0);
}


// test-prog.cpp
#if defined(NO_BOARD_LIB)
#include "chip.h"
#else
#include "board.h"
#endif
#endif

#include <cr_section_macros.h>

#include "test-lib.h"

testClass footy;

int main(void) {

#if defined (__USE_LPCOPEN)
#if !defined(NO_BOARD_LIB)
    // Read clock settings and update SystemCoreClock variable
    SystemCoreClockUpdate();
    // Set up and initialize all required blocks and
    // functions related to the board hardware
    Board_Init();
    // Set the LED to the state of "On"
    Board_LED_Set(0, true);
#endif
#endif

    footy.begin();

    // Force the counter to be placed into memory
    volatile static int i = 0 ;
    // Enter an infinite loop, just incrementing a counter
    while(1) {
        i++ ;
    }
    return 0 ;
}


Labels (1)
0 Kudos
Reply
7 Replies

1,724 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Hackscribble on Wed Sep 24 03:40:37 MST 2014
Problem solved. 

In my project's properties, I needed to move my library to the top of the library lists, so that it was above the chip library. 

This was in Quick Settings - Library Search Paths and Quick Settings - Libraries.

Thanks for the help, Fall Guy and lpcxpresso-support.

Ray
0 Kudos
Reply

1,724 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Hackscribble on Mon Sep 22 14:46:43 MST 2014
I had checked that early on.  Highlighted the function name in my code, right click, searched workspace.  Found the function in the library.

And cutting and pasting the function call to move it from my library to main cleared the error.
0 Kudos
Reply

1,724 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by TheFallGuy on Mon Sep 22 13:36:13 MST 2014
It makes me wonder if you spelt the function name correctly...
0 Kudos
Reply

1,724 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Hackscribble on Mon Sep 22 13:20:37 MST 2014
Thanks for the suggestions, lpcxpresso-support.  The C function in question is an LPCOpen function.  The LPCOpen library file already has extern "C" in it (see extract in reply 2 above).  However, I've added further extern "C"s in my library and program files, but no difference.

What I find interesting is that it is specifically Chip_I2C_Init which triggers the problem.  My library also calls the following LPCOpen functions (also presumably written in C) without problems.

Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_I2C0);
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 4, (IOCON_FUNC1 | I2C_FASTPLUS_BIT) | IOCON_DIGMODE_EN);
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 5, (IOCON_FUNC1 | I2C_FASTPLUS_BIT) | IOCON_DIGMODE_EN);
Chip_SYSCTL_PeriphReset(RESET_I2C0);


Since my last post, I found a workaround.  By looking at the source code for Chip_I2C_Init, I worked out that I could replace it with the calls to Chip_Clock_EnablePeriphClock and Chip_SYSCTL_PeriphReset.  The code compiles, links and works.

Thanks

Ray
0 Kudos
Reply

1,724 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpcxpresso-support on Sun Sep 21 23:52:00 MST 2014
If you are writing C++ but calling C functions, you need to tell the compiler which functions use C linkage. You do this by using
extern "c"

around your C functions or (more typically) around the include files that have C linkage. e.g.
extern "c" {
#include "board.h"
#inlcude other_c_linkage_headers.h
}


See http://stackoverflow.com/questions/1041866/in-c-source-what-is-the-effect-of-extern-c

If this isn't the problem, you may not be linking with the correct library (Debug vs Release?)
0 Kudos
Reply

1,724 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Hackscribble on Sun Sep 21 15:51:47 MST 2014
Do you mean the definition of Chip_I2C_Init()?  That is defined in the LPCOpen file "i2c_11u6x.h" and it does have extern.

#ifndef __I2C_11U6X_H_
#define __I2C_11U6X_H_

#include "i2c_common_11u6x.h"

#ifdef __cplusplus
extern "C" {
#endif

// snip

/**
 * @briefInitializes the LPC_I2C peripheral with specified parameter.
 * @paramid: I2C peripheral ID (I2C0, I2C1 ... etc)
 * @returnNothing
 */
void Chip_I2C_Init(I2C_ID_T id);

// snip


/**
 * @}
 */

 #ifdef __cplusplus
}
#endif

#endif /* __I2C_11U6X_H_ */
0 Kudos
Reply

1,724 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by TheFallGuy on Sun Sep 21 14:58:55 MST 2014
Use extern "c" around the function definition. If you don't understand, look it up!
0 Kudos
Reply