在开发嵌入式Linux软件以在I2C总线上进行通信时,有许多参考使用 i2c_smbus _ 函数。当软件项目中引用 i2c_smbus 等功能(例如 i2c_smbus_read_word_data 时,ARM8处理器错误,例如“ i2c_smbus_read_word_data”未在此范围内声明编译。
对以下头文件的调查表明缺少大多数 i2c_smbus 函数定义。
同样在以下引用i2c.h文件中定义了所有i2c_smbus。
如何解决这个问题?
研究参考
答案 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内核。