0

Has anybody tried using the i2c_smbus_write_byte or any similar function on Raspberry Pi 4?

I can't get it to compile; it fails at the linking with not finding it. I'm using it as described here: http://synfare.com/599N105E/hwdocs/rpi/rpii2c.html

All the headers recommended are there is and also the -li2c in the Makefile. What might the problem can be?

halfer
  • 19,824
  • 17
  • 99
  • 186
mjarvas
  • 11
  • 1
  • 8

2 Answers2

1

Might be worth checking to see if libi2c-dev is present on your system.

sudo apt-get install libi2c-dev

may be all that you need.

nivpeled
  • 1,810
  • 5
  • 17
  • Thanks for the quick reply but that was the first thing I checked. Buster uses now version 4 of this package. Version 3 contained all the smbus functions in the i2c-dev.h. So you only had to include this. But not anymore, theoretically you have to add now -li2c to use the functions but it doesn't seem to work. Definitely the functions disappeared from i2c-dev.h I checked it. But where are they then if not found even with -li2c? – mjarvas May 07 '20 at 12:42
1

The page you are linking to says:

With the Buster version, as of june 2019, the necessary details for using i2c_smbus_write_byte_data() and siblings, require the following include statements:

#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>

Using fgrep you can confirm that the function is declared in the /usr/include/i2c/smbus.h:

# cd /usr/include; fgrep -R i2c_smbus_write_byte *
i2c/smbus.h:extern __s32 i2c_smbus_write_byte(int file, __u8 value);
i2c/smbus.h:extern __s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value);

So this should work:

#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>

int main(void) {
  int i2c = open("/dev/i2c-1", O_RDWR);
  i2c_smbus_write_byte(i2c, 1);
  close(i2c);
  return 0;
}

I tested that this example compiles successfully in the latest Raspbian Buster Lite:

gcc test.c -otest -li2c

If you are using g++ instead of gcc, then you should wrap the include directives with extern "C":

extern "C" {
  #include <linux/i2c-dev.h>
  #include <i2c/smbus.h>
}
Jari Jokinen
  • 770
  • 3
  • 13
  • I tried your code and didn't compile for me. It stooped with the same "undefined reference" error. Although there are 2 differences, I'm using Buster desktop and not gcc but g++ (4.9). – mjarvas May 07 '20 at 13:47
  • It seems it comes from g++. I tried again your code and it compiles with gcc but not with g++4.9. I have to investigate into this direction. Thanks for your help. – mjarvas May 07 '20 at 14:03
  • 1
    With g++ you should wrap the include directives with extern "C" {}. I updated the answer. – Jari Jokinen May 07 '20 at 14:05