1

I'm trying to read a block of data from an imu (mpu9250) but when building with g++ mpu.cpp -o mpu i get the following error:

/tmp/cckh5V8w.o: In function 'imu::read_accel()': 
mpu_mine9250.cpp:(.text._ZN3imu10read_accelEv[_ZN3imu10read_accelEv]+0x94): undefined reference to 'i2c_smbus_read_block_data(int, unsigned char, unsigned char*)'
collect2: error: ld returned 1 exit status ```
int addr = 0x68;
int mpu_file;
char mpu_filename[250];
snprintf(mpu_filename, 250, "/dev/i2c-0");
if (ioctl(mpu_file, I2C_SLAVE, addr) < 0){
     exit(1);
}
__u8 buf[14];
__u8 reg = 0x3B;
int ans= i2c_smbus_read_block_data(mpu_file, reg, buf);

To include the libraries I've tried:

#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>

and also:

extern "C" {
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>
}

I've installed the libi2c-dev, libi2c0 and i2c-tools packages.

When using write(mpu_file, buf, 2) or read(mpu_file, buf, 1)it does work.

Thanks in advance!

  • Does this answer your question? [undefined reference to \`i2c\_smbus\_read\_word\_data(int, unsigned char)](https://stackoverflow.com/questions/50154296/undefined-reference-to-i2c-smbus-read-word-dataint-unsigned-char) – crdrisko Aug 30 '20 at 19:08
  • @crdrisko I've already tried that and still having the same error, thank you tho! – Adam El Messaoudi Aug 30 '20 at 19:23
  • Have you tried the part about linking the library and your project with the `-l` option? See the question part of the link. – crdrisko Aug 30 '20 at 19:34
  • Not only do you need to link the library with -l (hint - no need to have the `lib` part - so use `-li2c`) you may also need to specify the library location with -L – Den-Jason Aug 30 '20 at 19:56
  • @Den-Jason Thank you both for answering! I'm new to c++, the linking library thing it's new to me so sorry if I'm doing some dumb mistakes! I've tried the following: `g++ -o mpu mpu_mine9250.cpp /usr/lib/arm-linux-gnueabihf/libi2c.a`, `g++ -o mpu mpu_mine9250.cpp -li2c`, `g++ -o mpu mpu_mine9250.cpp -l:libi2c.a`, `g++ -o mpu mpu_mine9250.cpp -L/usr/lib/arm-linux-gnueabihf/libi2c.so -li2c` and other combinations but they all gave me the same error. (the library is linked correctly, because if I change the location it says that the directory was not found). – Adam El Messaoudi Aug 30 '20 at 21:06
  • How about the following: `g++ -o mpu mpu_mine9250.cpp -L/usr/lib/arm-linux-gnueabihf -li2c` and make sure you wrap the libraries in `extern C`? – crdrisko Aug 30 '20 at 23:22
  • Use in-kernel driver and forget about this dances in user space: https://elixir.bootlin.com/linux/latest/source/drivers/iio/imu/inv_mpu6050. More info about `libiio`: https://wiki.analog.com/resources/tools-software/linux-software/libiio. – 0andriy Aug 31 '20 at 08:30
  • for -L you only specify the directory – Den-Jason Aug 31 '20 at 08:51

1 Answers1

2

The solutions was:

1. Using extern C: I was using extern C, but included them in the regular way as well and that caused the problem.

extern "C"
{
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>
}

2. Linking libraries when building:

g++ -o mpu mpu_mine9250.cpp -li2c