How to access an IIO device driver in linux - linux

I a noob to Linux device drivers.
I have an IIO driver with me (for OPT3001 ambient light sensor) , operating over the I2C bus, which has been compiled successfully in the kernel (version 3.18). The device tree is modified to match the compatible field, present in the driver.
The problem is how do I access this driver to get some data in the userspace ?
The driver has some callbacks for read and write registered in a structure. Should I call them directly in my C file ?

you have differents possibilities :
your driver provide a /dev node you can open in you C file.
your driver provide informations through sysfs.
in case of a /dev node, you can have access to file operations (open, read, write, ioctl). you just have to open your file 1 time and each read() call will read the value from the sensor.
in case of sysfs, you should find the file to open/read in /sys/class/...

You can use the userspace API provided by:
#include <linux/i2c-dev.h>
Using it you can open de bus /dev/i2c-X (X=0,1,2,...), set device address using ioctl call, and use read and write operations to read and write to/from the bus.
Also, you can install "i2c-tools" package (apt-get install i2c-tools), to install userspace tools like i2cset, i2cget and i2cdetect, very useful for testing the I2C bus and the device connected to it.

Related

Accessing Linux Drivers

Simply put, can a user space application access device drivers running in kernel mode? If I want to read from the I2C Linux character driver, can a basic C executable (extensionless) do that or do I need to develop a kernel module specifically for that task? If a basic C app can access the I2C character driver, what does that gcc makefile look like?
Yes. User space application can access the kernel driver if the driver is character device or the driver exposing the stream interfaces.
Specific to i2c, user space application can write and reads to the i2c device via sysfs api.
Refer the kernel document here https://www.kernel.org/doc/Documentation/i2c/dev-interface

user-space application for tmp102 sensor driver

I have a thermo3 click which has tmp102 sensor.
To read data from it, I have written a user-space application using I2C as follows:
fd = open("/dev/i2c-0", O_RDWR))
ioctl(fd, I2C_SLAVE, 0x48)
read(fd, &buf, 2)
But then I found its driver in linux source code.
So I am wondering:
1) Can I write a user-space application which uses this driver's API's (means using driver's device file)?
2) How I2C user-space application works without using this driver (because this driver is not enabled in my kernel when I was using i2c user-space application) or This is the way I2C works?
1) This is an hwmon device, you don't have a device file to use. Instead the api is in /sys/class/hwmon. In particular, you want to read the /sys/class/hwmon/hwmonX/tempX_input files
2) By using /dev/i2c-0, your are directly communicating on the i2c bus, effectively bypassing any kernel driver. You then have to know the details for any device you use (registers to read and their meaning...) instead of using the generic Linux kernel abstraction.
User Level Application can not interact with hardware. They can communicate by system call (ioctl, open, read and write etc) and Sysfs(sysfs is a virtual file system).
1 :- Your device is hwmom device. Your Driver is "tmp102". Driver Expose these three temp1_input, temp1_max_hyst and temp1_max sysfs entry for user-level application.
SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, tmp102_show_temp, NULL , 0);
SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, tmp102_show_temp, tmp102_set_temp, 1);
SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, tmp102_show_temp,
tmp102_set_temp, 2);
You can read /sys/class/hwmom/tmp102/temp1_input sysfs file.
you can read and write these two sysfs file /sys/class/hwmom/tmp102/temp1_max_hyst and sys/class/hwmom/tmp102/temp1_max.
2 :- The files in /dev are actual devices files which UDEV creates at run time.A device file is an interface for a device driver that appears in a file system as if it were an ordinary file. Your driver has expose some other device file. thermal_zone_of_sensor_register(hwmon_dev, 0,hwmon_dev, &tmp102_of_thermal_ops). You have /dev/hwmom_dev node.
User-Level application can't directly communicate any of i2c-device or hardware. Linux kernel has limitation. Application need driver as interface to controle any of device.

difference between device file and device driver

I am currently reading the Linux Module Programming Guide and I have stumbled onto two terms that have confused a bit - device files and device driver. Upon goggling these terms I have come across the following-
A device driver is a piece of software that operates or controls a particular type of device.
A device file is an interface for a device driver that appears in a file system as if it were an ordinary file. In Unix-like operating systems, these are usually found under the /dev directory and are also called device nodes.
What I would like to know is -
1) Are device files an interface between user space programs and the device driver?
2) Does the program access the driver in the kernel via the appropriate device special file?
eg, when using say spidev char dev file, does that allow my userspace program to interact with spi.c and omap2_mcspi.c etc using simple read, write and ioctl calls?
One of the primary abstractions in Unix is the file (source):
Programs, services, texts, images, and so forth, are all files. Input and output devices, and generally all devices, are considered to be files, according to the system.
This lets users treat a variety of entities with a uniform set of operations, even through the implementation of those operations may be wildly different.
As you were getting at with your question, device files are the user facing side of the abstraction. This is what the user sees; a file that they can write to, read from, open, close, etc. The device drivers are the implementation of those operations.
So the user will make a call to a file operation such as write, and then the kernel will then use the device driver to carry out the operation.
Device File like /dev/spidevX.Y is a SW abstraction of a SPI device which exposes Linux low level SPI API to the userspace with syscalls (in Linux driver world known as "file operations"):
That is read(), write(), ioctl()...
spidev.c is a special kind of driver which is registered for generic SPI client(chip) devices, and it's main goal is to export Kernel low level SPI API to userspace.
There is a whole Linux SPI layer in between defined in spi.c
Device driver representing real HW SPI controller is where callbacks (hooks) are implemented and registered to the kernel as a part of spi_master (spi_controller)structure.
Here is a callback initialization for SPI message transfer:
master->transfer_one_message = atmel_spi_transfer_one_message;
everything in linux is a file.
device driver is a software used by operating system to communicate with device.
device driver makes use of device files.

Opening a device node in a device driver in linux

I am writing a device driver on Xillinux that will read and write data to an FPGA application over Xillybus.
Basically I want to create device nodes such as /dev/pe1, and when I write to the nodes my device driver will form packets of data and then write the packets into the xillybus nodes eg. /dev/xillybus_write_32
Is it possible to simply open an existing /dev node inside a kernel module, and then perform I/O operations on it? Or is it better to just write a userspace driver?
After reading LDD3 and some other articles on kernel development, I've decided to abandon the idea of writing my custom device driver and put the logic in runtime instead. Thanks for the advice goldilocks.

Accessing Linux /dev/USB as standard files to communicate with USB device

I'm researching ways to communicate with a USB device in Linux and would prefer to not write a Linux Kernel driver. I understand that libusb exists and is a user-land library that would work, but our embedded device doesn't support usbfs ( and would be really a pain to change kernels to add the support ).
So my question is basically this: Is it possible / advisable to communicate with a USB device by directly reading and writing to the /dev/USB or the udev file corresponding to the USB device thus bypassing the need for a custom Linux Driver and usbfs?
I'm hoping it's possible to communicate using the USB devices protocol just by reading / writing protocol packets directly through file-type read/write commands once the /dev/USB or udev device file is open.
Thoughts and suggestions please.
FOLLOW UP:
Since the USB device I needed to talk to is a USB HID class device, I was able to use libudev and the standard Linux USB HID RAW driver by reading / writing directly to /dev/hidraw0 ( or the appropriate /dev/hidraw device ). It wasn't necessary to write a custom driver for a simple USB HID device.
Jim, I don't think you can escape the need to write a driver and just manage to read the USB file in /dev. Because who defines as to what should happen when you do a read() on the USB device file? And who defines what action should be initiated when you invoke sysioctl()? Your driver! In other words, the device files are themselves incapable of anything until they are supported by the underlying drivers. In fact, you can treat the device files to be an abstraction of the underlying driver! So, no driver, no use of device file :(
I suggest you go through the following articles about how to write a driver and also understand the USB internals-
http://www.linux-usb.org/USB-guide/c15.html
http://www.linuxjournal.com/article/4786 ( Slightly outdated )

Resources