Linux device driver development process (rpm)

First, the classification Linux devices

 

Character device, the difference between the block devices, network devices, three devices are interactive mode data, respectively:

Byte stream data block, a data packet.

 

Two, VFS core structure

 

VFS core structure is defined in "linux / fs.h" header file.

 

1, struct inode structure

Owner, access time and other information recorded files. When first opening the file is created and initialized by the VFS. When all references have quit, release inode; user mode if more than one person at the same time to open a file, you only need to allocate a VFS inode.

 

2, struct file structure

Corresponding to the open state operation of the user. If you open the same file multiple times, the kernel will generate multiple file. file recorded file is opened, the file pointer or the like inside. When the file is completely closed, the release file.

 

3, struct file_operations structure

The structure comprises a plurality of function pointers, these functions realized by the driving, and concentrated file_operations in register to VFS.

General function of the drive to achieve are:

open

release

read

write

unlocked_ioctl

Driver may achieve are:

poll

mmap

fasync

flush

llseek

 

Third, the character device driver development process

 

(1) determine the hardware information

To determine the hardware number, physical address, interrupt number and other information;

 

(2) is to support the preparation of a private device structure

Not required to have a core structure private, but if multiple devices support the drive, preferably a design. Private structure designed entirely by the driving person, in general, of the structure, such as the address of the device will write the information and the like related apparatus.

 

(3) To support the device number assigned to each corresponding device

Driven device number assigned by char, the only requirement. In general, if a plurality of similar char driving device can support, the master should choose a number of these devices, then a particular minor number selected for each device. And other drivers try to pick a different major number. See can / proc / devices, files recorded in major number of other driving selection; may apply the kernel, the kernel allocates a major number.

 

#define DEV_MAJOR 50

...

dev_id = MKDEV(DEV_MAJOR, 0);

(4) Preparation file_operations structure

Centralized functions include open / release / read / write / unlocked_ioctl other functions, if the drive supports multiple devices, you must be able to distinguish himself in the function which device is accessed.

 

static struct file_operations mem_fops = {

.owner = THIS_MODULE,

.open = mem_open,

.release = mem_release,

.read = mem_read,

.write = mem_write,

.unlocked_ioctl = mem_ioctl,

};

(5) registration equipment

 

method one:

 

Using cdev structure, and the device number register to file_operations VFS. Generally, the structure comprises a private cdev structure. Using equipment cdev registered does not automatically create device files.

 

cdev_init(&mem_cdev, &mem_fops);

cdev_add(&mem_cdev, dev_id, 1);

cdev_del (& mem_cdev); // Chu销 cdev

Method Two:

 

Registration miscdevice (with misc instead of cdev registered, you can automatically create the device file)

In this case it does not need to define the primary device number, i.e., omitted #define DEV_MAJOR 50, while the need to place "linux / cdev.h" header file the header file "linux / miscdevice.h".

 

static struct miscdevice mem_miscdev = {

.minor = MISC_DYNAMIC_MINOR,

.name = "mem", // corresponding to / dev / mem device file

.fops = &mem_fops,

};

 

ret = misc_register(&mem_miscdev); //注册miscdevice

misc_deregister(&mem_miscdev); //注销miscdevice

cdev and miscdevice comparison:

(1) cdev the same drive can be realized corresponding to a plurality of devices, and can achieve a miscdevice corresponds to a device driver;

Automatic creation (2) cdev device file can not be achieved, and miscdevice can automatically create device files.

 

The above-described process is suitable for simpler devices, such as watchdog, led lights, and various sensors. Char driving apparatus more complex, often by the drive subsystem the code provided by the kernel design.

 

Fourth, how to access the register (SFR) in linux driver

 

1, the inner peripheral sheet (pripheral)

(1) Based on Three bus access

(2) Control register

(3) physical register address, by manual found no changes

 

2, external peripherals

(1) are connected by three buses rarely, usually connected by a UART, CAN, I2C, USB, SPI, MIPI, I2S, AC97 other bus. Chip must be provided corresponding to the main controller: the controller inside the <-> external peripherals

(2) off-chip peripherals are basically smart devices (not only hardware, and software)

(3) Some external peripherals through the register control, command control by others

(4) if a control register, the register is not a physical address, only the offset.

(5) To control the off-chip peripherals need to first understand the corresponding bus

 

3, the process of access registers

Linux since the MMU is enabled, so for driving it, can not directly use a physical address register, you must be mapped to a virtual address can be used.

 

Offset (1) register defines the base address and the physical register

 

#define GPIO_BASE 0x11000000

#define GPIO_SIZE 0x1000 //0x8

#define GPM4CON 0x2E0 // offset address

#define GPM4DAT 0x2E4 // offset address

GPIO_SIZE the range registers may be used in accordance with the total size of the register is calculated, such as using the two registers, in the range of 0x8; but the minimum unit of address mapping is 4K, and therefore a value less than 4K are possible.

 

(2) to map virtual addresses to physical addresses register, if the map is not successful, you can not access register

 

static void __iomem *vir_base;

vir_base = ioremap (GPIO_BASE, GPIO_SIZE);

if (! vir_base) {

printk("Cannot ioremap\n");

return -EIO;

}

(3) accessing registers, the general pattern of the base address plus an offset, in accordance with the size of the kernel registers, a series of functions

 

Access register 8

 

char value;

value = readB (vir_base + offset);

writeb(value, (vir_base + offset));

16-bit access register

 

short value;

value = readw (vir_base + offset);

writew(value, (vir_base + offset));

32-bit access registers

 

int value;

value = readl (vir_base + offset);

writel(value, (vir_base + offset));

64-bit access register

 

u64 value;

value = readq(vir_base + offset);

writeq (value, (vir_base + offset));

(4) Cancellation of mapping registers

 

iounmap (vir_base);

Guess you like

Origin www.cnblogs.com/yangjiquan/p/11488661.html