uboot串口命令cmd代码解析(uboot2012.04.01)

3 篇文章 0 订阅

一、uboot命令定义分析

1.1、.u_boot_cmd段

相信很多人在初次接触uboot都会找不到uboot命令表的定义在哪里,这是因为uboot命令表的起始地址定义在了链接脚本中,而uboot命令表的内容是使用section关键词指定变量到uboot命令表地址的。

在u-boot.lds文件中有如下一段代码:

 __u_boot_cmd_start = .;//.表示当前地址
 .u_boot_cmd : { *(.u_boot_cmd) }
 __u_boot_cmd_end = .;
  • 这段代码的意思是__u_boot_cmd_start这个变量的地址是为当前地址,我们不需要关注这个地址是多少;
  • .u_boot_cmd : { *(.u_boot_cmd) }声明了一个名为u_boot_cmd的的代码段,我们可以在c代码中使用section关键词指定变量或者函数到这个段所在的地址中;
  • __u_boot_cmd_end指定了u_boot_cmd段的结束地址,这个地址由系统自动计算;

1.2、U_BOOT_CMD宏定义

接下来我们看下U_BOOT_CMD的定义:

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

#define U_BOOT_CMD_COMPLETE(name,maxargs,rep,cmd,usage,help,comp) \
	cmd_tbl_t __u_boot_cmd_##name Struct_Section = \
		U_BOOT_CMD_MKENT_COMPLETE(name,maxargs,rep,cmd,usage,help,comp)
#define Struct_Section  __attribute__((unused, section(".u_boot_cmd"), \
		aligned(4)))
#define U_BOOT_CMD_MKENT_COMPLETE(name,maxargs,rep,cmd,usage,help,comp) \
	{#name, maxargs, rep, cmd, usage, _CMD_HELP(help) _CMD_COMPLETE(comp)}

将上述宏定义结合到一起得到如下关于U_BOOT_CMD的定义:

#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
    cmd_tbl_t __u_boot_cmd_##name __attribute__((unused, section(".u_boot_cmd"), \
		aligned(4))) = {#name, maxargs, rep, cmd, usage, _CMD_HELP(help) _CMD_COMPLETE(comp)}

##表示字符串连接符,在这个宏定义中,我们使用__attribute__关键词将__u_boot_cmd_##name变量指定到了.u_boot_cmd所在的段中。这样我们就可以通过__u_boot_cmd_start这个地址来访问U_BOOT_CMD定义的变量。

1.3、cmd_tbl_t结构体

你可以把uboot的命令理解成一张表,每个表格中记录了表的名称等信息。我们在查找表的时候可以根据表的名称来找到表所在的位置,然后访问表的每一个成员。

struct cmd_tbl_s {
	char		*name;		/* 命令名称			*/
	int		maxargs;	/* 命令的最大参数个数	*/
	int		repeatable;	/* 是否允许重复		*/
					/* Implementation function	*/
	int		(*cmd)(struct cmd_tbl_s *, int, int, char * const []);/*命令的回调函数*/
	char		*usage;		/* 使用信息	(short)	*/
#ifdef	CONFIG_SYS_LONGHELP
	char		*help;		/* 帮助信息	(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;

1.4、使用section指定代码段和定义全局数组的区别

u-boot.lds中定义的数据都是放在flash中的,也就是说uboot中的命令表示直接存储在flash中的,并不占用ram或者说内存空间。如果我们将命令表定义在全局数组中,那么它就会占用大量的内存空间,而不会占用flash空间。

二、uboot入口函数分析

enum command_ret_t cmd_process(int flag, int argc, char * const argv[],
			       int *repeatable)
{
	enum command_ret_t rc = CMD_RET_SUCCESS;
	cmd_tbl_t *cmdtp;

	/* Look up command in command table */
	cmdtp = find_cmd(argv[0]);
	if (cmdtp == NULL) {
		printf("Unknown command '%s' - try 'help'\n", argv[0]);
		return 1;
	}

    ...//省略部分代码
}

find_cmd函数用来查找对应的命令:

cmd_tbl_t *find_cmd (const char *cmd)
{
	int len = &__u_boot_cmd_end - &__u_boot_cmd_start;
	return find_cmd_tbl(cmd, &__u_boot_cmd_start, len);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值