您尚未登录。

楼主 # 2021-06-13 11:57:38

leeon231
会员
注册时间: 2021-06-11
已发帖子: 9
积分: 4.5

V3s cat 出现 I/O error

调试 W1 总线时, 设备注册没有问题
但是在查看 eeprom 数据时报错
/system/bin/sh: cat: eeprom: I/O error

离线

#1 2021-06-13 12:09:55

拉轰的脚踏车
会员
注册时间: 2020-03-20
已发帖子: 288
积分: 222

Re: V3s cat 出现 I/O error

命令行是啥? 驱动是怎么写的, 跟踪一下驱动的 write 函数.

离线

楼主 #2 2021-06-13 12:15:23

leeon231
会员
注册时间: 2021-06-11
已发帖子: 9
积分: 4.5

Re: V3s cat 出现 I/O error

lrwxrwxrwx root     root              2021-01-01 00:21 driver -> ../../../bus/w1/drivers/w1_slave_driver
-rw-rw-rw- root     root          128 2021-01-01 00:21 eeprom
-r--r--r-- root     root         4096 2021-01-01 00:21 id
-r--r--r-- root     root         4096 2021-01-01 00:21 name
lrwxrwxrwx root     root              2021-01-01 00:21 subsystem -> ../../../bus/w1
-rw-r--r-- root     root         4096 2021-01-01 00:21 uevent

cat eeprom 

/system/bin/sh: cat: eeprom: I/O error
static int w1_f0d_write(struct w1_slave *sl, int addr, int len, const u8 *data)
{
	int tries = W1_F0D_READ_RETRIES;
	u8 wrbuf[3];
	u8 rdbuf[W1_F0D_SCRATCH_SIZE];
	u8 cs;
	if ((addr & 1) || (len != 2)) {
		dev_err(&sl->dev, "%s: bad addr/len -  addr=%#x len=%d\n",
		    __func__, addr, len);
		return -1;
	}
retry:
	if (w1_reset_select_slave(sl)) {
		if (--tries)
			goto retry;
	}
	wrbuf[0] = W1_F0D_WRITE_EEPROM;
	wrbuf[1] = addr & 0xff;
	wrbuf[2] = 0xff; 
	w1_write_block(sl->master, wrbuf, sizeof(wrbuf));
	w1_write_block(sl->master, data, len);
	w1_read_block(sl->master, rdbuf, sizeof(rdbuf));

	if ((rdbuf[0] != data[0]) || (rdbuf[1] != data[1])) {
		if (--tries)
			goto retry;
		dev_err(&sl->dev,
			"could not write to eeprom, scratchpad compare failed %d times\n",
			W1_F0D_READ_RETRIES);
		pr_info("%s: rdbuf = %#x %#x data = %#x %#x\n",
		    __func__, rdbuf[0], rdbuf[1], data[0], data[1]);
		return -1;
	}

	w1_write_8(sl->master, W1_F0D_RELEASE);
	msleep(W1_F0D_TPROG_MS);
	cs = w1_read_8(sl->master);
	if (cs != W1_F0D_CS_OK) {
		if (--tries)
			goto retry;
		dev_err(&sl->dev, "save to eeprom failed = CS=%#x\n", cs);
		return -1;
	}
	return 0;
}

static ssize_t w1_f0d_write_bin(struct file *filp, struct kobject *kobj,
				struct bin_attribute *bin_attr,
				char *buf, loff_t off, size_t count)
{
	struct w1_slave *sl = kobj_to_w1_slave(kobj);
	int addr, len;
	int copy;
	count = w1_f0d_fix_count(off, count, W1_F0D_EEPROM_SIZE);
	if (count == 0)
		return 0;
	mutex_lock(&sl->master->mutex);
	addr = off;
	len = count;
	while (len > 0) {
		if (len < W1_F0D_SCRATCH_SIZE || addr & W1_F0D_SCRATCH_MASK) {
			char tmp[W1_F0D_SCRATCH_SIZE];
			if (w1_f0d_readblock(sl, addr & ~W1_F0D_SCRATCH_MASK,
					W1_F0D_SCRATCH_SIZE, tmp)) {
				count = -EIO;
				goto out_up;
			}
			copy = W1_F0D_SCRATCH_SIZE -
				(addr & W1_F0D_SCRATCH_MASK);
			if (copy > len)
				copy = len;
			memcpy(&tmp[addr & W1_F0D_SCRATCH_MASK], buf, copy);
			if (w1_f0d_write(sl, addr & ~W1_F0D_SCRATCH_MASK,
					W1_F0D_SCRATCH_SIZE, tmp) < 0) {
				count = -EIO;
				goto out_up;
			}
		} else {
			copy = W1_F0D_SCRATCH_SIZE;
			if (w1_f0d_write(sl, addr, copy, buf) < 0) {
				count = -EIO;
				goto out_up;
			}
		}
		buf += copy;
		addr += copy;
		len -= copy;
	}
out_up:
	mutex_unlock(&sl->master->mutex);
	return count;
}

读写权限是开放的
static struct bin_attribute w1_f0d_bin_attr = {
    .attr = {
        .name = "eeprom",
        .mode = S_IRUGO | S_IWUGO,
        //.mode = S_IRUSR|S_IRGRP|S_IROTH | S_IWUSR|S_IWGRP|S_IWOTH,
    },
    .size = W1_F0D_EEPROM_SIZE,
    .read = w1_f0d_read_bin,
    .write = w1_f0d_write_bin,
};

离线

#3 2021-06-13 12:18:04

拉轰的脚踏车
会员
注册时间: 2020-03-20
已发帖子: 288
积分: 222

Re: V3s cat 出现 I/O error

w1_f0d_write_bin( )

这里面加点调试语句看看

离线

楼主 #4 2021-06-13 14:44:09

leeon231
会员
注册时间: 2021-06-11
已发帖子: 9
积分: 4.5

Re: V3s cat 出现 I/O error

添加调试节点定位问题点定位在
w1_reset_select_slave(sl)  ->  w1_reset_bus(sl->master)

从代码来看应该是复位时序导致的问题,继续。。。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn