致命错误:i2c / smbus。h:没有这样的文件或目录?

时间:2022-02-26 09:40:21

I tried to compile some code, and I recieved this response while trying to compile:

我尝试编译一些代码,在尝试编译时收到了这个响应:

./smbus.c:26:23: fatal error: i2c/smbus.h: No such file or directory

/ smbus。c:26:23:致命错误:i2c / smbus。h:没有这样的文件或目录

compilation terminated. ./altitude_ai.c: In function

编译/ altitude_ai终止。。c:在函数

‘bmp085_Altitude’: ./altitude_ai.c:207:4: warning: implicit

:“bmp085_Altitude”。/ altitude_ai。c:207:4:警告:隐式

declaration of function ‘pow’ [-Wimplicit-function-declaration]

函数“pow”的声明[- wimplex -function-declaration]

./altitude_ai.c:207:14: warning: incompatible implicit declaration of

/ altitude_ai。c:207:14:警告:不相容的隐式声明

built-in function ‘pow’ [enabled by default]

内置函数' pow '[默认启用]

This is all the code I tried to compile:

这就是我试图编译的所有代码:

smbus.c

smbus.c

/*
    smbus.c - SMBus level access helper functions

    Copyright (C) 1995-97 Simon G. Vogl
    Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
    Copyright (C) 2012    Jean Delvare <khali@linux-fr.org>
    Copyright (C) 2012-2013 Donovan Roudabush <sharksfan98@gmail.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
    MA 02110-1301 USA.
*/

#include <errno.h>
#include <i2c/smbus.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include "smbus.h"
#define NULL 0

/* Compatibility defines */
#ifndef I2C_SMBUS_I2C_BLOCK_BROKEN
#define I2C_SMBUS_I2C_BLOCK_BROKEN I2C_SMBUS_I2C_BLOCK_DATA
#endif
#ifndef I2C_FUNC_SMBUS_PEC
#define I2C_FUNC_SMBUS_PEC I2C_FUNC_SMBUS_HWPEC_CALC
#endif

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

    args.read_write = read_write;
    args.command = command;
    args.size = size;
    args.data = data;

    err = ioctl(file, I2C_SMBUS, &args);
    if (err == -1)
        err = -errno;
    return err;
}


__s32 i2c_smbus_write_quick(int file, __u8 value)
{
    return i2c_smbus_access(file, value, 0, I2C_SMBUS_QUICK, NULL);
}

__s32 i2c_smbus_read_byte(int file)
{
    union i2c_smbus_data data;
    int err;

    err = i2c_smbus_access(file, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data);
    if (err < 0)
        return err;

    return 0x0FF & data.byte;
}

__s32 i2c_smbus_write_byte(int file, __u8 value)
{
    return i2c_smbus_access(file, I2C_SMBUS_WRITE, value,
                I2C_SMBUS_BYTE, NULL);
}

__s32 i2c_smbus_read_byte_data(int file, __u8 command)
{
    union i2c_smbus_data data;
    int err;

    err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
                   I2C_SMBUS_BYTE_DATA, &data);
    if (err < 0)
        return err;

    return 0x0FF & data.byte;
}

__s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value)
{
    union i2c_smbus_data data;
    data.byte = value;
    return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
                I2C_SMBUS_BYTE_DATA, &data);
}

__s32 i2c_smbus_read_word_data(int file, __u8 command)
{
    union i2c_smbus_data data;
    int err;

    err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
                   I2C_SMBUS_WORD_DATA, &data);
    if (err < 0)
        return err;

    return 0x0FFFF & data.word;
}

__s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value)
{
    union i2c_smbus_data data;
    data.word = value;
    return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
                I2C_SMBUS_WORD_DATA, &data);
}

__s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)
{
    union i2c_smbus_data data;
    data.word = value;
    if (i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
                 I2C_SMBUS_PROC_CALL, &data))
        return -1;
    else
        return 0x0FFFF & data.word;
}

/* Returns the number of read bytes */
__s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values)
{
    union i2c_smbus_data data;
    int i, err;

    err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
                   I2C_SMBUS_BLOCK_DATA, &data);
    if (err < 0)
        return err;

    for (i = 1; i <= data.block[0]; i++)
        values[i-1] = data.block[i];
    return data.block[0];
}

__s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length,
                 const __u8 *values)
{
    union i2c_smbus_data data;
    int i;
    if (length > I2C_SMBUS_BLOCK_MAX)
        length = I2C_SMBUS_BLOCK_MAX;
    for (i = 1; i <= length; i++)
        data.block[i] = values[i-1];
    data.block[0] = length;
    return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
                I2C_SMBUS_BLOCK_DATA, &data);
}

/* Returns the number of read bytes */
/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
   ask for less than 32 bytes, your code will only work with kernels
   2.6.23 and later. */
__s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, __u8 length,
                    __u8 *values)
{
    union i2c_smbus_data data;
    int i, err;

    if (length > I2C_SMBUS_BLOCK_MAX)
        length = I2C_SMBUS_BLOCK_MAX;
    data.block[0] = length;

    err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
                   length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN :
                I2C_SMBUS_I2C_BLOCK_DATA, &data);
    if (err < 0)
        return err;

    for (i = 1; i <= data.block[0]; i++)
        values[i-1] = data.block[i];
    return data.block[0];
}

__s32 i2c_smbus_write_i2c_block_data(int file, __u8 command, __u8 length,
                     const __u8 *values)
{
    union i2c_smbus_data data;
    int i;
    if (length > I2C_SMBUS_BLOCK_MAX)
        length = I2C_SMBUS_BLOCK_MAX;
    for (i = 1; i <= length; i++)
        data.block[i] = values[i-1];
    data.block[0] = length;
    return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
                I2C_SMBUS_I2C_BLOCK_BROKEN, &data);
}

/* Returns the number of read bytes */
__s32 i2c_smbus_block_process_call(int file, __u8 command, __u8 length,
                   __u8 *values)
{
    union i2c_smbus_data data;
    int i, err;

    if (length > I2C_SMBUS_BLOCK_MAX)
        length = I2C_SMBUS_BLOCK_MAX;
    for (i = 1; i <= length; i++)
        data.block[i] = values[i-1];
    data.block[0] = length;

    err = i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
                   I2C_SMBUS_BLOCK_PROC_CALL, &data);
    if (err < 0)
        return err;

    for (i = 1; i <= data.block[0]; i++)
        values[i-1] = data.block[i];
    return data.block[0];
}

smbus.h

smbus.h

/*
    smbus.h - SMBus level access helper functions

    Copyright (C) 1995-97 Simon G. Vogl
    Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
    Copyright (C) 2012-2013 Donovan Roudabush <sharksfan98@gmail.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    This software has been distrobuted for the Gryphon 7i series,
    maintained Jan 2013 by Donovan Roudabush at The Ballon Project
    This falls under GPL and Copyleft, but is intended for
    Research use.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
    MA 02110-1301 USA.

*/

#ifndef LIB_I2C_SMBUS_H
#define LIB_I2C_SMBUS_H

#include <linux/types.h>
#include <linux/i2c.h>

extern __s32 i2c_smbus_access(int file, char read_write, __u8 command,
              int size, union i2c_smbus_data *data);

extern __s32 i2c_smbus_write_quick(int file, __u8 value);
extern __s32 i2c_smbus_read_byte(int file);
extern __s32 i2c_smbus_write_byte(int file, __u8 value);
extern __s32 i2c_smbus_read_byte_data(int file, __u8 command);
extern __s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value);
extern __s32 i2c_smbus_read_word_data(int file, __u8 command);
extern __s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value);
extern __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value);

/* Returns the number of read bytes */
extern __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values);
extern __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length,
                    const __u8 *values);

/* Returns the number of read bytes */
/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
   ask for less than 32 bytes, your code will only work with kernels
   2.6.23 and later. */
extern __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, __u8 length,
                       __u8 *values);
extern __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command, __u8 length,
                        const __u8 *values);

/* Returns the number of read bytes */
extern __s32 i2c_smbus_block_process_call(int file, __u8 command, __u8 length,
                      __u8 *values);

#endif /* LIB_I2C_SMBUS_H */

altitude_ai.c

altitude_ai.c

#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <stdlib.h>

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

#define BMP085_I2C_ADDRESS 0x77

const unsigned char BMP085_OVERSAMPLING_SETTING = 3;

// Calibration values - These are stored in the BMP085
short int ac1;
short int ac2; 
short int ac3; 
unsigned short int ac4;
unsigned short int ac5;
unsigned short int ac6;
short int b1; 
short int b2;
short int mb;
short int mc;
short int md;

int b5; 

unsigned int temperature, pressure, altitude;


// Open a connection to the bmp085
// Returns a file id
int bmp085_i2c_Begin()
{
   int fd;
   char *fileName = "/dev/i2c-0";

   // Open port for reading and writing
   if ((fd = open(fileName, O_RDWR)) < 0)
      exit(1);

   // Set the port options and set the address of the device
   if (ioctl(fd, I2C_SLAVE, BMP085_I2C_ADDRESS) < 0) {               
      close(fd);
      exit(1);
   }

   return fd;
}

// Read two words from the BMP085 and supply it as a 16 bit integer
__s32 bmp085_i2c_Read_Int(int fd, __u8 address)
{
   __s32 res = i2c_smbus_read_word_data(fd, address);
   if (res < 0) {
      close(fd);
      exit(1);
   }

   // Convert result to 16 bits and swap bytes
   res = ((res<<8) & 0xFF00) | ((res>>8) & 0xFF);

   return res;
}

//Write a byte to the BMP085
void bmp085_i2c_Write_Byte(int fd, __u8 address, __u8 value)
{
   if (i2c_smbus_write_byte_data(fd, address, value) < 0) {
      close(fd);
      exit(1);
   }
}

// Read a block of data BMP085
void bmp085_i2c_Read_Block(int fd, __u8 address, __u8 length, __u8 *values)
{
   if(i2c_smbus_read_i2c_block_data(fd, address,length,values)<0) {
      close(fd);
      exit(1);
   }
}


void bmp085_Calibration()
{
   int fd = bmp085_i2c_Begin();
   ac1 = bmp085_i2c_Read_Int(fd,0xAA);
   ac2 = bmp085_i2c_Read_Int(fd,0xAC);
   ac3 = bmp085_i2c_Read_Int(fd,0xAE);
   ac4 = bmp085_i2c_Read_Int(fd,0xB0);
   ac5 = bmp085_i2c_Read_Int(fd,0xB2);
   ac6 = bmp085_i2c_Read_Int(fd,0xB4);
   b1 = bmp085_i2c_Read_Int(fd,0xB6);
   b2 = bmp085_i2c_Read_Int(fd,0xB8);
   mb = bmp085_i2c_Read_Int(fd,0xBA);
   mc = bmp085_i2c_Read_Int(fd,0xBC);
   md = bmp085_i2c_Read_Int(fd,0xBE);
   close(fd);
}

// Read the uncompensated temperature value
unsigned int bmp085_ReadUT()
{
   unsigned int ut = 0;
   int fd = bmp085_i2c_Begin();

   // Write 0x2E into Register 0xF4
   // This requests a temperature reading
   bmp085_i2c_Write_Byte(fd,0xF4,0x2E);

   // Wait at least 4.5ms
   usleep(5000);

   // Read the two byte result from address 0xF6
   ut = bmp085_i2c_Read_Int(fd,0xF6);

   // Close the i2c file
   close (fd);

   return ut;
}

// Read the uncompensated pressure value
unsigned int bmp085_ReadUP()
{
   unsigned int up = 0;
   int fd = bmp085_i2c_Begin();

   // Write 0x34+(BMP085_OVERSAMPLING_SETTING<<6) into register 0xF4
   // Request a pressure reading w/ oversampling setting
   bmp085_i2c_Write_Byte(fd,0xF4,0x34 + (BMP085_OVERSAMPLING_SETTING<<6));

   // Wait for conversion, delay time dependent on oversampling setting
   usleep((2 + (3<<BMP085_OVERSAMPLING_SETTING)) * 1000);

   // Read the three byte result from 0xF6
   // 0xF6 = MSB, 0xF7 = LSB and 0xF8 = XLSB
   __u8 values[3];
   bmp085_i2c_Read_Block(fd, 0xF6, 3, values);

   up = (((unsigned int) values[0] << 16) | ((unsigned int) values[1] << 8) | (unsigned int) values[2]) >> (8-BMP085_OVERSAMPLING_SETTING);

   return up;
}

// Calculate pressure given uncalibrated pressure
// Value returned will be in units of XXXXX
unsigned int bmp085_GetPressure(unsigned int up)
{
   int x1, x2, x3, b3, b6, p;
   unsigned int b4, b7;

   b6 = b5 - 4000;
   // Calculate B3
   x1 = (b2 * (b6 * b6)>>12)>>11;
   x2 = (ac2 * b6)>>11;
   x3 = x1 + x2;
   b3 = (((((int)ac1)*4 + x3)<<BMP085_OVERSAMPLING_SETTING) + 2)>>2;

   // Calculate B4
   x1 = (ac3 * b6)>>13;
   x2 = (b1 * ((b6 * b6)>>12))>>16;
   x3 = ((x1 + x2) + 2)>>2;
   b4 = (ac4 * (unsigned int)(x3 + 32768))>>15;

   b7 = ((unsigned int)(up - b3) * (50000>>BMP085_OVERSAMPLING_SETTING));
   if (b7 < 0x80000000)
      p = (b7<<1)/b4;
   else
      p = (b7/b4)<<1;

   x1 = (p>>8) * (p>>8);
   x1 = (x1 * 3038)>>16;
   x2 = (-7357 * p)>>16;
   p += (x1 + x2 + 3791)>>4;

   return p;
}

// Calculate temperature given uncalibrated temperature
// Value returned will be in units of 0.1 deg C
unsigned int bmp085_GetTemperature(unsigned int ut)
{
   int x1, x2;

   x1 = (((int)ut - (int)ac6)*(int)ac5) >> 15;
   x2 = ((int)mc << 11)/(x1 + md);
   b5 = x1 + x2;

   unsigned int result = ((b5 + 8)>>4);  

   return result;
}

// This Altitude part is stolen from some some unknown
// Arduino library.  The number divided into pressure for
// float A is derived from the local pressure as explained
// at http://learn.adafruit.com/bmp085/using-the-bmp085.
unsigned int bmp085_Altitude(float pressure)
{
   float A = pressure/101794.58;
   float B = 1/5.25588;
   float C = pow(A,B);
   C = 1 - C;
   C = C / 0.0000225577;

   return C;
}

int main(int argc, char **argv)

{

   bmp085_Calibration();

   temperature = bmp085_GetTemperature(bmp085_ReadUT());
   pressure = bmp085_GetPressure(bmp085_ReadUP());
        altitude = bmp085_Altitude(pressure);

   printf("Temperature\t%0.1f *F\n", ((double)temperature)/10 * 1.8 + 32);
   printf("Pressure\t%0.2f hPa\n", ((double)pressure)/100);
        printf("Altitude\t%0.1f Feet\n\n", ((double)altitude)*3.280839895);

   return 0;
}

Can you guys help me fix the error message? Thank you in advance~

你们能帮我修正错误信息吗?提前谢谢你~

1 个解决方案

#1


1  

I think the code is expecting two files both called smbus.h. One in the local directory and one in the system include directory in a sub directory i2c. You should be able to search for all instances of smbus.h with a command like find / -name "smbus.h" 2>/dev/null

我认为代码期望两个文件都叫做smbus.h。一个在本地目录中,一个在系统中,包括子目录i2c中的目录。您应该能够搜索smbus的所有实例。h具有查找/ -name“smbus”这样的命令。h " 2 > / dev / null

May take some time but worth the wait if it fixes the issue.

可能需要一些时间,但如果它解决了问题,那么值得等待。

I suspect you are missing the system files and you only have the one copy of smbus.h. If you do find another smbus.h is a directory named i2c you need to add the directory that contains the i2c directory to you system include path. I'm not sure how this is done. I think its an environment variable.

我怀疑您丢失了系统文件,您只有smbus.h的一个副本。如果你找到另一个smbus。h是一个名为i2c的目录,您需要将包含i2c目录的目录添加到系统包含路径中。我不知道这是怎么做到的。我认为这是一个环境变量。

Are there any instructions with the code to fetch an i2c support package?

是否有带代码的指令来获取i2c支持包?

sudo apt-get install <something>

EDIT: Actually you could cheat a bit if you do find the other file. Change the

编辑:实际上,如果你找到了另一个文件,你可以作弊一点。改变

<i2c/smbus.h>

to a

到一个

"i2c/smbus.h"

and add to the compile line in the make file

并添加到make文件的编译行

-I/where/ever/the/file/was

Assuming you found the file in

假设你找到了文件

/where/ever/the/file/was/i2c/smbus.h

#1


1  

I think the code is expecting two files both called smbus.h. One in the local directory and one in the system include directory in a sub directory i2c. You should be able to search for all instances of smbus.h with a command like find / -name "smbus.h" 2>/dev/null

我认为代码期望两个文件都叫做smbus.h。一个在本地目录中,一个在系统中,包括子目录i2c中的目录。您应该能够搜索smbus的所有实例。h具有查找/ -name“smbus”这样的命令。h " 2 > / dev / null

May take some time but worth the wait if it fixes the issue.

可能需要一些时间,但如果它解决了问题,那么值得等待。

I suspect you are missing the system files and you only have the one copy of smbus.h. If you do find another smbus.h is a directory named i2c you need to add the directory that contains the i2c directory to you system include path. I'm not sure how this is done. I think its an environment variable.

我怀疑您丢失了系统文件,您只有smbus.h的一个副本。如果你找到另一个smbus。h是一个名为i2c的目录,您需要将包含i2c目录的目录添加到系统包含路径中。我不知道这是怎么做到的。我认为这是一个环境变量。

Are there any instructions with the code to fetch an i2c support package?

是否有带代码的指令来获取i2c支持包?

sudo apt-get install <something>

EDIT: Actually you could cheat a bit if you do find the other file. Change the

编辑:实际上,如果你找到了另一个文件,你可以作弊一点。改变

<i2c/smbus.h>

to a

到一个

"i2c/smbus.h"

and add to the compile line in the make file

并添加到make文件的编译行

-I/where/ever/the/file/was

Assuming you found the file in

假设你找到了文件

/where/ever/the/file/was/i2c/smbus.h