run命令 uboot_uboot之run_command函数U_BOOT_CMD及命令表

uboot-1.1.6

#set machid 0456     这是用来设置mach id的

/*

* Configurable monitor commands definitions have been moved

* to include/cmd_confdefs.h

*/

include/command.h

如果要把一个变量放入.u_boot_cmd段,需要通过宏U_BOOOT_CMD实现。宏的定义如下:

#define Struct_Section  __attribute__ ((unused,section (".u_boot_cmd")))

#ifdef  CFG_LONGHELP

#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \

cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage, help}

#else /* no long help info */

#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \

cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name, maxargs, rep, cmd, usage}

#endif /* CFG_LONGHELP */

“##”与“#”都是预编译操作符,“##”有字符串连接的功能,“#”表示后面紧接着的是一个字符串。

#define Struct_Section  __attribute__ ((unused,section (".u_boot_cmd")))

其中,unused表示该函数或变量可能不使用,这个属性可以避免编译器产生警告信息。

凡通过U_BOOT_CMD定义的cmd_tbl_t变量会全部被放在.u_boot_cmd段当中。这也是在你写的.c文件的末尾必须要写的,为了完成注册这个动作。

在文件u-boot.lds中有如下定义:

__u_boot_cmd_start = .;

.u_boot_cmd : { *(.u_boot_cmd) }

__u_boot_cmd_end = .;

该段的含义为定义一个新段.u_boot_cmd。__u_boot_cmd_start为该段的第一个符号;__u_boot_cmd_end为该段的最后一个符号。

/*

* Monitor Command Table

*/

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) *//*简短的帮助信息*/

#ifdef CFG_LONGHELP

char  *help;  /* Help  message (long) *//*较详细的帮助信息*/

#endif

#ifdef CONFIG_AUTO_COMPLETE

/* do auto completion on the arguments *//*自动补全参数*/

int  (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]);

#endif

};

typedef struct cmd_tbl_s cmd_tbl_t;

/

common/command.c

Uboot中所有命令都是存放在这个特殊段中的。当用户输入一个命令时(需要与定义时的name变量同名),会在函数find_cmd中从__u_boot_cmd_start开始循环匹配,匹配到后就执行对应变量中的cmd项;如果直到__u_boot_cmd_end也没有发现,则匹配失败。

/***************************************************************************

* find command table entry for a command

*/

cmd_tbl_t *find_cmd (const char *cmd)

{

cmd_tbl_t *cmdtp;

cmd_tbl_t *cmdtp_temp = &__u_boot_cmd_start; /*Init value */

const char *p;

int len;

int n_found = 0;

/*

* Some commands allow length modifiers (like "cp.b");

* compare command name only until first dot.

*/

len = ((p = strchr(cmd, '.')) == NULL) ? strlen (cmd) : (p - cmd);

for (cmdtp = &__u_boot_cmd_start;

cmdtp != &__u_boot_cmd_end;

cmdtp++) {

if (strncmp (cmd, cmdtp->name, len) == 0) {

if (len == strlen (cmdtp->name))

return cmdtp; /* full match */

cmdtp_temp = cmdtp; /* abbreviated command ? */

n_found++;

}

}

if (n_found == 1) {   /* exactly one match */

return cmdtp_temp;

}

return NULL; /* not found or ambiguous command */

}

/

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)

{

//例如        run_command("nand read 0x40008000 0x400000 0x300000",0);

//        run_command("bootm 0x40008000",0);

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 (strlen(cmd) >= CFG_CBSIZE) {

puts ("## Command too long!\n");

return -1;

}

strcpy (cmdbuf, cmd);

/* Process separators and check for invalid

* repeatable commands

*/

#ifdef DEBUG_PARSER

printf ("[PROCESS_SEPARATORS] %s\n", cmd);

#endif

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 */

#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) {

rc = -1; /* no command at all */

continue;

}

/* Look up command in command table */

//在表中查找名字为setenv的结构体,

//找到名字相同的cmd_tbl_t结构体,就可以调用cmdtp->cmd执行动作

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;

}

#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;

}

//

common/cmd_nvedit.c

U_BOOT_CMD(

saveenv, 1, 0, do_saveenv,

"saveenv - save environment variables to persistent storage\n",

NULL

);

///

common/cmd_nvedit.c

U_BOOT_CMD(

setenv, CFG_MAXARGS, 0, do_setenv,

"setenv  - set environment variables\n",

"name value ...\n"

"    - set environment variable 'name' to 'value ...'\n"

"setenv name\n"

"    - delete environment variable 'name'\n"

);

///

一般run_command("usb start", 0);那么是调用cmd_usb.c里的do_usb

run_command("fatload usb 0 0x82000000 ESHOW", 0)  ,common/cmd_fat.c ,do_fat_fsload函数

U_BOOT_CMD(

usb,    5,    1,    do_usb,

"USB sub-system",

"reset - reset (rescan) USB controller\n"

"usb stop [f]  - stop USB [f]=force stop\n"

"usb tree  - show USB device tree\n"

"usb info [dev] - show available USB devices\n"

"usb storage  - show details of USB storage devices\n"

"usb dev [dev] - show or set current USB storage device\n"

"usb part [dev] - print partition table of one or all USB storage"

" devices\n"

"usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n"

"    to memory address `addr'"

"usb write addr blk# cnt - write `cnt' blocks starting at block `blk#'\n"

"    from memory address `addr'"

);

///

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值