Linux Device Driver-character Device Driver

Source: Internet
Author: User

The biggest feature of Linux devices is that device operations are like file operations. In the application layer, a hardware device is just a device file. Applications can operate hardware devices like operating files, such as open (), close (), read (), and write.

Below is a simple implementation of the character device driver test. c

# Include <Linux/types. h> <br/> # include <Linux/Fs. h> <br/> # include <Linux/mm. h> <br/> # include <Linux/errno. h> <br/> # include <Linux/module. h> <br/> # include <Linux/moduleparam. h> <br/> # include <Linux/kernel. h> <br/> # include <ASM/uaccess. h> <br/> # include <Linux/cdev. h> <br/> # include <Linux/IOCTL. h> <br/> # include <Linux/slab. h> <br/> # include <Linux/fcntl. h> <br/> # include <ASM/segment. h> <br/> # include <ASM/Io. h> <br/> # include <ASM/ARCH/regs-gpio.h> <br/> unsigned int test_major = 253; <br/> unsigned int test_minor = 0; <br/> struct cdev cdevc; <br/> module_license ("dual BSD/GPL"); <br/> static int read_test (struct file * file, char * Buf, int count, loff_t * f_pos) <br/>{< br/> printk ("/n read_test"); <br/> printk ("/n % d ", count); <br/> return count; <br/>}< br/> static int write_test (struct file * file, const char * Buf, int count, loff_t * f_pos) <br/>{< br/> printk ("/n write_test"); <br/> return count; <br/>}< br/> static int open_test (struct inode * inode, struct file * file) <br/>{< br/> printk ("/n open_test"); <br/> return 0; <br/>}< br/> static void release_test (struct inode * inode, struct file * file) <br/>{< br/> printk ("/n release_test"); <br/>}< br/> struct file_operations test_fops ={ <br/>. owner = this_module, <br/>. read = read_test, <br/>. write = write_test, <br/>. open = open_test, <br/>. release = release_test, <br/>}; <br/> int simple_c_init_module (void) <br/>{< br/> int result; <br/> dev_t Dev = 0; </P> <p> Dev = mkdev (test_major, test_minor); <br/> result = register_chrdev_region (Dev, 1, "test "); </P> <p> printk ("Major = % d, minor = % d/N", test_major, test_minor ); </P> <p> If (result <0) <br/> {<br/> printk (kern_info "test: Can't Get Major number/N "); <br/> return result; <br/>}</P> <p> cdev_init (& cdevc, & test_fops); <br/> cdevc. owner = this_module; <br/> cdevc. ops = & test_fops; <br/> result = cdev_add (& cdevc, Dev, 1); <br/> If (result) <br/> printk ("error % d adding test", result); <br/> return 0; <br/>}< br/> void simple_c_cleanup_module (void) <br/>{ <br/> dev_t Dev = 0; <br/> Dev = mkdev (test_major, test_minor); <br/> cdev_del (& cdevc ); <br/> unregister_chrdev_region (Dev, 1); <br/>}< br/> module_init (simple_c_init_module); <br/> module_exit (simple_c_cleanup_module );

 

Module Analysis

 

1. initialize the device driver struct

Struct file_operations test_fops = {
. Owner = this_module,
. Read = read_test,
. Write = write_test,
. Open = open_test,
. Release = release_test,
};

Defines the function called during device Io. In this module, the upper-layer read calls the underlying read_test, the write calls write_test, the open calls open_test, and the close calls release_test.

 

2. module_init Function

Int simple_c_init_module (void)
{
Int result;
Dev_t Dev = 0;

Dev = mkdev (test_major, test_minor );
Result = register_chrdev_region (Dev, 1, "test ");

Printk ("Major = % d, minor = % d/N", test_major, test_minor );

If (result <0)
{
Printk (kern_info "test: Can't Get Major number/N ");
Return result;
}

Cdev_init (& cdevc, & test_fops );
Cdevc. Owner = this_module;
Cdevc. Ops = & test_fops;
Result = cdev_add (& cdevc, Dev, 1 );
If (result)
Printk ("error % d adding test", result );
Return 0;
}

(1) first, mkdev is a device. test_major and test_minor are defined before the file respectively.

Unsigned int maid = 253;
Unsigned int test_minor = 0;

 

(2) register a device number in the specified range,

Result = register_chrdev_region (Dev, 1, "test ");

The function prototype is

Int register_chrdev_region (dev_t from, unsigned count, <br/> const char * Name );

The three parameters indicate the device number in the expected range for the first time, the number of devices required for the number of consecutive devices, the device or driver in this name, respectively.

 

(3) printk prints two device numbers in the kernel, similar to the printf function.

 

(4) initialize the character device structure cdev_init (& cdevc, & test_fops );
The two parameters indicate: the initialization of the structure, the file_operations of the device,

The function is used to remember to initialize the FoPs cdev so that it can be added to the system and cdev_add.

 

(5) assign a value to the structure cdevc of the character device

(6) Call int cdev_add (struct cdev * P, dev_t Dev, unsigned count );

Function: cdev_add adds the P struct to the system device so that it takes effect immediately. A negative error code returns an error.

 

3. module_exit (); Function

Void simple_c_cleanup_module (void)
{
Dev_t Dev = 0;
Dev = mkdev (test_major, test_minor );
Cdev_del (& cdevc );
Unregister_chrdev_region (Dev, 1 );
}

Function cdev_del-remove a character device from the system

The range of device numbers returned by the function unregister_chrdev_region.


4. Underlying Function Design

Static int read_test (struct file * file, char * Buf, int count, loff_t * f_pos) <br/>{< br/> printk ("/n read_test "); <br/> printk ("/n % d", count); <br/> return count; <br/>}< br/> static int write_test (struct file * file, const char * Buf, int count, loff_t * f_pos) <br/>{< br/> printk ("/n write_test"); <br/> return count; <br/>}< br/> static int open_test (struct inode * inode, struct file * file) <br/>{< br/> printk ("/n open_test"); <br/> return 0; <br/>}< br/> static void release_test (struct inode * inode, struct file * file) <br/>{< br/> printk ("/n release_test"); <br/>}

 

Demo:

Compile, make (makefile see http://blog.csdn.net/wanxiao009/archive/2010/06/13/5669665.aspx)

Generate Test. Ko

Minicom logon to the Development Board,

Sent to the Development Board,

Chmod + X test. Ko

Create a device node mknod/dev/test C 253 0 (253 0 is test_major, test_minor)

Insmod test. Ko

As shown in

 

Description: The character driver can be added to the kernel module. ^_^!

 

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.