Chinaunix首页 | 论坛 | 博客
  • 博客访问: 465411
  • 博文数量: 100
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 955
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-21 09:30
文章分类

全部博文(100)

文章存档

2017年(1)

2016年(16)

2015年(83)

我的朋友

分类: 嵌入式

2015-07-14 15:30:12


点击(此处)折叠或打开

  1. void main_loop(void)
  2. {
  3. #ifndef CONFIG_SYS_HUSH_PARSER
  4.     static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, };
  5.     int len;
  6.     int rc = 1;
  7.     int flag;
  8. #endif
  9. #ifdef CONFIG_PREBOOT
  10.     char *p;
  11. #endif

  12.     bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");

  13. #ifdef CONFIG_MODEM_SUPPORT
  14.     debug("DEBUG: main_loop: do_mdm_init=%d\n", do_mdm_init);
  15.     if (do_mdm_init) {
  16.         char *str = strdup(getenv("mdm_cmd"));
  17.         setenv("preboot", str); /* set or delete definition */
  18.         if (str != NULL)
  19.             free(str);
  20.         mdm_init(); /* wait for modem connection */
  21.     }
  22. #endif /* CONFIG_MODEM_SUPPORT */

  23. #ifdef CONFIG_VERSION_VARIABLE
  24.     {
  25.         setenv("ver", version_string); /* set version variable */
  26.     }
  27. #endif /* CONFIG_VERSION_VARIABLE */

  28. #ifdef CONFIG_SYS_HUSH_PARSER
  29.     u_boot_hush_start();
  30. #endif

  31. #if defined(CONFIG_HUSH_INIT_VAR)
  32.     hush_init_var();
  33. #endif

  34. #ifdef CONFIG_PREBOOT
  35.     p = getenv("preboot");
  36.     if (p != NULL) {
  37. # ifdef CONFIG_AUTOBOOT_KEYED
  38.         int prev = disable_ctrlc(1);    /* disable Control C checking */
  39. # endif

  40.         run_command_list(p, -1, 0);

  41. # ifdef CONFIG_AUTOBOOT_KEYED
  42.         disable_ctrlc(prev);    /* restore Control C checking */
  43. # endif
  44.     }
  45. #endif /* CONFIG_PREBOOT */

  46. #if defined(CONFIG_UPDATE_TFTP)
  47.     update_tftp(0UL);
  48. #endif /* CONFIG_UPDATE_TFTP */

  49. #ifdef CONFIG_BOOTDELAY
  50.     process_boot_delay();
  51. #endif
  52.     /*
  53.      * Main Loop for Monitor Command Processing
  54.      */
  55. #ifdef CONFIG_SYS_HUSH_PARSER
  56.     parse_file_outer();
  57.     /* This point is never reached */
  58.     for (;;);
  59. #else
  60.     for (;;) {
  61. #ifdef CONFIG_BOOT_RETRY_TIME
  62.         if (rc >= 0) {
  63.             /* Saw enough of a valid command to
  64.              * restart the timeout.
  65.              */
  66.             reset_cmd_timeout();
  67.         }
  68. #endif
  69.         len = readline (CONFIG_SYS_PROMPT);//打印提示符,例如SMDKV210#,之后开始从终端读取(接收)一行字符

  70.         flag = 0;    /* assume no special flags for now */
  71.         if (len > 0)
  72.             strcpy (lastcommand, console_buffer);
  73.         else if (len == 0)
  74.             flag |= CMD_FLAG_REPEAT;
  75. #ifdef CONFIG_BOOT_RETRY_TIME
  76.         else if (len == -2) {
  77.             /* -2 means timed out, retry autoboot
  78.              */
  79.             puts ("\nTimed out waiting for command\n");
  80. # ifdef CONFIG_RESET_TO_RETRY
  81.             /* Reinit board to run initialization code again */
  82.             do_reset (NULL, 0, 0, NULL);
  83. # else
  84.             return;        /* retry autoboot */
  85. # endif
  86.         }
  87. #endif

  88.         if (len == -1)
  89.             puts ("<INTERRUPT>\n");
  90.         else
  91.             rc = run_command(lastcommand, flag);

  92.         if (rc <= 0) {
  93.             /* invalid command or not repeatable, forget it */
  94.             lastcommand[0] = 0;
  95.         }
  96.     }
  97. #endif /*CONFIG_SYS_HUSH_PARSER*/
  98. }

  99. /*提示输入,读一行字符,存放到console_buffer字符数组
  100.  * Prompt for input and read a line.
  101.  * If CONFIG_BOOT_RETRY_TIME is defined and retry_time >= 0,
  102.  * time out when time goes past endtime (timebase time in ticks).
  103.  * Return:    number of read characters
  104.  *        -1 if break
  105.  *        -2 if timed out
  106.  */
  107. int readline (const char *const prompt)
  108. {
  109.     /*
  110.      * If console_buffer isn't 0-length the user will be prompted to modify
  111.      * it instead of entering it from scratch as desired.
  112.      */
  113.     console_buffer[0] = '\0';

  114.     return readline_into_buffer(prompt, console_buffer, 0);
  115. }
  116. /*提示输入,读一行字符,可设定超时功能,Ctrl+C中断
  117.  * Prompt for input and read a line.
  118.  * If CONFIG_BOOT_RETRY_TIME is defined and retry_time >= 0,
  119.  */

  120. int readline_into_buffer(const char *const prompt, char *buffer, int timeout)
  121. {
  122.     char *p = buffer;//缓冲区读写指针,缓冲区不包括提示符,而是从提示符之后开始编辑
  123.     
  124.     //如果有历史功能
  125. #ifdef CONFIG_CMDLINE_EDITING
  126.     unsigned int len = CONFIG_SYS_CBSIZE;
  127.     int rc;
  128.     static int initted = 0;

  129.     /*
  130.      * History uses a global array which is not
  131.      * writable until after relocation to RAM.
  132.      * Revert to non-history version if still
  133.      * running from flash.
  134.      */
  135.     if (gd->flags & GD_FLG_RELOC) {
  136.         if (!initted) {
  137.             hist_init();
  138.             initted = 1;
  139.         }

  140.         if (prompt)
  141.             puts (prompt);

  142.         rc = cread_line(prompt, p, &len, timeout);
  143.         return rc < 0 ? rc : len;

  144.     } else {
  145. #endif    /* CONFIG_CMDLINE_EDITING */
  146.     //如果没有历史编辑功能,从这里开始执行
  147.     char * p_buf = p;        //缓冲区首字符指针,即指向console_buffer[0]首字符,
  148.     int    n = 0;                /* buffer index        */ //缓冲区当前编辑位置
  149.     int    plen = 0;            /* prompt length    */    //提示符长度
  150.     int    col;                /* output column cnt    */ //列计数,包含提示符
  151.     char    c;

  152.     /* print prompt */
  153.     if (prompt) {
  154.         plen = strlen (prompt);//如果有提示符,则计算提示符长度
  155.         puts (prompt);            //打印提示符
  156.     }
  157.     col = plen;//列数初始化
  158. /*
  159.     n = plen;    //add by richad
  160.     plen = 0;     // To edit promt, plen should be 0, add by richard
  161.     p += n;        //Move pointer to the back of prompt, add by richard
  162. */

  163.     for (;;) {

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

  165.         c = getc();//输入一个字符

  166.         /*
  167.          * Special character handling
  168.          */
  169.         switch (c) {
  170.         case '\r':            /* Enter        */
  171.         case '\n':
  172.             *p = '\0';
  173.             puts ("\r\n");
  174.             return p - p_buf;

  175.         case '\0':            /* nul            */
  176.             continue;

  177.         case 0x03:            /* ^C - break        */
  178.             p_buf[0] = '\0';    /* discard input */ //console_buffer首字符清零,放弃输入
  179.             return -1;

  180.         case 0x15:            /* ^U - erase line    */    //NAK,清除一行字符,光标回到起点(不是本行起点,前面还有提示符)
  181.             while (col > plen) {//删除至提示符
  182.                 puts (erase_seq);//打印退格符,屏幕上的光标会左移
  183.                 --col;//列长度 - 1
  184.             }
  185.             p = p_buf;//指针复位,回到缓冲区起点
  186.             n = 0;
  187.             continue;

  188.         case 0x17:            /* ^W - erase word    */
  189.             p=delete_char(p_buf, p, &col, &n, plen);
  190.             while ((n > 0) && (*p != ' ')) {
  191.                 p=delete_char(p_buf, p, &col, &n, plen);
  192.             }
  193.             continue;

  194.         case 0x08:            /* ^H - backspace    */
  195.         case 0x7F:            /* DEL - backspace    */
  196.             p=delete_char(p_buf, p, &col, &n, plen);
  197.             continue;

  198.         default:
  199.             /*
  200.              * Must be a normal character then
  201.              */
  202.             if (n < CONFIG_SYS_CBSIZE-2) {
  203.                 if (c == '\t') {    /* expand TABs */
  204. #ifdef CONFIG_AUTO_COMPLETE
  205.                     /* if auto completion triggered just continue */
  206.                     *p = '\0';
  207.                     if (cmd_auto_complete(prompt, console_buffer, &n, &col)) {
  208.                         p = p_buf + n;    /* reset */
  209.                         continue;
  210.                     }
  211. #endif
  212.                     puts (tab_seq+(col&07));
  213.                     col += 8 - (col&07);
  214.                 } else {
  215.                     char buf[2];

  216.                     /*
  217.                      * Echo input using puts() to force an
  218.                      * LCD flush if we are using an LCD
  219.                      */
  220.                     ++col;
  221.                     buf[0] = c;
  222.                     buf[1] = '\0';
  223.                     puts(buf);
  224.                 }
  225.                 *p++ = c;
  226.                 ++n;
  227.             } else {            /* Buffer full        */
  228.                 putc ('\a');
  229.             }
  230.         }
  231.     }
  232. #ifdef CONFIG_CMDLINE_EDITING
  233.     }
  234. #endif
  235. }

  236. /* 删除一个字符,
  237.  * *buffer    : 缓冲区起点指针
  238.  * *p        : 移动指针
  239.  * *colp    : 当前列计数, 计入prompt,如果prompt为空,colp = 0。colp等于屏幕列坐标
  240.  * *np        : 缓冲区字符计数,为了检查输入字符是否超出上限(512字节)
  241.  *    plen    : 命令行提示符长度,修改colp时检查colp是否<plen,防止提示符被误删
  242.  */
  243.  
  244.  p=delete_char(p_buf, p, &col, &n, plen);
  245.  
  246. static char * delete_char (char *buffer, char *p, int *colp, int *np, int plen)
  247. {
  248.     char *s;

  249.     if (*np == 0) {//如果缓冲区没有字符,退出
  250.         return (p);
  251.     }

  252.     if (*(--p) == '\t') {            /* will retype the whole line    */
  253.         while (*colp > plen) {
  254.             puts (erase_seq);
  255.             (*colp)--;
  256.         }
  257.         for (s=buffer; s<p; ++s) {
  258.             if (*s == '\t') {
  259.                 puts (tab_seq+((*colp) & 07));
  260.                 *colp += 8 - ((*colp) & 07);
  261.             } else {
  262.                 ++(*colp);
  263.                 putc (*s);
  264.             }
  265.         }
  266.     } else {
  267.         puts (erase_seq);
  268.         (*colp)--;
  269.     }
  270.     (*np)--;缓冲区计数-1
  271.     return (p);
  272. }


  273. ////////////////////////////////////////////////////////////
  274. //    rc = cread_line(prompt, p, &len, timeout);//读一行字符到缓冲区p, uint len = CONFIG_SYS_CBSIZE;

  275. /* cread_line: 控制台读一行字符,带历史、编辑功能,
  276.  * *const promt    : 指向提示符的指针,只读
  277.  * *buf        : 缓冲区指针
  278.  * *len        : 控制台字符长度
  279.  */

  280. static int cread_line(const char *const prompt, char *buf, unsigned int *len,
  281.         int timeout)
  282. {
  283.     unsigned long num = 0;
  284.     unsigned long eol_num = 0;//行末计数
  285.     unsigned long wlen;
  286.     char ichar;
  287.     int insert = 1;
  288.     int esc_len = 0;
  289.     char esc_save[8];
  290.     int init_len = strlen(buf);//console_buffer字符长度
  291.     int first = 1;
  292.     
  293.     if (init_len)//如果console_buffer有字符串,打印其中的字符串并调整*len为总长度,初始值为CONFIG_SYS_CBSIZE = 512,
  294.     //目的是为了调整num和eol_num
  295.         cread_add_str(buf, init_len, 1, &num, &eol_num, buf, *len);//增加(打印)字符串buf到控制台缓冲区,并重新调整num和eol_num

  296.     while (1) {

  297.         ichar = getcmd_getch();//等待用户输入一个字符ichar

  298.         if ((ichar == '\n') || (ichar == '\r')) {
  299.             putc('\n');
  300.             break;
  301.         }

  302.         /*
  303.          * handle standard linux xterm esc sequences for arrow key, etc.
  304.          */
  305.         if (esc_len != 0) {
  306.             if (esc_len == 1) {
  307.                 if (ichar == '[') {
  308.                     esc_save[esc_len] = ichar;
  309.                     esc_len = 2;
  310.                 } else {
  311.                     cread_add_str(esc_save, esc_len, insert,
  312.                          &num, &eol_num, buf, *len);
  313.                     esc_len = 0;
  314.                 }
  315.                 continue;
  316.             }

  317.             switch (ichar) {

  318.             case 'D':    /* <- key */
  319.                 ichar = CTL_CH('b');
  320.                 esc_len = 0;
  321.                 break;
  322.             case 'C':    /* -> key */
  323.                 ichar = CTL_CH('f');
  324.                 esc_len = 0;
  325.                 break;    /* pass off to ^F handler */
  326.             case 'H':    /* Home key */
  327.                 ichar = CTL_CH('a');
  328.                 esc_len = 0;
  329.                 break;    /* pass off to ^A handler */
  330.             case 'A':    /* up arrow */
  331.                 ichar = CTL_CH('p');
  332.                 esc_len = 0;
  333.                 break;    /* pass off to ^P handler */
  334.             case 'B':    /* down arrow */
  335.                 ichar = CTL_CH('n');
  336.                 esc_len = 0;
  337.                 break;    /* pass off to ^N handler */
  338.             default:
  339.                 esc_save[esc_len++] = ichar;
  340.                 cread_add_str(esc_save, esc_len, insert,
  341.                      &num, &eol_num, buf, *len);
  342.                 esc_len = 0;
  343.                 continue;
  344.             }
  345.         }

  346.         switch (ichar) {
  347.         case 0x1b:
  348.             if (esc_len == 0) {
  349.                 esc_save[esc_len] = ichar;
  350.                 esc_len = 1;
  351.             } else {
  352.                 puts("impossible condition #876\n");
  353.                 esc_len = 0;
  354.             }
  355.             break;

  356.         case CTL_CH('a'):
  357.             BEGINNING_OF_LINE();
  358.             break;
  359.         case CTL_CH('c'):    /* ^C - break */
  360.             *buf = '\0';    /* discard input */
  361.             return (-1);
  362.         case CTL_CH('f'):
  363.             if (num < eol_num) {
  364.                 getcmd_putch(buf[num]);
  365.                 num++;
  366.             }
  367.             break;
  368.         case CTL_CH('b'):
  369.             if (num) {
  370.                 getcmd_putch(CTL_BACKSPACE);
  371.                 num--;
  372.             }
  373.             break;
  374.         case CTL_CH('d'):
  375.             if (num < eol_num) {
  376.                 wlen = eol_num - num - 1;
  377.                 if (wlen) {
  378.                     memmove(&buf[num], &buf[num+1], wlen);
  379.                     putnstr(buf + num, wlen);
  380.                 }

  381.                 getcmd_putch(' ');
  382.                 do {
  383.                     getcmd_putch(CTL_BACKSPACE);
  384.                 } while (wlen--);
  385.                 eol_num--;
  386.             }
  387.             break;
  388.         case CTL_CH('k'):
  389.             ERASE_TO_EOL();
  390.             break;
  391.         case CTL_CH('e'):
  392.             REFRESH_TO_EOL();
  393.             break;
  394.         case CTL_CH('o'):
  395.             insert = !insert;
  396.             break;
  397.         case CTL_CH('x'):
  398.         case CTL_CH('u'):
  399.             BEGINNING_OF_LINE();
  400.             ERASE_TO_EOL();
  401.             break;
  402.         case DEL:
  403.         case DEL7:
  404.         case 8:
  405.             if (num) {
  406.                 wlen = eol_num - num;
  407.                 num--;
  408.                 memmove(&buf[num], &buf[num+1], wlen);
  409.                 getcmd_putch(CTL_BACKSPACE);
  410.                 putnstr(buf + num, wlen);
  411.                 getcmd_putch(' ');
  412.                 do {
  413.                     getcmd_putch(CTL_BACKSPACE);
  414.                 } while (wlen--);
  415.                 eol_num--;
  416.             }
  417.             break;
  418.         case CTL_CH('p'):
  419.         case CTL_CH('n'):
  420.         {
  421.             char * hline;

  422.             esc_len = 0;

  423.             if (ichar == CTL_CH('p'))
  424.                 hline = hist_prev();
  425.             else
  426.                 hline = hist_next();

  427.             if (!hline) {
  428.                 getcmd_cbeep();
  429.                 continue;
  430.             }

  431.             /* nuke the current line */
  432.             /* first, go home */
  433.             BEGINNING_OF_LINE();

  434.             /* erase to end of line */
  435.             ERASE_TO_EOL();

  436.             /* copy new line into place and display */
  437.             strcpy(buf, hline);
  438.             eol_num = strlen(buf);
  439.             REFRESH_TO_EOL();
  440.             continue;
  441.         }
  442. #ifdef CONFIG_AUTO_COMPLETE
  443.         case '\t': {
  444.             int num2, col;

  445.             /* do not autocomplete when in the middle */
  446.             if (num < eol_num) {
  447.                 getcmd_cbeep();
  448.                 break;
  449.             }

  450.             buf[num] = '\0';
  451.             col = strlen(prompt) + eol_num;
  452.             num2 = num;
  453.             if (cmd_auto_complete(prompt, buf, &num2, &col)) {
  454.                 col = num2 - num;
  455.                 num += col;
  456.                 eol_num += col;
  457.             }
  458.             break;
  459.         }
  460. #endif
  461.         default:
  462.             cread_add_char(ichar, insert, &num, &eol_num, buf, *len);
  463.             break;
  464.         }
  465.     }
  466.     *len = eol_num;
  467.     buf[eol_num] = '\0';    /* lose the newline */

  468.     if (buf[0] && buf[0] != CREAD_HIST_CHAR)
  469.         cread_add_to_hist(buf);
  470.     hist_cur = hist_add_idx;

  471.     return 0;
  472. }

  473. //在当前光标位置增加(打印)字符串*str,调整num、eol_num,和缓冲buf内容
  474. static void cread_add_str(char *str, int strsize, int insert, unsigned long *num,
  475.      unsigned long *eol_num, char *buf, unsigned long len)
  476. {
  477.     while (strsize--) {
  478.         cread_add_char(*str, insert, num, eol_num, buf, len);
  479.         str++;
  480.     }
  481. }

  482. //在当前光标位置增加(打印)一个字符,调整num、eol_num,和缓冲buf内容
  483. static void cread_add_char(char ichar, int insert, unsigned long *num,
  484.      unsigned long *eol_num, char *buf, unsigned long len)
  485. {
  486.     unsigned long wlen;//字长

  487.     /* room ??? */
  488.     if (insert || *num == *eol_num) {
  489.         if (*eol_num > len - 1) {
  490.             getcmd_cbeep();//超出512个字节,报警并返回
  491.             return;
  492.         }
  493.         (*eol_num)++;// 末尾长度+1
  494.     }

  495.     if (insert) {//以插入方式增加字符
  496.         wlen = *eol_num - *num;// 1 - 0
  497.         if (wlen > 1) {
  498.             memmove(&buf[*num+1], &buf[*num], wlen-1);//以可重叠方式将num位置开始的全部内容向右挪动一个字符,被挪动的字符数为wlen-1即eol_num - num
  499.         }

  500.         buf[*num] = ichar;//
  501.         putnstr(buf + *num, wlen);//回显
  502.         (*num)++;
  503.         while (--wlen) {
  504.             getcmd_putch(CTL_BACKSPACE);
  505.         }
  506.     } else {//非插入方式,直接覆盖字符,并回显
  507.         /* echo the character */
  508.         wlen = 1;
  509.         buf[*num] = ichar;
  510.         putnstr(buf + *num, wlen);
  511.         (*num)++;
  512.     }
  513. }


阅读(1995) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~