zoukankan      html  css  js  c++  java
  • find_cmd函数分析

     一、概述 

    1、函数位置

      common/command.c 

    2、函数功能分析   

      解析命令的关键环节是如何根据输入命令查找对应命令的信息,从而跳转到对应命令的函数处执行程序。这必然涉及到如何存放命令的详细信息这个问题。因为一种存法,对应一种查法,进而取法。也就是说,实际上是两个问题:

    (1)命令的详细信息是如何存放的

    (2)如何在命令存储区查找是否有与输入命令匹配的命令

        就这两个问题,我们来分别分析uboot的设计方法。

    二、".u_boot_cmd"环境变量存储区

    1、命令详细信息存储结构体

    struct cmd_tbl_s {
      char     *name;     /* Command Name     */
      int     maxargs;    /* maximum number of arguments    */
      int     repeatable;    /* autorepeat allowed?     */
      /* Implementation function    */
      int     (*cmd)(struct cmd_tbl_s *, int, int, char *[]);
      char     *usage;     /* Usage message    (short)    */
      #ifdef    CFG_LONGHELP
      char     *help;     /* Help message    (long)    */
      #endif
      #ifdef CONFIG_AUTO_COMPLETE
      /* do auto completion on the arguments */
      int     (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]);
      #endif
    };
    
    typedef struct cmd_tbl_s    cmd_tbl_t;

    2、把命令的详细信息安排在".u_boot_cmd"存储区

    (1)相关声明

    #define Struct_Section __attribute__ ((unused,section (".u_boot_cmd"))) 
    
    
    #define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) 
    cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}

    ##    代表字符串连接符

    #      代表转换为字符串

    (2)实例说明

    int do_hello (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
    {
    
    }
    
    U_BOOT_CMD(
    md, 3, 1, do_hello,
    "md - memory display
    ",
    "[.b, .w, .l] address [# of objects]
     - memory display
    "
    );
    U_BOOT_CMD(
    hello, 3, 1, do_hello,
    "md - memory display
    ",
    "[.b, .w, .l] address [# of objects]
     - memory display
    "
    );
    展开后为:
    cmd_tbl_t __u_boot_cmd_hello
    __attribute__ ((unused,section (".u_boot_cmd"))) 
    ={
        "hello", 3, 1, do_hello,
        "md - memory display
    ",
        "[.b, .w, .l] address [# of objects]
     - memory display
    "
    };

        可见,实际上就是定义了一个cmd_tbl_t类型的变量"__u_boot_cmd_hello",并且强制性的将其存储在".u_boot_cmd"段,等号后边的就是该变量的初始值。

    三、具体分析find_cmd函数

    函数功能:查找命令是否存在,如果存在就将命令结构体地址返回
    /***************************************************************************
    * find command table entry for a command
    */
    cmd_tbl_t *find_cmd (const char *cmd)
    {
    cmd_tbl_t *cmdtp;
    cmd_tbl_t *cmdtp_temp = &__u_boot_cmd_start; /*Init value */
    const char *p;
    int len;
    int n_found = 0;

    /*
    * Some commands allow length modifiers (like "cp.b");
    * compare command name only until first dot.
    */
    len = ((p = strchr(cmd, '.')) == NULL) ? strlen (cmd) : (p - cmd);
    //获取命令的长度,因为uboot支持命令的简写,但是以'.'为分隔符

    //下边的for循环就是在命令结构体存储区中,从前到后依次查找是否有匹配的命令
    for (cmdtp = &__u_boot_cmd_start;
    cmdtp != &__u_boot_cmd_end;
    cmdtp++) {
    if (strncmp (cmd, cmdtp->name, len) == 0) {
    if (len == strlen (cmdtp->name))
    return cmdtp; /* full match */

    cmdtp_temp = cmdtp; /* abbreviated command ? */
    n_found++;
    }
    }
    if (n_found == 1) { /* exactly one match */ //如果简写命令只有一个匹配,那么说明就是要找的命令
    //但是,倘若超过一个就不知道所谓的简写是哪一个命令了
    return cmdtp_temp;
    }

    return NULL; /* not found or ambiguous command */
    }

    参考资料:U-Boot启动第二阶段代码分析

  • 相关阅读:
    初识Mysql 连接器的收获(包含JDBC API最新文档)以及一些c++的有用技巧
    重拾 ”多项式“ 给我的启示
    vs2015下配置MySQL,使之能使用c++连接完美运行
    在CentOS上使用yum安装java
    CentOS 用yum安装中文输入法
    Redhat Linux RHEL5配置CentOS YUM更新源
    转:Linux下which、whereis、locate、find 命令的区别
    Centos 挂载NTFS格式的USB硬盘
    scp采用无密码在两台linux服务器之间传输数据
    转:Andriod studio技巧合集
  • 原文地址:https://www.cnblogs.com/amanlikethis/p/3556413.html
Copyright © 2011-2022 走看看