Home PC Games Linux Windows Database Network Programming Server Mobile  
           
  Home \ Linux \ Linux character device - a simple character device model     - CentOS 6.6 install rsync server (Server)

- Java inheritance initialization problem (Programming)

- Linux find command to find files (Linux)

- Ubuntu under VirtualBox virtual machine serial port settings (Linux)

- CentOS 7 Change Hostname (Linux)

- Ubuntu root user profiles (Programming)

- Java application server WildFly (Server)

- Mahout source code analysis: FP-Growth algorithm parallelization (Programming)

- Apache Spark1.1.0 deployment and development environment to build (Server)

- MongoDB polymerization being given (Database)

- DataGuard a hardware issue warnings found (Database)

- OpenJDK 7 compiled under Ubuntu 14.04.3 64-bit (Linux)

- The headers for the current running kernel were not found when VirtualBox installation enhancements (Linux)

- pscp use Detailed Windows and Linux each file transfer tool (Linux)

- Android start automatically and add and delete a desktop shortcut (Programming)

- Ora-00600 [fast hot Atkins soft _ that _ Oh, of course not _less_ profile] (Database)

- Justniffer installed on Ubuntu 15.04 (Linux)

- Linux process stack and process function stack frame (Linux)

- How to disable IPv6 on Ubuntu, Linux Mint, Debian (Linux)

- MySQL flip-flop (Database)

 
         
  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:      
 
- Redis master-slave replication switch (Database)
- GitHub multiplayer co-development configuration (Linux)
- C ++ inheritance and derived (induction principle) (Programming)
- Linux use logs to troubleshoot (Linux)
- Hive start being given: Found class jline.Terminal, but interface was expected (Database)
- Java Cookie Comments (Programming)
- MySQL query plan key_len know all (Database)
- True and false in Perl (Programming)
- Oracle 11g R2 RAC RMAN backup script example (Database)
- C language files update in real time (Programming)
- Camera-based face recognition OpenCV crawl and storage format (Python) (Linux)
- Android Service Lifecycle and usage (Programming)
- Linux security configuration (Linux)
- To install and use the Doxygen under Linux (Linux)
- Oracle Automatic Diagnostic Repository (Automatic Diagnostic Repository, ADR) (Database)
- gzip, bzip2, xz, tar, zip compression, archive Detailed (Linux)
- QBit development of micro-services (Server)
- ORA-12537: TNS: connection closed error process (Database)
- Firewall types and instructions (Linux)
- CentOS6 5 source compiler installation Hadoop2.5.1 (Server)
     
           
     
  CopyRight 2002-2020 newfreesoft.com, All Rights Reserved.