You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

配置I2C_TIMEOUT缩短I2C通信超时失效问题求助

I2C_TIMEOUT 设置无效,实际超时始终约1秒的问题

问题描述

我尝试通过设置I2C_TIMEOUT将I2C通信超时缩短至10-20ms,使用故障I2C设备时能稳定触发ETIMEDOUT错误,但无论设置I2C_TIMEOUT为何值,实际超时始终约1秒(最近一次设置500ms时,超时为1036498619纳秒)。

BeagleBone 系统信息

debian@BeagleBone:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 11 (bullseye)
Release:    11
Codename:   bullseye

debian@BeagleBone:~$ uname -r
5.10.168-ti-r77

debian@BeagleBone:~$ uname -a
Linux BeagleBone 5.10.168-ti-r77 #1bullseye SMP PREEMPT Wed Feb 28 21:05:58 UTC 2024 armv7l GNU/Linux

I2C 内核配置

debian@BeagleBone:~$ zcat /proc/config.gz | grep -i i2c | grep -v "^#"
CONFIG_NFC_PN533_I2C=m
CONFIG_NFC_ST_NCI_I2C=m
CONFIG_NFC_NXP_NCI_I2C=m
CONFIG_REGMAP_I2C=y
CONFIG_AD525X_DPOT_I2C=m
CONFIG_MOUSE_ELAN_I2C=m
CONFIG_MOUSE_ELAN_I2C_I2C=y
CONFIG_MOUSE_SYNAPTICS_I2C=m
CONFIG_TOUCHSCREEN_AD7879_I2C=m
CONFIG_TOUCHSCREEN_AR1021_I2C=y
CONFIG_INPUT_AD714X_I2C=m
CONFIG_TCG_TIS_I2C_ATMEL=y
CONFIG_TCG_TIS_I2C_INFINEON=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_COMPAT=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MUX=y
CONFIG_I2C_ARB_GPIO_CHALLENGE=m
CONFIG_I2C_MUX_GPIO=y
CONFIG_I2C_MUX_PCA954x=m
CONFIG_I2C_MUX_PINCTRL=y
CONFIG_I2C_ATR=m
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_ALGOBIT=y
CONFIG_I2C_GPIO=y
CONFIG_I2C_OMAP=y
CONFIG_I2C_DIOLAN_U2C=m
CONFIG_I2C_ROBOTFUZZ_OSIF=m
CONFIG_I2C_TAOS_EVM=m
CONFIG_I2C_TINY_USB=m
CONFIG_I2C_SLAVE=y
CONFIG_I2C_SLAVE_EEPROM=y
CONFIG_PINCTRL_MCP23S08_I2C=m
CONFIG_SENSORS_LTC2947_I2C=m
CONFIG_SENSORS_OCC_P8_I2C=m
CONFIG_STMPE_I2C=y
CONFIG_VIDEO_V4L2_I2C=y
CONFIG_I2C_SI4713=m
CONFIG_VIDEO_IR_I2C=m
CONFIG_DRM_I2C_NXP_TDA998X=y
CONFIG_DRM_I2C_ADV7511=y
CONFIG_DRM_I2C_ADV7511_AUDIO=y
CONFIG_DRM_I2C_ADV7511_CEC=y
CONFIG_SND_SOC_I2C_AND_SPI=m
CONFIG_SND_SOC_CS42L51_I2C=m
CONFIG_SND_SOC_CS4271_I2C=m
CONFIG_SND_SOC_ES8328_I2C=m
CONFIG_SND_SOC_PCM3168A_I2C=m
CONFIG_SND_SOC_PCM512x_I2C=m
CONFIG_SND_SOC_SIGMADSP_I2C=m
CONFIG_SND_SOC_TLV320AIC23_I2C=m
CONFIG_SND_SOC_WM8804_I2C=m
CONFIG_I2C_HID=y
CONFIG_RTC_I2C_AND_SPI=y
CONFIG_SEEED_I2C_HD44780=m
CONFIG_ADT7316_I2C=m
CONFIG_ADE7854_I2C=m
CONFIG_GREYBUS_I2C=m
CONFIG_ADXL345_I2C=m
CONFIG_ADXL372_I2C=m
CONFIG_BMA400_I2C=m
CONFIG_BMC150_ACCEL_I2C=m
CONFIG_IIO_ST_ACCEL_I2C_3AXIS=m
CONFIG_KXSD9_I2C=m
CONFIG_MMA7455_I2C=m
CONFIG_BME680_I2C=m
CONFIG_SCD30_I2C=m
CONFIG_IIO_MS_SENSORS_I2C=m
CONFIG_IIO_ST_SENSORS_I2C=m
CONFIG_AD5696_I2C=m
CONFIG_BMG160_I2C=m
CONFIG_FXAS21002C_I2C=m
CONFIG_MPU3050_I2C=m
CONFIG_IIO_ST_GYRO_I2C_3AXIS=m
CONFIG_HTS221_I2C=m
CONFIG_BMI160_I2C=m
CONFIG_FXOS8700_I2C=m
CONFIG_INV_ICM42600_I2C=m
CONFIG_INV_MPU6050_I2C=m
CONFIG_IIO_ST_LSM6DSX_I2C=m
CONFIG_ST_UVIS25_I2C=m
CONFIG_BMC150_MAGN_I2C=m
CONFIG_IIO_ST_MAGN_I2C_3AXIS=m
CONFIG_SENSORS_HMC5843_I2C=m
CONFIG_SENSORS_RM3100_I2C=m
CONFIG_BMP280_I2C=m
CONFIG_MPL115_I2C=m
CONFIG_MS5611_I2C=m
CONFIG_IIO_ST_PRESS_I2C=m
CONFIG_ZPA2326_I2C=m
CONFIG_VL53L0X_I2C=m
CONFIG_CRYPTO_DEV_ATMEL_I2C=y

代码实现

通用类头文件与成员

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

#define MACRO_TO_CHECK_ERRNO(foo) {};

// 构造函数中初始化
std::string bus_name_;
uint8_t addr_;
int fd_;

驱动打开与配置函数

bool I2cDriver::open()
{
    MACRO_TO_CHECK_ERRNO(fd_ = ::open(bus_name_.c_str(), O_RDWR | O_NONBLOCK));
    MACRO_TO_CHECK_ERRNO(ioctl(fd_, I2C_SLAVE, addr_));
    MACRO_TO_CHECK_ERRNO(ioctl(fd_, I2C_PEC, 0));
    MACRO_TO_CHECK_ERRNO(ioctl(fd_, I2C_TIMEOUT, 50)); // 单位为10ms,50对应500ms
    return true;
}

设备写入操作函数

bool I2cDriver::write_handler(std::vector<uint8_t> &write_data) const
{
    pseudo_validate_data();

    const uint32_t num_msgs = 1;
    struct i2c_msg msgs[num_msgs]; // 来自i2c.h

    // 准备写消息
    msgs[0].addr = addr_;
    msgs[0].flags = 0;
    msgs[0].len = (uint16_t)write_data.size();
    msgs[0].buf = write_data.data();

    // 构建写事务
    struct i2c_rdwr_ioctl_data ioctl_data;
    ioctl_data.msgs = msgs;
    ioctl_data.nmsgs = num_msgs;

    // 执行写操作
    double start = pseudo_get_time();
    if (ioctl(fd_, I2C_RDWR, &ioctl_data) < 0)
    {
        double end = pseudo_get_time();
        i2c_timeout_log << "WRITE " << errnoname(errno) << ": " << end - start
                        << ": " << dev_name_.c_str() << std::endl;        
        return false;
    }

    return true;
}

内容的提问来源于stack exchange,提问作者Collin Peterson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 02:42:01