1 Overview of Bus Device Driver Model
With the continuous advancement of technology, the system topology is becoming more and more complex, and the requirements for intelligent power management and hot-swap support are becoming higher and higher. The 2.3 kernel can no longer meet these requirements. In order to adapt to this situation, the Linux 2.6 kernel provides a new kernel device model.
The function of the bus is to sense whether the device is connected to USB, network card, etc. The bus device driver model better supports hot-plug devices and provides better portability.
In the device model, we will see that the device driver is mainly composed of three parts: bus, driver, and device. Through these three standard components, various complex devices are grouped together to simplify the writing of device drivers. Next, we will study the three parts of bus, driver, and device.
2 Bus
1 Bus Description
In the Linux kernel, the bus is represented by the bus_type structure, the most important of which is the bus name and matching function.
struct bus_type {
const char *name; /*bus name*/
int (*match) (struct device *dev, struct device_driver *drv); /*Driver and device matching function*/
………
}
2 Bus Registration
The bus registration uses the following function
bus_register(struct bus_type *bus)
If successful, the new bus will be added to the system and the corresponding directory can be seen under /sys/bus.
3 Bus deregistration
The bus deregistration uses the following function
void bus_unregister(struct bus_type *bus)
Code example bus.c:
#include #include #include #include int my_match (struct device *dev, struct device_driver *drv) //Match the newly added bus and the newly added device. If they match, return non-zero, otherwise return zero { return 0; } struct bus_type my_bus_type = { //define bus .name="my_bus", .match=my_match, }; int my_bus_init() { int ret; ret=bus_register(&my_bus_type);//Register a bus return right; } void my_bus_exit() { bus_unregister(&my_bus_type); //Unregister bus } module_init(my_bus_init); module_exit(my_bus_exit); MODULE_LICENSE("GPL"); After compiling the code, copy the bus.ko code to the development board. After loading the module, you can view the bus we added to the Linux system through the ls /sys/bus command. driver 1 Driver Description In the Linux kernel, drivers are represented by the device_driver structure. struct device_driver { { const char *name; /*Driver name*/ struct bus_type *bus; /*The bus where the driver is located*/ int (*probe) (struct device *dev); ……… } When a device is added to the bus, the probe function will be called to process the device accordingly when the bus and the device match. 2 Driver Registration The driver registration uses the following function int driver_register(struct device_driver *drv) 3 Driver deregistration The driver's deregistration uses the following function void driver_unregister(struct device_driver *drv) Code example driver.c #include #include #include #include extern struct bus_type my_bus_type; //Use an external module int my_probe(struct device *dev) { printk(KERN_WARNING"driver found the device !n"); return 0; } struct device_driver my_driver = { .name="my_dev", //This name is very important and must be the same as the device name .bus=&my_bus_type, //The bus to be mounted .probe=my_probe, //When the device name and the driver name are the same, call the probe function }; int my_driver_init() { int ret; ret = driver_register(&my_driver); //Register driver return right; } void my_driver_exit() { driver_unregister(&my_driver); //Unregister the driver } module_init(my_driver_init); module_exit(my_driver_exit); MODULE_LICENSE("GPL"); After the code is numbered, copy the driver.ko code to the development board. After loading the insmod driver.ko module, you can view the bus we added to the Linux system through the ls /sys/bus command. From the experimental results, we have mounted the drivers driver on the my_bus bus. Enter drivers and you can see the driver name my_dev we created. 4 Equipment 1. Description of the device In the Linux kernel, devices are represented by the struct device structure. struct device { { const char *init_name; /*Device name*/ struct bus_type *bus; /*The bus where the device is located*/ ……… } The name of the device should be consistent with the name of the driver under the driver. 2. Device Registration The device registration uses the following function int device_register(struct device *dev) 3. Device deregistration The device deregistration uses the following function void device_unregister(struct device *dev) Code example: device.c #include #include #include #include extern struct bus_type my_bus_type; //Call the my_bus_type bus in bus.c struct device my_dev={ .init_name="my_dev", /*The name of the device should be the same as the driver name*/ .bus=&my_bus_type, /*The bus where the device is located*/ }; int my_device_init() { int ret; ret = device_register(&my_dev); //Device registration return right; } void my_device_exit() { device_unregister(&my_dev); //Deregister the device } module_init(my_device_init); module_exit(my_device_exit); MODULE_LICENSE("GPL"); bus.c #include #include #include #include int my_match (struct device *dev, struct device_driver *drv) //Match the newly added bus and the newly added device. If they match, return non-zero, otherwise return zero { //Match the name in the driver module with the name in the device module //return !strncmp(dev->init_name,drv->name,strlen(drv->name)); /*In the Core.c file in the kernel source code, dev->init_name = NULL in the device_register() function will be cleared. The following matches will match a null pointer. */ return !strncmp(dev->kobj_name,drv->name,strlen(drv->name)); /*Actually, init_name is assigned to kobj.name. So in the strncmp() function, it should be dev->kobj.name*/ //return 0; } struct bus_type my_bus_type = { .name="my_bus", .match=my_match, }; EXPORT_SYMBOL(my_bus_type); //Export module to driver.c device.c int my_bus_init() { int ret; ret=bus_register(&my_bus_type); return right; } void my_bus_exit() { bus_unregister(&my_bus_type); } module_init(my_bus_init); module_exit(my_bus_exit); MODULE_LICENSE("GPL"); driver.c #include #include #include #include extern bus_type my_bus_type; //Use an external module int my_probe(struct device *dev) { printk(KERN_WARNING"driver found the device it can handle!n"); return 0; } struct device_driver = my driver{ .name="my_dev"; //This name is very important and must be the same as the device name .bus=&my_bus_type; //The bus to be mounted .probe=my_probe; //When the device name and the driver name are the same, call the probe function }; int my_driver_init() { int ret; ret = driver_register(&my_driver); //Register driver return right; } void my_driver_exit() { void driver_unregister(&my_driver); //Unregister the driver } module_init(my_driver_init); module_exit(my_driver_exit); MODULE_LICENSE("GPL"); Makefile obj-m := bus.o device.o driver.o KDIR :=/home/S5-driver/lesson7/linux-ok6410 all: make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm clean: rm -f *.of *.ko *.bak Because the matching function in bus.c has modified the code, see the match code in bus.c for details, so after compiling the module here, you need to restart the development board and copy bus.ko, driver.ko and device.ko to the development board. We see the result we expect, "driver found the device!", which means that the match function on the bus has matched the driver and the device, and then calling the probe function will result in the expected result. 5 Platform Bus Device Design 1 Platform Bus Overview Platform bus: Platform bus is a virtual bus added to the Linux 2.6 kernel. Its advantage is that it uses the bus model to manage devices and drivers, which improves the portability of programs. With the platform bus, we don't need to create a bus ourselves, we just need to mount it on the platform bus. In the kernel code platform.c, there is a structure struct bus_type platform_bus_type. In this structure, there is a matching function match. Match is mainly used to match the device name and the driver name. This is the same as the match function mentioned above, both of which match the device name and the driver name. 2 Description of the platform bus Platform devices are described using struct platform_device struct platform_device { const char *name; /*Device name*/ int id; /*Device number, used together with the device name*/ struct device dev; u32 num_resources; struct resource *resource; /*Device resources, including base address and interrupt number*/ } struct resource { resource_size_t start; resource_size_t end; const char *name; unsigned long flags; /*resource type*/ struct resource *parent, *sibling, *child; }; 3 Platform bus registration Register platform devices using the platform_device_register function int platform_device_register(struct platform_device *pdev) 4. Deregistration of platform bus Unregister the platform device using the platform_device_register function int platform_device_register(struct platform_device *pdev) Combined with the above basic knowledge, modify the key driver in the previous section to the platform driver mode. The module code key_dev.c of the platform device is given below #include #include #include #include #define GPNCON 0x7f008830
Previous article:Lao Cha's ARM study notes: chapter-1 (button driver design)
Next article:Character Device Driver (II)
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- Programming of receiving and sending data via the serial port of a single-chip microcomputer
- MSP430 MCU UART_FIFO send and receive
- Network serial port transparent transmission solution
- ADI & Shijian New Infrastructure Series Episode 3 - Answer 5G Instrumentation and Testing Questions to Win Prizes!
- How does MATLAB output fixed-length hexadecimal data (automatically fill high bits with zeros) and store it in a file?
- [Evaluation of Anxinke Bluetooth Development Board PB-02-Kit] Display driver for OLED screen
- After the BOOST topology switch tube is turned on, the current flow problem
- 36 "Ten Thousand Miles" Raspberry Pi Car——ROS Learning (VSCode to Implement Hello World)
- Not only 51, in the eyes of teacher Guo Tianxiang, MSP430 can also be learned in ten days
- Thank you for having you + my master @chat, laugh, make noise