一、原理

    菜单其实就是一个uboot中的命令,和其他的命令没有什么差别。

  uboot启动时,如果进入uboot命令模式,先运行这个命令,就会打印出一个菜单界面。

    在uboot的命令模式,通过键入“menu”命令,同样可以调出这个界面。

二、操作步骤

1、在common目录下创建cmd_menu.c

内容如下:

#include <common.h>
#include <command.h>

#ifdef CONFIG_CMD_MENU

#define USE_TFTP_DOWN        1
#define USE_USB_DOWN        2

extern char console_buffer[];

/*
 * Reads and returns a character from the serial port
 *   - Times out after delay iterations checking for presence of character
 *   - Sets *error_p to UART error bits or - on timeout
 *   - On timeout, sets *error_p to -1 and returns 0
 */
static char awaitkey(unsigned long delay, int* error_p)
{
    int i;
    char c;

    if (delay == -1) {
        while (1) {
            if (tstc()) /* we got a key press    */
                return getc();
        }
    }
    else {        
        for (i = 0; i < delay; i++) {
            if (tstc()) /* we got a key press    */
                return getc();
            udelay (10*1000);
        }
    }
    
    if (error_p)
        *error_p = -1;
    return 0;
}


static int bBootFrmNORFlash(void)
{
    volatile unsigned int *pdw = (volatile unsigned int *)0;
    unsigned int dwVal;

    dwVal = *pdw;       
    *pdw = 0x12345678;
    if (*pdw != 0x12345678)
    {
        return 1;
    }
    else
    {
        *pdw = dwVal;
        return 0;
    }
}

void main_menu_usage(char menu_type)
{

    if (bBootFrmNORFlash())
        printf("\r\n#####     Boot for Nor Flash Main Menu    #####\r\n");
    else
        printf("\r\n#####     Boot for Nand Flash Main Menu    #####\r\n");

    if( menu_type == USE_USB_DOWN)
    {
        printf("#####     EmbedSky USB download mode     #####\r\n\n");
    }
    else if( menu_type == USE_TFTP_DOWN)
    {
        printf("#####     EmbedSky TFTP download mode     #####\r\n\n");
    }
    

    if( menu_type == USE_USB_DOWN)
    {
        printf("[1] Download u-boot or STEPLDR.nb1 or other bootloader to Nand Flash\r\n");
    }
    else if( menu_type == USE_TFTP_DOWN)
    {
        printf("[1] Download u-boot.bin to Nand Flash\r\n");
    }
    printf("[2] Download Eboot (eboot.nb0) to Nand Flash\r\n");
    printf("[3] Download Linux Kernel (zImage.bin) to Nand Flash\r\n");
    if( menu_type == USE_USB_DOWN)
    {
#ifdef CONFIG_SURPORT_WINCE    
        printf("[4] Download WinCE NK.bin to Nand Flash\r\n");
#endif
        printf("[5] Download CRAMFS image to Nand Flash\r\n");
    }
    else if( menu_type == USE_TFTP_DOWN)
    {
        printf("[4] Download stepldr.nb1 to Nand Flash\r\n");
        printf("[5] Set TFTP parameters(PC IP,TQ2440 IP,Mask IP...)\r\n");
    }
    printf("[6] Download YAFFS image (root.bin) to Nand Flash\r\n");
    printf("[7] Download Program (uCOS-II or TQ2440_Test) to SDRAM and Run it\r\n");

    printf("[8] Boot the system\r\n");
    printf("[9] Format the Nand Flash\r\n");
    printf("[0] Set the boot parameters\r\n");
    printf("[a] Download User Program (eg: uCOS-II or TQ2440_Test)\r\n");
    printf("[b] Download LOGO Picture (.bin) to Nand  Flash \r\n");
    printf("[l] Set LCD Parameters \r\n");
    if( menu_type == USE_USB_DOWN)
    {
        printf("[n] Enter TFTP download mode menu \r\n");
    }

    if (bBootFrmNORFlash())
        printf("[o] Download u-boot to Nor Flash\r\n");
    if( menu_type == USE_TFTP_DOWN)
        printf("[p] Test network (TQ2440 Ping PC's IP) \r\n");

    printf("[r] Reboot u-boot\r\n");
    printf("[t] Test Linux Image (zImage)\r\n");
    if( menu_type == USE_USB_DOWN)
    {
        printf("[q] quit from menu\r\n");
    }
    else if( menu_type == USE_TFTP_DOWN)
    {
        printf("[q] Return main Menu \r\n");
    }

    printf("Enter your selection: ");
}

void tftp_menu_shell(void)
{
    char c;
    char cmd_buf[200];

    while (1)
    {
        main_menu_usage(USE_TFTP_DOWN);
        c = awaitkey(-1, NULL);
        printf("%c\n", c);
        switch (c)
        {
            case '1':
            {
            strcpy(cmd_buf, "tftp 0x30000000 u-boot.bin; nand erase bios; nand write.jffs2 0x30000000 bios $(filesize)");
            run_command(cmd_buf, 0);
            break;
            }

            case '2':
            {
                sprintf(cmd_buf, "tftp 0x30000000 eboot.nb0; nand erase eboot; nand write.jffs2 0x30000000 eboot $(filesize)");
                run_command(cmd_buf, 0);
                break;
            }

            case '3':
            {
                strcpy(cmd_buf, "tftp 0x30000000 zImage.bin; nand erase kernel; nand write.jffs2 0x30000000 kernel $(filesize)");
                run_command(cmd_buf, 0);
                break;
            }

            case '4':
            {
                strcpy(cmd_buf, "tftp 0x30000000 stepldr.nb1; nand erase kernel; nand write.jffs2 0x30000000 kernel $(filesize)");
                run_command(cmd_buf, 0);
                break;
            }

            case '5':
            {
                char param_buf1[25];
                char param_buf2[25];
                char param_buf3[25];

                printf("Enter the TFTP Server(PC) IP address:(xxx.xxx.xxx.xxx)\n");
                readline(NULL);
                strcpy(param_buf1,console_buffer);
                sprintf(cmd_buf, "setenv serverip %s",param_buf1);
                run_command(cmd_buf, 0);

                printf("Enter the SKY2440/TQ2440 IP address:(xxx.xxx.xxx.xxx)\n");
                readline(NULL);
                strcpy(param_buf2,console_buffer);
                sprintf(cmd_buf, "setenv ipaddr %s",param_buf2);
                run_command(cmd_buf, 0);

                printf("Enter the Mask IP address:(xxx.xxx.xxx.xxx)\n");
                readline(NULL);
                strcpy(param_buf3,console_buffer);
                sprintf(cmd_buf, "setenv netmask %s",param_buf3);
                run_command(cmd_buf, 0);

                printf("Save TFTP IP parameters?(y/n)\n");
                if (getc() == 'y' )
                {
                    printf("y");
                    getc() == '\r';
                    printf("\n");
                    sprintf(cmd_buf, "saveenv");
                    run_command(cmd_buf, 0);
                }
                else
                {
                    printf("Not Save it!!!\n");
                }
                break;
            }

            case '6':
            {
                strcpy(cmd_buf, "tftp 0x30000000 root.bin; nand erase root; nand write.yaffs 0x30000000 root $(filesize)");
                run_command(cmd_buf, 0);
                break;
            }

            case '7':
            {
                char tftpaddress[12];
                char filename[32];

                printf("Enter downloads to SDRAM address:\n");
                readline(NULL);
                strcpy(tftpaddress, console_buffer);

                printf("Enter program name:\n");
                readline(NULL);
                strcpy(filename, console_buffer);

                sprintf(cmd_buf, "tftp %s %s", tftpaddress, filename);
                printf("tftp %s %s\n", tftpaddress, filename);
                run_command(cmd_buf, 0);

                sprintf(cmd_buf, "go %s", tftpaddress);
                run_command(cmd_buf, 0);
                break;
            }

            case '8':
            {
                    printf("Start Linux ...\n");
                    strcpy(cmd_buf, "boot_zImage");
                    run_command(cmd_buf, 0);
                break;
            }

            case '9':
            {
                strcpy(cmd_buf, "nand scrub ");
                run_command(cmd_buf, 0);
//                erase_menu_shell();
                break;
            }

            case 'A':
            case 'a':
            {
                char filename[32];

                printf("Enter program name:\n");
                readline(NULL);
                strcpy(filename, console_buffer);

                sprintf(cmd_buf, "tftp 0x30000000 %s; nand erase 0x0 $(filesize+1); nand write.jffs2 0x30000000 0x0 $(filesize+1)", filename);
                run_command(cmd_buf, 0);
                break;
            }

            case 'B':
            case 'b':
            {
                strcpy(cmd_buf, "tftp 0x30000000 logo.bin; nand erase logo; nand write.jffs2 0x30000000 logo $(filesize)");
                run_command(cmd_buf, 0);
                break;
            }

            case 'O':
            case 'o':
            {
                if (bBootFrmNORFlash())
                {
                    strcpy(cmd_buf, "tftp 0x30000000 uboot.bin; protect off all; erase 0 +$(filesize); cp.b 0x30000000 0 $(filesize)");
                    run_command(cmd_buf, 0);
                }
                break;
            }

            case 'P':
            case 'p':
            {
                char *serverip;
                serverip=getenv("serverip");
                printf("TQ2440 ping PC IP:ping %s\n",serverip);
                sprintf(cmd_buf, "ping %s",serverip);
                run_command(cmd_buf, 0);
                break;
            }

            case 'R':
            case 'r':
            {
                strcpy(cmd_buf, "reset");
                run_command(cmd_buf, 0);
                break;
            }
            
            case 'T':
            case 't':
            {
                strcpy(cmd_buf, "tftp 0x30008000 zImage.bin; test_zImage");
                run_command(cmd_buf, 0);
                break;
            }

            case 'Q':
            case 'q':
            {
                return;
                break;
            }
            default: ;
        }
    }

}


int do_menu (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
    tftp_menu_shell();
    return 0;
}

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"
);

#endif /* #ifdef CONFIG_CMD_MENU */

2、修改common/Makefile

COBJS    = main.o ACEX1K.o altera.o bedbug.o circbuf.o \
      cmd_ace.o cmd_autoscript.o \
           ......
            virtex2.o xilinx.o crc16.o xyzModem.o cmd_mac.o cmd_menu.o

3、修改common/main.c,调用菜单命令(menu)

    if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
# ifdef CONFIG_AUTOBOOT_KEYED
        int prev = disable_ctrlc(1);    /* disable Control C checking */
# endif

# ifndef CFG_HUSH_PARSER
        run_command (s, 0);
# else
        parse_string_outer(s, FLAG_PARSE_SEMICOLON |
                    FLAG_EXIT_FROM_LOOP);
# endif

# ifdef CONFIG_AUTOBOOT_KEYED
        disable_ctrlc(prev);    /* restore Control C checking */
# endif
    }
    
#ifdef CONFIG_CMD_MENU
    run_command("menu", 0);
#endif

4、修改include/configs/TQ2440.h

/***********************************************************
 * Command definition
 ***********************************************************/
#define CONFIG_COMMANDS \
            (CONFIG_CMD_DFL     | \
            CFG_CMD_CACHE     | \
            CFG_CMD_NAND     | \
            /*CFG_CMD_EEPROM |*/ \
            /*CFG_CMD_I2C     |*/ \
            /*CFG_CMD_USB     |*/ \
            CFG_CMD_REGINFO  | \
            CFG_CMD_DATE     | \
            CFG_CMD_REGINFO  | \
            CFG_CMD_PING     | \
            CFG_CMD_ELF)
            
#define CONFIG_CMD_MENU 1

 

参考网页:uboot中的快捷菜单的制作说明

posted on 2014-02-24 16:49  amanlikethis  阅读(1543)  评论(0编辑  收藏  举报