Embedded-Linux-Device-Driver/C3/Input-and-Output-Control/English

From Script | Spoken-Tutorial
Jump to: navigation, search
Visual Cue Narration
Slide 1:

Welcome slide:

Welcome to the spoken tutorial on Input and Output Control
Slide 2:

Learning objectives:

In this tutorial, we will learn about
  • Ioctl function and
  • Data transfer between userspace and kernel space using ioctl function
Slide 3 :

System Requirements:

To record this tutorial, I am using,
  • VirtualBox 5.2.
  • Ubuntu Linux 18.04 LTS operating system.
  • Linux kernel version 5.0.0-31 generic.
  • gedit text editor.
Slide 4:

Prerequisites:

To follow this tutorial, you should be familiar with:
  • C programming language
  • Basics of Linux kernel

If not, then go through the C/C++ and Linux spoken tutorials on this website.

Slide 5:

Ioctl (input/output control)

  • It is mainly used to handle some specific operations of a device.
  • For example, ioctl function can be used to rewind a tape drive.
  • By default, the kernel does not have a system call for such device operations.
Slide 6:

IOCTl() - Example

In this tutorial, we will learn to transfer data to the driver using the ioctl function.

The user program test.c will send and receive integer data to and from the driver.

Point to the folder and file in desktop Point to the files.

Go to the DeviceDriver folder in the Desktop which we have created earlier.

I have created a directory named Ioctl. I have saved simple_driver dot c, Makefile and test dot c files.

I’ll use these files for demonstration.

Slide 7 :

Code files:

  • The files used in this tutorial are available in the Code Files link on this tutorial page.
  • Please download and extract them
  • Make a copy and then use them while practising
Open the terminal

Type >> cd Desktop/DeviceDriver/Ioctl

Open the terminal by pressing ALT+Ctrl+T keys simultaneously.

Go to the directory where Ioctl is saved on your system.

Press Enter key after every command.

Type >> gedit simple_driver.c

Type gedit space simple_driver dot c.

We have already learnt the open, close, read and write operations on a device.

I have defined the required code to implement the ioctl functions.
HIghlight :

<linux/ioctl.h>

#define MAGIC 'M'#defineSET_DATA_IOW(MAGIC,1u,int)

#defineGET_DATA_IOR(MAGIC,2u,int)

We have to include the ioctl dot h header file.

The macros used in the ioctl functions are defined in this header file. Write and Read commands are defined with the macros as shown here.

Highlight

#define SET_DATA_IOW(MAGIC,1u,int)

MAGIC 1u Int

IOW specifies the write command operation.

MAGIC is an 8-bit magic number which is unique to this driver.

1u specifies the unique command number.

It should not be used by any other driver.

Int represents the data type of the command argument.

Highlight : #define MAGIC 'M'

M

https://www.kernel.org/doc/Documentation/ioctl/ioctl-number.txt

I have used M as the magic number in our driver.

For other MAGIC numbers, refer to this website.

Highlight:

static int x = 0;

static int y= 100;

I have declared two variables x and y.

Data from the user space will be stored in the variable x.

Similarly, data stored in y variable is passed to the user space.

Highlight

static long mydevice_ioctl(struct file *f,unsigned int ioctl_num,unsigned long ioctl_param);

.unlocked_ioctl = mydevice_ioctl

We have to write the ioctl function protocol at the start of the program.

Add an ioctl function pointer mydevice_ioctl, in the file operations structure.

Highlight

static long mydevice_ioctl(struct file *f,unsigned int ioctl_num,unsigned long ioctl_param)

f Ioctl_num ioctl_param

Let us see the ioctl function now.

It has three parameters as shown here. f is the file descriptor of the appropriate device file. ioctl_num is the ioctl command that is called from the userspace. ioctl_param is the argument passed from the userspace.

According to the user ioctl function commands, the switch case will be executed.
HIghlight :

SET_DATA copy_from_user()

copy_from_user will copy the user ioctl parameter to the kernel space variable x.
HIghlight :

GET_DATA copy_to_user()

Copy_to_user function will copy the value of variable y from the kernel space to the user space.

Our program is ready with ioctl function definitions.

Open the terminal. Save and close the file.

Switch back to the terminal.

Type >> gedit test.c

Let’s open the user program.

Type gedit space test dot c.

Highlight

#define MAGIC 'M'

#define SET_DATA _IOW(MAGIC,1u,int)

#define GET_DATA _IOR(MAGIC,2u,int)

This program will pass the arguments and commands to the driver.

We have to define these commands similar to the driver commands.

We will use them in the ioctl function.

Highlight

Static unsigned int g = 0;

Static unsigned int h = 0;

The integer type variables g and h are defined as shown here.

We will use them later on in this code.

Highlight : open()

if(fd < 0)

File open operation failed.

open function opens the new_device.

If it fails then it will display the failure message and terminate the program.

Highlight

ioctl(fd, SET_DATA,&g)<0)

ioctl() function.

The user ioctl function will internally call the driver’s ioctl function.

You can use the ioctl system call only after opening the device file.

HIghlight:

fd SET_DATA g

The first parameter is the device file descriptor number.

And the second parameter is the command that needs to be executed.

The third parameter is the argument to the driver. It will display the negative value on failure.

Highlight

scanf() GET_DATA, h ioctl()

We will pass any integer value at runtime to a driver using the argument g. Similarly, we pass the GET_DATA command to ioctl function.

After execution of this function, we will get the data from the driver in h variable.

HIghlight close() The close system call will close the new_device file.
Highlight

the printf messages.

The printf messages will display the respective information on the terminal.
Save the program.

Open the terminal

Type >> clear

Save and close the file.

Switch back to the terminal.

Clear the screen.

Type >> gedit Makefile Save a file. Click on the close button.

Let us create a Makefile to compile our driver.

Type gedit space Makefile.

Copy the code as shown or you can use downloaded Makefile.

Close the file and switch back to the terminal.

Type >> make all Now, let us compile the driver.

Type make space all.

Type >> clear Clear the screen.
Type >> sudo su

Type >> clear

Type sudo space su to be a superuser and type the system password.
Type >> insmod simple_driver.ko Let’s now load the driver.

Type insmod space simple_driver dot ko

Type >> clear Clear the screen.

Type >> gcc -c test.c

Type >> gcc -o test.out test.o

Type >> ./test.out

Let’s compile and execute the user program.

Type gcc space hyphen c space test dot c.

Type gcc space hyphen o space test dot out space test dot o.

Type dot slash test dot out.

Highlight

the respective printk message

Type the integer value

The printk messages.

The output message shows that the device is opened successfully.

Now, type the integer value that you want to pass to the driver.

I’ll type 500.

The output shows the data copied from the driver to user space variable h. The print message shows that the device is closed by close system call.

Type >> clear Clear the screen.
Highlight

Type >> dmesg | grep simple_driver Highlight : Respective printk messages. Type >> clear

Type the dmesg command as shown here.

The output shows that the ioctl function of the driver is executed.

It shows the data from the user space is copied to the kernel space driver variable x.

Clear the screen.

Type rmmod simple_driver.ko

Type >> clear

Let us unload the driver.

Type rmmod simple_driver.ko

Clear the screen. Type exit.

Type:

cd /usr/include/asm-generic/

Cat ioctl.h

Highlight

In this tutorial, we have discussed IOW and IOR macros.

To know more about other commands, go to the directory asm hyphen generic as shown.

Let us open the ioctl.h file.

Type cat ioctl.h

You can get more details about other commands from the ioctl.h file

With this we come to the end of this tutorial. Let us summarize.
Slide 8 :

Summary:

In this tutorial, we learnt
  • Ioctl function()
  • Data transfer between user space and kernel space using ioctl function
Slide 9 :

Assignment :

As an assignment.
  1. Compile and load simple_driver dot c
  2. Compile and execute test.c
  3. Pass a different integer values as per your choice
  4. See the output using dmesg command.
Slide 10:

About Spoken Tutorial Project:

  • The video at the following link summarizes the Spoken Tutorial project.
  • Please download and watch it.
Slide 11:

Spoken Tutorial workshops :

The Spoken Tutorial Project Team conducts workshops and gives certificates.

For more details, please write to us.

Slide 12:

Forum questions :

Please post your timed queries in this forum
Slide 13:

Forum for specific questions :

  • Do you have any general or technical questions on Embedded Linux Device Driver?
  • Please visit the FOSSEE forum and post your question.
Slide 14:

Acknowledgment:

The Spoken Tutorial Project is funded by MHRD, Government of India.
Slide 15:

Thank you slide:

This tutorial has been contributed by FOSSEE and Spoken Tutorial Project, IIT Bombay.

This is usha signing off.

Thanks for watching.

Contributors and Content Editors

Nancyvarkey, Nirmala Venkat