u-boot 之 run_comman()函数的理解


/*
** 在u-boot-1.1.6中添加自定义命令的步骤:
** 1.增加一个u-boot命令文件,可以在common目录下复制一个文件名是cmd_***的文件,重命名为cmd_mynew.c;
** 2.把文件放置目录dir: common/cmd_mynew.c;
** 3.文件内大体包括这些内容:
       3.1包含需要的头文件:common.h, command.h, mynew.h, .......;
       3.2添加u-boot命令宏:
               U_BOOT_CMD(
                mynew, CFG_MAXARGS, 1,    do_mynew,
                "mynew      - test my add new u-boot command.\n",
                "print some message to show.\n"
                " ...... \n"
               );
       3.3实现u-boot命令函数do_***(),比如这里的do_mynew().
*/

/*
** u-boot-1.1.6 的命令实现过程 理解。
** run_command函数位于dir:common/main.c

** 由于这个函数移植的时候基本不需要修改,并且本身注释也很清楚,所以没有花

** 太多的时间去注释和理解。
*/
/****************************************************************************
 * returns:
 *    1  - command executed, repeatable
 *    0  - command executed but not repeatable, interrupted commands are
 *         always considered not repeatable
 *    -1 - not executed (unrecognized, bootd recursion or too many args)
 *           (If cmd is NULL or "" or longer than CFG_CBSIZE-1 it is
 *           considered unrecognized)
 *
 * WARNING:
 *
 * We must create a temporary copy of the command since the command we get
 * may be the result from getenv(), which returns a pointer directly to
 * the environment data, which may change magicly when the command we run
 * creates or modifies environment variables (like "bootp" does).
 */

int run_command (const char *cmd, int flag)
{
    cmd_tbl_t *cmdtp;
    char cmdbuf[CFG_CBSIZE];    /* working copy of cmd        */
    char *token;                /* start of token in cmdbuf    */
    char *sep;                    /* end of token (separator) in cmdbuf */
    char finaltoken[CFG_CBSIZE];
    char *str = cmdbuf;
    char *argv[CFG_MAXARGS + 1];    /* NULL terminated    */
    int argc, inquotes;
    int repeatable = 1;
    int rc = 0;

    /*
    ** ctrlc_was_pressed = 0; 清除先前的控制命令
    */

    clear_ctrlc();                 /* forget any previous Control C */
    
    /*
    ** 如果命令cmd是空的或者Null,那么返回-1.
    */

    if (!cmd || !*cmd) 
    {
        return -1;      /* empty command */
    }

    /*
    ** 如果cmd命令太长,则输出提示:command too long!
    ** 且返回-1.
    */

    if (strlen(cmd) >= CFG_CBSIZE) 
    {
        puts ("## Command too long!\n");
        return -1;
    }

    /*
    ** 把u-boot命令(cmd)内容复制到cmdbuf。
    */

    strcpy (cmdbuf, cmd);

    /* 
    ** Process separators and check for invalid repeatable commands.
    */

    while (*str) 
    {

        /*
         * Find separator, or string end
         * Allow simple escape of ';' by writing "\;"

         * 要明白这段解析命令参数的方法,要知道命令在内存中存放的格式

         * 暂时还没有精力去了解,留给以后。
         */

        for (inquotes = 0, sep = str; *sep; sep++) 
        {
            if ((*sep=='\'') && (*(sep-1) != '\\'))
                inquotes=!inquotes;

            if (!inquotes &&
                (*sep == ';') &&    /* separator        */
                ( sep != str) &&    /* past string start    */
                (*(sep-1) != '\\'))    /* and NOT escaped    */
                break;
        }

        /*
         * Limit the token to data between separators
         */

        token = str;
        if (*sep) {
            str = sep + 1;    /* start of command for next pass */
            *sep = '\0';
        }
        else
            str = sep;    /* no more commands for next pass */

        /* find macros in this token and replace them */
        process_macros (token, finaltoken);

        /* Extract arguments */
        if ((argc = parse_line (finaltoken, argv)) == 0) 
        {
            rc = -1;    /* no command at all */
            continue;
        }

        /* Look up command in command table */
        if ((cmdtp = find_cmd(argv[0])) == NULL) 
        {
            printf ("Unknown command '%s' - try 'help'\n", argv[0]);
            rc = -1;    /* give up after bad command */
            continue;
        }

        /* found - check max args */
        if (argc > cmdtp->maxargs) 
        {
            printf ("Usage:\n%s\n", cmdtp->usage);
            rc = -1;
            continue;
        }

        /* 
        ** OK - call function to do the command.
        ** 调用命令执行函数。
        */

        if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {
            rc = -1;
        }

        repeatable &= cmdtp->repeatable;

        /* Did the user stop this? */
        if (had_ctrlc ())
            return 0;    /* if stopped then not repeatable */
    }

    return rc ? rc : repeatable;
}

/*
** u-boot中的cmd_tbl_t命令结构体:
** dir: include/command.h
*/

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),命令提示---短内容    */
    char    *help;        /* Help  message    (long),命令提示---长内容    */
    /*
    ** do auto completion on the arguments.
    ** 自动执行命令???
    */

    int        (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]);
};
typedef struct cmd_tbl_s    cmd_tbl_t;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值