admin管理员组

文章数量:1122851

run

一.  run_main_loop 到 cmd_process处理过程

之前文章了解了 uboot的命令格式组成。本文简单分析下 cmd_process函数对 uboot命令的处理过程。

本文继上一篇文章的学习,地址如下:

uboot启动流程-run_main_loop 到 cmd_process处理说明二-CSDN博客

二.  cmd_process函数处理命令过程

1.  函数调用关系

这里主要分析一下 uboot 的命令行处理过程。

通过分析可知, cli_loop 函数通过一系列调用,最终调用 cmd_process函数处理命令。调用关系如下:

2.  cmd_process函数处理命令过程

cmd_process 函数定义在文件 common/command.c 中,函数内容如下:
enum command_ret_t cmd_process(int flag, int argc, char * const argv[],int *repeatable, ulong *ticks)
{enum command_ret_t rc = CMD_RET_SUCCESS;cmd_tbl_t *cmdtp;/* Look up command in command table */cmdtp = find_cmd(argv[0]);if (cmdtp == NULL) {printf("Unknown command '%s' - try 'help'\n", argv[0]);return 1;}/* found - check max args */if (argc > cmdtp->maxargs)rc = CMD_RET_USAGE;#if defined(CONFIG_CMD_BOOTD)/* avoid "bootd" recursion */else if (cmdtp->cmd == do_bootd) {if (flag & CMD_FLAG_BOOTD) {puts("'bootd' recursion detected\n");rc = CMD_RET_FAILURE;} else {flag |= CMD_FLAG_BOOTD;}}
#endif/* If OK so far, then do the command */if (!rc) {if (ticks)*ticks = get_timer(0);rc = cmd_call(cmdtp, flag, argc, argv);if (ticks)*ticks = get_timer(*ticks);*repeatable &= cmdtp->repeatable;}if (rc == CMD_RET_USAGE)rc = cmd_usage(cmdtp);return rc;
}

cmd_process 函数 调用函数 find_cmd函数 在命令表中找到指定的命令, find_cmd 函数内容如下:
 
cmd_tbl_t *find_cmd(const char *cmd)
{cmd_tbl_t *start = ll_entry_start(cmd_tbl_t, cmd);const int len = ll_entry_count(cmd_tbl_t, cmd);return find_cmd_tbl(cmd, start, len);
}

参数 cmd 就是所查找的命令名字, uboot 中的命令表其实就是 cmd_tbl_t 结构体数组,通 过 ll_entry_star t 函数得到数组的第一个元素,也就是命令表起始地址。 通过 ll_entry_count 函数得到数组长度,也就是命令表的长度。 最终通过 find_cmd_tbl 函数在命令表中找到所需的命 令,每个命令都有一个 name 成员,所以将参数 cmd 与命令表中每个成员的 name 字段都对比 一下,如果相等的话就说明找到了这个命令,找到以后就返回这个命令。

  cmd_process 函数中,找到命令以后肯定就要执行这个命令了, 调用 cmd_call函数来执行具体的命令,cmd_call 函数内容如下:
static int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{int result;result = (cmdtp->cmd)(cmdtp, flag, argc, argv);if (result)debug("Command failed, result=%d\n", result);return result;
}

在前面的分析中我们知道, cmd_tbl_t 的 cmd 成员就是具体的命令处理函数,所以,cmd_call 函数中,第5行 调用 cmdtp 的 cmd 成员来处理具体的命令,返回值为命令的执行结果。 cmd_process 中会检测 cmd_tbl 的返回值,如果返回值为 CMD_RET_USAGE ,就会调用 cmd_usage 函数输出命令的用法,其实就是输出 cmd_tbl_t 的 usage 成员变量。

本文标签: run