Home PC Games Linux Windows Database Network Programming Server Mobile  
           
  Home \ Linux \ Linux character device - a simple character device model     - Additional SQL Server 5123 database reported error (Database)

- Enterprise Hadoop cluster architecture - DNS installation (Server)

- Write perfect printf (Programming)

- The principle Httpclient4.4 (execution request) (Programming)

- OpenGL Superb Learning Notes - GLSL language foundation (Programming)

- error 1819 (HY000): your password does not satisfy the current policy requirements (Database)

- Build their own recursive DNS server (Server)

- Configuring Eclipse Note Templates (Linux)

- MySQL High Availability plan several options (Database)

- Ubuntu clean up unnecessary disk space usage (Linux)

- Use $ BASH ENV variable to mention the right way under Linux (Linux)

- Ubuntu 14.04 LTS next upgrade gcc to gcc-4.9, gcc-5 version (Linux)

- How to display a dialog Bash Shell script (Programming)

- CentOS 6.5 installation VNCServer implement graphical access (Server)

- Redis is installed and set up Ubuntu 14.04 from the environment under the main ssdb (Server)

- C language sorting instance (select, bubble, insert, binary, fast) (Programming)

- Zabbix Agent for Linux Installation and Configuration (Server)

- Processor in protected mode of protection (Linux)

- Python Django direct implementation of sql statement (Programming)

- VMware virtual machine to install CentOS 7 (Linux)

 
         
  Linux character device - a simple character device model
     
  Add Date : 2018-11-21      
         
         
         
  Linux character device

one. Using character device driver

1. Compile / install the driver
In the Linux system, the driver usually program structure kernel modules to be encoded. Therefore, compile / install a driver, its essence is to compile / install a kernel module.

2. The character device file
Through the character device file, the application can use the corresponding character device drivers to control a character device.

Create a character device files, there are two general methods:
1. Use the mknod command
mknod / dev / filename c major device number minor device number
2. Create a function in the driver

two. Character-driven programming model

Device description of the structure

Driver Model
In the Linux system, the type of equipment is very diverse, such as: character devices, block devices, network interface devices, USB devices, PCI devices, platform equipment, miscellaneous equipment ......, and different types of equipment, but also means that the corresponding driver different models, thus leading us need to learn so many driver model. It can extract some common rules have driven many from these models, it is crucial that we can learn Linux driver.
 
1. Device description of the structure

In any driver model, the device will use the kernel of a structure will be described. Our character device using structcdev described in the kernel.
struct cdev {
struct kobject kobj;
struct module * owner;
const struct file_operations * ops; // set device operation
struct list_head list;
dev_t dev; // device number
unsigned int count; // number of devices
};

1.1 Device Number

Check the / dev directory device number

1.1 minor number

2.1 Device Number - Operating

Linux kernel used to define the type of device number dev_t, dev_t essence of this type of 32-bit unsigned int, including high resolution 12-based devices, low 20 to the minor number.
Question 1: If you know the major number, minor number, type how combined into dev_t
A: dev_t dev = MKDEV (major number, minor device number)

Question 2: how to break out of the main equipment from dev_t in?
A: The major number = MAJOR (dev_t dev)
Question 3: How to break out of the minor number from dev_t?
A: minor number = MINOR (dev_t dev)

1.1 Device Number - Distribution

How to assign a major number for the device?
Static Application
Developers choose a number as the main equipment, and then use the application through to the kernel function register_chrdev_region. Disadvantages: If the device has been used by the application number of other kernel drivers used, the application fails.
Dynamic allocation
Use alloc_chrdev_region available major number assigned by the kernel.
Advantages: Because the kernel know which number has been used, it will not cause has been assigned to the use of numbers.

1.1 Device Number - logout

Regardless of the method of assigning the device number, should exit when driving, use unregister_chrdev_region
Function to release the device number.

1.2 Operating function set

2.2 Operating function set

Struct file_operations is a collection of function pointers, in the definition of energy
Operation of the device. Structure function pointer to a function driver,
These functions implement an operation for devices that do not support the set operation
Function pointer is set to NULL. E.g:
struct file_operations dev_fops = {

.llseek = NULL,
.read = dev_read,
.write = dev_write,
.ioctl = dev_ioctl,
.open = dev_open,
.release = dev_release,
};

2.1 character device initialization

2.1 Description Structure - Distribution

Cdev define static and dynamic variables can be used in two ways
- static allocation
struct cdev mdev;
- Dynamic Allocation
struct cdev * pdev = cdev_alloc ();

2.1 Description Structure - Initialization

Initializes struct cdev use cdev_init function to complete.
cdev_init (struct cdev * cdev, const struct file_operations * fops)

parameter:
cdev: cdev structure to be initialized
fops: equipment operation corresponding function set

2.1 Description Structure - Register

Character device registered user cdev_add function to complete.
cdev_add (struct cdev * p, dev_t dev, unsigned count)

parameter:
p: to be added to the kernel's character device structure
dev: device number
count: The number of devices such equipment

2.1 hardware initialization

According to the corresponding hardware chip manual initialization is complete.

2.2 for device operation

2.2 hands with you to analyze

analysis
file_operations

2.2 prototype device operation

int (* open) (struct inode *, struct file *)
Open devices, open system response


int (* release) (struct inode *, struct file *);
Turn off the device in response to the system call close


loff_t (* llseek) (struct file *, loff_t, int)
Relocation read pointer lseek system call response

ssize_t (* read) (struct file *, char __user *, size_t, loff_t *)
Data read from the device in response to the read system call


ssize_t (* write) (struct file *, const char __user *, size_t, loff_t *)
Data is written to the device in response to the write system call

2.2 Struct file

In the Linux system, each open file, the kernel will be associated with a struct file, which when you open files created by the kernel, the file is closed after release.

Important members:
loff_t f_pos / * file read and write pointers * /
struct file_operations * f_op / * the file corresponding to the operation * /

2.2 Struct inode

Each association will be present in the file system inside the file inode structure, which is mainly used to record information on the physical file. Therefore, on behalf of it and open the file file structure is different. Not associated with a document file structure was not open, but it will be associated with a inode structure.
Important members:
dev_t i_rdev: device number

3.2 Equipment Operation -open

open device driver method is used to initialize the preparatory work for future operations. Most drivers
In, open to complete the following tasks:
Indicate the minor number
Boot Device

3.2 Equipment Operation -release

Action release coincided with the open method of contrast. This device is sometimes also referred to close, it should:
Turn off the device.

3.2 Equipment Operation -read

read device method is usually done two things:
Read data from the device (hardware belonging to access class action)
Read the data back to the application
ssize_t (* read) (struct file * filp, char __user * buff, size_t count, loff_t * offp)
Parametric analysis:
filp: file structure pointer associated with a character device file is created by the kernel.
buff: the device to read data from, needs to be saved to the location. This parameter is provided by the call to read the system.
count: the amount of data requested, provide this parameter by the call to read the system.
offp: read-write file location, after removing the kernel from the file structure passed in.

buff parameter is derived from the user space pointer, such pointers not to be a direct reference to the kernel code, you must use a special function


int copy_from_user (void * to, const void __user * from, int n)
int copy_to_user (void __user * to, const void * from, int n)

3.2 Equipment Operation -write

write device method is usually done two things:
Remove data from the address provided in the application data will be written to the device (hardware belonging to access class action)
ssize_t (* write) (struct file *, const char __user *, size_t, loff_t *)
Its parameters are similar to read

2.3 Driver logout

When we unloaded from the kernel driver when the need to complete the logoff function cdev_del character device.

Write a character device automatically assigned manually assign a character device node number of examples and APP

Manual installation steps:

Insmod char_dev.ko

Check the device number of characters

cat / proc / devices

Then install the device node

mknod / dev / my_chardev c 248 0

Then test app

./my_char_dev_app 1

Kernel driver code char_dev.c

#include < linux / module.h>
#include < linux / init.h>
#include < linux / io.h>
#include < linux / fs.h>
#include < asm / device.h> // The following three header files are dynamically created due to the need to increase the
#include < linux / device.h>
#include < linux / cdev.h>
#include "my_cdev.h"
struct cdev cdev;
dev_t devno; // here is the dynamic allocation device number

int my_cdev_open (struct inode * node, struct file * filp)
{
    printk ( "! my_cdev_open sucess \ n");
    return 0;
}

long my_cdev_ioctl (struct file * filp, unsigned int cmd, unsigned long arg)
{
    switch (cmd)
    {
        case LED_ON:
            printk ( "LED_ON is set \ n!");
            return 0;
        case LED_OFF:
            printk ( "LED_OFF is set \ n!");
            return 0;
        default:
            return -EINVAL;
    }
}

struct file_operations my_cdev_fops =
{
    .open = my_cdev_open,
    .unlocked_ioctl = my_cdev_ioctl,

};

static int my_cdev_init (void)
{
    int ret;
    / ** Dynamically allocated device number * /
    ret = alloc_chrdev_region (& devno, 0,1, "my_chardev");
    if (ret)
    {
        printk ( "alloc_chrdev_region fail \ n!");
        unregister_chrdev_region (devno, 1);
        return ret;
    }
    else
    {
        printk ( "! alloc_chrdev_region sucess \ n");
    }
    / ** * Initialize the description of the structure /
    cdev_init (& cdev, & my_cdev_fops);
    / ** * Register description of the structure /
    ret = cdev_add (& cdev, devno, 1);
    if (ret)
    {
        printk ( ". cdev add fail \ n");
        unregister_chrdev_region (devno, 1);
        return ret;
    }
    else
    {
        printk ( "cdev add sucess \ n!");
    }
    
    return 0;
}
static void my_cdev_exit (void)
{
    cdev_del (& cdev);
    unregister_chrdev_region (devno, 1);
    printk ( "! my_cdev_exit sucess \ n");
}
module_init (my_cdev_init);
module_exit (my_cdev_exit);
MODULE_LICENSE ( "GPL");
MODULE_AUTHOR ( "YEFEI");
MODULE_DESCRIPTION ( "YEFEI Driver");

APP header my_cdev.h

#ifndef __MY_CDEV_H__
#define __MY_CDEV_H__

#define LED_MAGIC 'L'
#define LED_ON _IO (LED_MAGIC, 0)
#define LED_OFF _IO (LED_MAGIC, 1)

#endif

APP test file my_char_dev_app.c

#include < sys / stat.h>
#include < sys / types.h>
#include < sys / ioctl.h>
#include < fcntl.h>
#include < stdio.h>
#include "my_cdev.h"

int main (int argc, char * argv [])
{
    int fd;
    int cmd;
    if (argc <2)
    {
        printf ( "Please enter secend param \ n!");
        return 0;
    }
    cmd = atoi (argv [1]);
    fd = open ( "/ dev / my_chardev", O_RDWR);
    if (fd <0)
    {
        printf ( "! Open dev / my_chardev fail \ n");
        close (fd);
        return 0;
    }
    switch (cmd)
    {
        case 1:
            ioctl (fd, LED_ON);
            break;
        case 2:
            ioctl (fd, LED_OFF);
            break;
        default:
            break;
    }
    close (fd);
    return 0;
}
     
         
         
         
  More:      
 
- Linux operating system security management skills notes (Linux)
- How to configure a server in a MySQL Cluster (Database)
- Linux user directory (Linux)
- To install Samba server on CentOS 6.6 (Server)
- How to install Gnome 3.10 in Ubuntu 13.10 (Linux)
- About phpwind 5.01-5.3 0day analysis of the article (Linux)
- Revised OpenJDK Java Memory Model (Programming)
- Smooth upgrade to OpenSSH 6.7 Procedure (Linux)
- Use Linux built-in firewall to improve network access control (Linux)
- Definition Format Oracle basis of various statements (Database)
- Linux common network tools: Scan routing of mtr (Linux)
- Bash environment is automatically install and initialize oh-my-zsh & autojump zsh (Linux)
- Linux iptables: basic principles and rules (Linux)
- ElasticSearch - Basic Concepts (Server)
- Getting the Linux shell expr use (Programming)
- Dockerfile use to build a mirror-based CentOS 7 (Linux)
- ACL permissions Linux command (Linux)
- Installation of network monitoring ntopng under CentOS 6.4 (Linux)
- JavaScript: understanding regular expressions (Programming)
- To install HDRMerge 0.4.3 under ubuntu (Linux)
     
           
     
  CopyRight 2002-2020 newfreesoft.com, All Rights Reserved.