Linux Device Drivers (2) character device drivers (1)

Source: Internet
Author: User

Download this mp3-(right click)

Start the Linux Device Driver journey with music. The next few logs will record the compilation and testing of the "character device driver.

I chose to paste code and describe to analyze and design our driver, because it is clear.

The user-defined header file demo. H is as follows:

The custom header file # ifndef _ demo_h _ # DEFINE _ demo_h _ # include <Linux/IOCTL. h>/* needed for the _ Iow etc stuff used later *//************************ * ******************************* macros to help debugging *** **************************************** * ************/# UNDEF pdebug/* UNDEF it, just in case */# ifdef demo_debug # ifdef _ KERNEL __# define pdebug (FMT, argS ...) printk (kern_debug "Demo:" FMT, # ARGs) # else // USR space # define pdebug (FMT, argS ...) fprintf (stderr, FMT, ## ARGs) # endif # else # define pdebug (FMT, argS ...) /* Not debugging: nothing */# endif # UNDEF pdebugg # define pdebugg (FMT, argS ...) /* nothing: it's a placeholder * // device number # define demo_major 224 # define demo_minor 0 # define command1 1 # define command2 2 // device structure struct demo_dev {struct cdev; /* char device structure */}; // function declaration ssize_t demo_read (struct file * filp, char _ User * Buf, size_t count, loff_t * f_pos ); ssize_t demo_write (struct file * filp, const char _ User * Buf, size_t count, loff_t * f_pos); loff_t evaluate (struct file * filp, loff_t off, int whence ); int demo_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, unsigned long Arg); # endif/* _ demo_h _*/

It must be noted that

   1:  #define DEMO_MAJOR 224 
   2:  #define DEMO_MINOR 0
Here are the definitions of the Primary and Secondary device numbers respectively. The usage of the Primary and Secondary device numbers will be explained in the source code.
There are a lot of function declarations below. These functions should be written to the driver. Next we will explain the specific implementation.
The following is the source file demo. C.
   1:  #include <linux/module.h>
   2:  #include <linux/kernel.h>
   3:  #include <linux/fs.h>
   4:  #include <linux/errno.h>
   5:  #include <linux/types.h>
   6:  #include <linux/fcntl.h>
   7:  #include <linux/cdev.h>
   8:  #include <linux/version.h>
   9:  #include <linux/vmalloc.h>
  10:  #include <linux/ctype.h>
  11:  #include <linux/pagemap.h>
  12:   
  13:  #include "demo.h"
  14:   
  15:  MODULE_AUTHOR("sunnysun");
  16:  MODULE_LICENSE("Dual BSD/GPL");
  17:   
  18:  struct DEMO_dev *DEMO_devices;
  19:  static unsigned char demo_inc=0;
  20:  static u8 demoBuffer[256];
 
The following lists various header files, struct definitions, variable definitions, and macro calls.
When the header file uses the content, you can go to the url I provided to view the source code.
MODULE_AUTHOR("sunnysun");
MODULE_LICENSE("Dual BSD/GPL");
The two macros here are from
#include <linux/module.h>
Who is the author of the first macro voice module? For specific licenses recognized by the second macro for the kernel, "GPL" (applicable to any version of the GNU General Public License ),
"GPL V2" (applicable only to GPL version 2), "GPL and additional rights", "dual BSD/GPL", "dual MPL/GPL", and "proprietary ". unless your
The module is clearly identified with a free license recognized by the kernel, otherwise it is assumed that it is private, and the kernel is "dirty" during module loading.
Similar macros are as follows:
Module_descripion (a one-person-readable statement about modules ),
Module_version ),
Module_alias (another name known to the module ),
Module_device_table (to inform the user space, which devices are supported by the module ).
 
Let's talk about it below:
struct DEMO_dev *DEMO_devices;
We can see that this struct is from the demo. h header file.
struct DEMO_dev 
{
    struct cdev cdev;      /* Char device structure        */
};
The result shows that struct cdev runs from there. In fact, this struct is the character device structure in Linux, short for char device.
Find in Linux KernelLinux/Include/Linux/Cdev. hWe can find the implementation of this struct:
 
   1:  struct cdev {
   2:              struct kobject kobj;
3: struct module * owner; // Module
   4:              const struct file_operations *ops;
5: // file operation structure. When writing a driver, most of the functions in the structure are implemented.
   6:              struct list_head list;
7: dev_t dev; // device number
   8:              unsigned int count;
   9:  };
 
When I looked at this struct, I found the new struct kobject.
This struct will be explained later. The usage of struct cdev is described first. The following functions are used to operate the cdev struct:
void cdev_init(struct cdev *, const struct file_operations *);
Initialize and establish a connection between cdev and file_operation.
struct cdev *cdev_alloc(void);   
Dynamically apply for a cdev memory.
void cdev_put(struct cdev *p);
Release.
int cdev_add(struct cdev *, dev_t, unsigned);
Register a device, usually in the loading function of the driver module.
void cdev_del(struct cdev *);
Logging out of a device usually occurs in the uninstall function of the driver module. When registering, you should first call:
int register_chrdev_region(dev_t from,unsigned count,const char *name)
This function can be replaced by the following function:
int alloc_chrdev_region(dev_t *dev,unsigned baseminor,unsigned count,const char *name)
The difference between them is that when register_chrdev_region () is used for a known device number, and the other is used for dynamic application, the advantage is that it will not cause a conflict of device numbers. After cancellation, you should call:
void unregister_chrdev_region(dev_t from,unsigned count)

Function to release the device number.
The ordered relationships between them are as follows:

Register_chrdev_region () --> cdev_add () // this process is in the loading Module
Cdev_del () --> unregister_chrdev_region () // this process is in the uninstall Module

The prototype of the cdev_add () function is as follows:

#include <linux/cdev.h>
int cdev_add(struct cdev *p, dev_t dev, unsigned count);

The third parameter is the cdev struct pointer;
The third parameter is the device number expressed in the dev_t type (the device number expressed in the dev_t type is implemented using the mkdev (INT major, int minor) macro );
The 3rd parameter indicates the number of device numbers.

Cdev_add ()The function implementation code is:

   1:  /**
   2:  * cdev_add() - add a char device to the system
   3:  * @p: the cdev structure for the device
   4:  * @dev: the first device number for which this device is responsible
   5:  * @count: the number of consecutive minor numbers corresponding to this
   6:  *         device
   7:  *
   8:  * cdev_add() adds the device represented by @p to the system, making it
   9:  * live immediately.  A negative error code is returned on failure.
  10:  */
  11:  int cdev_add(struct cdev *p, dev_t dev, unsigned count)
  12:  {
  13:          p->dev = dev;
  14:          p->count = count;
  15:          return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);
  16:  }

Generally, the value of count is 1, but in some cases it may be a number greater than 1. For example, a SCSI tape drive allows you to select an operation mode (such as density) in an application by assigning multiple device numbers to each physical device ).
If cdev_add fails, a negative value is returned, indicating that the driver cannot be loaded to the system. However, it will usually succeed. Once the cdev_add returns, the device will be "active", so the corresponding operation method (the various functions defined in the file_operations structure) it can also be called by the kernel.

So far, this struct indicates the end. The following describes the implementation and application of the kobject struct.

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.