-
Notifications
You must be signed in to change notification settings - Fork 320
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
Comments
Can you provide more information on your hardware setup and the version of libiio you are using? |
Hi, Sure. The HW is icm20600 chip and libiio is 0.21. Any more question please let me know. Thanks. Best Regards, |
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, |
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, |
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 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, |
Hi Paul, I upgrade the libiio to v0.23 and do two tests as below:
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, |
Hi Hermes, Please provide the output of -Paul |
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, |
I mean the output of the |
OK, here it is:
|
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 |
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, |
You need to use 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 |
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:
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:
|
What arguments did you pass to |
|
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 |
The interrupt is 200 Hz:
and if I switch to local context, it works as expected. Best Regards, |
Hi Hermes, Did you change the number of kernel buffers with How much time is spent between two calls to |
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 ** (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. |
I was asking about the time spent in your application between two calls to Maybe check inside IIOD how much time is spent in its own call to |
OK, so:
it takes about 565281 - 551660 ~~ 10 ms in my application. And in iiod:
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:
Does these info expected? I only run one application during the test. Best Regards, |
I think all your problems are related to the channels sorting difference. Could you run |
Sure. Thanks for your help.
|
Could you apply this small patch to the libiio running on the target, and run iio_info again?
|
Hi Paul, Here is new output for iio_info with your patch:
|
Hi Hermes, Could you return the result of: |
Hi Paul,
|
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 <[email protected]>
Hi Hermes, Could you try the branch |
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 <[email protected]>
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, |
Could you add the output of |
Sure. I add one more print before your change to make sure it has been called.
|
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 <[email protected]>
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, 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 |
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, |
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 <[email protected]>
Hi Hermes, Great news! Thanks to you for debugging the issue. 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, |
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 <[email protected]>
Hi Paul, Yes, we verify the latest patch, everything works good here. You can merge it. Thanks again for your great support! Best Regards, |
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 <[email protected]>
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
The text was updated successfully, but these errors were encountered: