[PATCH v3] i2c_tools.c: add i2ctransfer utility

Nikolaus Voss nv at vosn.de
Mon Feb 11 10:16:00 UTC 2019


Hi Denys,

many thanks for reviewing and merging this. For my use case it works as 
expected with your modifications.

On Sun, 10 Feb 2019, Denys Vlasenko wrote:
> On Sun, Feb 10, 2019 at 7:24 PM Denys Vlasenko <vda.linux at googlemail.com> wrote:
>> On Mon, Jan 7, 2019 at 2:29 PM Nikolaus Voss <nv at vosn.de> wrote:
>>> i2ctransfer sends and receives user defined i2c messages
>>> v2: apply Xabier's comments: add -a option, don't decrement argc,
>>>     use bb_show_usage() and xzalloc()
>>> v3: fix possible out of bound access to msgs[nmsgs]
>>>
>>> Reviewed-by: Xabier Oneca -- xOneca <xoneca at gmail.com>
>>> Signed-off-by: Nikolaus Voss <nikolaus.voss at loewensteinmedical.de>
>>> ---
>>>  miscutils/i2c_tools.c | 206 +++++++++++++++++++++++++++++++++++++++++-
>>>  1 file changed, 205 insertions(+), 1 deletion(-)
>>>
>>> +                       switch (*arg_ptr++) {
>>> +                       case 'r': flags |= I2C_M_RD; break;
>>> +                       case 'w': break;
>>> +                       default:
>>> +                               bb_show_usage();
>>> +                       }
>>> +
>>> +                       len = strtoul(arg_ptr, &end, 0);
>>> +                       if (len > 0xffff || arg_ptr == end)
>>> +                               bb_error_msg_and_die("Error: Length invalid: %s\n", *argv);
>>> +
>>> +                       arg_ptr = end;
>>> +                       if (*arg_ptr) {
>>> +                               if (*arg_ptr++ != '@')
>>> +                                       bb_error_msg_and_die("Error: Unknown separator after length: %s\n",
>>> +                                                    *argv);
>>> +                               bus_addr = xstrtou_range(arg_ptr, 0, first, last);
>>> +
>>> +                               if (!(opts & opt_f))
>>> +                                       i2c_set_slave_addr(fd, bus_addr, opts & opt_f);
>>
>> This last if() looks fishy. What is it trying to accomplish?

It skips kernel range and busy checking if -f is set:
/tmp # i2cdetect -y 6
i2cdetect: warning: can't use SMBus quick write command, will skip some 
addresses
      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:
10:
20:
30: -- -- -- -- UU -- -- --
40:
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60:
70:
/tmp # i2ctransfer -y 6 w1 at 0x34 0 r1
i2ctransfer: can't set address to 0x34: Device or resource busy
/tmp # i2ctransfer -f -y 6 w1 at 0x34 0 r1
0x04

As range checking is already done in user mode, only busy checking is 
effective, which is skipped if the force flag of i2c_set_slave_addr() is 
set. So i2c_set_slave_addr() could/should be be called unconditionally, 
the above example would create exactly the same output.

Nikolaus


More information about the busybox mailing list