转载:http://blog.chinaunix.net/uid-22030783-id-366971.html
第一步:
COBJS-$(CONFIG_CMD_MENU) += cmd_menu.o
编写cmd_menu.c的内容:
定义一个uboot cmd:
- U_BOOT_CMD(
- menu, 3, 0, do_menu,
- "menu - display a menu, to select the items to do something\n",
- " - display a menu, to select the items to do something"
- );
cmd的名为 menu 执行的动作是do_menu函数
U_BOOT_CMD(name,maxargs,rep,cmd,usage,help)参数含义如下:
name:命令名[非字符串]但在U_BOOT_CMD中用”#”符号转化为字符串;
maxargs:命令的最大参数个数;
rep:是否自动重复(按Enter键是否会重复执行);
cmd:该命令对应的响应函数;
usage:简短的使用说明(字符串);
help:较详细的使用说明(字符串);
在内存中保存命令的help字段会占用一定的内存,通过配置U-Boot可以选择是否保存help字段。
若在include/configs/mini2440.h中定义了CONFIG_SYS_LONGHELP宏,
则在U-Boot中使用help命令查看某个命令的帮助信息时将显示usage和help字段的内容,
否则就只显示usage字段的内容。
U_BOOT_CMD宏在include/command.h中定义:
#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}
“##”与“#”都是预编译操作符,“##”有字符串连接的功能,“#”表示后面紧接着的是一个字符串。[cmd_tbl_t在include/command.h中定义]
第二步:
实现do_menu
- int do_menu (cmd_tbl_t *cmdtp,int flag,int argc, char*argv[])
- {
- menu_shell();
- return 0;
- }
这里调用menu_shell函数
第三步:
- void menu_shell(void)
- {
- char cmd_buf[200];
- while (1)
- {
- main_menu_usage();//打印菜单
- c = awaitkey(-1,NULL);//等待按键的输入
- printf("%c\n", c);
- switch (c)
- {
- case '1'://输入‘1’执行的动作
- {
- .....
- break;
- }
- case '2'://输入‘2’执行的动作
- {
- .....
- break;
- }
- case '3'://输入‘3’执行的动作
- {
- .....
- break;
- }
- .....
- ....
- }
- }
- }
menu_shell就是一个while循环,调用main_menu_usage打印菜单,然后awaitkey,再switch输入的键值,
执行相应的case
我的main_menu_usage如下:
- void main_menu_usage(void)
- {
- printf("[1] 烧写bootloader到nandflash\r\n");
- printf("[2] 烧写Linux Kernel到nandflash\r\n");
- printf("[3] 烧写yaffs2文件系统到nandflash\r\n");
- printf("[4] 下载程序在SDRAM中运行\r\n");
- printf("[5] 设置uboot参数\r\n");
- printf("[6] 格式化Nandflash\r\n");
- printf("[7] 启动Linux系统\r\n");
- printf("[8] 进入Shell模式\r\n");
- printf("[9] 重启uboot\r\n");
- if (bBootFrmNORFlash == 1)
- printf("[0] 下载bootloader到NorFlash\r\n");
- printf("Enter your selection: ");
- }
以烧写uboot到nandflash为例,case 1:中的内容为:
- strcpy(cmd_buf,"usbslave 1 0x30000000; nand erase bios; nand write.jffs2 0x30000000 bios 0x100000");
- run_command(cmd_buf, 0);
- break;
按照这个依次写每个case
再main.c中调用menu命令:
main_loop函数中在abortboot (bootdelay) 结束后加入:
- #ifdef CONFIG_CMD_MENU
- run_command("menu", 0);
- #endif
编译uboot下载到FLASH中就能看到菜单了
//========================================================================================
//=======下面的关键代码:waitconsoleinput =====================================
//========================================================================================
(1)、在common目录下新增cmd_menu.c文件,代码如下:
#include <common.h>
#include <command.h>
static char waitconsoleinput(unsigned long delay)
{
int i;
if (-1 == delay) {
while (1) {
if(tstc()){
return getc();
}
}
}
else {
for (i = 0; i < delay; i++) {
if(tstc()){
return getc();
}
udelay(10*1000);/*时间快的话自己调整下*/
}
}
return 0;
}
void menu_usage(void)
{
printf("\r\n=========Menu for XXX=========\r\n");
printf("\r\n");
printf("[1] download Linux(zImage) and boot kernel \r\n");
printf("[2] Reset\r\n");
printf("[q] Exit\r\n");
printf("\r\n");
printf("Please Input: ");
}
void menu_shell(void)
{
char c;
char cmdbuf[128];
while (1)
{
menu_usage();
c = waitconsoleinput(-1);
switch (c)
{
case '1':
strcpy(cmdbuf, "tftp 0x20008000 zImage; go 0x20008000");
run_command(cmdbuf, 0);
break;
case 'r':
strcpy(cmdbuf, "reset");
run_command(cmdbuf, 0);
break;
case 'q':
return;
};
};
}
int do_menu (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
menu_shell();
return 0;
}
U_BOOT_CMD(
bootmenu, 1, 0, do_menu,
"Boot Menu",
"U-boot Boot Menu\n"
);
(2)、修改common目录下的Makefile文件
添加如下:
COBJS-y += bootmenu.o
本篇文章来源于 Linux公社网站(www.linuxidc.com) 原文链接:http://www.linuxidc.com/Linux/2012-12/76091.htm