Linux driver programming-device Model 3-platform Device Analysis

Source: Internet
Author: User
According to the device model described above, another one is created today. Platform device version & quot; helloworld & quot;

According to the device model described above, another one is created today. The "hello world" of the platform device version ".

If the platform device is used as the bus, onlyDeviceAndDriver. Now there are two problems:

1) howDeviceMounted to platform deviceBusDevice List.

2) howDriverAdd it to the device linked list of the bus.

1. add the device to the bus.

To addDeviceTo the list of devices on the bus, the common function used isDevice_register ()But for platform devices, there is a more easy-to-use registration function encapsulated on this function.Platform_driver_register (). In short, these two functions are used to complete registration, and the specific registration has two methods:

A) use the device initialization in the board-level file to add your device to the corresponding device value. The device will be automatically loaded when the system loads the device. However, the problem is that the kernel needs to be re-compiled.

B). Using module loading, since the modular kernel is left to the user's Kernel portal. In addition to loading the driver, it must be used to modify the kernel. The following procedure uses the second method.

The following is a simple example.

// for test driver#include 
 
  #include 
  
   #include 
   
    #include 
    
     #include 
     
      #include #include 
      
       #include 
       
        #define HELLO_NAM"hello_test"static struct resource hello_res[] = {[0] = {.start = 0,.end = 0x1,.flags = IORESOURCE_MEM,},[1] = {.start = 0x2,.end = 0x3,.flags = IORESOURCE_MEM,},};static struct platform_device hello_device = {.name = HELLO_NAM,.id = 0,.num_resources = ARRAY_SIZE(hello_res),.resource = hello_res,};static int __init hello_init( void){return platform_device_register( &hello_device);}static void __exit hello_exit(){platform_device_unregister( &hello_device);}MODULE_LICENSE("GPL");module_init( hello_init);module_exit( hello_exit);
       
      
     
    
   
  
 
2. add the driver to the bus.

AboveDeviceSuccessfully addedBusNowDriverLoaded. The information record struct used in the general driver isDevice_driverHowever, for ease of use, the platform device has another encapsulation structure.Platform_driver. The driver registration function used in a common driver isDriver_register ()The encapsulated product on the device platform isPlatform_driver_register (). The complete example is

# Include
 
  
# Include
  
   
# Include
   
    
# Include
    
     
# Include
     
      
# Include
      
        # Include
       
         # Define HELLO_NAME "hello_test" static int hello_probe (struct platform_device * dev) {struct resource * pRes = NULL; printk ("hello_probe ............ \ n "); pRes = platform_get_resource (dev, IORESOURCE_MEM, 1); if (NULL! = PRes) {printk ("resource: % d, % d, % s \ n", pRes-> start, pRes-> end, pRes-> name );} device_register (struct device * dev); return 0; // return 0 to accept this test} static int hello_remove (struct platform_device * dev) {printk ("hello_remove ......................... \ n "); return 0;} static struct platform_driver hello_drv = {. probe = hello_probe ,. remove = hello_remove ,. driver = {. name = HELLO_NAME ,. owner = THIS_MODULE, },}; static int _ init hello_init (void) {driver_register (struct device_driver * drv); return platform_driver_register (& hello_drv );} static void _ exit hello_exit (void) {platform_driver_unregister (& hello_drv);} MODULE_LICENSE ("GPL"); module_init (hello_init); module_exit (hello_exit );
       
      
     
    
   
  
 
3. platfrom is an instance of the device model.

The source code of platform shows that it is only an instance of the device model. Let's take a look at platforn_device. Its information structure is

Struct platform_device {const char * name; // the device name, which is used to match the intid with the driver; // struct devicedev; // u32num_resources, a general-purpose device member; // resource count struct resource * resource; // resource array struct platform_device_id * id_entry ;};

The information structure shows that platform_device contains a universal device struct member dev. Dev is the information node that ultimately works on the bus. Let's look at the registration function.

Int platform_device_add (struct platform_device * pdev) {int I, ret = 0; if (! Pdev) return-EINVAL; // if (! Pdev-> dev. parent) pdev-> dev. parent = & platform_bus; pdev-> dev. bus = & platform_bus_type; if (pdev-> id! =-1) dev_set_name (& pdev-> dev, "% s. % d ", pdev-> name, pdev-> id); elsedev_set_name (& pdev-> dev, pdev-> name ); // add the resource to a global resource linked list for (I = 0; I <pdev-> num_resources; I ++) {struct resource * p, * r = & pdev-> resource [I]; if (r-> name = NULL) r-> name = dev_name (& pdev-> dev ); p = r-> parent; if (! P) {if (resource_type (r) = IORESOURCE_MEM) // Default resource linked list p = & iomem_resource; else if (resource_type (r) = IORESOURCE_IO) p = & ioport_resource;} if (p & insert_resource (p, r) {printk (KERN_ERR "% s: failed to claim resource % d \ n ", dev_name (& pdev-> dev), I); ret =-EBUSY; goto failed ;}} // The most familiar figure is ret = device_add (& pdev-> dev );......}

Finally, relying on"Device_add (& pdev-> dev)", Completed the task of adding the device to the bus (platform bus. The subsequent operation is the general device registration operation.

Now let's take a look at the driver part. its information structure is

Struct platform_driver {int (* probe) (struct platform_device *); // exist as a probe function. if 0 is returned, int (* remove) (struct platform_device *) is selected *); void (* shutdown) (struct platform_device *); int (* suspend) (struct platform_device *, pm_message_t state); int (* suspend_late) (struct platform_device *, pm_message_t state ); int (* resume_early) (struct platform_device *); int (* resume) (struct platform_device *); struct device_driver driver; // struct platform_device_id * id_table ;};

In addition to the core generic device driver, callback function interfaces are also included.

Int platform_driver_register (struct platform_driver * drv) {// The driver belongs to the platform device bus drv-> driver. bus = & platform_bus_type; if (drv-> probe) drv-> driver. probe = platform_drv_probe; if (drv-> remove) drv-> driver. remove = platform_drv_remove; if (drv-> shutdown) drv-> driver. shutdown = platform_drv_shutdown; if (drv-> suspend) drv-> driver. suspend = platform_drv_suspend; if (drv-> resume) drv-> driver. resume = platform_drv_resume; // return driver_register (& drv-> driver );}

Through its registration code, it is easy to find"Driver_register (& drv-> driver)".

By analyzing the device and driver, you can easily see the relationship between the device model and the platform device.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.