Uboot中的命令实现(一)命令的声明

最近看了一款STM32设计的模块,其通过串口实现的命令解释器十分灵活好用,因此也想借鉴移植一个命令解释器到自己的设备中,进而想到了UBOOT中的命令实现,准备跟踪U-BOOT里的命令解释器,并将其移植到STM单片机中,作为一个通用模板来使用。别的不说了,RTFSC (Read the fucking source code )!

uboot中的命令解释函数在command.c 和command.h中,他的声明

倒着跟踪U_BOOT中的命令声明与注册。

先来看一下cmd_help.c 文件中,关于help命令的注册过程,需要声明一个执行函数,do_help,一般均为do_XXX命名。其函数符合cmd_tbl_t 中的成员函数的声明。

static int do_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	cmd_tbl_t *start = ll_entry_start(cmd_tbl_t, cmd);
	const int len = ll_entry_count(cmd_tbl_t, cmd);
	return _do_help(start, len, cmdtp, flag, argc, argv);
}

U_BOOT_CMD(
	help,	CONFIG_SYS_MAXARGS,	1,	do_help,
	"print command description/usage",
	"\n"
	"	- print brief description of all commands\n"
	"help command ...\n"
	"	- print detailed usage of 'command'"
);

struct cmd_tbl_s的定义,在command.h中,定义如下:其中包括了函数名,函数最大参数个数,函数是否支持自动重复调用(再次发送ENTER键时自动执行),函数的实际执行函数,用途说明及帮助。如果定义了自动执行,还包括自动执行的函数。

 

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 * const []);
	char		*usage;		/* Usage message	(short)	*/
#ifdef	CONFIG_SYS_LONGHELP
	char		*help;		/* Help  message	(long)	*/
#endif
#ifdef CONFIG_AUTO_COMPLETE
	/* do auto completion on the arguments */
	int		(*complete)(int argc, char * const argv[], char last_char, int maxv, char *cmdv[]);
#endif
};

typedef struct cmd_tbl_s	cmd_tbl_t;

U_BOOT_CMD的定义如下

#define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd,		\
				_usage, _help, _comp)			\
		{ #_name, _maxargs, _rep, _cmd, _usage,			\
			_CMD_HELP(_help) _CMD_COMPLETE(_comp) }

#define U_BOOT_CMD_MKENT(_name, _maxargs, _rep, _cmd, _usage, _help)	\
	U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd,		\
					_usage, _help, NULL)

#define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, _comp) \
	ll_entry_declare(cmd_tbl_t, _name, cmd) =			\
		U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd,	\
						_usage, _help, _comp);

#define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help)		\
	U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, NULL)

U_BOOT_CMD是 U_BOOT_CMD_COMPLETE的特殊调用,只是他的自动执行函数为NULL。

U_BOOT_COMPLETE相当于一个声明函数

#define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, _comp) \
	ll_entry_declare(cmd_tbl_t, _name, cmd) =			\
		U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd,	\
						_usage, _help, _comp);

ll_entry_declare的定义为:

#define ll_entry_declare(_type, _name, _list)				\
	_type _u_boot_list_2_##_list##_2_##_name __aligned(4)		\
			__attribute__((unused,				\
			section(".u_boot_list_2_"#_list"_2_"#_name)))

U_BOOT_CMD_MKENT_COMPLETE宏的定义为:

#define U_BOOT_CMD_MKENT(_name, _maxargs, _rep, _cmd, _usage, _help)	\
	U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd,		\
					_usage, _help, NULL)

在其中又使用了U_BOOT_CMD_MKENT_COMPLETE宏,这时候是不是有点想骂人XXXX,为啥搞这么多宏????再来看看U_BOOT_CMD_MKENT_COMPLETE的定义

#define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd,		\
				_usage, _help, _comp)			\
		{ #_name, _maxargs, _rep, _cmd, _usage,			\
			_CMD_HELP(_help) _CMD_COMPLETE(_comp) }

这回终于快到头了,再来看看_CMD_HELP 和_CMD_COMPLETE。

#ifdef CONFIG_AUTO_COMPLETE
# define _CMD_COMPLETE(x) x,
#else
# define _CMD_COMPLETE(x)
#endif
#ifdef CONFIG_SYS_LONGHELP
# define _CMD_HELP(x) x,
#else
# define _CMD_HELP(x)

如果定义了CONFIG_AUTO_COMPLETE 和CONFIG_SYS_LONGHELP,只是多一个,或少一个参数的问题,正好对应到cmt_tbl_t结构体的定义。这里我们按照不定义这两个宏来跟踪代码。整体展开这个UBOOT_CMD

ll_entry_declare(cmd_tbl_t, help,  do_help)=
 {"help", CONFIG_SYS_MAXARGS, 1, do_help, 
"print command description/usage",
"\n"
"	- print brief description of all commands\n"
"help command ...\n"
"	- print detailed usage of 'command'"
};

cmd_tbl_t  _u_boot_list_2_do_help_2_help _aligned(4) __attribute__((unused, section(".u_boot_list_2_"help))) = 
 {"help", CONFIG_SYS_MAXARGS, 1, do_help, 
"print command description/usage",
"\n"
"	- print brief description of all commands\n"
"help command ...\n"
"	- print detailed usage of 'command'"
};

可是这里没有注册函数,也没有调用的地方,直接就完成了命令的注册,这里一定又有什么奇技淫巧,一定就在cmd_tbl_t 声明后面的一票XXXXXXXX身上出的问题。

这里用到了一个函数,也就是section()函数,其中_aligned(4)代表使用4字节对齐存储,__attribute__(unused,section(".u_boot_list_2_help)表使用未使用的section,另外再来一个函数来解释__attribute__

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值