Drive classification
1 General classification
1.1 Character device: a device with a byte as the smallest access unit, usually supporting open, close, read, and write system calls. Such as serial port, LED, button
1.2 Block device: A device with a block as the smallest access unit (a block is generally 512 bytes or a multiple of 512 bytes). In linux, block devices are allowed to transmit any number of bytes. Such as hard disk, flash, SD card.
1.3 Network interface: responsible for sending and receiving data packets, it can be a hardware device, such as a network card, or a pure software device, such as a loopback interface (lo)
2 Bus taxonomy
1.1 USB devices
1.2 PCI Devices
1.3 Platform bus device
study method
1 Build the driver model
2 Add hardware operation
3 Drive test
hardware access
1 Address mapping
1.1 Static mapping
void *ioremap(physaddr,size)
physaddr: The physical address to be mapped
size: the length of the mapped area
Return value: mapped virtual address
1.2 Dynamic Mapping
The user specifies the mapping relationship in advance, and the physical address is automatically mapped to the virtual address when the kernel is started.
struct map_desc
{
unsigned long virtual;/mapped virtual address
unsigned long pfn;/page frame number where the physical address is located
unsigned long length;/map length
unsigned int type;/mapped device type
}
2 Register read and write
unsigned ioread8(void *addr)
unsigned ioread16(void *addr)
unsigned readb(address)
unsigned readw(address)
unsigned readl(address)
void iowrite8(u8 value,void *addr)
void iowrite16(u16 value,void *addr)
void iowrite32(u32 value,void *addr)
void writeb(unsigned value, address)
void writew(unsigned value, address)
void writel(unsigned value, address)
use of the drive
1 Compile and install the driver
1.1 Create Makefile
obj-m := memdev.o
KDIR: = / home /… / linux-tq2440
all:
make–C $( KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm
1.2 Copy the driver (kernel module) to /…/rootfs
1.3 Install the driver
insmod memdev.ko
1.4 View lsmod
2 character device file
2.1 View the main device number
cat /proc/devices
Main device number Device name
2.2 Create device file
mknod /dev/file name c device number secondary device number (0~255)
3 applications
3.1 Open character device file
fd = open(“/dev/memdev0”,O_RDWR);
3.2 Manipulating character device files
write(fd,&buf,sizeof(int));
read(fd,&buf,sizeof(int));
3.3 Close character device file
close(fd);
3.4 Compilation (static compilation)
arm-linux-gcc –static filename.c –O filename
character device driver model
1 Device description structure cdev
1.1 Structure Definition
struct cdev
{
struct kobject kobl;
struct module *owner;
const struct file operations *ops ;//Device operation set
struct lis thead list;
dev_t dev;//Device number.
unsigned int count; number of devices
}
1.2 Device number type dev_t
1.2.1 Introduction to dev_t: It is essentially a 32-bit unsigned int, the upper 12 bits are the major device number, and the lower 20 bits are the minor device number.
1.2.2 Operation equipment number:
dev_t dev=MKDEV (major device number, minor device number)
Major device number=MAJOR(dev_t dev)
Minor device number = MINOR(dev_t dev)
1.2.3 Apply for equipment number:
Static application: intregister_chrdev_region(dev_t first, unsigned int count, char *name);
first: the starting device number to be allocated, usually 0;
count: total number of consecutive device numbers
name: device name (cat /proc/devices )
Dynamic application: intalloc_chrdev_region(dev_t *dev,unsigned int -firstminor,unsigned int -count,char*name)
dev: The location where the obtained device number is saved
-firstminor: The starting device number to be allocated, usually 0;
-count: total number of consecutive device numbers
name: device name (cat /proc/devices )
1.2.4 Unregister the device number: unregister_chardev_region
1.3 Operation set struct file operations
1.3.1 Introduction to structfile operations: A collection of function pointers that define the operations that can be performed on the device. Set to NULL for unsupported operations
1.3.2 例:struct file operations dev_fops =
{
.llseek = NULL;
.read= dev_read,
.write= dev_write,
.ioctl= dev_inctl,
.open= dev_open,
.release= dev_release,
};
2 Driver initialization
2.1 Assign device description structure
Static allocation: structcdev mdev;
Dynamic allocation: structcdev *pdev = cdev_alloc();
2.2 Initialize the device description structure
cdev_init(struct cdev*cdev,const struct file_operations *fops)
*cdev: cdev structure to be initialized/*fops: operation function set corresponding to the device
2.3 Registering Device Description Structure
cdev_add(struct cdev *p,dev_t dev,unsignedcount)
p: the character device structure to be added to the kernel
dev: device number
count: the number of devices of this type of device
2.4 Hardware initialization
3 Device operation (device method)
3.1 int (*open) (struct inode *,struct file *) Open the device and respond to the open system
3.1.1 structfile:
3.1.1.1 In the linux system, each open file is associated with a structfile, which is created by the kernel when the file is opened and released after the file is closed
3.1.1.2 Important members
loff_t f_pos //File read and write pointer
struct file_operation*f_op //The operation corresponding to the file
3.1.2 structinode
3.1.2.1 Each file existing in the file system is associated with an inode structure that records the physical information of the file.
3.1.2.2 Important members:
dev_t i_rdev //device number
3.2 int (*release) (struct inode *,struct file*) Close the device and respond to the close system
3.3 loff_t (*llseek) (struct file *,loff_t,int) Relocate the read and write pointers and respond to the lseek system call
3.4 ssize_t(*read) (struct file *,char _user *,size_t,loff_t *) Read data from the device and respond to the read system call
3.4.1 Parameter analysis:
filp: The file structure pointer associated with the character device file, created by the kernel
buff: The location where the data read from the device needs to be saved, provided by the read system call
count: The amount of data requested to be transferred, provided by the read system call
offp: file read and write position, taken from the file structure by the kernel and passed in
3.4.2 Reading data from the device (hardware access operation)
3.4.3 Return the read data to the application
3.5 ssize_t(*write) (struct file *,const char _user *,size_t,loff_t *) Write data to the device and respond to the write system call
3.5.1 Parameter analysis:
filp: The file structure pointer associated with the character device file, created by the kernel
buff: The location where the data read from the device needs to be saved, provided by the read system call
count: The amount of data requested to be transferred, provided by the read system call
offp: file read and write position, taken from the file structure by the kernel and passed in
3.5.2 Fetch data from the address provided by the application
3.5.3 Write data to the device (hardware access class operation)
4 Driver logout
4.1 Uninstall the driver with the cdev_del function