u-boot命令体系
u-boot命令体系
一、从main_loop
开始
每一次执行main_loop
就是完成cmd读取、解析、执行的一次过程。
run_command
分析
cmd_tbl_s
结构体
该结构体存储待执行的指令,包含参数数量限制,是否可重复,实现功能的函数的指针,usgae和相应help。
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
};
函数分析
如何查找某命令的命令结构体
- 命令结构体的组织形式
定义结构体时,给所有结构体附加特定段属性,link时将所有具有该段属性的内容链接在一起。
在链接脚本中定义__u_boot_cmd_start
与__u_boot_cmd_end
。
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
- 如何为命令结构体附加特定段属性
#define Struct_Section __attribute__ ((unused,section (".u_boot_cmd")))
#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}
利用GCC编译器特性,为其附加段属性。
最终效果类似于./common/command.c
:
int
do_version (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
extern char version_string[];
printf ("\n%s\n", version_string);
return 0;
}
U_BOOT_CMD(
version, 1, 1, do_version,
"version - print monitor version\n",
NULL
);
find_cmd
/***************************************************************************
* 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 */
}