zoukankan      html  css  js  c++  java
  • uboot中的命令体系

    一、uboot的命令体系介绍以及实例分析:

     U-Boot 的命令实现大多在 common 目录下。在该目录下命令的代码文件都是以“ cmd_”开头的,如下图所示:

          

      其中每一个文件都是一个命令实现的代码文件,而且文件名和命令名称是相关的,例如 cmd_nand.c 是实现 nand 命令的文件,从而实现模块化,这样就可以方便我们管理和添加自己的命令。

    下面,我们用一个示例来讲解u-boot中如何管理这套命令体系的,以及如何添加一个自定义的命令。

        

    这里涉及了几个要点,第一个是cmd_tbl_t结构体:

      

      不难看出cmd_tbl_t结构体主要是包含了命令的一些信息,最关键的是想通过回调函数的形式来实现用户的自定义功能。

    那么接下来来分析一个重点 U_BOOT_CMD:

      

      这里会涉及一些编译器相关的知识,struct_Section的意思是想将一个结构体标记成".u_boot_cmd"属性(__attribute__是编译器的扩展属性,具体可以查看gcc手册)。而这里的 __u_boot_cmd##name 的含义是将 name添加上 __u_boot_cmd_ 前缀。

    于是我们可以将最上面的version例子来拆解:

      

    二、uboot中对命令的注册、存储、索引:

      结合上面的例子,发现使用U_BOOT_CMD宏可以向uboot添加一条命令, 通过填充该宏的参数,完成对该条命令对应的结构体的填充,便完成了注册的功能。

    而在U_BOOT_CMD宏中给每条命令声明了 用户自定义段属性,使得在链接时会将具有该段属性的结构体按照顺序排布在一起,类似于结构体数组,这就是uboot命令的存储方式。

    既然在uboot中存储了具有段属性的结构体数组,那么在查找命令的时候,只需要遍历该数组,如果找到返回该命令结构体的首地址即可。在uboot中是通过find_cmd函数查找命令的,如下图所示:

     1 /**
     2  * find command table entry for a command
     3  * 如果查找成功,返回结构体首地址
     4  */
     5 cmd_tbl_t *find_cmd_tbl (const char *cmd, cmd_tbl_t *table, int table_len)
     6 {
     7     cmd_tbl_t *cmdtp;
     8     cmd_tbl_t *cmdtp_temp = table;    /*Init value */
     9     const char *p;
    10     int len;
    11     int n_found = 0;
    12 
    13     /*
    14      * Some commands allow length modifiers (like "cp.b");
    15      * compare command name only until first dot.
    16      */
    17     len = ((p = strchr(cmd, '.')) == NULL) ? strlen (cmd) : (p - cmd);
    18 
    19     for (cmdtp = table; cmdtp != table + table_len;cmdtp++) {
    20         if (strncmp (cmd, cmdtp->name, len) == 0) {
    21             if (len == strlen (cmdtp->name))
    22                 return cmdtp;    /* 完全匹配 */
    23 
    24             cmdtp_temp = cmdtp;    /* abbreviated command ? */
    25             n_found++;
    26         }
    27     }
    28     if (n_found == 1) {            /* exactly one match */
    29         return cmdtp_temp;
    30     }
    31 
    32     return NULL;    /* 没有找到命令 */
    33 }
    34 
    35 cmd_tbl_t *find_cmd (const char *cmd)
    36 {
    37     /* __u_boot_cmd_end 和 __u_boot_cmd_start 是链接脚本中标记命令结构体数组的首尾地址*/
    38     int len = &__u_boot_cmd_end - &__u_boot_cmd_start;
    39     return find_cmd_tbl(cmd, &__u_boot_cmd_start, len);
    40 }
    View Code

    链接脚本(u-boot.lds):

      

     三、向uboot中添加自定义命令:

      通过分析,我们也可以自己实现一个uboot命令。

      1. 在common文件夹下建立一个以"cmd_xxx"的文件
      2. 参考cmd_version.c并结合具体的业务修改。
      3. 修改uboot/common/Makefile,添加上xxx.o(xxx为对应的命令文件): 
      4. 重新编译链接,下载烧录测试。

      这样一个uboot命令就添加成功了。当然我们这里只是简单的介绍了uboot中的命令体系,实际的产品需要根据您的业务来编写具体的命令函数等。

  • 相关阅读:
    深拷贝和浅拷贝
    【.NET MVC分页】.NET MVC 使用pagelist 分页
    Win10开启IIS
    Win10开启IIS
    目前问题:plupload上传带参数到后台
    目前问题:plupload上传带参数到后台
    jquery怎样获取html页面中的data-xxx
    .Net MVC删除图片
    .Net MVC删除图片
    AlloyClip的简单使用
  • 原文地址:https://www.cnblogs.com/qiabaowei/p/8546838.html
Copyright © 2011-2022 走看看