Re: read /dev/iio:device0 return -1 (Invalid argument)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Jonathan,

Right now, the app is able to read the data from /dev/iio:device0 with
success (not data loss). Currently, the app read 1 sample (with 9
channels of 4 bytes each one) every time (using "read" function).

I still have some doubts about my implementation, because, sometimes
there is data lost.

For example, when the app try to read more than 1 sample (for example,
2 samples: 72 bytes, using "read"), the results are strange. For
instance, when the app is using libiio, the function iio_buffer_refill
return -1 and is not able to receive data. In this case, the buffer
(at iio_device_create_buffer) need to be setup with 1 sample to work.

Below some assumptions/questions:

- The buffer/length define the kfifo length (in samples, not in
bytes)? In this case, the buffer must be multiple of 36 bytes right?
- At user space, the application can read 36 bytes or more (i.e. 72,
...) (/dev/iio:device0) (but not less)? According with the buffer
length.

Thanks


On Sat, Dec 12, 2015 at 8:41 PM, Julio Cruz <jcsistemas2001@xxxxxxxxx> wrote:
> OK, I understood! Thanks
>
> I will use 32 bits for storage in all the channels
>
> On Sat, Dec 12, 2015 at 8:35 PM, Jonathan Cameron
> <jic23@xxxxxxxxxxxxxxxxxxxxx> wrote:
>> On 12/12/15 12:24, Julio Cruz wrote:
>>> HI Jonathan,
>> Hi Julio
>>
>> I've kept the list cc'd as this sort of conversation acts as
>> 'free' documentation solving other people's problems in future.
>>
>>>
>>> Thanks for your quick reply.
>>>
>>> When you mention the alignment, I remember some things that I did
>>> about it, as below.
>>>
>>> When I started testing the _trigger_handler, I found that the driver
>>> calculate indio_dev->scan_bytes. This value is not clear to me
>>> because, for example, 1 channel is 3 bytes,
>> It shouldn't be. Padding is to the nearest power of 2 bytes so should
>> be 4.  The non power of two realbits may have resulted in an unexpected
>> path in which case we should add a sanity check to catch this.
>>> and for 2 channels is 8
>>> bytes (1 byte padding). The channel spec are realbits = 24 and
>>> storagebits = 24.
>> Storage bits should be a power of 2.  So in this case 32 bytes.
>> Might seem wasteful but processors handle aligned data a lot
>> more easily so to keep rates up it is usually better to burn a small
>> amount of memory and keep everything aligned.
>>
>>  At that point, I fixed the frame buffer size to 27
>>> (used at iio_push_to_buffers) assuming that the same buffer could be
>>> read at user space.
>>>
>>> Please, may I know if this approach is correct?
>> Sorry nope, the buffer structure assumes power of 2 alignment everywhere.
>>>
>>> The SPI device send 9 channels, 3 bytes each one (for a total of 27
>>> bytes) and each channels is 24 bits width.
>> Unfortunately you'll have to do unpacking of this before pushing to the buffer.
>> It'll have to happen somewhere anyway (as userspace code would need to unpack
>> it otherwise).
>>
>> It's actually relatively unusual to find a device that does this sort of
>> packing.  We have talked in the past about allowing this sort of packing and
>> modifying the buffer infrastructure to accept it, but I'm unconvinced that
>> it is worth the added complexity + cost in userspace complexity.
>>
>> Jonathan
>>>
>>> Thanks
>>>
>>> Julio
>>>
>>>
>>> On Sat, Dec 12, 2015 at 7:51 PM, Jonathan Cameron <jic23@xxxxxxxxxx> wrote:
>>>> On 12/12/15 08:36, Julio Cruz wrote:
>>>>> Hi,
>>>>>
>>>>> I get an error trying to read /dev/iio:device0 in a custom application
>>>>> (C/C++), however in a terminal the command "cat /dev/iio_device0"
>>>>> return data.
>>>>>
>>>>> Below the procedure:
>>>>>
>>>>> - enable channels
>>>>> - setup trigger
>>>>> - setup buffer lenght
>>>>> - enable buffer (the SPI interrupt is setup properly and all the
>>>>> trigger handler are done)
>>>>> - read /dev/iio_device0
>>>>>
>>>>> It's a SPI device acquiring 27 bytes @ 1KHz.
>>>> Reading this again after point 4 below this makes me ask the question
>>>> what are you pushing into the buffer? 27 bytes seems unlikely given
>>>> the alignment requirements.
>>>>
>>>>>
>>>>> Results:
>>>>>
>>>>> 1. Custom application (based on generic_buffer.c): function 'read'
>>>>> return -1 and strerror(errno) return "Invalid argument"
>>>>> 2. iio_readdev (libiio): show the message "Unable to refill buffer:
>>>>> Input/output error"
>>>>> 3. In terminal, the command "cat /dev/iio_device0" show values (no
>>>>> readable) while the buffer is enable.
>>>>>
>>>>> Any suggestion?
>>>>>
>>>>> Thanks for your help!
>>>> Sounds like you are ultimately getting that error from a call to
>>>>  iio_buffer_read_first_n_outer
>>>> so what can return -EINVAL (which is -1)?
>>>>
>>>> 1) Buffer not being allocated (seems unlikely - that's really just to
>>>> pick up on bugs in side the driver)
>>>> 2) read_first_n from the buffer not supplied - again not likely.
>>>> 3) wait_event_interruptible returns it - unlikely.
>>>> 4) read_first_n which comes from the buffer implementation is returning -EINVAL
>>>> This last one seems most likely.
>>>>
>>>> So I am guessing you are using the kfifo buffer (most common option).
>>>> Reasons this can return -EINVAL are
>>>> 1) kfifo not initialized (unlikely)
>>>> 2) Read length is less than the buffer element size (which is the full scan storage
>>>> size)
>>>> 3) an error from kfifo_to_user (unlikely)
>>>>
>>>> So I'm guessing you are reading too small an amount of data. (tricky to chase
>>>> down without adding further printk's etc to the relevant bits of kernel code)
>>>> If I've 'guessed' right, interesting question is how this came about.
>>>> How many bytes is it trying to read?
>>>>
>>>> Note that IIO has strict alignment requirements - any element must be aligned
>>>> to it's own size and this will in some case add lots of padding.  The full buffer
>>>> element will be a multiple of the largest element in the scan.  If you have a timestamp
>>>> for example at 64bits the whole buffer element will be a multiple of 8bytes.
>>>>
>>>> Jonathan
>>>>> --
>>>>> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
>>>>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>>
>>>>
>>
--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux