【i2cdetect工具原理说明】

i2cdetect工具原理说明

在嵌入式的开发,特别是与硬件交互时,经常会使用i2cdetect工具用于判断器件是否存在,但是返回显示的UU和–实际表示什么含义?

i2cdetect的使用示例

i2cdetect -y {bus}
例如:i2cdetect -y 10
i2cdetect扫描结果

i2cdetect原理

i2cdetect工具来源于i2c-tools:https://github.com/suapapa/i2c-tools.git

  1. 当使用i2cdetect工具扫描到实际器件时,显示器件地址;
  2. 当使用i2cdetect工具未扫描到实际器件时,显示--
  3. 当使用i2cdetect工具扫描时,发现地址已在驱动使用,显示UU
4. 遍历扫描地址0x08-0x77,i2c-tools工具中的函数 目录:tools/i2cdetect.c
static int scan_i2c_bus(int file, int mode, unsigned long funcs,
            int first, int last)
5.  首先使用ioctl(file, I2C_SLAVE, address)时,发现地址已经在驱动中使用,会返回EBUSY,显示为'UU',例如,eeprom驱动已经在/sys目录下创建了对应eeprom的文件,此时使用ioctl(file, I2C_SLAVE, address)命令访问此地址时返回EBUSY
调用kernel中的函数driver/i2c/i2c-dev.c中调用
static const struct file_operations i2cdev_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.read		= i2cdev_read,
	.write		= i2cdev_write,
	.unlocked_ioctl	= i2cdev_ioctl,
	.compat_ioctl	= compat_i2cdev_ioctl,
	.open		= i2cdev_open,
	.release	= i2cdev_release,
};
6. 在0x30-0x3f和0x50-0x5f使用MODE_READ,其他地址使用MODE_QUICK
MODE_READ对应函数i2c_smbus_read_byte(file),读一个byte,但是读取过程不符合标准i2c访问路径,仅是用于检测地址是否存在,所以访问过程是发送地址都直接进行了读字节操作,此时返回的字节是当前器件地址指向的位置,有些器件是offset为0位置所在的值,有些器件不是

MODE_QUICK对应函数i2c_smbus_write_quick(file, I2C_SMBUS_WRITE)
- drivers/i2c/i2c-core-smbus.c
- s32 i2c_smbus_read_byte(const struct i2c_client *client)
- - i2c_smbus_xfer(client->adapter, client->addr, client->flags,
                I2C_SMBUS_READ, 0,
                I2C_SMBUS_BYTE, &data);
- - - s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
             unsigned short flags, char read_write,
             u8 command, int protocol, union i2c_smbus_data *data) i2ctrace在这个函数中添加
- - - - res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write,
                      command, protocol, data); 此处进行的MODE_READ和MODE_QUICK的区分,MODE_READ是写完地址后直接读取一个字节数据; MODE_QUICK 仅写地址后判断是否有ACK响应
- - - - - status = __i2c_transfer(adapter, msg, nmsgs);
- drivers/i2c/busses/i2c-aspeed.c
- - .master_xfer   = aspeed_i2c_master_xfer

i2c访问成功返回对应的'地址',访问失败返回'--'

获取8bit地址,bit0读是1写是0
static inline u8 i2c_8bit_addr_from_msg(const struct i2c_msg *msg)
{
    return (msg->addr << 1) | (msg->flags & I2C_M_RD ? 1 : 0);
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值