为什么i2c_smbus功能不可用? (I2C - 嵌入式Linux)

时间:2014-08-06 11:22:19

标签: c++ c arm embedded-linux i2c

在开发嵌入式Linux软件以在I2C总线上进行通信时,有许多参考使用 i2c_smbus _ 函数。当软件项目中引用 i2c_smbus 等功能(例如 i2c_smbus_read_word_data 时,ARM8处理器错误,例如“ i2c_smbus_read_word_data”未在此范围内声明编译。

对以下头文件的调查表明缺少大多数 i2c_smbus 函数定义。

  • /usr/arm-linux-gnueabi/include/linux/i2c.h
  • /usr/arm-linux-gnueabi/include/linux/i2c-dev.h

同样在以下引用i2c.h文件中定义了所有i2c_smbus。

如何解决这个问题?

研究参考

  1. Using I2C from userspace in Linux
  2. I2C Communication from Linux Userspace – Part II
  3. I2C dev interface

4 个答案:

答案 0 :(得分:12)

因为您的应用程序使用了错误的头文件。

如果您在标题中的extern函数上看到i2c_smbus_read_word_data(),则它是内核的头文件,但不适用于您的应用。 Linux内核具有i2c_smbus_read_word_data()和其他i2c smbus功能供内部使用。但它们是a)不是系统调用,或b)无法从您的应用程序访问。

而是获取i2c-tools from lm-sensors并安装它。如果您使用的是Debian,只需

sudo apt-get install libi2c-dev

并使用i2c_smbus_read_word_data()或他们提供的任何其他界面。 i2c-dev是一个仅包含头的包,这意味着没有要链接的库。所有函数都是使用ioctl()定义的内联函数。

e.g。)

static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command,
                                     int size, union i2c_smbus_data *data)
{
        struct i2c_smbus_ioctl_data args;

        args.read_write = read_write;
        args.command = command;
        args.size = size;
        args.data = data;
        return ioctl(file,I2C_SMBUS,&args);
}
   :
static inline __s32 i2c_smbus_read_word_data(int file, __u8 command)
{
        union i2c_smbus_data data;
        if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
                             I2C_SMBUS_WORD_DATA,&data))
                return -1;
        else
                return 0x0FFFF & data.word;
}

答案 1 :(得分:2)

我今天遇到了这个。 i2c_smbus_*函数定义于:

/usr/include/linux/i2c-dev.h

...但是当我尝试在旧版本的Ubuntu上为ARM交叉编译时,我遇到了以下错误:

i2c_smbus_read_block_data was not declared in this scope

原来在等效的ARM特定位置定义的函数

/usr/arm-linux-gnueabi/include/linux/i2c-dev.h

交叉编译时,第二个较旧的头文件是使用的文件。不得不在本地重新声明一些内联的i2c_smbus _...函数来解决这个问题。

答案 2 :(得分:2)

基于 https://unix.stackexchange.com/questions/621854/usr-include-linux-i2c-dev-h-does-not-contain-i2c-smbus-read-word-data-functio,我发现这修复了函数未定义的错误:

#include <i2c/smbus.h>

我目前正在处理引用各种 i2c_smbus 函数的遗留代码。它有:

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

它无法编译。当然,这个包含曾经可以工作,但似乎 lib 的头文件在某个时候发生了变化。我最近确实刷新/重新安装了 libi2c-dev。

请注意,我添加了上述包含。我无法删除原始包含。还是需要的。

仅供参考:我还没有尝试过交叉编译。

答案 3 :(得分:1)

来自i2c Linux kernel documentation

  

请注意,有两个文件名为&#34; i2c-dev.h&#34;在那里,一个与Linux内核一起分发,意味着包含在内核驱动程序代码中,另一个与i2c-tools一起分发,并且意味着包含在用户空间程序中。你显然想要第二个。

所以你需要包含来自i2c-tools的i2c-dev.h而不是Linux内核。