Character Device driver Model

Source: Internet
Author: User

Character-driven programming model:

1. Device Description Structure Cdev

1.1 structure definition

1.2 Device number

1.3 Device Operation Set

In the Linux system, the types of devices are very diverse, such as: Character devices, block devices, network interface devices, USB devices, PCI devices, platform equipment, hybrid devices ..., and the device type is different, it also means that the corresponding driver model is different, which led to the need to master a lot of driver model. Then it is not possible to extract some common rules from these many drive models, which is the key to our ability to learn the Linux drive.



View the device number can be seen by viewing the device number in the/dev directory


Secondary device number


Operation of the device number:


Assignment of the device number:


Logoff of the device number:

Regardless of the method used to assign the device number, you should use the Unregister_chrdev_region function to release the device numbers when the driver exits.

Set of operating functions:


Set of operating functions:



2. Character device driver Model


Describe the allocation of structs:

Cdev variables can be defined using both static and dynamic methods.

Static assignment: struct Cdev mdev;

Dynamic assignment: struct Cdev *pdev = Cdev_alloc ();

Describe the initialization of the structure:


To describe the registration of a struct:

The registration of the character device is done using the Cdev_add function, the function prototype:

Cdev_add (struct Cdev *p, dev_t Dev, unsigned count)

Parameters:

P: Character device structure to be added to the kernel

Dev: Device number

Count: Number of devices for this type of device

The rest is to complete the initialization according to the corresponding chip manual.

To implement device operations:


Device Operation prototype:

Turn on the device in response to the open system call

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


Turn off the device in response to the close system call

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


Relocate read-write pointers in response to Lseek system calls

loff_t (*llseek) (struct file*, loff_t, int)


Read the data from the device in response to the read system call

ssize_t (*read) (struct file*, char __user *, size_t, Lofft *)


Writes data to the device in response to a write system call

ssize_t (*write) (struct file*, char __user *, size_t, Lofft *)

struct file: In a Linux system, each open file is associated with a struct file in the kernel, which is created when the kernel is opened and released after the file is closed.

Important Members:

loff_t F_pos/* file read/write pointer */

struct File_operations *f_op/* The action for reading the file */


struct Inode

Each file that exists in the file system is associated with an inode structure, which is primarily used to record the physical information of a file. Therefore, it differs from the file structure that represents open files. When a file is not opened, it is not associated with the file structure, but it is associated with an inode structure.

Important members: dev_t I_RDEV/* Device number */


Device Operation---Open

The open device method is used by the driver to perform initialization preparation for subsequent operations, and in most drivers, open completes the following tasks:

1> marking the secondary device number

2.> Boot Device

Device Operation---Release

The release method works just as opposed to open. This device method is sometimes called close, and it is used to turn off the device

Device Operation---Read




Device Operation---Write


Finally, the driver is logged out: When we unload the driver from the kernel, we need to make the Cdev_del function to complete the character device logoff.




3. Example driven analysis


Here's a sample code to drive a well-written character:

MEMDEV.C file

#include <linux/module.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/cdev.h > #include <asm/uaccess.h>int dev1_registers[5];int dev2_registers[5];struct cdev Cdev; dev_t devno;/* File Open function */int mem_open (struct inode *inode, struct file *filp) {/* Get secondary device number */int num = MINOR (inode-&gt        ; i_rdev);    if (num==0) filp->private_data = dev1_registers;    else if (num = = 1) filp->private_data = dev2_registers;  else Return-enodev; Invalid secondary device number return 0; }/* file Release function */int mem_release (struct inode *inode, struct file *filp) {return 0;}   /* Read function */static ssize_t mem_read (struct file *filp, char __user *buf, size_t size, loff_t *ppos) {unsigned long p = *ppos;  unsigned int count = size;  int ret = 0; int *register_addr = filp->private_data;  /* Obtain the device's register base address */* To determine if the read position is valid */if (P >= 5*sizeof (int)) return 0;  if (Count > 5*sizeof (int)-P) Count = 5*sizeof (int)-p; /* Read data to User space */if (Copy_to_user (buf, RegiSter_addr+p, Count)) {ret =-efault;    } else {*ppos + = count;  ret = count; } return ret;}  /* Write function */static ssize_t mem_write (struct file *filp, const char __user *buf, size_t size, loff_t *ppos) {unsigned long p =  *ppos;  unsigned int count = size;  int ret = 0; int *register_addr = filp->private_data;  /* Get the device's register address */* parse and get valid write length */if (P >= 5*sizeof (int)) return 0;      if (Count > 5*sizeof (int)-P) Count = 5*sizeof (int)-p;  /* Write data from user space */if (Copy_from_user (Register_addr + p, buf, count)) ret =-efault;    else {*ppos + = count;  ret = count; } return ret;}    /* Seek file Locator function */static loff_t mem_llseek (struct file *filp, loff_t offset, int whence) {loff_t newpos;        Switch (whence) {case seek_set:newpos = offset;      Break        Case Seek_cur:newpos = Filp->f_pos + offset;      Break        Case seek_end:newpos = 5*sizeof (int)-1 + offset;      Break    Default:return-einval; } if ((newpos<0) | |    (newpos>5*sizeof (int)))        Return-einval;    Filp->f_pos = Newpos; return newpos;}  /* File operation struct */static const struct file_operations mem_fops ={. Llseek = Mem_llseek,. Read = Mem_read,. Write = Mem_write, . open = Mem_open,. Release = mem_release,};/* device driver module load function */static int memdev_init (void) {/* Initialize CDEV structure */Cdev_init (&AMP;CD    EV, &AMP;MEM_FOPS);  /* Register character device */alloc_chrdev_region (&AMP;DEVNO, 0, 2, "Memdev"); Cdev_add (&cdev, Devno, 2);}   /* Module unload function */static void memdev_exit (void) {Cdev_del (&cdev); /* Unregister device */Unregister_chrdev_region (DEVNO, 2); /* Release device number */}module_license ("GPL"); Module_init (Memdev_init); Module_exit (Memdev_exit);

Makefile file

Obj-m: = Memdev.okdir: =/home/s5-driver/lesson7/linux-tiny6410/all:make-c $ (kdir) m=$ (PWD) modules cross_compile= Arm-linux-arch=armclean:rm-f *.ko *.o *.mod.o *.mod.c *.symvers *.bak *.order

Compile the driver module and sync to the Development Board via the root file system of the NFS mounted Dev board



Installing the driver module Insmod Memdev.ko


Create a character device file: (because the application is using the device file to drive communication with the corresponding device, the instructions above)

Character device files and character device drivers are also linked by the main device number!

Cat/proc/device can see the main device number and device driver name!


From the above can be seen device driver Memdev corresponding device driver number is 252

Below to create a character device file with Mknod


Mdmdev0 the name of the device file (as long as it does not repeat with other names)

C stands for the creation of a character device file

252 is the device driver above the corresponding main device number 0 represents the secondary device number, here is a non-negative on the line

Application to access character device drivers via character device files: (here is the virtual character device file, as can be seen through the memdev.c above)

Read-memdev.c

#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>int main () { int FD = 0;int DST = 0;/* to open the device file */FD = open ("/dev/memdev0", O_RDWR);/* Write Data */read (FD, &DST, sizeof (int));p rintf ("DST is% D\n ", DST);/* close Device */close (FD); return 0;}
Write-memdev.c

#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>int main () { int fd = 0;int src = 2013;/* Open the device file */FD = open ("/dev/memdev0", O_RDWR);/* Write Data */write (FD, &SRC, sizeof (int));/* Turn off the device */ Close (FD); return 0;}


Cross-compiling, use static compilation here! Because some library boards have not been ported to the past!

For example, if you do not use the-static option to compile WRITE-MEM.C, running the application on the Development Board will appear



Here you can see that this app is running with libc.so.6 this dynamic link library! Then go to the Development Board of the system on the Lib directory down to see if there is no this library.


Empty, nothing, so there are two ways to solve this problem, one is to copy the library to the Lib directory, one way is to compile the time with the-static option to choose the static compilation of the method of compiling the program!


This is how the entire character device driver and application are linked together as well as the entire character driven device model introduction over!

Character Device driver Model

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.