zoukankan      html  css  js  c++  java
  • uboot驱动模型(DM)分析(二)

    上篇分析了两个关键宏U_BOOT_DRIVER及U_BOOT_DEVICES的作用,有了上篇的基础,本文将分析:

    1.上篇中的uboot_list段中的信息如何被用起来?

    2.uclass,uclass_driver,udevice,driver之间的关系?

    从board_r.c中的initr_dm函数开始分析:

    1 static const struct driver_info root_info = {
    2     .name        = "root_driver",
    3 };

     1 /* This is the root driver - all drivers are children of this */
     2 U_BOOT_DRIVER(root_driver) = {
     3     .name    = "root_driver",
     4     .id    = UCLASS_ROOT,
     5     .priv_auto_alloc_size = sizeof(struct root_priv),
     6 };
     7 
     8 /* This is the root uclass */
     9 UCLASS_DRIVER(root) = {
    10     .name    = "root",
    11     .id    = UCLASS_ROOT,
    12 };

    initr_dm

      ret = dm_init_and_scan(false);

        dm_init

          INIT_LIST_HEAD(&DM_UCLASS_ROOT_NON_CONST);  //#define DM_UCLASS_ROOT_NON_CONST (((gd_t *)gd)->uclass_root) 创建头结点gd->uclass_root

          ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST);

            drv = lists_driver_lookup_name(info->name);  //lists_driver_lookup_name("root_driver")  

                 struct driver *drv =ll_entry_start(struct driver, driver);  //通过上篇分析,此处得到的是uboot_list_2_driver_1的地址

                  const int n_ents = ll_entry_count(struct driver, driver);  //uboot_list_2_driver_3-uboot_list_2_driver_1即得到长度

                  for (entry = drv; entry != drv + n_ents; entry++) {    //遍历,通过name字段匹配,匹配成功得到driver结构体地址

                    if (!strcmp(name, entry->name))
                       return entry;
                  }

               device_bind_common(parent, drv, info->name, (void *)info->platdata, 0, ofnode_null(), platdata_size, devp);

                ret = uclass_get(drv->id, &uc);            

                  struct uclass *uc;

                  uc = uclass_find(id);              

                  if (!uc)

                    return uclass_add(id, ucp); //通过上面得到的drv中的id字段(UCLASS_ROOT)进行匹配,匹配成功得到对应的uclass_driver结构体地址

                  uc->uc_drv = uc_drv;  //uclass root的uclass_driver指向uclass_driver root   

                  INIT_LIST_HEAD(&uc->sibling_node);
                  INIT_LIST_HEAD(&uc->dev_head);
                  list_add(&uc->sibling_node, &DM_UCLASS_ROOT_NON_CONST);

                .......

                //关键代码如下

                INIT_LIST_HEAD(&dev->sibling_node);
                INIT_LIST_HEAD(&dev->child_head);
                INIT_LIST_HEAD(&dev->uclass_node);

                dev->name = name;

                dev->node = node;

                dev->parent = parent;

                dev->driver = drv;

                dev->uclass = uc;

                ......

                ret = uclass_bind_device(dev);

                  uc = dev->uclass;

                  list_add_tail(&dev->uclass_node, &uc->dev_head);

    ---------------------------------------------------------------------------------------------------------------------------------------------

    经过上述源码阅读,下面将上述关系用图的形式更直观的表现出来:

            

      

            

  • 相关阅读:
    STM32 Cubemx 输出可调频率与占空比的PWM
    程序员必知的十大基础实用算法及其讲解
    [51单片机]18B20驱动函数
    《嵌入式怎么学?新人十问及解答》
    Google Chrome快捷键大全
    SSD、高级格式化硬盘,4K,分区,对齐,Ghost能不能用的解释用SSD的都可以看看
    资源下载
    Nexus Root Toolkit教程——刷机
    校园卡植入手机教程
    基于Visual c++ 2012的php扩展开发
  • 原文地址:https://www.cnblogs.com/gs1008612/p/8253213.html
Copyright © 2011-2022 走看看