run_main_loop 到 cmd_process处理说明三

一.  run_main_loop 到 cmd_process处理过程

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

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

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

二.  cmd_process函数处理命令过程

1.  函数调用关系

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

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

run_main_loop 到 cmd_process处理说明三_第1张图片

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 成员变量。

你可能感兴趣的:(uboot,系统移植篇,java,前端,javascript)