Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1854911
  • 博文数量: 473
  • 博客积分: 13997
  • 博客等级: 上将
  • 技术积分: 5953
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-22 11:52
文章分类

全部博文(473)

文章存档

2014年(8)

2013年(38)

2012年(95)

2011年(181)

2010年(151)

分类: LINUX

2012-02-11 12:12:08

接下来我们主要分析main_loop()

common/main.c:

void main_loop (void)

{

#ifndef CFG_HUSH_PARSER

    static char lastcommand[CFG_CBSIZE] = { 0, };

    int len;

    int rc = 1;

    int flag;

#endif

 

#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)

    char *s;

    int bootdelay;

#endif

#ifdef CONFIG_PREBOOT

    char *p;

#endif

#ifdef CONFIG_BOOTCOUNT_LIMIT

    unsigned long bootcount = 0;

    unsigned long bootlimit = 0;

    char *bcs;

    char bcs_set[16];

#endif /* CONFIG_BOOTCOUNT_LIMIT */

 

#if defined(CONFIG_VFD) && defined(VFD_TEST_LOGO)   /*smdk2410没定义*/

    ulong bmp = 0;     /* default bitmap */

    extern int trab_vfd (ulong bitmap);

 

#ifdef CONFIG_MODEM_SUPPORT

    if (do_mdm_init)

        bmp = 1;    /* alternate bitmap */

#endif

    trab_vfd (bmp);

#endif  /* CONFIG_VFD && VFD_TEST_LOGO */

 

#ifdef CONFIG_BOOTCOUNT_LIMIT   /*smdk2410没定义*/

    bootcount = bootcount_load();

    bootcount++;

    bootcount_store (bootcount);

    sprintf (bcs_set, "%lu", bootcount);

    setenv ("bootcount", bcs_set);

    bcs = getenv ("bootlimit");

    bootlimit = bcs ? simple_strtoul (bcs, NULL, 10) : 0;

#endif /* CONFIG_BOOTCOUNT_LIMIT */

 

#ifdef CONFIG_MODEM_SUPPORT /*smdk2410没定义*/

    debug ("DEBUG: main_loop:   do_mdm_init=%d/n", do_mdm_init);

    if (do_mdm_init) {

        uchar *str = strdup(getenv("mdm_cmd"));

        setenv ("preboot", str);  /* set or delete definition */

        if (str != NULL)

            free (str);

        mdm_init(); /* wait for modem connection */

    }

#endif  /* CONFIG_MODEM_SUPPORT */

 

#ifdef CONFIG_VERSION_VARIABLE /*smdk2410没定义*/

    {

        extern char version_string[];

 

        setenv ("ver", version_string);  /* set version variable */

    }

#endif /* CONFIG_VERSION_VARIABLE */

 

#ifdef CFG_HUSH_PARSER /*smdk2410没定义*/

    u_boot_hush_start ();

#endif

 

#ifdef CONFIG_AUTO_COMPLETE /*smdk2410没定义*/

    install_auto_complete();

#endif

 

#ifdef CONFIG_PREBOOT /*smdk2410没定义*/

    if ((p = getenv ("preboot")) != NULL) {

# ifdef CONFIG_AUTOBOOT_KEYED /*smdk2410没定义*/

        int prev = disable_ctrlc(1);   /* disable Control C checking */

# endif

 

# ifndef CFG_HUSH_PARSER /*smdk2410没定义*/

        run_command (p, 0);

# else

        parse_string_outer(p, FLAG_PARSE_SEMICOLON |

                    FLAG_EXIT_FROM_LOOP);

# endif

 

# ifdef CONFIG_AUTOBOOT_KEYED /*smdk2410没定义*/

        disable_ctrlc(prev);   /* restore Control C checking */

# endif

    }

#endif /* CONFIG_PREBOOT */

 

/**/

#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)

    s = getenv ("bootdelay");

    bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;

 

    debug ("### main_loop entered: bootdelay=%d/n/n", bootdelay);

 

# ifdef CONFIG_BOOT_RETRY_TIME

    init_cmd_timeout ();

# endif /* CONFIG_BOOT_RETRY_TIME */

 

#ifdef CONFIG_BOOTCOUNT_LIMIT

    if (bootlimit && (bootcount > bootlimit)) {

        printf ("Warning: Bootlimit (%u) exceeded. Using altbootcmd./n",

                (unsigned)bootlimit);

        s = getenv ("altbootcmd");

    }

    else

#endif /* CONFIG_BOOTCOUNT_LIMIT */

        s = getenv ("bootcmd");  /*smdk2410下这个环境变量是空的*/

 

    debug ("### main_loop: bootcmd=/"%s/"/n", s ? s : "");

 

    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_MENUKEY

    if (menukey == CONFIG_MENUKEY) {

        s = getenv("menucmd");

        if (s) {

# ifndef CFG_HUSH_PARSER

        run_command (s, 0);

# else

        parse_string_outer(s, FLAG_PARSE_SEMICOLON |

                    FLAG_EXIT_FROM_LOOP);

# endif

        }

    }

#endif /* CONFIG_MENUKEY */

#endif  /* CONFIG_BOOTDELAY */

 

#ifdef CONFIG_AMIGAONEG3SE

    {

        extern void video_banner(void);

        video_banner();

    }

#endif

 

    /*

     * Main Loop for Monitor Command Processing

     */

     /*

      * 最核心的就是下面这个死循环了

      */

#ifdef CFG_HUSH_PARSER

    parse_file_outer();

    /* This point is never reached */

    for (;;);

#else

    for (;;) {

#ifdef CONFIG_BOOT_RETRY_TIME

        if (rc >= 0) {

            /* Saw enough of a valid command to

             * restart the timeout.

             */

            reset_cmd_timeout();

        }

#endif

        len = readline (CFG_PROMPT);

 

        flag = 0;   /* assume no special flags for now */

        if (len > 0)

            strcpy (lastcommand, console_buffer);

        else if (len == 0)

            flag |= CMD_FLAG_REPEAT;

#ifdef CONFIG_BOOT_RETRY_TIME

        else if (len == -2) {

            /* -2 means timed out, retry autoboot

             */

            puts ("/nTimed out waiting for command/n");

# ifdef CONFIG_RESET_TO_RETRY

            /* Reinit board to run initialization code again */

            do_reset (NULL, 0, 0, NULL);

# else

            return;     /* retry autoboot */

# endif

        }

#endif

 

        if (len == -1)

            puts ("/n");

        else

            rc = run_command (lastcommand, flag);

 

        if (rc <= 0) {

            /* invalid command or not repeatable, forget it */

            lastcommand[0] = 0;

        }

    }

#endif /*CFG_HUSH_PARSER*/

}

该函数比较长,但核心就是不停的从串口获取命令并解析执行此命令, 这个功能就在函数尾部的那个死循环里, 我们重点就是分析这个循环。

 

先看readline()

common/main.c:

/****************************************************************************/

/*

 * Prompt for input and read a line.

 * If  CONFIG_BOOT_RETRY_TIME is defined and retry_time >= 0,

 * time out when time goes past endtime (timebase time in ticks).

 * Return:  number of read characters

 *      -1 if break

 *      -2 if timed out

 * 上面的注释说的很清楚了,就是提示用户输入命令,并读取这个命令

*/

int readline (const char *const prompt)

{

    char   *p = console_buffer;   /* console_buffer 是个全局变量*/

    int n = 0;             /* buffer index    */

    int plen = 0;          /* prompt length   */

    int col;               /* output column cnt   */

    char    c;

 

    /* print prompt */

    if (prompt) { /*如果要输出提示符,则输出*/

        plen = strlen (prompt);

        puts (prompt);  //前面分析过了

    }

    col = plen;

 

    for (;;) {

#ifdef CONFIG_BOOT_RETRY_TIME  /*sdmk2410没定义*/

        while (!tstc()) {  /* while no incoming data */

            if (retry_time >= 0 && get_ticks() > endtime)

                return (-2);    /* timed out */

        }

#endif

        WATCHDOG_RESET();      /* Trigger watchdog, if needed */

 

#ifdef CONFIG_SHOW_ACTIVITY /*sdmk2410没定义*/

        while (!tstc()) {

            extern void show_activity(int arg);

            show_activity(0);

        }

#endif

        c = getc();  /*从串口获取用户输入的命令*/

 

        /*

         * Special character handling

         */

        /*下面这个switch就是处理不同的字符了*/

        switch (c) {

        case '/r':             /* Enter        */

        case '/n':

            *p = '/0';

            puts ("/r/n");

            return (p - console_buffer);  /*输入结束*/

 

        case '/0':             /* nul          */  /*忽略,继续*/

            continue;

 

        case 0x03:             /* ^C - break*//*呵呵,linux下的ctrl+c功能*/

            console_buffer[0] = '/0';  /* discard input */

            return (-1);

 

        case 0x15:             /* ^U - erase line */ /*删除*/

            while (col > plen) {

                puts (erase_seq);

                --col;

            }

            p = console_buffer;

            n = 0;

            continue;

 

        case 0x17:             /* ^W - erase word *//*删除*/

            p=delete_char(console_buffer, p, &col, &n, plen);

            while ((n > 0) && (*p != ' ')) {

                p=delete_char(console_buffer, p, &col, &n, plen);

            }

            continue;

 

        case 0x08:             /* ^H  - backspace */

        case 0x7F:             /* DEL - backspace */

            p=delete_char(console_buffer, p, &col, &n, plen);/*删除*/

            continue;

 

        default:   /*获取常规字符*/

            /*

             * Must be a normal character then

             */

            if (n < CFG_CBSIZE-2) {

                if (c == '/t') {   /* expand TABs     */

#ifdef CONFIG_AUTO_COMPLETE

                   /* if auto completion triggered just continue */

                    /*自动补全功能,熟悉linux的肯定知道*/

                   *p = '/0';

                   if (cmd_auto_complete(prompt, console_buffer, &n, &col)) {

                       p = console_buffer + n; /* reset */

                       continue;

                   }

#endif

                   puts (tab_seq+(col&07));

                   col += 8 - (col&07);

                } else {

                    ++col;      /* echo input      */

                   putc (c);

                }

                *p++ = c;/*把字符保存在buffer*/

                ++n;

            } else {           /* Buffer full     */

                putc ('/a');

            }

        }

    }

}

上面这个函数就是提示用户输入,然后一直等待用户输入,指到用户输入完成, 然后获取用户数据,并存入全局变量console_buffer中。

 

再来回顾下那个for循环

common/main.c:

void main_loop (void)

{

……

#ifdef CFG_HUSH_PARSER

    parse_file_outer();

    /* This point is never reached */

    for (;;);

#else

    for (;;) {

#ifdef CONFIG_BOOT_RETRY_TIME

        if (rc >= 0) {

            /* Saw enough of a valid command to

             * restart the timeout.

             */

            reset_cmd_timeout();

        }

#endif

        len = readline (CFG_PROMPT); /*获取用户下的command*/

 

        flag = 0;   /* assume no special flags for now */

        if (len > 0)

            strcpy (lastcommand, console_buffer);  /*command存入lastcommand*/

        else if (len == 0)

            flag |= CMD_FLAG_REPEAT;

#ifdef CONFIG_BOOT_RETRY_TIME

        else if (len == -2) {

            /* -2 means timed out, retry autoboot

             */

            puts ("/nTimed out waiting for command/n");

# ifdef CONFIG_RESET_TO_RETRY

            /* Reinit board to run initialization code again */

            do_reset (NULL, 0, 0, NULL);

# else

            return;     /* retry autoboot */

# endif

        }

#endif

 

        if (len == -1)

            puts ("/n");

        else

            rc = run_command (lastcommand, flag); /*执行command*/

 

        if (rc <= 0) {

            /* invalid command or not repeatable, forget it */

            lastcommand[0] = 0;

        }

    }

#endif /*CFG_HUSH_PARSER*/

}

OK!核心中的核心就是run_command函数了,一猜就知道是用户执行所有用户下达命令的函数。Let’s go
阅读(1756) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~