How to access iio device data in user space

Hi all,

I’m currently experimenting with some imu’s (mpu9250, bmi088,…) and I have found that there are drivers available for those in the JP4.5 linux kernel. The devices have been successfully added to the device-tree and modprobe finishes without issues. After enabling scan_elements and enabling the device I am not allowed to access /dev/iio:device* with the error “Device or resource busy”.
After some debugging I have found that I can poll some data from an “nvs” node in sysfs. It appears that nvs-service is taking control of these files but I have not been able to find documentation on how to use this nvs-service to access the data in user space.
Would it be possible to get some documentation on how to do this?

Best regards,
Nico

hello Nico,

this failure usually reported by the device is occupied by other drivers,
could you please refer to below topic for the patches to IIO devices.
for example, NVIDIA Sensor IIO Kernel Changes Break Common IIO Drivers - #12 by ShaneCCC
thanks

Hi @JerryChang,

It appears that the patches you suggested have already been merged in JP4.5 which is the one I am using but I am still experiencing the issue.

Best regards,
Nico

hello Nico,

please share the details by checking sysnode.
for example,
$ ls -l /sys/bus/iio/devices/iio:device*/nvs

Hi @JerryChang ,

This is the output of that command:

PS. Running my app as root or with sudo does not sove the Device or Resource busy issue.

-rw-rw-r-- 1 root root 4096 May 6 17:16 /sys/bus/iio/devices/iio:device0/nvs
-rw-rw-r-- 1 root root 4096 May 6 17:16 /sys/bus/iio/devices/iio:device1/nvs
-rw-rw-r-- 1 root root 4096 May 7 12:00 /sys/bus/iio/devices/iio:device2/nvs

Best regards,
Nico

Attaching documentation for how to access NVS IIO device in user space.

I see that the links don’t work in the PDF so here is the Word version.
NVS_Client.docx (72.2 KB)

@ELilliebjerg,

Thank you very much for the documentation.
I couldn’t find the accompanying header files to go with libsensors.hal-client.nvs.so so I created one based on you rdocumentation and tried it out on a Jetson TX1. It appears that getSensors always returns 0 even after I disable nvs-service. In the last case I would expect this to return one of the errors listed in the docs.
After disabling nvs-service, the ownership of /dev/iio::device* is released but I can’t see any updates being written to it while it’s corresponding nvs node is still being updated.

Best regards,
Nico

Are the NVS kernel drivers being loaded after the system boots? If so, the NVS initialization is missing the drivers when creating the sensor list.
Can you make a call to clientOpen? That call looks to be more accurate for return codes.

I have no idea to be honest. My goal was to read the imu like a normal iio device but it appeared to be hogged by the NVS framework. The clientOpen call returns -EAGAIN but without the proper header files I can’t guarantee my implementation is correct.

Header file should be at sensors/hal-client/NvSensor.h

Disclaimer: It has been a while since I did sensors. There may be some misinformation.

So you don’t care if NVS is up and working in user space? You just want to use IIO directly?
If so, then this might help; those NVS drivers are a superset of IIO so you should be able to use IIO as-is. Note that the drivers are actually NVS HW drivers with an NVS IIO module. Meaning all NVS kernel drivers use the same IIO component. The NVS IIO component creates the driver’s nvs node. It’s a debug node. You’ve figured out that reading from it without a prior write will respond with the data. Here are the rest of the functions when you write the below value and then read from it:
0 => clears debug key
1 => version of driver IIO module
2 => how many errors driver has encountered. Resets after read. This is usually I2C errors.
3 => reset device. This is a hard reset.
4 => device register dump.
5 => NVS device information.
6 => toggle debug spew.
7 => toggle sensor data spew.
8 => toggle sensor data buffer spew.
9 => toggle IRQ spew.

Thanks again.

I had indeed figured out the message spewing. Until now I only manage to read from the nvs node through parsing. This nvs node does not generate a POLLIN event so I can’t use inotify and really have to poll frequently. I’m not sure if there are some read/write hazards using this nvs node polling e.g. reading and parsing the nvs node while the driver is writing to it.

Originally I wanted to use IIO as-is, but I got Resource busy because it is being used by the NVS service, hence this topic.

PS. I can’t seem to find the file NvSensor.h in the kernel nor in rootfs. Which package is this file a part of?

Like I say, the nvs node is strictly a debug node and not intended to acquire data with it. All NVS kernel drivers push data through the IIO buffer mechanism. However, I think IIO allows you to read snapshots of the data through the elements nodes(??) much like the nvs node does.

NVSensor.h has nothing to do with the kernel. Unfortunately, I don’t know what is on your system or how much source comes with this Nvidia product. Attaching header file. NvSensor.h (3.9 KB)

Indeed, reading the raw element nodes still works but in that case it seems next to impossible to get time synchronized values for e.g. pitch, roll and yaw as they do not have timestamps per value attached in that case. As far as my limited knowledge about iio drivers goes I was under the impression time synchronized values could be parsed by reading the /dev/iio::device* sysfs nodes which does not seem to work as expected.

PS. I am using Jetpack JP4.5 on Jetson TX1

Perhaps one of the NVS_INPUT or NVS_RELAY modes could work better, haven’t tried them yet

Oh that’s why the nvs node is used. Makes sense. Well I don’t know much about IIO and found it…um, frustrating, hence why all the drivers, regardless of the data type, push through the buffer mechanism.
NVS_INPUT will work, but I know even less about the kernel’s input subsystem. It will still use a buffering push. NVS_INPUT is the same NVS driver but with the NVS input component instead of the IIO component.
As for NVS_RELAY, I never finished that.
It sounds like the best bet is to get NVS in user space working. Do you know what process you’re in. I think NVS is in the media process. We can skip all the NVSC IPC and talk to NVS directly for debugging insights… I’m thinking out loud. Let me get back to you on what the next steps could be to get NVS working.

Do you know what kernel version you are using?

Hi Nico,

Is this still an issue to support? Any update?

Hi @kayccc,

Apologies, this post got lost in my bottomless TODO pit :)

It appears that the nvs-service takes control of the node and is only being released when /sysfs/…/buffer/enable is activated. From that point on the standard /dev/iio::device* can be accessed for buffer reads without needing any specific NVS structs. After enabling /sysfs/…/buffer/enable the /sysfs/…/enable is automatically activated, so the /sysfs/…/enable must be deactivated after disabling /sysfs/…/buffer/enable otherwise the device hangs on the next call to /sysfs/…/buffer/enable.

Best regards,
Nico

Glad to know issue resolved, thanks for your update.