Friday 20 July 2018

IOCTL

Operating system segregates virtual memory into kernel space and user space.  Kernel space is strictly reserved for running the kernel, kernel extensions, and most device drivers. In contrast, user space is the memory area where all user mode applications work and this memory can be swapped out when necessary. 
There are many ways to Communicate between the User space and Kernel Space, they are:
  • IOCTL
  • Procfs
  • Sysfs
  • Configfs
  • Debugfs
  • Sysctl
  • UDP Sockets
  • Netlink Sockets

IOCTL

IOCTL is referred as Input and Output Control, which is used to talking to device drivers. Some real time applications of ioctl is Ejecting the media from a “cd” drive, to change the Baud Rate of Serial port, Adjust the Volume, Reading or Writing device registers, etc. We already have write and read function in our device driver. But it is not enough for all cases.


Steps involved in IOCTL

There are some steps involved to use IOCTL.
  • Create IOCTL command in driver
  • Write IOCTL function in driver
  • Create IOCTL command in User space application
  • Use IOCTL system call in User space

Create IOCTL Command in Driver

To implement a new ioctl command we need to follow the following steps.
1. Define the ioctl code
#define "ioctl name" __IOX("magic number","command number","argument type")
where IOX can be :
“IO”: an ioctl with no parameters
“IOW”: an ioctl with write parameters (copy_from_user)
“IOR”: an ioctl with read parameters (copy_to_user)
“IOWR”: an ioctl with both write and read parameters
  • The Magic Number is a unique number or character that will differentiate our set of ioctl calls from the other ioctl calls. some times the major number for the device is used here.
  • Command Number is the number that is assigned to the ioctl .This is used to differentiate the commands from one another.
  • The last is the type of data.
2. Add the header file linux/ioctl.h to make use of the above mentioned calls.
Example:

Write/Read IOCTL function in driver

static long etx_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
         switch(cmd) {
                case WR_VALUE:
                        copy_from_user(&value ,(int32_t*) arg, sizeof(value));
                        printk(KERN_INFO "Value = %d\n", value);
                        break;
                case RD_VALUE:
                        copy_to_user((int32_t*) arg, &value, sizeof(value));
                        break;
        }
        return 0;
}
Where
   : is the file pointer to the file that was passed by the application.
 : is the ioctl command that was called from the user space.
   : are the arguments passed from the user space.
With in the function “ioctl” we need to implement all the commands that we defined above. 

Device Driver Source Code


Application Source Code

Building Driver and Application

  • Build the driver by using Makefile (sudo make)
  • Use below line in terminal to compile the user space application.
gcc -o test_app test_app.c

Execution (Output)

As of now, we have driver.ko and test_app. Now we will see the output.
  • Load the driver using sudo insmod driver.ko
  • Run the application (sudo ./test_app)
*********************************
*******WWW.EmbeTronicX.com*******
Opening Driver
Enter the Value to send
  • Enter the value to pass
23456
Writing Value to Driver
Reading Value from Driver
Value is 23456
Closing Driver
  • Now check the value using dmesg
Device File Opened...!!!
Value = 23456
Device File Closed...!!!


No comments:

Post a Comment