1, Driving equipment classification
Character device driver, block device driver and network device driver.
1. Character device driver
It is the driver with the largest space, because there are the most character devices. From the simplest lighting to I2C, SPI and audio, it belongs to the type of character device driver.
2. Block device drive
It is the driver of memory devices, such as EMMC, NAND, SD card, U SB flash disk and other storage devices. Because these storage devices are based on storage blocks, they are called block devices.
3. Network device driver
Network driver, whether wired or wireless, belongs to the category of network device driver.
be careful:
Block device and network device drivers are more complex than character device drivers. Because of their complexity, semiconductor manufacturers generally write them for us and can be used directly in most cases.
A device can belong to a variety of device driver types, such as USB WIFI. It uses USB interface, so it belongs to character device, but it can access the Internet, so it also belongs to network device driver.
2, Linux kernel driver operator function set
dir: include/linux/fs.h
name: file_operations
struct file_operations { struct module *owner; /* owner The pointer of the module is generally set to THIS_MODULE */ loff_t (*llseek) (struct file *, loff_t, int); /* Used to modify the current read / write location of the file */ ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); /* Used to read device files */ ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); /* Used to write (send) data to the device */ ssize_t (*read_iter) (struct kiocb *, struct iov_iter *); ssize_t (*write_iter) (struct kiocb *, struct iov_iter *); int (*iterate) (struct file *, struct dir_context *); int (*iterate_shared) (struct file *, struct dir_context *); unsigned int (*poll) (struct file *, struct poll_table_struct *); /* Polling function, used to query whether the device can read and write non blocking */ long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); /* Provides the control function for the device, corresponding to the ioctl of the application */ long (*compat_ioctl) (struct file *, unsigned int, unsigned long); /* On 64 bit systems, 32-bit applications call compat -- IOCTL; On 32-bit systems, 32-bit applications call unlocked_ioctl*/ int (*mmap) (struct file *, struct vm_area_struct *); /* It is used to map the memory of the device to the process space (i.e. user space). Generally, frame buffer devices will use this function, such as LCD */ int (*open) (struct inode *, struct file *); /* open Function to open a device file */ int (*flush) (struct file *, fl_owner_t id); int (*release) (struct inode *, struct file *); /* Used to release and close the device file, corresponding to the close function of the application */ int (*fsync) (struct file *, loff_t, loff_t, int datasync); int (*fasync) (int, struct file *, int); /* It is used to refresh the data to be processed and refresh the data in the buffer to the disk */ int (*lock) (struct file *, int, struct file_lock *); ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); int (*check_flags)(int); int (*flock) (struct file *, int, struct file_lock *); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); int (*setlease)(struct file *, long, struct file_lock **, void **); long (*fallocate)(struct file *file, int mode, loff_t offset, loff_t len); void (*show_fdinfo)(struct seq_file *m, struct file *f); #ifndef CONFIG_MMU unsigned (*mmap_capabilities)(struct file *); #endif ssize_t (*copy_file_range)(struct file *, loff_t, struct file *, loff_t, size_t, unsigned int); int (*clone_file_range)(struct file *, loff_t, struct file *, loff_t, u64); ssize_t (*dedupe_file_range)(struct file *, u64, u64, struct file *, u64); };
Note: the comment section is an important operation function.
3, Outlet and inlet of drive module
/* Drive entry function */ static int __init xxx_init(void) { /* Specific content of the entry function: register the device driver */ return 0; } /* Drive exit function */ static int __exit xxx_exit(void) { /* Specific content of the entry function: log off the device driver */ return 0; } /* Specify the above two functions as the driver's entry and exit functions */ moudle_init(xxx_init); // Called when the driver is loaded module_exit(xxx_exit); // Called when the driver is unloaded
So far, a driver module mainly includes common operation functions (write, read, etc.) plus exit and entry functions.
4, Calling process of Linux application to driver
But in Linux system, how does the application program used by users call the driver function at the bottom? See the figure below:
In Linux, everything is a file. After the driver is loaded successfully, a corresponding file will be generated in the / dev directory. The application can operate the hardware through the file named / dev/xxx.
Applications run in user space, while Linux drivers are part of the kernel and run in kernel space. The user space cannot directly enter the kernel for operation. The user space needs to be "trapped" into the kernel space through the method of system call, so as to realize the operation of the underlying driver. Open, close, read, write and other functions are provided by the c library. The system call is a part of the c library. Take calling the open function as an example. The whole process is as follows:
At this point, the general calling process of Linux driver is over. For learners who have just come into contact with Linux driver, they need to have a general framework, otherwise they will easily lose their direction.
Later, when writing the driver, look at the driver requirements, operate the application, start to analyze the functions to be implemented, and then correspond to the specific driver functions.
This article is the process that the author first joined the company, learning driven development, combined with the development guide of punctual atom and the actual development situation. Thank those who helped me in my study.