Linux Device Driver category, character device driver, how to add cdev to the kernel ?, Driver category cdev
1. Linux Device Driver category
By hardware of Managed Devices
Character Device
Access by byte streams, which can be accessed sequentially or at specified locations
Touch screen LCD for serial port terminals
Block Device
In Unix systems, Block devices are accessed based on certain data blocks, and the data blocks are 512 bytes and 1 K.
In Linux, Block devices can be accessed either by data blocks or byte streams, the difference between a block device and a character device is that the data structure and operation methods of Block devices and character devices in linux are different.
Network Device
NICs and network devices are generally implemented in combination with TCP/IP protocol stacks.
2. Character Device Driver
The role of the driver:
1. Manage the corresponding hardware
2. provide users with methods to access hardware (interfaces)
How do applications access hardware?
In linux, hardware devices are stored as device files. Device Files (characters and blocks) are stored in/dev/
Then the application needs to access the hardware to access the corresponding device file.
How do applications access device files?
You can call a system call to access a device file in the same way as accessing a common file.
Open read write ioctl mmap close ......
How does an application find the corresponding hardware driver in many drivers through device files?
The device file contains the following attributes:
Whether the device file is a character device file (c) or a block device file (B)
The device file also includes two important attributes: The primary device number and the secondary device number.
The application finds the corresponding driver through the master device number.
A driver has only one master device number.
Role of sub-device number
The device number is used to find the device individual to access.
Device No.: master device No. and sub-device No.
Data Type:
Dev_t (unsigned int)
12-bit high: master device number
Lower than 20 bits: Secondary device number
Device number operation macro
MAJOR
MINOR
MKDEV
The device number is a system resource. to bind the driver to the device number, you must first apply for the device number resource from the kernel. Only after the application is complete can you bind the device number to the driver.
How do I apply for a device number from the kernel?
Static and Dynamic Allocation
Static allocation
1> check which master device numbers have been used
Cat/proc/devices
Character devices: Character device
1 mem
5/dev/tty
5/dev/console
5/dev/ptmx
10 misc
13 input
21 sg
29 fb
81 video4linux
89 i2c
90 mtd
116 alsa
128 ptm
136 pts
204 s3c2410_serial
252
253 pvrsrvkm
254 rtc
Block devices: Block devices
1 ramdisk
259 blkext
7 loop
8 sd
31 mtdblock
65 sd
66 sd
67 sd
68 sd
69 sd
70 sd
71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
179 mmc
254 device-mapper
2> then, assign the device number based on the number of your devices. Generally, the device number starts from 0.
Dev_t dev = MKDEV (primary device number, secondary device number );
3> call register_chrdev_region to apply to the kernel
Note: The master device number cannot be 0.
Dynamic Allocation
Request from kernel directly by calling alloc_chrdev_region
Release Device number
Unregister_chrdev_region
Four important data structures of linux character device drivers
1> struct file
Purpose: Describe the status attributes after the file is opened.
Life cycle: the kernel is successfully created from open.
Close to close kernel destruction
Important members:
Const struct file_operations * f_op;
Unsigned int f_flags;
// File operation attributes
Loff_t f_pos;
// File operation location
2> struct file_operations
Defines the set of file operation functions. When the user space calls the corresponding system call, it will call the corresponding function in the file_operations Member of the file structure.
3> struct inode
Role: describes the physical structure of a file.
Lifecycle: The file exists and the kernel is created.
File destruction: inode corresponding to kernel destruction
Important members:
Dev_t I _rdev;
// Storage device number
Struct cdev * I _cdev;
// Point to a character device
4> struct cdev
Represents a single character Device Driver
Important data members:
Const struct * ops;
// A set of operation functions driven by character Devices
Dev_t dev;
// Device number
A file has only one inode and can have multiple files.
How does struct file find file_operations in cdev?
1> the application calls open and finally calls sys_open
2> sys_open: create a file struct to describe the open information of the file.
3> Find the corresponding cdev through the master device number
4> assign the file_operations member in cdev to the file_operations member in file.
5> sys_open finally calls the open function in file_operations in cdev
6> in the future, all operations on the device files in the user space will be accessed by the file_operations member in cdev, that is, the operations on the hardware.
Read --> sys_read --> file-> f_op-> read --> cdev-> ops-> read
Write --> sys_write --> file-> f_op-> write --> cdev-> ops-> write
How to add cdev to the kernel
1> assign an operator set to initialize the struct file_operations File
Struct file_operations cdd_fops = {
. Open =...
. Read = ....
. Write =...
.....
};
2> assign a device driver to initialize struct cdev with one character
Struct cdev cdd_cdev;
Cdev_init (& cdd_cdev, & cdd_fops );
// Cdd_cdev.ops = cdd_fops;
3> Add cdev to the kernel
Cdev_add (& cdd_cdev, device number, number of devices );
The result is to add cdd_cdev to the cdev array of the kernel. The subscript is indexed by the device number.
Once cdev is added, a real character device driver is available in the kernel.
Create a device file
Static creation:
Mknod cdd c 251 0
Dynamic Creation:
Create a device class: class_create
Create a device file: device_create
To implement the driver for a character device:
1> apply for a device number (static/dynamic)
2> Register cdev to the kernel
3> Create a device
4> Create A Device File
Use a character device driver to operate LEDs
GPIO Interface
The kernel defines a series of GPIO operation functions.
Apply for GPIO: gpio_request
Release GPIO: gpio_free
Set GPIO to output: gpio_direction_output
Set GPIO as input: gpio_direction_input
Set the up and down of GPIO: initi_gpio_setpull
Initi_gpio_pull_none
Initi_gpio_pull_down
Initi_gpio_pull_up
Set output value: gpio_set_value
Read input value: gpio_get_value
Printf ("key_val = % # x \ n", key_val); // a line break is required before printing on the terminal.
Printf is not printed to the terminal, but to the output buffer.