Character device driver (program design)-①

Source: Internet
Author: User

Via:http://blog.sina.com.cn/s/blog_7ec8fc2c010157lc.html

1. Driver design

1) Drive classification

The drive is divided into character device driver, network interface driver, block device driver! These three categories, of which the first two are the focus.

①, character devices

A character device is a device that is accessed on its own, and the character driver is responsible for driving the character device, which is usually the first open, close, read, and write system calls!

②, block equipment

In most Unix systems, block devices cannot process data in bytes, and can only transmit a single block of data at a time or multiple lengths of 512 bytes (or a larger number of 2 powers).

For Linux, it allows a block device to transmit any number of bytes. Therefore, the difference between a block and a character device is only driven by a different interface to the kernel.

③, network interface

Any kind of network is done through an interface, an interface is usually a hardware device (eth0), but it can also be a purely software device, such as a loopback interface (LO). A network interface is responsible for sending and receiving data messages.

2) Driver installation

Method one, module mode

Method Two, directly compiled into the kernel

This method is to directly modify the Kconfig and Makefie (these two files should be placed in the location of your program, such as:/drivers/char directory you want to put a hello.c program, and then modify the directory of Kconfig and Makefile Oh, yes.)

3) Use of the driver

Directly take the country to embed the diagram is OH:

2, character device driver program design

First of all, introduce the following knowledge points:

▲: Device number

▲: Create a Device file

▲: Device Registration

▲: Important Data structure

▲: Equipment operation

1) Primary and secondary equipment number

The character device is accessed by a self-out device file. The character device file uses the "C" identifier of the first column of the output of ls-l.

If you use the Ls-l command, you will see that the number of friends in the device file entry is 2 (separated by a comma) These numbers are the primary and secondary device numbers for the device files.

①, device number function

The main device number is used to identify the driver that is connected to the device file (that is, the main device number is connected to the character device file and character device driver ). The secondary device number is used by the driver to determine which device is operating.

that is, the main device number is used to reflect the device type, and the secondary device number is used to differentiate between devices of the same type.

Description of ②, device number

▲: The kernel uses dev_t to describe the device number (which is essentially the unsigned int 32-bit integer, where the high 12 bits are the primary device number, and the lower 20 bits are the secondary device number).

▲:major (dev_t Dev)

Break out the main device number from the dev_t!

▲:minor (dev_t Dev)

Break out the secondary device number from the dev_t!

③, assigning the main device number

Static applications can be used, dynamic allocation of two methods.

A, static application

Method:

First, according to Documentation/devices.txt, determine a master device number that is not used, and then use the Register_chrdev_region function to register the device number!

Advantages:

Simple

Disadvantages:

Once the drive is widely used, this randomly selected master device number may cause a device number conflict and prevent the driver from registering.

Register_chrdev_region

function function:

Request to use count devices starting from (the main device number is unchanged, the secondary device number increases or decreases).

Function Prototypes:

int register_chrdev_region (dev_t from,unsigned count,const char *name)

Parameter description:

From: You want to apply the first device number

Count: Number of device numbers you would like to request to use

Name: Device name (reflected in/proc/devices).

Tip: The device number consists of the main device number and the secondary device number, the kernel provides macro MKDEV (Ma,mi) to form the device number, the macro MAJOR (dev) can be extracted from the device number of the main device number, through the macro MINOR (dev) can be raised from the device number from the device number.

return value:

Successful return 0, failed with a negative return value of the error number.

B, dynamic distribution

Method:

Assigning a device number using alloc_chrdev_region

Advantages:

Simple, easy to drive promotion

Disadvantages:

The device file cannot be created before the driver can be installed (because the main device number was not assigned before the installation).

Workaround:

After the driver is installed, query the device number from the/proc/devices

Alloc_chrdev_region

function function:

The request kernel dynamically allocates count number of device numbers, and this device number starts at Baseinor

Function Prototypes:

int alloc_chrdev_region (dev_t *dev,unsigned baseminor,unsigned count,const char *name)

Parameter description:

Dev: The device number assigned to

Baseminor: Start this device number

Count: Number of secondary device numbers that need to be assigned

Name: Device name (reflected in/proc/devices)

return value:

Successful return 0, failed with a negative return value of the error number.

④, logoff device number

Regardless of the method you use to assign the device number, you should release the device numbers when they are not being used.

Unregister_chrdev_region

function function:

To release count number of devices from start

Function Prototypes:

void Unregister_chrdev_region (dev_t from,unsigned count)

Parameter description:

From: The first device number to be deleted

Count: Number of device numbers to remove

return value:

No

⑤, creating a device file

Method One,

Manually created using the Mknod command

Where Mknod usage:

Mknod filename Type Major minor

Parameter meaning:

FileName: Device file name

Type: Device file type

Major: Main device number

Minor: Secondary device number

Routines:

Mknod serial0 C 100 0

Method two, automatically create

He said it would be introduced later, so we'll talk about it later!

2) Important structure

In the Linux character device driver program, there are three very important data structures:

struct file

struct Innod

struct file_operations

①, struct file

Represents an open file. Each open file in the system has an associated struct file in the kernel space (note: This file will be generated every time it is opened). It is created by the kernel when the file is opened and released after the file is closed!

Important Members:

loff_t F_pos

struct File_operation *f_op

②, struct inode

Used to log the physical information of a file. Therefore, it differs from the file structure that represents open files. A file can correspond to multiple file structures, but only one inode structure!

Important Members:

dev_t I_rdev: Device number

③, struct file_operations

A collection of function pointers that define the operations that can be run on the device.

The members in the struct point to functions in the drive that implement a special operation and leave NULL for unsupported operations.

For example, this structure can be written like this:

struct File_operation mem_fops = {

. Owner = This_module,

. Llseek = Mem_seek,

. Read = Mem_read,

. write = Mem_write,

. IOCTL = Mem_ioctl,

. open = Mem_open,

. Release = Mem_release,

};

3) Device Registration

In the Linux 2.6 kernel, character devices are described using struct Cdev.

The registration of a character device can be divided into the following 3 steps:

▲: Allocation Cdev

▲: Initialize Cdev

▲: Add Cdev

①, device registration (allocation)

Assign a struct CDEV

Function Prototypes:

Stuct Cdev *cdev_alloc (void)

return value:

A pointer to the CDEV struct was returned successfully, and NULL was returned by failure.

②, device registration (initialization)

The allocation of struct Cdev can be done using the Cdev_alloc function.

function function:

Initializes a struct CDEV

Function Prototypes:

void Cdev_init (Cdev *cdev,const struct file_operations *fops)

Parameter description:

Cdev: Cdev structure to initialize

FoPs: The set of operating functions corresponding to the device (where the main members of the file_operations structure are already described above)!

return value:

No

③, device registration (ADD)

The initialization of struct Cdev is done using the Cdev_init function.

function function:

Register a Struct_cdev, add the system to add the character device

Function Prototypes:

int Cdev_add (struct Cdev *p,dev_t dev,unsigned count)

Parameter description:

P: Character device structure to be added to the kernel

Dev: Device number

Count: Number of devices added

return value:

Successful return 0, failed with a negative return value of the error number.

④, logoff character device

Function Prototypes:

int Cdev_del (struct Cdev *p)

Parameter description:

P: The character device structure to unregister

return value:

Successful return 0, failed to return negative error number

4) Device operation

After completing the registration of the driver, the next step is to implement the operation supported by the device!!!

That is to implement the corresponding member in the file_operations structure.

①, open

Function Description:

The first operation in a device file does not require the driver to declare a corresponding method.

If this item is NULL, the device is turned on successfully, but your driver will not be notified.

Function Prototypes:

Int (*open) (struct inode *inode,struct file *filp)

Parameter description:

Inode: As a file node, there is only one node, no matter how many files the user opens, it only corresponds to an inode structure.

FILP: Whenever a file is opened, it corresponds to the file struct, which is usually used to track the state information of the files at run time.

②, Release

Function Description:

The kernel invokes the driver release () function when the last user process that opens the device executes a close () system call. The main task of the function is to clean up the unfinished input and output operations, release the resources, and customize the reset of the flag for the user.

This operation is referenced when the file structure is disposed, as if open,release could be NULL.

Function Prototypes:

Int (*release) (struct inode *inode,struct file *filp)

Parameter description:

With open operation

③, read

Function Description:

Used to fetch data from the device. The return value represents the number of bytes successfully read

Function Prototypes:

ssize_t (*read) (struct file *filp,char __user *buffer,size_t size,loff_t *p)

Function Description:

FILP: Target file struct-body pointer

Buffer: buffers that correspond to the placement of information (both the User space memory address)

Size: Length of information to read

P: The position of the read relative to the beginning of the file offset, after reading the information, the pointer will generally move, the value of the move is to read the length of the information value)

④, write

Function Description:

Sends the data to the device, and the return value represents the byte function that was successfully written (note: This operation and the previous read of the file file are blocking operations).

Function Prototypes:

ssize_t (*write) (struct file *filp,contst char __user *buffer,size_t count,loff_t *ppos)

Parameter description:

FILP: Target file struct-body pointer

Buffer: The hehe buffer to write to the file

Size: The length of information to write

Poos: The current offset position, which is usually used to determine if the write file is out of bounds

⑤, Llseek

Function Description:

Initializes a struct CDEV

Function Prototypes:

loft_t (*llseek) (struct file *filp,loff_t p,int orig)

Parameter description:

FILP: Target file struct-body pointer

P: Target offset for file positioning

Orig: The starting address for the location of the file, which can be the beginning of the file (Seek_set, 0), the current position (Seek_cur, 1), the end of the file (Seek_end, 2).

5) Read and write

For reading and writing, here are some explanations:

FILP is a file pointer, and count is the amount of data that is requested for transmission. The buff parameter points to the data cache, and finally, OFFP indicates where the file is currently accessed!

Where: The buff parameter of the read and write methods is a user-space pointer. Therefore, it cannot be consumed directly by the kernel code, for the following reasons:

User hole home pointers may not be valid at all in kernel space-there is no mapping for that address!

In this way, the kernel provides a special function to permanently access the user space of the pointer, for example:

int copy_from_user (void *to,const void __user *from,int N)

int Copy_to_user (void __user *to,const void *from,int N)

By the way, let's introduce some more:

A function that can pass a variable of kernel space to the address of a user's space is similar to the following:

Get_user (VAR,PTR);

Put_user (VAR,PTR);

Long Stmcpy_from_user (char *dst,const char __user *src,long count);

Strlen_user (str);

These functions are used to make the necessary data interactions with the user space using kernel space, which is too restrictive to pass the data using the return value of the system call.

Character device driver (program design)-①

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.