gpt4 book ai didi

c - 为什么这个 C 程序不能编译?错误 : undefined reference to `i2c_smbus_read_byte_data'

转载 作者:太空宇宙 更新时间:2023-11-04 08:21:34 26 4
gpt4 key购买 nike

编辑:我创建了带有标题和更恰当/清晰细节的其他主题:

How to resolve the link error "undefined reference to `i2c_smbus_read_byte_data'"

__

我试图用 C 语言编译单个程序以通过 I2C 总线读取和写入设备,但出现此错误:

Error: undefined reference to i2c_smbus_read_byte_data

我已经安装了这些软件包:libi2c-devi2c-tools

我正在使用 Ubuntu 和 arm-linux-gnueabi-gcc 编译器(与 Eclipse Luna IDE 交叉编译)

完整代码如下:

/*
http://www.zerozone.it/2014/05/primi-esperimenti-con-la-beaglebone-black-collegare-10dof-via-i2c/

DOF10 I2C Test program

v0.1 - 05.05.2014

I wrote this program just to test DOF10 funcionality with my BeagleBone Black.

You can buy DOF10 module and a beagleBone from eBay with few dollars...have fun !

Written by Michele <o-zone@zerozone.it> Pinassi

BLOG @ www.zerozone.it

Feel free to use this code as you want. No any warranty, in any case: use at your own risks !

*/

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>

#define DEBUG

#define L3G4200D_I2C_ADDR 0x69
#define ADXL345_I2C_ADDR 0x53

typedef signed char s8;
typedef unsigned char u8;
typedef signed short s16;
typedef unsigned short u16;
typedef signed int s32;
typedef unsigned int u32;
typedef signed long s64;
typedef unsigned long u64;

int i2cHandle; // Bus I2C file handle

int I2C_setAddress(unsigned char deviceAddr) {
if (ioctl(i2cHandle, I2C_SLAVE, deviceAddr) < 0) {
printf("Error while set I2C address 0x%x: %d error\n",deviceAddr,errno);
return -1;
}
return 0;
}

unsigned char I2C_readByte(unsigned char deviceAddr,unsigned char regAddr) {
unsigned char res;

I2C_setAddress(deviceAddr);

res = i2c_smbus_read_byte_data(i2cHandle,regAddr);

#ifdef DEBUG
printf("[DEBUG] 0x%x @ 0x%x => 0x%x\n",deviceAddr,regAddr,res);
#endif

return res;
}

int I2C_writeWord(unsigned char deviceAddr, __u8 regAddr, __u16 value) {
int res;

I2C_setAddress(deviceAddr);

res = i2c_smbus_write_word_data(i2cHandle, regAddr, value);
if(res < 0) {
printf("Error writing 0x%x to 0x%x register on i2c bus\n",value, regAddr);
return -1;
}
return 1;
}

int I2C_writeByte(unsigned char deviceAddr, __u8 regAddr, __u8 value) {
int res;

I2C_setAddress(deviceAddr);

res = i2c_smbus_write_byte_data(i2cHandle, regAddr, value);
if(res < 0) {
printf("Error writing 0x%x to 0x%x register on i2c bus\n",value, regAddr);
return -1;
}
return 1;
}

// 0: 250 dps - 1: 500 dps - 2: 2000 dps
int L3G4200D_init(char fullScale) {
if(I2C_readByte(L3G4200D_I2C_ADDR,0x0F)!=0xD3) {
printf("ERROR communicating with L3D4200D !\n");
return -1;
}

// Enable x, y, z and turn off power down:
I2C_writeByte(L3G4200D_I2C_ADDR, 0x20, 0b00001111);

// If you'd like to adjust/use the HPF, you can edit the line below to configure CTRL_REG2:
I2C_writeByte(L3G4200D_I2C_ADDR, 0x21, 0b00000000);

// Configure CTRL_REG3 to generate data ready interrupt on INT2
// No interrupts used on INT1, if you'd like to configure INT1
// or INT2 otherwise, consult the datasheet:
I2C_writeByte(L3G4200D_I2C_ADDR, 0x22, 0b00001000);

// CTRL_REG4 controls the full-scale range, among other things:
fullScale &= 0x03;
I2C_writeByte(L3G4200D_I2C_ADDR, 0x23, fullScale<<4);

// CTRL_REG5 controls high-pass filtering of outputs, use it if you'd like:
I2C_writeByte(L3G4200D_I2C_ADDR, 0x24, 0b00000000);
}

void L3G4200D_getGyroValues() {
int x,y,z;

x = (I2C_readByte(L3G4200D_I2C_ADDR, 0x29)&0xFF)<<8; // MSB
x |= (I2C_readByte(L3G4200D_I2C_ADDR, 0x28)&0xFF); // LSB

y = (I2C_readByte(L3G4200D_I2C_ADDR, 0x2B)&0xFF)<<8;
y |= (I2C_readByte(L3G4200D_I2C_ADDR, 0x2A)&0xFF);

z = (I2C_readByte(L3G4200D_I2C_ADDR, 0x2D)&0xFF)<<8;
z |= (I2C_readByte(L3G4200D_I2C_ADDR, 0x2C)&0xFF);

printf("L2D4200D = X:%d Y:%d Z:%d\n",x,y,z);
}

void ADXL345_init() {
// Set +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
I2C_writeByte(ADXL345_I2C_ADDR,0x31,0x01);

// Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
I2C_writeByte(ADXL345_I2C_ADDR,0x2D,0x08);
}

void ADXL345_readAccel() {
int x,y,z;
// each axis reading comes in 10 bit resolution, ie 2 bytes. LSB first, MSB next

x = (I2C_readByte(ADXL345_I2C_ADDR, 0x33)&0xFF)<<8; // MSB
x |= (I2C_readByte(ADXL345_I2C_ADDR, 0x32)&0xFF); // LSB

y = (I2C_readByte(ADXL345_I2C_ADDR, 0x35)&0xFF)<<8; // MSB
y |= (I2C_readByte(ADXL345_I2C_ADDR, 0x34)&0xFF); // LSB

z = (I2C_readByte(ADXL345_I2C_ADDR, 0x37)&0xFF)<<8; // MSB
z |= (I2C_readByte(ADXL345_I2C_ADDR, 0x36)&0xFF); // LSB

printf("ADXL345 = X:%d Y:%d Z:%d\n",x,y,z);
}

void main(int argc, char *argv[]) {
char filename[20];

printf("Open I2C bus...");

snprintf(filename, 19, "/dev/i2c-1");
i2cHandle = open(filename, O_RDWR);
if (i2cHandle < 0) {
printf("Error while opening device %s: %d error\n",filename,errno);
exit(1);
}

printf("OK !\nInitializing L3G4200D...");
L3G4200D_init(2);

printf("OK !\nInitializing ADXL345...");
ADXL345_init();

printf("OK !\n");

while(1) {
L3G4200D_getGyroValues();
ADXL345_readAccel();
sleep(1);
}

close(i2cHandle);
}

最佳答案

如果库安装正确,那么这看起来像是链接器问题。
您可以验证 i2c_smbus_read_byte_data() 是否在

中定义
Linux/drivers/i2c/i2c-core.c

并且有一个函数原型(prototype),

include/linux/i2c.h

所以也许你可以做一个

#include <linux/i2c.h>

关于c - 为什么这个 C 程序不能编译?错误 : undefined reference to `i2c_smbus_read_byte_data' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33181714/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com