命令:1 usbslave 1 0x30000000 ;
2 nand erase root
3 nand write.yaffs 0x30000000 root $(filesize)
然后在run_command中一一解析他们
int run_command (const char *cmd, int flag)
//cmd正是从串口获得的字符串
{
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;
#IFdef debug_PARSER
printf ("[RUN_COMMAND] cmd[%p]=\"", cmd);
puts (cmd ? cmd : "NULL"); /* use puts - string may be loooong */
puts ("\"\n");
#endif
clear_ctrlc(); /* forget any previous Control C */
if (!cmd || !*cmd) {
return -1; /* empty command */
}
//下面if语句判断命令是否太长,
//还是避免有些变态的家伙输入了超过CFG_CBSIZE个字符的命令
if (strlen(cmd) >=CFG_CBSIZE)// 命令从console_buffer搬运到lastcommand中) {
puts ("## Command too long!\n");
return -1;
strcpy (cmdbuf, cmd); //对命令又进行了一次拷贝
/* Process separators and check for invalidrepeatable commands*/
#ifdef DEBUG_PARSER
printf ("[PROCESS_SEPARATORS] %s\n", cmd);
#endif
//str就是指向cmdbuf的指针, 其实这些东西都是针对的刚才那行命令
//注释很清楚, 找到;作为命令结束符, 因为多个命令可以一次输入, 并以;分割.
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;
}
//如果上面for循环找到一条以';'结束的命令, 那么sep指向命令末尾
/*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 */
#ifdef DEBUG_PARSER
printf ("token: \"%s\"\n", token);
#endif
/* find macros in this token and replace them */
process_macros (token, finaltoken); //处理宏,临时生成的环境变量
/* Extract arguments */ //提取参数
if ((argc = parse_line (finaltoken, argv)) == 0) //解析这些字符,argv[]
{
rc = -1; /* no command at all */
continue;
}
/* Look up command in command table */
if ((cmdtp = find_cmd(argv[0])) == NULL) //第一个参数argv[0]就被存入了,这是个命令;cmdtp是一个结构体
{
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;
}
#if (CONFIG_COMMANDS & CFG_CMD_BOOTD)
/* avoid "bootd" recursion */
if (cmdtp->cmd == do_bootd) {
#ifdef DEBUG_PARSER
printf ("[%s]\n", finaltoken);
#endif
if (flag & CMD_FLAG_BOOTD) {
puts ("'bootd' recursion detected\n");
rc = -1;
continue;
} else {
flag |= CMD_FLAG_BOOTD;
}
}
#endif /* CFG_CMD_BOOTD */
/* 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;
} //run_command函数结束了
我所理解的就是:用这个循环for (inquotes = 0, sep = str; *sep; sep++),去找到;作为命令结束符, 因为多个命令可以一次引入, 并以;分割。然后调用函数,依次去执行这些命令。
我所不理解的就是:
1:它把解析出来的命令(比如:nand erase root)放在哪呢?
2:终端一般只输入一个命令,但是此处却是三个命令(usbslave 1 0x30000000; nand erase root; nand write.yaffs 0x30000000 root $(filesize)),怎么调用函数去处理这三条命令呢?
3:argc和argv是串口输入的命令,和这菜单的命令(usbslave 1 0x30000000; nand erase root; nand write.yaffs 0x30000000 root $(filesize))有关系吗?
0