u-boot的命令实现(添加自定义命令)

丶灬走出姿态 提交于 2020-01-18 01:01:06

Uboot如何实现控制台命令?我们从几个方面进行分析

使用

 常用的命令有help、bootm等等。有的命令有参数,有的命令没参数,有的参数可以有参数也可以没参数。

例如help命令:

    help         //列出当前uboot所有支持的命令
    help  命令   //查看指定命令的帮助

我们输入的命令help被接收后,uboot会寻找名为help的命令,并执行对应的函数,那么命令是如何被定义的?又是如何执行的?我们需要通过源码进行分析。

 源码分析

 我们以help命令为例进行分析。

1、命令的定义

先从文件结构上看,所有的命令源码都在uboot的common文件夹下,文件命名形式为cmd_*.c,*代表命令名字。

从代码上看,每个命令由一个cmd_tbl_t类型结构体描述。

struct cmd_tbl_s {
	char    *name;		    /* 命令名			            */
	int     maxargs;	    /* 命令最多可带参数           	*/
	int     repeatable;	    /* 命令是否可重复执行		    */
					        /* 实现命令函数           	    */
	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;

help命令定义如下,这是宏定义的形式,我们还原一下经过预处理之后的形式

U_BOOT_CMD(
	help,	CFG_MAXARGS,	1,	do_help,
	"help    - print online help\n",
	"[command ...]\n"
	"    - show help information (for 'command')\n"
	"'help' prints online help for the monitor commands.\n\n"
	"Without arguments, it prints a short usage message for all commands.\n\n"
	"To get detailed help information for specific commands you can type\n"
  "'help' with one or more command names as arguments.\n"
);

首先找到U_BOOT_CMD();的宏定义,这里有几个知识点,#和##作用、第一行的宏定义

1、#和##:#的作用是转换为字符串。 ##的作用是连接前后的内容

2、__attribute__ ((unused,section (".u_boot_cmd")))就是把定义的内容标记为.u_boot_cmd段。在程序连接的时候有作用。

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

经过预处理之后help命令的定义就变成了如下的形式


cmd_tbl_t __u_boot_cmd_help __attribute__ ((unused,section (".u_boot_cmd"))) = {
    help,	
    CFG_MAXARGS,	
    1,	
    do_help,
    "help    - print online help\n",
    "[command ...]\n"
    "    - show help information (for 'command')\n"
    "'help' prints online help for the monitor commands.\n\n"
    "Without arguments, it prints a short usage message for all commands.\n\n"
    "To get detailed help information for specific commands you can type\n"
    "'help' with one or more command names as arguments.\n"
}

 这样看来命令定义的方式就很明显了,其他命令也是使用相同的方式定义的,接下来分析他是如何被初始化和被使用的。

2、命令的初始化和使用

在命令被定义的时候有一个段的定义就是这个__attribute__ ((unused,section (".u_boot_cmd")))。在uboot的链接脚本中有这段的定义,就是把所有使用这种方式定义的命令都连接在了一起,也就是完成了命令的初始化

	__u_boot_cmd_start = .;
	.u_boot_cmd : { *(.u_boot_cmd) }
	__u_boot_cmd_end = .;

使用则只需要检索命令名字就可以了。

了解了原理添加自定义的命令自然就不是难事了。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!