uboot命令解析:
(1)bootdelay没有打断,跑的是autoboot_command
abortboot
—>run_command_list (bootcmd)
(2)否则走的cli_loop
cli_loop
–>cli_simple_loop
----> cli_readline
—>run_command_repeatable
-----> (解析命令 匹配命令 运行命令 )
以下是从uboot源码抽取的例子
#ifndef __COMMAND_H
#define __COMMAND_H
struct cmd_tbl
{
char*name;
int (*cmd)(struct cmd_tbl*cmd,int flags,int argc,char *const argv[]);
char *usage;
};
#define UART_CMD_NUMBER (100)
void uart_cmd_init(void);
struct cmd_tbl*find_cmd_tbl(const char*cmd);
#endif /* __COMMAND_H */
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "command.h"
#define CONFIG_BOOTDELAY 5
#define CONFIG_SYS_PROMPT "=> "
static const char tab_seq[] = " "; /* used to expand TABs */
static int stored_bootdelay;
char console_buffer[256];
const char*bootdelay_process(void)
{
char*s;
int bootdelay;
//s = env_get("bootdelay");
bootdelay = CONFIG_BOOTDELAY;
s = "bootcmd";
stored_bootdelay = bootdelay;
return s;
}
void cli_init(void)
{
}
int cli_readline_into_buffer(const char*const prompt,char*buffer,int timeout)
{
char *p = buffer;
char*p_buf = p;
int n = 0;
int plen = 0;
int col;
char c;
if(prompt)
{
plen = strlen(prompt);
printf(prompt); // puts 会自动换行
}
for(;;)
{
c = getchar();
switch(c)
{
case '\r':
case '\n':
*p = '\0';
puts("\r\n");
return p-p_buf;
default:
*p++ = c;
++n;
}
}
}
int cli_readline(const char*const prompt)
{
console_buffer[0] = '\0';
return cli_readline_into_buffer(prompt,console_buffer,0);
}
#define isblank(c) (c == ' ' || c == '\t')
int run_command_repeatable(const char*cmd,int flag)
{
char cmdbuf[256];
char *str = cmdbuf;
char *line = cmdbuf;
int argc;
char*argv[10];
int nargs = 0;
struct cmd_tbl *cmdtp;
int result;
int i = 0;
if (!cmd || !*cmd)
{
return -1;
}
strcpy(cmdbuf, cmd);
while (nargs < 10)
{
/* skip any white space */
while (isblank(*line))
++line;
if (*line == '\0')
{
argv[nargs] = NULL;
break;
}
argv[nargs++] = line;
while (*line && !isblank(*line))
++line;
if (*line == '\0')
{
argv[nargs] = NULL;
break;
}
*line++ = '\0';
}
argc = nargs;
for(i=0;i<argc;i++)
{
printf(" argv[%d] %s\n",i,argv[i]);
}
cmdtp = find_cmd_tbl(argv[0]);
if(cmdtp == NULL)
{
printf("UnKnown command '%s' - try 'help'\n",argv[0]);
return 1;
}
//printf("cmdtp.name is%s\n",cmdtp->name);
result = cmdtp->cmd(cmdtp,flag,argc,argv);
if (result)
{
printf("Command failed, result=%d\n", result);
}
}
void cli_loop(void)
{
int len;
int flag;
int rc = 1;
char c;
static char lastcommand[256] = {0};
for(;;)
{
memset(lastcommand,0,256);
len = cli_readline(CONFIG_SYS_PROMPT);
if(len>0)
{
//printf("uart intput %s\n",lastcommand);
strcpy(lastcommand,console_buffer);
}
if(len == -1)
{
puts("<INTERRUPT>\n");
}
else
{
rc = run_command_repeatable(lastcommand,flag);
}
}
}
void main_loop(void)
{
const char*s;
cli_init();
s = bootdelay_process();
cli_loop();
printf("No CLI available\n");
}
int main()
{
uart_cmd_init();
main_loop();
return 0;
}
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "command.h"
static int cmd_count ;
static int do_bdinfo(struct cmd_tbl*cmd,int flags,int argc,char *const argv[])
{
printf("do_bdinfo \n");
return 0;
}
static int do_bootm(struct cmd_tbl*cmd,int flags,int argc,char *const argv[])
{
printf("do_bootm argv[1] is%s \n",argv[1]);
return 0;
}
static int do_ls(struct cmd_tbl*cmd,int flags,int argc,char *const argv[])
{
printf("do_ls argv[1] is%s \n",argv[1]);
return 0;
}
static struct cmd_tbl uart_cmd[UART_CMD_NUMBER] =
{
{"bdinfo",do_bdinfo},
{"bootm",do_bootm},
{"ls",do_ls},
};
void uart_cmd_init(void)
{
int i;
for(i=0;i<UART_CMD_NUMBER;i++)
{
if(uart_cmd[i].name == NULL)
{
cmd_count = i;
break;
}
}
if(cmd_count>UART_CMD_NUMBER)
{
printf("check cmd cout \n");
}
}
struct cmd_tbl*find_cmd_tbl(const char*cmd)
{
struct cmd_tbl* cmdtp;
struct cmd_tbl* cmdtp_tmp = (struct cmd_tbl*)uart_cmd ;
int i = 0;
while(i<cmd_count)
{
if(strcmp(cmd,uart_cmd[i].name)==0)
{
return &uart_cmd[i];
}
i++;
}
return NULL;
}
修改#define CONFIG_SYS_PROMPT "uboot "