Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iio_refill_buffer() return different when use local context and network context #740

Closed
ChenhuiZhang opened this issue Aug 31, 2021 · 36 comments · Fixed by #744
Closed

iio_refill_buffer() return different when use local context and network context #740

ChenhuiZhang opened this issue Aug 31, 2021 · 36 comments · Fixed by #744
Assignees

Comments

@ChenhuiZhang
Copy link

Hi all,

I'm using iiod to let multiple application can access the 3 accel and 3 gyro data, but it get some problem when enable network context.
E.g. when I enable channel 0/1/2 4/5/6 to fetch 3 accel and 3 gyro data, if I create a local context, it works as expect, each iio_refill_buffer() return the sample with 12 bytes (2 * 3 + 2 * 3), and if I use iio_buffer_foreach_sample() I could get some print as below:

** Message: 11:32:54.555: Read 2 from accel_x
** Message: 11:32:54.555: Read 2 from accel_y
** Message: 11:32:54.556: Read 2 from accel_z
** Message: 11:32:54.556: Read 2 from anglvel_x
** Message: 11:32:54.556: Read 2 from anglvel_y
** Message: 11:32:54.556: Read 2 from anglvel_z
** Message: 11:32:54.556: Read 2 from accel_x
** Message: 11:32:54.556: Read 2 from accel_y
** Message: 11:32:54.557: Read 2 from accel_z
** Message: 11:32:54.557: Read 2 from anglvel_x
** Message: 11:32:54.557: Read 2 from anglvel_y
** Message: 11:32:54.557: Read 2 from anglvel_z

But when I switch to the network context, the sample size seems double: 24 bytes (from iio_buffer_step()), and compare with local context, I get half data (e.g. I use block refill(), so in local context I could call refill 8 times in one second, but in network context, I only could call 4 times), but the sample size (from iio_buffer_step()) is double (12 -> 24). But if I still call iio_buffer_foreach_sample(), I got below print:

** Message: 11:34:36.032: Read 2 from accel_x
** Message: 11:34:36.033: Read 2 from accel_y
** Message: 11:34:36.033: Read 2 from accel_z
** Message: 11:34:36.033: Read 2 from anglvel_y
** Message: 11:34:36.034: Read 2 from anglvel_z
** Message: 11:34:36.034: Read 8 from timestamp
** Message: 11:34:36.034: Read 2 from accel_x
** Message: 11:34:36.035: Read 2 from accel_y
** Message: 11:34:36.035: Read 2 from accel_z
** Message: 11:34:36.035: Read 2 from anglvel_y
** Message: 11:34:36.036: Read 2 from anglvel_z
** Message: 11:34:36.036: Read 8 from timestamp

So it seems the data in call back is wrong. And now I only have one client connect to iiod server, so it should same as we use local context, right? Why I got such difference between local and network context?

Anyone have any suggestion? Thanks.

Best Regards,
Hermes

@tfcollins
Copy link
Contributor

Can you provide more information on your hardware setup and the version of libiio you are using?

@ChenhuiZhang
Copy link
Author

Hi,

Sure. The HW is icm20600 chip and libiio is 0.21.

Any more question please let me know. Thanks.

Best Regards,
Hermes

@pcercuei
Copy link
Contributor

pcercuei commented Sep 1, 2021

Hi,

Since you are multiplexing the output to multiple applications, this is totally expected. Each application will get the samples that correspond to the union of all the channels enabled by the various applications, and will then have to demultiplex the data with iio_buffer_foreach_sample(), or iio_channel_read().

Note that if you run iiod with the -D option, the demultiplexing will happen inside IIOD. However this is not a "safe" solution, as this option will be removed at some point in the future.

Cheers,
-Paul

@ChenhuiZhang
Copy link
Author

Hi Paul,

Thanks for the info. But for my case here, I only have one client work with iiod. And I also try the iio_buffer_foreach_sample(), in the sample_cb() I print each channel, but the result is also strange, it only print channel accl_x, accl_y, acc_z, and angl_y, angl_z and timestamp. So it miss angl_x but another channel timestamp.

I also try to force decode the 24 bytes sample as accl_x + accl_y + accl_z + angl_x + angl_y + angl_z and repeat again, it seems the date is correct. which means I ask for 25 samples in one buffer_refill(), but actually it return in 50 samples (2 samples in one sample_size)

I also doubt if there is something wrong in the icm20600 driver, but if I use local context, it works. I guess something is wrong in the network part. Do you know if there is something I can debug from the iiod? To print more info regarding the multiplexing part. Thanks!

Best Regards,
Hermes

@pcercuei
Copy link
Contributor

pcercuei commented Sep 2, 2021

Hi Hermes,

The iio_device and iio_buffer both have a channel mask (the field is named "mask"). When a bit is set, the corresponding channel (in order of appearance in the iio_device structure) is enabled. If zero, it is disabled.

The one in iio_device represents the channels that you did enable with iio_channel_enable(). The one in iio_buffer represents the channels for which the buffer has samples.

Could you print these two, for instance after refilling?

Also, please provide the output of iio_info.

By the way, just to be sure that we are not debugging a bug that was already fixed before, please consider updating to libiio v0.23 on both your target and your PC.

Cheers,
-Paul

@ChenhuiZhang
Copy link
Author

Hi Paul,

I upgrade the libiio to v0.23 and do two tests as below:

  1. Create a local context and run the application.
  2. Create a network context and run the application.

Detail log you could find here: https://gist.github.com/ChenhuiZhang/bbff8e5bd07cf04a5afa156454f6ddc7.

The big difference is if I switch local context to network (even there is only one client), the buffer refill return the sample size is difference and content seems has something wrong( raw looks ok, but if demux by iio_buffer_foreach_sample() it seems wrong).

Best Regards,
Hermes

@pcercuei
Copy link
Contributor

pcercuei commented Sep 6, 2021

Hi Hermes,

Please provide the output of iio_info on both sides (local and remote).

-Paul

@ChenhuiZhang
Copy link
Author

It has include in the log file. I enable the iio_debug(), the local is iiod, and the remote (actually in same machine) is application. Or do you mean something else?

Best Regards,
Hermes

@pcercuei
Copy link
Contributor

pcercuei commented Sep 6, 2021

I mean the output of the iio_info program.

@ChenhuiZhang
Copy link
Author

OK, here it is:

IIO context created with local backend.
Backend version: 0.23 (git tag: 92d6a35)
Backend description string: Linux axis-b8a44f276d49 4.14.173-axis8-devel #1 SMP PREEMPT Tue Aug 31 10:46:05 UTC 2021 aarch64
IIO context has 2 attributes:
	local,kernel: 4.14.173-axis8-devel
	uri: local:
IIO context has 4 devices:
	iio:device0: e801d000.adc (buffer capable)
		1 channels found:
			voltage1:  (input, index: 0, format: le:u12/16>>0)
			3 channel-specific attributes found:
				attr  0: enable value: 1
				attr  1: raw value: 785
				attr  2: scale value: 0.805664062
		1 device-specific attributes found:
				attr  0: sampling_frequency value: 150000
		1 buffer-specific attributes found:
				attr  0: watermark value: 1
		Current trigger: trigger0(e801d000.adc-dev0)
	iio:device1: icm20600 (buffer capable)
		9 channels found:
			accel_x:  (input, index: 0, format: be:S16/16>>0)
			6 channel-specific attributes found:
				attr  0: calibbias value: -620
				attr  1: matrix value: 0, 0, 0; 0, 0, 0; 0, 0, 0
				attr  2: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  3: raw value: -16566
				attr  4: scale value: 0.000598
				attr  5: scale_available value: 0.000598 0.001196 0.002392 0.004785
			accel_y:  (input, index: 1, format: be:S16/16>>0)
			6 channel-specific attributes found:
				attr  0: calibbias value: 0
				attr  1: matrix value: 0, 0, 0; 0, 0, 0; 0, 0, 0
				attr  2: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  3: raw value: 814
				attr  4: scale value: 0.000598
				attr  5: scale_available value: 0.000598 0.001196 0.002392 0.004785
			accel_z:  (input, index: 2, format: be:S16/16>>0)
			6 channel-specific attributes found:
				attr  0: calibbias value: -9216
				attr  1: matrix value: 0, 0, 0; 0, 0, 0; 0, 0, 0
				attr  2: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  3: raw value: 130
				attr  4: scale value: 0.000598
				attr  5: scale_available value: 0.000598 0.001196 0.002392 0.004785
			temp:  (input)
			3 channel-specific attributes found:
				attr  0: offset value: 8170
				attr  1: raw value: 8272
				attr  2: scale value: 0.003059
			anglvel_x:  (input, index: 4, format: be:S16/16>>0)
			5 channel-specific attributes found:
				attr  0: calibbias value: 0
				attr  1: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  2: raw value: -4
				attr  3: scale value: 0.001064724
				attr  4: scale_available value: 0.000133090 0.000266181 0.000532362 0.001064724
			anglvel_y:  (input, index: 5, format: be:S16/16>>0)
			5 channel-specific attributes found:
				attr  0: calibbias value: 0
				attr  1: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  2: raw value: -12
				attr  3: scale value: 0.001064724
				attr  4: scale_available value: 0.000133090 0.000266181 0.000532362 0.001064724
			anglvel_z:  (input, index: 6, format: be:S16/16>>0)
			5 channel-specific attributes found:
				attr  0: calibbias value: 0
				attr  1: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  2: raw value: 6
				attr  3: scale value: 0.001064724
				attr  4: scale_available value: 0.000133090 0.000266181 0.000532362 0.001064724
			timestamp:  (input, index: 7, format: le:S64/64>>0)
			gyro:  (input, WARN:iio_channel_get_type()=UNKNOWN)
			1 channel-specific attributes found:
				attr  0: matrix value: 0, 0, 0; 0, 0, 0; 0, 0, 0
		4 device-specific attributes found:
				attr  0: current_timestamp_clock value: realtime

				attr  1: sampling_frequency value: 50
				attr  2: sampling_frequency_available value: 10 20 50 100 200 500
				attr  3: self_test ERROR: Permission denied (13)
		1 buffer-specific attributes found:
				attr  0: watermark value: 1
		Current trigger: trigger1(icm20600-dev1)
	trigger0: e801d000.adc-dev0
		0 channels found:
		No trigger on this device
	trigger1: icm20600-dev1
		0 channels found:
		No trigger on this device

@pcercuei
Copy link
Contributor

pcercuei commented Sep 6, 2021

From what I can see, with the local backend you enable the accel x/y/z channels and angvel x/y/z, and on the network backend you enable the accel x/y/z, angvel y/z and timestamp channels. Since "timestamp" gives 8-byte data, you end up with 18 bytes of actual data which is then padded to 24 bytes.

My guess is that you expect angvel x/y/z to be the channels 4/5/6 and harcode that in your application; but this is not an assumption you should make. If that's the case, please use iio_device_find_channel instead, to get pointers to the accel x/y/z and angvel x/y/z channels.

@ChenhuiZhang
Copy link
Author

Interesting to know. So you mean the angvel channel for x/y/z are not fixed? Or it depend on the something else? So I need to use iio_device_find_channel to get the correct channel and enable them?

Best Regards,
Hermes

@pcercuei
Copy link
Contributor

pcercuei commented Sep 6, 2021

You need to use iio_device_find_channel, yes. This is the safest thing to do, since you know for sure that you are getting the right channels.

With that said... it should not be different between the local and network backends, so if the ordering of the channels is indeed different between the local and network backends, then it should be fixed.

If you run iio_info over the network (with iio_info -u ip:127.0.0.1, replace with the real IP address), then you should be able to confirm that the channels are not ordered the same way.

@ChenhuiZhang
Copy link
Author

Hi Paul,

I just do a quick test, I enable all 6 channels by iio_device_find_channel(), the sample size looks correct, but I still only get half data in one second. See below log:

DEBUG: MSG_TRUNC is supported
DEBUG: Creating context...
DEBUG: Added  attr 'sampling_frequency' to device 'iio:device0'
DEBUG: Added buffer attr 'watermark' to device 'iio:device0'
DEBUG: Added device 'iio:device0' to context 'xml'
DEBUG: Added  attr 'current_timestamp_clock' to device 'iio:device1'
DEBUG: Added  attr 'sampling_frequency' to device 'iio:device1'
DEBUG: Added  attr 'sampling_frequency_available' to device 'iio:device1'
DEBUG: Added  attr 'self_test' to device 'iio:device1'
DEBUG: Added buffer attr 'watermark' to device 'iio:device1'
DEBUG: Added device 'iio:device1' to context 'xml'
DEBUG: Added device 'trigger0' to context 'xml'
DEBUG: Added device 'trigger1' to context 'xml'
** Message: 11:34:52.909: Enable accel_x: 0x55ad47b4c0
** Message: 11:34:52.910: Enable accel_y: 0x55ad46ec50
** Message: 11:34:52.911: Enable accel_z: 0x55ad463a20
** Message: 11:34:52.911: Enable anglvel_x: 0x55ad464dd0
** Message: 11:34:52.913: Enable anglvel_y: 0x55ad464f70
** Message: 11:34:52.914: Enable anglvel_z: 0x55ad465130
In iio_device_get_sample_size_mask, mask: 0x3f, words: 1
** Message: 11:34:52.918: ---Fall detection algorithm running---
In iio_device_get_sample_size_mask, mask: 0x3f, words: 1
In iio_buffer_refill, buffer->mask: 0x3f
DEBUG: Reading mask
DEBUG: mask[0] = 0x0000003f
In iio_device_get_sample_size_mask, mask: 0x3f, words: 1

** (process:1475): WARNING **: 11:34:53.437: sample_size: 12, length: 300

** (process:1475): WARNING **: 11:34:53.439: 4183 476500
In iio_buffer_refill, buffer->mask: 0x3f
DEBUG: Reading mask
DEBUG: mask[0] = 0x0000003f
In iio_device_get_sample_size_mask, mask: 0x3f, words: 1

** (process:1475): WARNING **: 11:34:53.688: sample_size: 12, length: 300

** (process:1475): WARNING **: 11:34:53.689: 4183 726596
In iio_buffer_refill, buffer->mask: 0x3f
DEBUG: Reading mask
DEBUG: mask[0] = 0x0000003f
In iio_device_get_sample_size_mask, mask: 0x3f, words: 1

** (process:1475): WARNING **: 11:34:53.938: sample_size: 12, length: 300

** (process:1475): WARNING **: 11:34:53.939: 4183 977099
In iio_buffer_refill, buffer->mask: 0x3f
DEBUG: Reading mask
DEBUG: mask[0] = 0x0000003f
In iio_device_get_sample_size_mask, mask: 0x3f, words: 1

** (process:1475): WARNING **: 11:34:54.188: sample_size: 12, length: 300

** (process:1475): WARNING **: 11:34:54.189: 4184 226671
In iio_buffer_refill, buffer->mask: 0x3f
DEBUG: Reading mask
DEBUG: mask[0] = 0x0000003f
In iio_device_get_sample_size_mask, mask: 0x3f, words: 1

** (process:1475): WARNING **: 11:34:54.439: sample_size: 12, length: 300

** (process:1475): WARNING **: 11:34:54.440: 4184 477982
In iio_buffer_refill, buffer->mask: 0x3f
DEBUG: Reading mask
DEBUG: mask[0] = 0x0000003f
In iio_device_get_sample_size_mask, mask: 0x3f, words: 1

** (process:1475): WARNING **: 11:34:54.689: sample_size: 12, length: 300

** (process:1475): WARNING **: 11:34:54.689: 4184 727176
In iio_buffer_refill, buffer->mask: 0x3f
DEBUG: Reading mask
DEBUG: mask[0] = 0x0000003f
In iio_device_get_sample_size_mask, mask: 0x3f, words: 1

** (process:1475): WARNING **: 11:34:54.941: sample_size: 12, length: 300

** (process:1475): WARNING **: 11:34:54.944: 4184 981782
In iio_buffer_refill, buffer->mask: 0x3f
DEBUG: Reading mask
DEBUG: mask[0] = 0x0000003f
In iio_device_get_sample_size_mask, mask: 0x3f, words: 1

** (process:1475): WARNING **: 11:34:55.190: sample_size: 12, length: 300

** (process:1475): WARNING **: 11:34:55.191: 4185 228535
In iio_buffer_refill, buffer->mask: 0x3f
DEBUG: Reading mask
DEBUG: mask[0] = 0x0000003f
In iio_device_get_sample_size_mask, mask: 0x3f, words: 1

** (process:1475): WARNING **: 11:34:55.442: sample_size: 12, length: 300

** (process:1475): WARNING **: 11:34:55.445: 4185 482830
In iio_buffer_refill, buffer->mask: 0x3f
DEBUG: Reading mask
DEBUG: mask[0] = 0x0000003f
In iio_device_get_sample_size_mask, mask: 0x3f, words: 1

** (process:1475): WARNING **: 11:34:55.692: sample_size: 12, length: 300

** (process:1475): WARNING **: 11:34:55.695: 4185 732566
In iio_buffer_refill, buffer->mask: 0x3f
DEBUG: Reading mask
DEBUG: mask[0] = 0x0000003f
In iio_device_get_sample_size_mask, mask: 0x3f, words: 1

** (process:1475): WARNING **: 11:34:55.941: sample_size: 12, length: 300

** (process:1475): WARNING **: 11:34:55.943: 4185 981172
In iio_buffer_refill, buffer->mask: 0x3f
DEBUG: Reading mask
DEBUG: mask[0] = 0x0000003f
In iio_device_get_sample_size_mask, mask: 0x3f, words: 1

** (process:1475): WARNING **: 11:34:56.191: sample_size: 12, length: 300

** (process:1475): WARNING **: 11:34:56.192: 4186 229685
In iio_buffer_refill, buffer->mask: 0x3f

sample_size: 12, length: 300 means 300/12 = 25 sample count, but I set the sample_freq is 200, so it expect 8 times return from buffer_refill() in one second, but now it's only 4 times.

And yes, from iio_info -u ip:127.0.0.1, I see a different channel mapping:

root@axis-b8a44f276d49:~# iio_info -u ip:127.0.0.1
Library version: 0.23 (git tag: 92d6a35)
Compiled with backends: local xml ip
DEBUG: MSG_TRUNC is supported
DEBUG: Creating context...
DEBUG: Added  attr 'sampling_frequency' to device 'iio:device0'
DEBUG: Added buffer attr 'watermark' to device 'iio:device0'
DEBUG: Added device 'iio:device0' to context 'xml'
DEBUG: Added  attr 'current_timestamp_clock' to device 'iio:device1'
DEBUG: Added  attr 'sampling_frequency' to device 'iio:device1'
DEBUG: Added  attr 'sampling_frequency_available' to device 'iio:device1'
DEBUG: Added  attr 'self_test' to device 'iio:device1'
DEBUG: Added buffer attr 'watermark' to device 'iio:device1'
DEBUG: Added device 'iio:device1' to context 'xml'
DEBUG: Added device 'trigger0' to context 'xml'
DEBUG: Added device 'trigger1' to context 'xml'
IIO context created with network backend.
Backend version: 0.23 (git tag: 92d6a35)
Backend description string: 127.0.0.1 Linux axis-b8a44f276d49 4.14.173-axis8-devel #1 SMP PREEMPT Tue Aug 31 10:46:05 UTC 2021 aarch64
IIO context has 3 attributes:
	local,kernel: 4.14.173-axis8-devel
	uri: ip:127.0.0.1
	ip,ip-addr: 127.0.0.1
IIO context has 4 devices:
	iio:device0: e801d000.adc (buffer capable)
		1 channels found:
			voltage1:  (input, index: 0, format: le:u12/16>>0)
			3 channel-specific attributes found:
				attr  0: enable value: 1
				attr  1: raw value: 729
				attr  2: scale value: 0.805664062
		1 device-specific attributes found:
				attr  0: sampling_frequency value: 150000
		1 buffer-specific attributes found:
				attr  0: watermark value: 1
		Current trigger: trigger0(e801d000.adc-dev0)
	iio:device1: icm20600 (buffer capable)
		9 channels found:
			accel_x:  (input, index: 0, format: be:S16/16>>0)
			6 channel-specific attributes found:
				attr  0: calibbias value: -620
				attr  1: matrix value: 0, 0, 0; 0, 0, 0; 0, 0, 0
				attr  2: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  3: raw value: -2066
				attr  4: scale value: 0.004785
				attr  5: scale_available value: 0.000598 0.001196 0.002392 0.004785
			accel_y:  (input, index: 1, format: be:S16/16>>0)
			6 channel-specific attributes found:
				attr  0: calibbias value: 0
				attr  1: matrix value: 0, 0, 0; 0, 0, 0; 0, 0, 0
				attr  2: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  3: raw value: 94
				attr  4: scale value: 0.004785
				attr  5: scale_available value: 0.000598 0.001196 0.002392 0.004785
			accel_z:  (input, index: 2, format: be:S16/16>>0)
			6 channel-specific attributes found:
				attr  0: calibbias value: -9216
				attr  1: matrix value: 0, 0, 0; 0, 0, 0; 0, 0, 0
				attr  2: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  3: raw value: 17
				attr  4: scale value: 0.004785
				attr  5: scale_available value: 0.000598 0.001196 0.002392 0.004785
			anglvel_x:  (input, index: 4, format: be:S16/16>>0)
			5 channel-specific attributes found:
				attr  0: calibbias value: 0
				attr  1: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  2: raw value: -4
				attr  3: scale value: 0.001064724
				attr  4: scale_available value: 0.000133090 0.000266181 0.000532362 0.001064724
			anglvel_y:  (input, index: 5, format: be:S16/16>>0)
			5 channel-specific attributes found:
				attr  0: calibbias value: 0
				attr  1: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  2: raw value: -14
				attr  3: scale value: 0.001064724
				attr  4: scale_available value: 0.000133090 0.000266181 0.000532362 0.001064724
			anglvel_z:  (input, index: 6, format: be:S16/16>>0)
			5 channel-specific attributes found:
				attr  0: calibbias value: 0
				attr  1: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  2: raw value: 7
				attr  3: scale value: 0.001064724
				attr  4: scale_available value: 0.000133090 0.000266181 0.000532362 0.001064724
			timestamp:  (input, index: 7, format: le:S64/64>>0)
			temp:  (input)
			3 channel-specific attributes found:
				attr  0: offset value: 8170
				attr  1: raw value: 8336
				attr  2: scale value: 0.003059
			gyro:  (input, WARN:iio_channel_get_type()=UNKNOWN)
			1 channel-specific attributes found:
				attr  0: matrix value: 0, 0, 0; 0, 0, 0; 0, 0, 0
		4 device-specific attributes found:
				attr  0: current_timestamp_clock value: realtime

				attr  1: sampling_frequency value: 200
				attr  2: sampling_frequency_available value: 10 20 50 100 200 500
				attr  3: self_test ERROR: Permission denied (13)
		1 buffer-specific attributes found:
				attr  0: watermark value: 1
		Current trigger: trigger1(icm20600-dev1)
	trigger0: e801d000.adc-dev0
		0 channels found:
		No trigger on this device
	trigger1: icm20600-dev1
		0 channels found:
		No trigger on this device
DEBUG: Writing command: 
EXIT

@pcercuei
Copy link
Contributor

pcercuei commented Sep 6, 2021

What arguments did you pass to iio_device_create_buffer?

@ChenhuiZhang
Copy link
Author

buffer = iio_device_create_buffer(dev, 25, false);

@pcercuei
Copy link
Contributor

pcercuei commented Sep 6, 2021

The refill process seems to take exactly 250ms, looking at your timestamps. The logical explanation would be that your trigger doesn't actually run at 200 Hz, but at 100 Hz. If it's interrupt-driven, running watch -n1 cat /proc/interrupts on the target should show you that about ~100 interrupts per second are generated for the trigger device.

@ChenhuiZhang
Copy link
Author

The interrupt is 200 Hz:

root@axis-b8a44f276d49:~# cat /proc/interrupts | grep inv && sleep 1 && cat /proc/interrupts | grep inv
 43:      30215          0          0          0      GPIO  26 Edge      inv_mpu
 43:      30426          0          0          0      GPIO  26 Edge      inv_mpu

and if I switch to local context, it works as expected.

Best Regards,
Hermes

@pcercuei
Copy link
Contributor

pcercuei commented Sep 7, 2021

Hi Hermes,

Did you change the number of kernel buffers with iio_device_set_kernel_buffers? (you don't have to, the default value should be fine).

How much time is spent between two calls to iio_buffer_refill?

@ChenhuiZhang
Copy link
Author

Yes, I set the kernel buffers to 8, the default is 4.

The time seem around 200+ ms:

** (process:723): WARNING **: 10:26:17.221: Before 62 319361
In iio_buffer_refill, buffer->mask: 0x3f
DEBUG: Reading mask
DEBUG: mask[0] = 0x0000003f
In iio_device_get_sample_size_mask, mask: 0x3f, words: 1

** (process:723): WARNING **: 10:26:17.453: After 62 551660

BTW, do you know when can I add some debug print in real read and dispatch in iiod? Thanks.

@pcercuei
Copy link
Contributor

pcercuei commented Sep 7, 2021

I was asking about the time spent in your application between two calls to iio_buffer_refill, not the time spent within iio_buffer_refill itself. There we already know that the time spent in the refill operation is about 250 ms.

Maybe check inside IIOD how much time is spent in its own call to iio_buffer_refill (in ops.c). It should be almost instant, a few milliseconds at most.

@ChenhuiZhang
Copy link
Author

OK, so:

** (process:723): WARNING **: 10:26:17.221: Before 62 319361
In iio_buffer_refill, buffer->mask: 0x3f
DEBUG: Reading mask
DEBUG: mask[0] = 0x0000003f
In iio_device_get_sample_size_mask, mask: 0x3f, words: 1

** (process:723): WARNING **: 10:26:17.453: After 62 551660

** (process:723): WARNING **: 10:26:17.454: sample_size: 12, length: 300

... 

** (process:723): WARNING **: 10:26:17.467: Before 62 565281
In iio_buffer_refill, buffer->mask: 0x3f
DEBUG: Reading mask
DEBUG: mask[0] = 0x0000003f
In iio_device_get_sample_size_mask, mask: 0x3f, words: 1

** (process:723): WARNING **: 10:26:17.703: After 62 801787

it takes about 565281 - 551660 ~~ 10 ms in my application.

And in iiod:

Mar 24 11:48:05 iiod[1353]: Starting IIO Daemon version 0.23.92d6a35
Mar 24 11:48:05 iiod[1353]: IPv6 support enabled
Mar 24 11:48:05 iiod[1353]: New client connected from 0.0.0.0
Mar 24 11:48:05 iiod[1353]: New client connected from 0.0.0.0
Mar 24 11:48:05 iiod[1353]: DEBUG: Mask[0]: 0x0000003f
Mar 24 11:48:05 iiod[1353]: DEBUG: Added thread to client list
Mar 24 11:48:05 iiod[1353]: DEBUG: Adding new device thread to device list
Mar 24 11:48:05 iiod[1353]: DEBUG: R/W thread started for device icm20600
Mar 24 11:48:05 iiod[1353]: In iio_device_get_sample_size_mask, mask: 0x37, words: 1
Mar 24 11:48:05 iiod[1353]: In iio_device_get_sample_size_maskWARNING: iiod Before 4970 354207
Mar 24 11:48:05 iiod[1353]: WARNING: iiod After 4970 477662
Mar 24 11:48:05 iiod[1353]: WARNING: iiod Before 4970 478548
Mar 24 11:48:05 iiod[1353]: WARNING: iiod After 4970 602584
Mar 24 11:48:05 iiod[1353]: WARNING: iiod Before 4970 614481
Mar 24 11:48:05 iiod[1353]: WARNING: iiod After 4970 728032
Mar 24 11:48:05 iiod[1353]: WARNING: iiod Before 4970 728934
Mar 24 11:48:05 iiod[1353]: WARNING: iiod After 4970 853103
Mar 24 11:48:05 iiod[1353]: WARNING: iiod Before 4970 874668
Mar 24 11:48:05 iiod[1353]: WARNING: iiod After 4970 978122
Mar 24 11:48:05 iiod[1353]: WARNING: iiod Before 4970 978527
Mar 24 11:48:06 iiod[1353]: WARNING: iiod After 4971 103354
Mar 24 11:48:06 iiod[1353]: WARNING: iiod Before 4971 117666
Mar 24 11:48:06 iiod[1353]: WARNING: iiod After 4971 229124
Mar 24 11:48:06 iiod[1353]: WARNING: iiod Before 4971 231468

It takes 100+ ms to finish the buffer_refill().

I just have one more question: the first mask shows 0x3f, but later it get_sample_size_mask returns 0x37? Is that correct? And in later log, I saw iiod print something as below:

Mar 24 11:48:09  iiod[1353]: DEBUG: IIO device icm20600 reopened with new mask:
Mar 24 11:48:09  iiod[1353]: DEBUG: Mask[0] = 0x0000003f
Mar 24 11:48:09  iiod[1353]: In iio_device_get_sample_size_mask, mask: 0x37, words: 1
Mar 24 11:48:09  iiod[1353]: DEBUG: Waiting for completion...
Mar 24 11:48:09  iiod[1353]: In iio_buffer_refill, buffer->mask: 0x37
Mar 24 11:48:09  iiod[1353]: In iio_device_get_sample_size_mask, mask: 0x37, words: 1
Mar 24 11:48:09  iiod[1353]: In iio_buffer_refill, buffer->mask: 0x37
Mar 24 11:48:09  iiod[1353]: In iio_device_get_sample_size_mask, mask: 0x37, words: 1
Mar 24 11:48:09  iiod[1353]: DEBUG: Exiting rw_buffer with code 0
Mar 24 11:48:09  iiod[1353]: DEBUG: Waiting for completion...
Mar 24 11:48:09  iiod[1353]: In iio_buffer_refill, buffer->mask: 0x37
Mar 24 11:48:09  iiod[1353]: In iio_device_get_sample_size_mask, mask: 0x37, words: 1
Mar 24 11:48:09  iiod[1353]: In iio_buffer_refill, buffer->mask: 0x37
Mar 24 11:48:09  iiod[1353]: In iio_device_get_sample_size_mask, mask: 0x37, words: 1
Mar 24 11:48:09  iiod[1353]: DEBUG: Exiting rw_buffer with code 0
Mar 24 11:48:09  iiod[1353]: DEBUG: Waiting for completion...
Mar 24 11:48:09  iiod[1353]: In iio_buffer_refill, buffer->mask: 0x37
Mar 24 11:48:09  iiod[1353]: In iio_device_get_sample_size_mask, mask: 0x37, words: 1
Mar 24 11:48:09  iiod[1353]: In iio_buffer_refill, buffer->mask: 0x37
Mar 24 11:48:09  iiod[1353]: In iio_device_get_sample_size_mask, mask: 0x37, words: 1
Mar 24 11:48:09  iiod[1353]: DEBUG: Exiting rw_buffer with code 0
Mar 24 11:48:09  iiod[1353]: DEBUG: Waiting for completion...

Does these info expected? I only run one application during the test.

Best Regards,
Hermes

@pcercuei
Copy link
Contributor

pcercuei commented Sep 7, 2021

I think all your problems are related to the channels sorting difference.

Could you run iio_genxml and give me the XML it prints? Then I can try to debug it locally.

@ChenhuiZhang
Copy link
Author

Sure. Thanks for your help.

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE context [<!ELEMENT context (device | context-attribute)*><!ELEMENT context-attribute EMPTY><!ELEMENT device (channel | attribute | debug-attribute | buffer-attribute)*><!ELEMENT channel (scan-element?, attribute*)><!ELEMENT attribute EMPTY><!ELEMENT scan-element EMPTY><!ELEMENT debug-attribute EMPTY><!ELEMENT buffer-attribute EMPTY><!ATTLIST context name CDATA #REQUIRED version-major CDATA #REQUIRED version-minor CDATA #REQUIRED version-git CDATA #REQUIRED description CDATA #IMPLIED><!ATTLIST context-attribute name CDATA #REQUIRED value CDATA #REQUIRED><!ATTLIST device id CDATA #REQUIRED name CDATA #IMPLIED label CDATA #IMPLIED><!ATTLIST channel id CDATA #REQUIRED type (input|output) #REQUIRED name CDATA #IMPLIED><!ATTLIST scan-element index CDATA #REQUIRED format CDATA #REQUIRED scale CDATA #IMPLIED><!ATTLIST attribute name CDATA #REQUIRED filename CDATA #IMPLIED><!ATTLIST debug-attribute name CDATA #REQUIRED><!ATTLIST buffer-attribute name CDATA #REQUIRED>]><context name="local" version-major="0" version-minor="23" version-git="92d6a35" description="Linux axis-b8a44f276d49 4.14.173-axis8-devel #1 SMP PREEMPT Tue Aug 31 10:46:05 UTC 2021 aarch64" ><context-attribute name="local,kernel" value="4.14.173-axis8-devel" /><context-attribute name="uri" value="local:" /><device id="iio:device0" name="e801d000.adc" ><channel id="voltage1" type="input" ><scan-element index="0" format="le:u12/16&gt;&gt;0" scale="0.805664" /><attribute name="enable" filename="in_voltage1_enable" /><attribute name="raw" filename="in_voltage1_raw" /><attribute name="scale" filename="in_voltage1_scale" /></channel><attribute name="sampling_frequency" /><buffer-attribute name="watermark" /></device><device id="iio:device1" name="icm20600" ><channel id="accel_x" type="input" ><scan-element index="0" format="be:S16/16&gt;&gt;0" scale="0.000598" /><attribute name="calibbias" filename="in_accel_x_calibbias" /><attribute name="matrix" filename="in_accel_matrix" /><attribute name="mount_matrix" filename="in_accel_mount_matrix" /><attribute name="raw" filename="in_accel_x_raw" /><attribute name="scale" filename="in_accel_scale" /><attribute name="scale_available" filename="in_accel_scale_available" /></channel><channel id="accel_y" type="input" ><scan-element index="1" format="be:S16/16&gt;&gt;0" scale="0.000598" /><attribute name="calibbias" filename="in_accel_y_calibbias" /><attribute name="matrix" filename="in_accel_matrix" /><attribute name="mount_matrix" filename="in_accel_mount_matrix" /><attribute name="raw" filename="in_accel_y_raw" /><attribute name="scale" filename="in_accel_scale" /><attribute name="scale_available" filename="in_accel_scale_available" /></channel><channel id="accel_z" type="input" ><scan-element index="2" format="be:S16/16&gt;&gt;0" scale="0.000598" /><attribute name="calibbias" filename="in_accel_z_calibbias" /><attribute name="matrix" filename="in_accel_matrix" /><attribute name="mount_matrix" filename="in_accel_mount_matrix" /><attribute name="raw" filename="in_accel_z_raw" /><attribute name="scale" filename="in_accel_scale" /><attribute name="scale_available" filename="in_accel_scale_available" /></channel><channel id="temp" type="input" ><attribute name="offset" filename="in_temp_offset" /><attribute name="raw" filename="in_temp_raw" /><attribute name="scale" filename="in_temp_scale" /></channel><channel id="anglvel_x" type="input" ><scan-element index="4" format="be:S16/16&gt;&gt;0" scale="0.001065" /><attribute name="calibbias" filename="in_anglvel_x_calibbias" /><attribute name="mount_matrix" filename="in_anglvel_mount_matrix" /><attribute name="raw" filename="in_anglvel_x_raw" /><attribute name="scale" filename="in_anglvel_scale" /><attribute name="scale_available" filename="in_anglvel_scale_available" /></channel><channel id="anglvel_y" type="input" ><scan-element index="5" format="be:S16/16&gt;&gt;0" scale="0.001065" /><attribute name="calibbias" filename="in_anglvel_y_calibbias" /><attribute name="mount_matrix" filename="in_anglvel_mount_matrix" /><attribute name="raw" filename="in_anglvel_y_raw" /><attribute name="scale" filename="in_anglvel_scale" /><attribute name="scale_available" filename="in_anglvel_scale_available" /></channel><channel id="anglvel_z" type="input" ><scan-element index="6" format="be:S16/16&gt;&gt;0" scale="0.001065" /><attribute name="calibbias" filename="in_anglvel_z_calibbias" /><attribute name="mount_matrix" filename="in_anglvel_mount_matrix" /><attribute name="raw" filename="in_anglvel_z_raw" /><attribute name="scale" filename="in_anglvel_scale" /><attribute name="scale_available" filename="in_anglvel_scale_available" /></channel><channel id="timestamp" type="input" ><scan-element index="7" format="le:S64/64&gt;&gt;0" /></channel><channel id="gyro" type="input" ><attribute name="matrix" filename="in_gyro_matrix" /></channel><attribute name="current_timestamp_clock" /><attribute name="sampling_frequency" /><attribute name="sampling_frequency_available" /><attribute name="self_test" /><buffer-attribute name="watermark" /></device><device id="trigger0" name="e801d000.adc-dev0" ></device><device id="trigger1" name="icm20600-dev1" ></device></context>

@pcercuei
Copy link
Contributor

pcercuei commented Sep 7, 2021

Could you apply this small patch to the libiio running on the target, and run iio_info again?

diff --git a/context.c b/context.c
index fc91d494..b7b787d8 100644
--- a/context.c
+++ b/context.c
@@ -307,6 +307,7 @@ struct iio_device * iio_context_find_device(const struct iio_context *ctx,
 
 static void reorder_channels(struct iio_device *dev)
 {
+	struct iio_channel **channels = dev->channels;
 	bool found;
 	unsigned int i;
 
@@ -314,10 +315,12 @@ static void reorder_channels(struct iio_device *dev)
 	do {
 		found = false;
 		for (i = 1; i < dev->nb_channels; i++) {
-			struct iio_channel **channels = dev->channels;
 			long ch1 = channels[i - 1]->index;
 			long ch2 = channels[i]->index;
 
+			IIO_INFO("Channel %s has index %ld, channel %s has index %ld\n",
+				    channels[i - 1]->id, ch1, channels[i]->id, ch2);
+
 			if (ch1 == ch2 && ch1 >= 0) {
 				ch1 = channels[i - 1]->format.shift;
 				ch2 = channels[i]->format.shift;
@@ -327,6 +330,9 @@ static void reorder_channels(struct iio_device *dev)
 				struct iio_channel *bak = channels[i];
 				channels[i] = channels[i - 1];
 				channels[i - 1] = bak;
+				IIO_INFO("Reorder channels %s and %s\n",
+					    channels[i - 1]->id,
+					    channels[i]->id);
 				found = true;
 			}
 		}
diff --git a/xml.c b/xml.c
index 5de1ef85..417accb5 100644
--- a/xml.c
+++ b/xml.c
@@ -228,6 +228,7 @@ static struct iio_channel * create_channel(struct iio_device *dev, xmlNode *n)
 		}
 	}
 
+	IIO_INFO("Create channel %s\n", chn->id);
 	iio_channel_init_finalize(chn);
 
 	return chn;

@ChenhuiZhang
Copy link
Author

Hi Paul,

Here is new output for iio_info with your patch:

root@axis-b8a44f276d49:~# iio_info 
Library version: 0.23 (git tag: 92d6a35)
Compiled with backends: local xml ip
Channel accel_z has index 2, channel anglvel_y has index 5
Channel anglvel_y has index 5, channel anglvel_z has index 6
Channel anglvel_z has index 6, channel accel_y has index 1
Recorder channels accel_y and anglvel_z
Channel anglvel_z has index 6, channel accel_x has index 0
Recorder channels accel_x and anglvel_z
Channel anglvel_z has index 6, channel anglvel_x has index 4
Recorder channels anglvel_x and anglvel_z
Channel anglvel_z has index 6, channel temp has index 3
Recorder channels temp and anglvel_z
Channel anglvel_z has index 6, channel timestamp has index 7
Channel timestamp has index 7, channel gyro has index -2
Channel accel_z has index 2, channel anglvel_y has index 5
Channel anglvel_y has index 5, channel accel_y has index 1
Recorder channels accel_y and anglvel_y
Channel anglvel_y has index 5, channel accel_x has index 0
Recorder channels accel_x and anglvel_y
Channel anglvel_y has index 5, channel anglvel_x has index 4
Recorder channels anglvel_x and anglvel_y
Channel anglvel_y has index 5, channel temp has index 3
Recorder channels temp and anglvel_y
Channel anglvel_y has index 5, channel anglvel_z has index 6
Channel anglvel_z has index 6, channel timestamp has index 7
Channel timestamp has index 7, channel gyro has index -2
Channel accel_z has index 2, channel accel_y has index 1
Recorder channels accel_y and accel_z
Channel accel_z has index 2, channel accel_x has index 0
Recorder channels accel_x and accel_z
Channel accel_z has index 2, channel anglvel_x has index 4
Channel anglvel_x has index 4, channel temp has index 3
Recorder channels temp and anglvel_x
Channel anglvel_x has index 4, channel anglvel_y has index 5
Channel anglvel_y has index 5, channel anglvel_z has index 6
Channel anglvel_z has index 6, channel timestamp has index 7
Channel timestamp has index 7, channel gyro has index -2
Channel accel_y has index 1, channel accel_x has index 0
Recorder channels accel_x and accel_y
Channel accel_y has index 1, channel accel_z has index 2
Channel accel_z has index 2, channel temp has index 3
Channel temp has index 3, channel anglvel_x has index 4
Channel anglvel_x has index 4, channel anglvel_y has index 5
Channel anglvel_y has index 5, channel anglvel_z has index 6
Channel anglvel_z has index 6, channel timestamp has index 7
Channel timestamp has index 7, channel gyro has index -2
Channel accel_x has index 0, channel accel_y has index 1
Channel accel_y has index 1, channel accel_z has index 2
Channel accel_z has index 2, channel temp has index 3
Channel temp has index 3, channel anglvel_x has index 4
Channel anglvel_x has index 4, channel anglvel_y has index 5
Channel anglvel_y has index 5, channel anglvel_z has index 6
Channel anglvel_z has index 6, channel timestamp has index 7
Channel timestamp has index 7, channel gyro has index -2
IIO context created with local backend.
Backend version: 0.23 (git tag: 92d6a35)
Backend description string: Linux axis-b8a44f276d49 4.14.173-axis8-devel #1 SMP PREEMPT Tue Aug 31 10:46:05 UTC 2021 aarch64
IIO context has 2 attributes:
	local,kernel: 4.14.173-axis8-devel
	uri: local:
IIO context has 4 devices:
	iio:device0: e801d000.adc (buffer capable)
		1 channels found:
			voltage1:  (input, index: 0, format: le:u12/16>>0)
			3 channel-specific attributes found:
				attr  0: enable value: 1
				attr  1: raw value: 774
				attr  2: scale value: 0.805664062
		1 device-specific attributes found:
				attr  0: sampling_frequency value: 150000
		1 buffer-specific attributes found:
				attr  0: watermark value: 1
		Current trigger: trigger0(e801d000.adc-dev0)
	iio:device1: icm20600 (buffer capable)
		9 channels found:
			accel_x:  (input, index: 0, format: be:S16/16>>0)
			6 channel-specific attributes found:
				attr  0: calibbias value: -620
				attr  1: matrix value: 0, 0, 0; 0, 0, 0; 0, 0, 0
				attr  2: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  3: raw value: -16535
				attr  4: scale value: 0.000598
				attr  5: scale_available value: 0.000598 0.001196 0.002392 0.004785
			accel_y:  (input, index: 1, format: be:S16/16>>0)
			6 channel-specific attributes found:
				attr  0: calibbias value: 0
				attr  1: matrix value: 0, 0, 0; 0, 0, 0; 0, 0, 0
				attr  2: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  3: raw value: 898
				attr  4: scale value: 0.000598
				attr  5: scale_available value: 0.000598 0.001196 0.002392 0.004785
			accel_z:  (input, index: 2, format: be:S16/16>>0)
			6 channel-specific attributes found:
				attr  0: calibbias value: -9216
				attr  1: matrix value: 0, 0, 0; 0, 0, 0; 0, 0, 0
				attr  2: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  3: raw value: 134
				attr  4: scale value: 0.000598
				attr  5: scale_available value: 0.000598 0.001196 0.002392 0.004785
			temp:  (input)
			3 channel-specific attributes found:
				attr  0: offset value: 8170
				attr  1: raw value: 7424
				attr  2: scale value: 0.003059
			anglvel_x:  (input, index: 4, format: be:S16/16>>0)
			5 channel-specific attributes found:
				attr  0: calibbias value: 0
				attr  1: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  2: raw value: -7
				attr  3: scale value: 0.001064724
				attr  4: scale_available value: 0.000133090 0.000266181 0.000532362 0.001064724
			anglvel_y:  (input, index: 5, format: be:S16/16>>0)
			5 channel-specific attributes found:
				attr  0: calibbias value: 0
				attr  1: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  2: raw value: -13
				attr  3: scale value: 0.001064724
				attr  4: scale_available value: 0.000133090 0.000266181 0.000532362 0.001064724
			anglvel_z:  (input, index: 6, format: be:S16/16>>0)
			5 channel-specific attributes found:
				attr  0: calibbias value: 0
				attr  1: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  2: raw value: 8
				attr  3: scale value: 0.001064724
				attr  4: scale_available value: 0.000133090 0.000266181 0.000532362 0.001064724
			timestamp:  (input, index: 7, format: le:S64/64>>0)
			gyro:  (input, WARN:iio_channel_get_type()=UNKNOWN)
			1 channel-specific attributes found:
				attr  0: matrix value: 0, 0, 0; 0, 0, 0; 0, 0, 0
		4 device-specific attributes found:
				attr  0: current_timestamp_clock value: realtime

				attr  1: sampling_frequency value: 200
				attr  2: sampling_frequency_available value: 10 20 50 100 200 500
				attr  3: self_test ERROR: Permission denied (13)
		1 buffer-specific attributes found:
				attr  0: watermark value: 1
		Current trigger: trigger1(icm20600-dev1)
	trigger0: e801d000.adc-dev0
		0 channels found:
		No trigger on this device
	trigger1: icm20600-dev1
		0 channels found:
		No trigger on this device

@pcercuei
Copy link
Contributor

pcercuei commented Sep 7, 2021

Hi Hermes,

Could you return the result of:
cat /sys/bus/iio/devices/iio:device1/scan_elements/in_temp_index
and:
cat /sys/bus/iio/devices/iio:device1/scan_elements/in_temp_type

@ChenhuiZhang
Copy link
Author

Hi Paul,

root@axis-b8a44f276d49:~# cat /sys/bus/iio/devices/iio:device1/scan_elements/in_temp_index
3
root@axis-b8a44f276d49:~# cat /sys/bus/iio/devices/iio:device1/scan_elements/in_temp_type
be:s16/16>>0

pcercuei added a commit that referenced this issue Sep 8, 2021
Previously, the detection of buffer-capable channels would fail when the
channel had attributes outside the scan_elements/ folder, as the channel
would be correctly marked as non-buffer-capable when the first attribute
was found, but was never changed to buffer-capable when scan-elements
attributes were later found.

Fixes #740.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
@pcercuei
Copy link
Contributor

pcercuei commented Sep 8, 2021

Hi Hermes,

Could you try the branch local-fix-scan-element on your target? I added a commit that should fix the sorting issue, and hopefully fix everything else as well.

pcercuei added a commit that referenced this issue Sep 8, 2021
Previously, the detection of buffer-capable channels would fail when the
channel had attributes outside the scan_elements/ folder, as the channel
would be correctly marked as non-buffer-capable when the first attribute
was found, but was never changed to buffer-capable when scan-elements
attributes were later found.

It went unnoticed until now, most likely because there is generally more
than one channel of a given type (e.g. "voltage") in the scan elements,
and those channels of the same type share common attributes.

Fixes #740.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
@ChenhuiZhang
Copy link
Author

Hi Paul,

I cherry-pick your patch. But the problem still there.

And I also find if I enable channel by iio_device_find_channel(), both local and network context don't get the correct data(e.g. the g should get with 9.8) from buffer_refill(), but if I switch back to enable channel by index (0x77) the data looks correct, but for network context, the sample size and freq is wrong.

Best Regards,
Hermes

@pcercuei
Copy link
Contributor

pcercuei commented Sep 8, 2021

Could you add the output of iio_info with the patch?

@ChenhuiZhang
Copy link
Author

Sure. I add one more print before your change to make sure it has been called.

root@axis-00408c290806:~# iio_info 
Library version: 0.23 (git tag: 92d6a35)
Compiled with backends: local xml ip
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
set is_scan_element to true
Channel accel_z has index 2, channel anglvel_y has index 5
Channel anglvel_y has index 5, channel anglvel_z has index 6
Channel anglvel_z has index 6, channel accel_y has index 1
Recorder channels accel_y and anglvel_z
Channel anglvel_z has index 6, channel accel_x has index 0
Recorder channels accel_x and anglvel_z
Channel anglvel_z has index 6, channel anglvel_x has index 4
Recorder channels anglvel_x and anglvel_z
Channel anglvel_z has index 6, channel temp has index 3
Recorder channels temp and anglvel_z
Channel anglvel_z has index 6, channel timestamp has index 7
Channel timestamp has index 7, channel gyro has index -2
Channel accel_z has index 2, channel anglvel_y has index 5
Channel anglvel_y has index 5, channel accel_y has index 1
Recorder channels accel_y and anglvel_y
Channel anglvel_y has index 5, channel accel_x has index 0
Recorder channels accel_x and anglvel_y
Channel anglvel_y has index 5, channel anglvel_x has index 4
Recorder channels anglvel_x and anglvel_y
Channel anglvel_y has index 5, channel temp has index 3
Recorder channels temp and anglvel_y
Channel anglvel_y has index 5, channel anglvel_z has index 6
Channel anglvel_z has index 6, channel timestamp has index 7
Channel timestamp has index 7, channel gyro has index -2
Channel accel_z has index 2, channel accel_y has index 1
Recorder channels accel_y and accel_z
Channel accel_z has index 2, channel accel_x has index 0
Recorder channels accel_x and accel_z
Channel accel_z has index 2, channel anglvel_x has index 4
Channel anglvel_x has index 4, channel temp has index 3
Recorder channels temp and anglvel_x
Channel anglvel_x has index 4, channel anglvel_y has index 5
Channel anglvel_y has index 5, channel anglvel_z has index 6
Channel anglvel_z has index 6, channel timestamp has index 7
Channel timestamp has index 7, channel gyro has index -2
Channel accel_y has index 1, channel accel_x has index 0
Recorder channels accel_x and accel_y
Channel accel_y has index 1, channel accel_z has index 2
Channel accel_z has index 2, channel temp has index 3
Channel temp has index 3, channel anglvel_x has index 4
Channel anglvel_x has index 4, channel anglvel_y has index 5
Channel anglvel_y has index 5, channel anglvel_z has index 6
Channel anglvel_z has index 6, channel timestamp has index 7
Channel timestamp has index 7, channel gyro has index -2
Channel accel_x has index 0, channel accel_y has index 1
Channel accel_y has index 1, channel accel_z has index 2
Channel accel_z has index 2, channel temp has index 3
Channel temp has index 3, channel anglvel_x has index 4
Channel anglvel_x has index 4, channel anglvel_y has index 5
Channel anglvel_y has index 5, channel anglvel_z has index 6
Channel anglvel_z has index 6, channel timestamp has index 7
Channel timestamp has index 7, channel gyro has index -2
IIO context created with local backend.
Backend version: 0.23 (git tag: 92d6a35)
Backend description string: Linux axis-00408c290806 4.14.173-axis8-devel #1 SMP PREEMPT Tue Aug 31 10:46:05 UTC 2021 aarch64
IIO context has 2 attributes:
	local,kernel: 4.14.173-axis8-devel
	uri: local:
IIO context has 4 devices:
	iio:device0: e801d000.adc (buffer capable)
		1 channels found:
			voltage1:  (input, index: 0, format: le:u12/16>>0)
			3 channel-specific attributes found:
				attr  0: enable value: 1
				attr  1: raw value: 1414
				attr  2: scale value: 0.805664062
		1 device-specific attributes found:
				attr  0: sampling_frequency value: 150000
		1 buffer-specific attributes found:
				attr  0: watermark value: 1
		Current trigger: trigger0(e801d000.adc-dev0)
	iio:device1: icm20600 (buffer capable)
		9 channels found:
			accel_x:  (input, index: 0, format: be:S16/16>>0)
			6 channel-specific attributes found:
				attr  0: calibbias value: -280
				attr  1: matrix value: 0, 0, 0; 0, 0, 0; 0, 0, 0
				attr  2: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  3: raw value: 203
				attr  4: scale value: 0.004785
				attr  5: scale_available value: 0.000598 0.001196 0.002392 0.004785
			accel_y:  (input, index: 1, format: be:S16/16>>0)
			6 channel-specific attributes found:
				attr  0: calibbias value: 254
				attr  1: matrix value: 0, 0, 0; 0, 0, 0; 0, 0, 0
				attr  2: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  3: raw value: 2044
				attr  4: scale value: 0.004785
				attr  5: scale_available value: 0.000598 0.001196 0.002392 0.004785
			accel_z:  (input, index: 2, format: be:S16/16>>0)
			6 channel-specific attributes found:
				attr  0: calibbias value: -512
				attr  1: matrix value: 0, 0, 0; 0, 0, 0; 0, 0, 0
				attr  2: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  3: raw value: 24
				attr  4: scale value: 0.004785
				attr  5: scale_available value: 0.000598 0.001196 0.002392 0.004785
			temp:  (input)
			3 channel-specific attributes found:
				attr  0: offset value: 8170
				attr  1: raw value: 6592
				attr  2: scale value: 0.003059
			anglvel_x:  (input, index: 4, format: be:S16/16>>0)
			5 channel-specific attributes found:
				attr  0: calibbias value: 0
				attr  1: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  2: raw value: -18
				attr  3: scale value: 0.001064724
				attr  4: scale_available value: 0.000133090 0.000266181 0.000532362 0.001064724
			anglvel_y:  (input, index: 5, format: be:S16/16>>0)
			5 channel-specific attributes found:
				attr  0: calibbias value: 0
				attr  1: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  2: raw value: -11
				attr  3: scale value: 0.001064724
				attr  4: scale_available value: 0.000133090 0.000266181 0.000532362 0.001064724
			anglvel_z:  (input, index: 6, format: be:S16/16>>0)
			5 channel-specific attributes found:
				attr  0: calibbias value: 0
				attr  1: mount_matrix value: 1, 0, 0; 0, 1, 0; 0, 0, 1
				attr  2: raw value: -4
				attr  3: scale value: 0.001064724
				attr  4: scale_available value: 0.000133090 0.000266181 0.000532362 0.001064724
			timestamp:  (input, index: 7, format: le:S64/64>>0)
			gyro:  (input, WARN:iio_channel_get_type()=UNKNOWN)
			1 channel-specific attributes found:
				attr  0: matrix value: 0, 0, 0; 0, 0, 0; 0, 0, 0
		4 device-specific attributes found:
				attr  0: current_timestamp_clock value: realtime

				attr  1: sampling_frequency value: 200
				attr  2: sampling_frequency_available value: 10 20 50 100 200 500
				attr  3: self_test ERROR: Permission denied (13)
		1 buffer-specific attributes found:
				attr  0: watermark value: 1
		Current trigger: trigger1(icm20600-dev1)
	trigger0: e801d000.adc-dev0
		0 channels found:
		No trigger on this device
	trigger1: icm20600-dev1
		0 channels found:
		No trigger on this device

pcercuei added a commit that referenced this issue Sep 8, 2021
Previously, the detection of buffer-capable channels would fail when the
channel had attributes outside the scan_elements/ folder, as the channel
would be correctly marked as non-buffer-capable when the first attribute
was found, but was never changed to buffer-capable when scan-elements
attributes were later found.

It went unnoticed until now, most likely because there is generally more
than one channel of a given type (e.g. "voltage") in the scan elements,
and those channels of the same type share common attributes.

Fixes #740.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
@pcercuei
Copy link
Contributor

pcercuei commented Sep 8, 2021

Indeed, the fix does not seem to be working as I thought.

The exact problem is that the "temp" channel is not detected as buffer capable. If it was, iio_info would print:
temp: (input, index: 3, format: be:S16/16>>0)

This causes the channels to be ordered differently in the local backend and the network backend, which in turn causes a misunderstanding between the client and server sides as they don't agree on the channel masks. Your client application then doesn't get the samples for the channels it asked for, and if it gets samples for 5 channels while it asked for 6, then refilling the buffer will take twice as long.

I just force-push a new commit that changed my solution a little bit. Could you try it out?

Thanks for helping fixing our bugs!

-Paul

@ChenhuiZhang
Copy link
Author

Hi Paul,

Good news. It seems works as expected now. Thanks a lot Paul.

But I will do some more test to verify it. I may update the results tomorrow. Thanks again for your help.

Best Regards,
Hermes

pcercuei added a commit that referenced this issue Sep 8, 2021
Previously, the detection of buffer-capable channels would fail when the
channel had attributes outside the scan_elements/ folder, as the channel
would be correctly marked as non-buffer-capable when the first attribute
was found, but was never changed to buffer-capable when scan-elements
attributes were later found.

It went unnoticed until now, most likely because there is generally more
than one channel of a given type (e.g. "voltage") in the scan elements,
and those channels of the same type share common attributes.

Fixes #740.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
@pcercuei
Copy link
Contributor

pcercuei commented Sep 8, 2021

Hi Hermes,

Great news! Thanks to you for debugging the issue.
I force-pushed once again, my fix is a single-line now, but it should still work.

We will wait for the results of your tests then. If you confirm it's definitely fixed, we will most likely create a v0.24 release.

Cheers,
-Paul

pcercuei added a commit that referenced this issue Sep 8, 2021
Previously, the detection of buffer-capable channels would fail when the
channel had attributes outside the scan_elements/ folder, as the channel
would be correctly marked as buffer-capable when the first attribute
was found, but then overriden as non-buffer-capable as soon as an
attribute outside the scan_elements/ folder was found.

It went unnoticed until now, most likely because there is generally
either scan-elements attributes or non-scan-elements attributes, and
rarely both.

Fixes #740.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
@ChenhuiZhang
Copy link
Author

Hi Paul,

Yes, we verify the latest patch, everything works good here. You can merge it. Thanks again for your great support!

Best Regards,
Hermes

pcercuei added a commit that referenced this issue Sep 17, 2021
Previously, the detection of buffer-capable channels would fail when the
channel had attributes outside the scan_elements/ folder, as the channel
would be correctly marked as buffer-capable when the first attribute
was found, but then overriden as non-buffer-capable as soon as an
attribute outside the scan_elements/ folder was found.

It went unnoticed until now, most likely because there is generally
either scan-elements attributes or non-scan-elements attributes, and
rarely both.

Fixes #740.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants