Embedded-Linux-Device-Driver/C3/Input-and-Output-Control/English
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
|
Slide 3 :
System Requirements: |
To record this tutorial, I am using,
|
Slide 4:
Prerequisites: |
To follow this tutorial, you should be familiar with:
If not, then go through the C/C++ and Linux spoken tutorials on this website. |
Slide 5:
Ioctl (input/output control) |
|
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: |
|
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
|
Slide 9 :
Assignment : |
As an assignment.
|
Slide 10:
About Spoken Tutorial Project: |
|
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 : |
|
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. |