find_cmd函数分析
?一、概述?
1、函數位置
common/command.c?
2、函數功能分析???
解析命令的關鍵環節是如何根據輸入命令查找對應命令的信息,從而跳轉到對應命令的函數處執行程序。這必然涉及到如何存放命令的詳細信息這個問題。因為一種存法,對應一種查法,進而取法。也就是說,實際上是兩個問題:
(1)命令的詳細信息是如何存放的
(2)如何在命令存儲區查找是否有與輸入命令匹配的命令
? ? 就這兩個問題,我們來分別分析uboot的設計方法。
二、".u_boot_cmd"環境變量存儲區
1、命令詳細信息存儲結構體
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_LONGHELPchar *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;2、把命令的詳細信息安排在".u_boot_cmd"存儲區
(1)相關聲明
#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}## ? ?代表字符串連接符
# ? ? ?代表轉換為字符串
(2)實例說明
int do_hello (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) {}U_BOOT_CMD( md, 3, 1, do_hello, "md - memory display\n", "[.b, .w, .l] address [# of objects]\n - memory display\n" ); U_BOOT_CMD( hello, 3, 1, do_hello, "md - memory display\n", "[.b, .w, .l] address [# of objects]\n - memory display\n" );展開后為: cmd_tbl_t __u_boot_cmd_hello __attribute__ ((unused,section (".u_boot_cmd"))) ={"hello", 3, 1, do_hello,"md - memory display\n","[.b, .w, .l] address [# of objects]\n - memory display\n" };
? ? 可見,實際上就是定義了一個cmd_tbl_t類型的變量"__u_boot_cmd_hello",并且強制性的將其存儲在".u_boot_cmd"段,等號后邊的就是該變量的初始值。
三、具體分析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);
//獲取命令的長度,因為uboot支持命令的簡寫,但是以'.'為分隔符
//下邊的for循環就是在命令結構體存儲區中,從前到后依次查找是否有匹配的命令
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 */
}
?
參考資料:U-Boot啟動第二階段代碼分析
總結
以上是生活随笔為你收集整理的find_cmd函数分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 孕妇梦到蝴蝶什么预兆
- 下一篇: 软件测试 -- alpha测试和bet