Linux driver Development Children's shoes come and worship:-)
Learning about Linux device-driven development naturally encounters concepts and techniques such as character device drivers, platform device drivers, device-driven models, and SYSFS. It is very confusing for beginners, and even for Linux-based engineers, a better understanding of these technologies is relatively good. A deep understanding of the principles required to be very familiar with the device driver-related frameworks and model code. There are many articles about these technologies on the web, but it is very difficult to find a comparison and correlation analysis of these technologies. It is difficult for developers to be familiar with a point and to share it, but it is very necessary and meaningful to focus on imparting technology and experience to learners, and horizontally comparing the various drive-related knowledge points and vertically profiling the entire Linux drive software hierarchy.
This article is still from the point of view of demand to understand the above knowledge point, the existence is reasonable, the above technical knowledge can exist, that is to represent it has certain role. We focus on understanding the role of each technology point and identify its role in driving development.
First, the device driver
Linux device drivers are divided into three types, including character device drivers, block device drivers, and network device drivers. Character devices can only access device memory in sequential order by byte stream, and cannot be accessed randomly. The mouse, touch screen, LCD and so on are the representative of the character device. Block devices can randomly access the arbitrary address of the device memory, the hard disk, SD card, NAND Flash is the representative of the block device. Network device refers to a network card with a socket socket to communicate with the device. This article takes the character device as an example to tell the relevant knowledge.
Second, character device driver
For the character device driver frame, please refer to the two articles of the embedded Penguin circle:
Linux character device driver profiling
Creation and Mdev of Linux device files
1. Character Device driven longitudinal relationship
From the < Linux character device driver profiling >, it can be seen that the application layer access device driver is very simple, that is, through the open interface to finally obtain the device-driven operation interface set struct file_opertions. And the arguments passed in the Open interface are/ The device name under the Dev directory. From the creation and mdev> of the <linux device file, it is known that the device file node inode of the device name stores the device number, while the global array cdev_map in the drive frame maintains the relationship between the device number and the file_opertions. That is, the application layer-to-bottom relationship is primarily (ignoring the VFS layer):
Device name--device number-->file_opertions
The relationship of the local FD and File_opertions returned by the Open function (ignoring the process data structure) is as follows:
Fd-->file (Current process data structure member), File_opertions
In this way, the file_opertions can be obtained through FD, that is, the read and write functions, the IOCTL function and so on can be called by read and write interfaces.
2. Character device-driven tasks
1) Character device driver The most essential task should be to provide file_opertions of the various open, read, write, ioctl and other interfaces to achieve.
In addition, from the above description, the following tasks are involved in order for the application layer to invoke the file_opertions to the underlying:
2) apply for the device number and register the device number and file_opertions (Cdev_add interface) to the CDEV_MAP array in the drive frame. This should be responsible for the character device driver, involving its active to the system to prepare its own existence.
3) Create the device file in the/dev directory, including the device number. Whether this is driven by a character device is debatable. The character device driver is located at the kernel level, and if it is responsible for this task, then the driver needs to know the name of the device it is creating. Simple character driver is OK, if it is USB and other pluggable devices, how can the driver know what device name to create? Some people say that a set of rules can be written. That's true, but wouldn't it be better if you put this set of rules into the application layer, where the application developer would define the rule (as Mdev did)? Because the application is directly programmed to access this device name corresponding to the device driver. So character device drivers should not be directly responsible for the creation of device files.
3. Who will create the device file
Somebody has to come out and do it, otherwise the application layer how to access ah?
One way is for the user to use the Mknod command in the shell to create the device file, passing in both the device name and the device number. This is a manual approach, very unscientific. But it is a way to demonstrate.
Another approach is to rely on the device model to assist in creating device files. This is also one of the functions of the device model.
4. Character device driver programming process
1) define the struct file_opertions my_fops and implement each of the interfaces, such as open, read, write, ioctl and other interfaces.
2) Implement the drive entry function, such as Chardev_init
static int __init chardev_init (void) {
Alloc_chrdev_region (&devno,...); /Request Device number
My_cdev=cdev_alloc ();
Cdev_init (My_cdev,&my_fops);
Cdev_add (My_fops,devno, 1);//Registered device number and file_opertions
}
3) Module_init (chardev_init);//Macros define the initialization entry function. The uninstallation process does not explain.
4) Insmod after loading this module, you can manually create a device file on the shell command line using Mknod.
5) The application layer can be accessed by opening the device file with open.
5. Summary
It can be seen that the character device-driven core framework is not directly related to the device model, the platform device driver, and does not work as expected.
Three, the device drive model
We mainly talk about the role and role of the device driver model in Linux drive, and the principle and implementation of the device model are discussed in this article.
1. The role of the device-driven model
1) The device driver model implements the uevent mechanism, invoking the Medv of the application layer to create the device file. This has been discussed above.
2) The device driver model provides a device-driven view of the user layer through the Sysfs file system, as follows.
Just a visual expression that helps you understand the device model, similar to the Windows-based device management program, does not have a graphical representation of the relationship in embedded Linux. However, users can access the/sys folder through the command window by using the LS naming to obtain various bus, device, drive information and relationships. As you can see, in the/sys top-level directory, there are three key subdirectories, the device class, the device, and the bus.
The device is a specific device, in/sys/devices/is the creation of the actual file node. Devices that appear in other directories, such as device classes and sub-directories below the bus, use symbolic links to refer to files in the/sys/devices/directory.
Device class is to classify the various devices under/sys/devices/to reflect the common properties of a class of devices, such as mouse and touch screen are all belong to input device class.
The bus directory is the core directory of the bus, device, and drive model. Because both the device and the driver are attached to some kind of bus, such as USB, PCI and platform bus. Devices and drivers rely on the management of the bus to find each other, such as when the device is registered to the bus to find the driver, while the driver register to find the device it can support.
Most importantly, without a device model, it is difficult for the application layer to know the relationship between the drive and the device, because character device drivers do not provide this information, which can be cumbersome for device-driven managers.
In fact, the bus class, device devices, and driver device_driver in the kernel will not expose all the information to the user layer, for example, these three data structures have corresponding private data structure, which is used for the kernel to maintain the link table relationship driven by the subordinate bus device. If exposed to the user layer, it is easy to modify the user layer and make the system chaotic. In fact, the user layer cares only about the view associations of the three, and how their associations are implemented at the bottom doesn't need to be cared for.
3) The device driver model provides a unified power management mechanism. Obviously, we don't see a power management interface in the File_operations interface of the character device driver. For the operating system, power consumption management is essential. Power management should not be the responsibility of the application developer, but should be the responsibility of the system, such as the phone for a long time without touch, it will go into hibernation. This change in state should be done by the system, and the various devices entering sleep mode should also be completed by the system. Therefore file_operations does not provide the power management interface to the application is reasonable. and the device model as a system management mechanism, it is very reasonable to provide power management.
If the device data structure has a struct dev_pm_info power power dissipation attribute parameter, the drive DEVICE_DRIVER data structure has a struct dev_pm_ops *pm power operation interface.
4) The device driver model provides a reference count of various object instances to prevent objects from being mistakenly deleted by the application layer. All data structures of the device model are inherited Kobject, and Kobject provides the underlying count functionality.
5) The device driver model provides a way for the application layer, the user and the kernel can interact through SYSFS, such as by modifying the contents of the device in the/sys directory, that is, you can directly modify the device corresponding parameters.
In summary, the device-driven model focuses on the management of the kernel-to-bus, device, and driver, and exposes these management information to the application layer, while the character device driver focuses on device-driven functionality implementation.
2. The core interface of the device-driven model
Bus_register (struct bus_type *bus) Registration bus
Device_add (struct device *dev) registering the device
Driver_register (struct device_driver*drv) registered driver
Class_create (owner, name) Create a device class
Wait a minute
3. Device driver model and character device driver differences
The device-driven model focuses on the management of the bus, device, and driver of the kernel and exposes these management information to the application layer, while the character device driver focuses on device-driven feature implementations.
Iv.. sysfs File System
1.SYSFS file system and device-driven model relationships
The Sysfs file system is a vehicle in which device-driven models can expose their management information to users. The relationship between them is as follows:
1) The subordinate relationship of the device driver model (such as the child device and the parent device) is represented by the parent directory and subdirectory of the Sysfs file system.
2) The peer relationship of the device driver model (such as the device management device and the specific device) is implemented through the directory symbolic link of the Sysfs file system.
3) The properties of the device driver model (such as the device's parameter and device name, device number, etc.) are recorded by the file contents of the Sysfs file system.
4) The Kobject in the device-driven model data structure correspond to the directories in the Sysfs file system, while the struct attribute members in the data structure correspond to the files in the Sysfs file system. The corresponding meaning is to continue with kobject device, device_driver and bus, etc. in the process of registering with the system will call Sysfs Create_dir interface to create the corresponding directory, and contains a struct Device, Device_driver, and bus for the attribute member property call SYSFS's Sysfs_create_file interface to create the file during registration to the system.
2.sysfs Core Interface
Sysfs_create_file (struct kobject * kobj,const struct attribute * attr) Creating a property file
Sysfs_create_dir (struct kobject * kobj) Create directory
int sysfs_open_file (struct inode *inode,struct file *file) to open SYSFS file system format
Sysfs_read_file (struct file *file, Char__user *buf, size_t count, loff_t *ppos) Read operations
Sysfs_write_file (struct file *file, Constchar __user *buf, size_t count, loff_t *ppos) write operations
3. Sysfs file system and properties file read/write
The Sysfs_read_file is a read-write entry for the Sysfs file system, but the driver needs to provide real read and write operations to the system, which is the show and store interface in the struct SYSFS_OPS data structure.
SYSFS is a memory-based file system where power-down is lost, and all operating interfaces Sysfs access to the in-memory kernel data structures. If a user reads the contents of a property file (such as Dev) with a cat command, the following process is generated:
1) fd=open ("Dev")->vfs_open ("Dev")->sysfs_open ("Dev") gets the handle to the file
2) Read ()->vfs_read ()->sysfs_read_file ()->sysfs_ops->show () The show interface is the device that generates the properties file at the time of registration and provides the system with a read interface to the file. In the implementation of the read interface, it is natural to read access to the attribute parameter.
/sys mounts the Sysfs file system, so all operations on files or directories in the/sys directory are accessed through the interface of the Sysfs file.
V. Platform device driver
Platform device driver "platform" refers to the platform bus, that is, Platform_bus_type, is a number of Linux bus, such as USB bus, PCI bus, I²c bus and so on. Only the platform bus is a virtual bus that is specifically designed to manage the controllers on the SOC (e.g., watchdog, LCD, RTC, etc.), which are directly accessible to the device on the CPU's bus. Devices such as USB and PCI have access to devices other than the SOC chip through specific timing. The relationship between platform device drivers is a subset of the device-driven model, and the platform is considered a bus concept, and the relationship between the two is easy to understand.
1. Relationship between platform device driver and device driver model
1) The Platform device driver interface creates the relevant platform device class (/sys/class/platform_bus), Platform Bus (/sys/bus/platform), platform Device (/sys/devices/) on the device-driven model view.
2) platform Device (Platform_device) and Platform device driver (platform_driver) are registered on the platform bus, that is, in the/sys/bus/platform/directory to create the corresponding device and driver directory.
3) The Platform bus is responsible for matching the device and driver that is registered to it, and the probe interface that matches the driver after successful callback.
4) The Platform device driver uses the device driver model interface to assist in creating the corresponding device files (located in the/dev/directory).
The related interfaces include:
Platform_device_register (Structplatform_device *pdev) registered platform device
Platform_driver_register (structplatform_driver *drv) registered platform device driver
The implementation of the two interface will match the platform driver and the device, and the successful match will call the driver's probe interface.
2. Platform device driver and character device driver relationship
We assume that this platform device is a character device.
The relationship between the platform device driver and the character device driver starts with the driver's probe interface, which is the task to accomplish the character device driver in the probe interface, that is, to request the device number through the alloc_chrdev_region and the struct file_ through the Cdev_add registration drive. Opertions. In addition, in order to automatically create the device files accessed by the application tier, call the Class_create and Device_create interfaces to create the corresponding device class and device under the Platform device class and issue the Uevent event, calling Mdev to create the device file.
3. Platform device-driven development process
1) Move the implementation of the Char_init function driven by the character device to the probe interface of the platform_driver.
2) Call Platform_device_register and Platform_driver_register separately to register the device and driver in Char_init. In fact, for a well-ported system, Platform_device_register is done in the Linux boot process. Therefore char_init generally only platform_driver_register registered driver.
Detailed platform device-driven implementation principles and development process are described in another article. The focus of this session is to illustrate the relationship between character device drivers, device driver models, and SYSFS and platform device drivers.
Bo main public number: embedded Penguin Circle, hundred percent original share embedded Linux development experience Knowledge, absolutely dry!
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Character device drivers, platform device drivers, device-driven models, SYSFS relationships