Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1342735
  • 博文数量: 244
  • 博客积分: 1039
  • 博客等级: 少尉
  • 技术积分: 1562
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-06 09:40
文章分类

全部博文(244)

文章存档

2021年(2)

2019年(6)

2018年(2)

2014年(1)

2013年(187)

2012年(47)

分类: 嵌入式

2013-05-12 07:56:50

习惯了了linux下的命令自动补全,换做uboot下的单个字符的输入长串命令,实在是不太习惯。常常在uboot下习惯性的按TAB键。为了习惯,下面来实现uboot的命令的自动补全。 这个功能的实现非常容易,只是在/include/configs/开发板头文件.h(我的是micro2440.h)添加一个配置宏: #define CONFIG_CMDLINE_EDITING//#ifdef CONFIG_CMDLINE_EDITING //#undef CONFIG_AUTO_COMPLETE //#else #define CONFIG_AUTO_COMPLETE //开启命令自动补全函数的编译 编译,运行,功能实现 另外还碰到了一个奇怪的问题,把我卡了很久。每次在我执行这个命令后 setenv bootcmd "nand read 31000000 0x60000 500000;bootm 31000000" 会出现uboot立即自启动内核,也就是立即执行了bootm 31000000 这个命令。 原因找了很久,最后定为在/include/configs/开发板头文件.h(我的是micro2440.h)这个文件。这个文件某个宏定义有问题或者是未定义导致这个问题的出现。是哪一个宏呢? 看uboot 源码 不难找到问题所在 文件/cmmon/main.c [cpp] view plaincopyprint? #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 就将执行红色部分代码,分析这部分代码在CFG_PROMPT>=0时执行strcpy (lastcommand, console_buffer);函数,即等待串口缓冲区得数据 ,如果有数据,将把数据复制到lastcommand这个串中,然后执行rc = run_command (lastcommand, flag);而恰恰就是run_command (lastcommand, flag);这个函数有问题,函数内把带有 ; 号的命令作为下一个命令执行了,所以出现了bootm 自启动内核的问题. 而定义 CFG_HUSH_PARSER 宏将执行parse_file_outer();函数,函数内最后调用,cmmon/hush.c 文件的int parse_stream_outer(struct in_str *inp, int flag)函数 [cpp] view plaincopyprint? do { ctx.type = flag; initialize_context(&ctx); update_ifs_map(); if (!(flag & FLAG_PARSE_SEMICOLON) || (flag & FLAG_REPARSING)) mapset((uchar *)";{1}|", 0); inp->promptmode=1; rcode = parse_stream(&temp, &ctx, inp, '\n'); #ifdef __U_BOOT__ if (rcode == 1) flag_repeat = 0; #endif if (rcode != 1 && ctx.old_flag != 0) { syntax(); #ifdef __U_BOOT__ flag_repeat = 0; #endif } if (rcode != 1 && ctx.old_flag == 0) { done_word(&temp, &ctx); done_pipe(&ctx,PIPE_SEQ); #ifndef __U_BOOT__ run_list(ctx.list_head); #else code = run_list(ctx.list_head); if (code == -2) { /* exit */ b_free(&temp); code = 0; /* XXX hackish way to not allow exit from main loop */ if (inp->peek == file_peek) { printf("exit not allowed from main input shell.\n"); continue; } break; } if (code == -1) flag_repeat = 0; #endif } else { if (ctx.old_flag != 0) { free(ctx.stack); b_reset(&temp); } #ifdef __U_BOOT__ if (inp->__promptme == 0) printf("\n"); inp->__promptme = 1; #endif temp.nonnull = 0; temp.quote = 0; inp->p = NULL; free_pipe_list(ctx.list_head,0); } b_free(&temp); } while (rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP)); 会发现条件rcode != -1 && !(flag & FLAG_EXIT_FROM_LOOP)是一直满足的,就进入了另一个命令提示输入循环,这个循环避免上面那个现象。 代码没看的太仔细,分析的可能还存在问题,希望遇到同样问题的朋友如果发现分析错误能够多多指正。
阅读(1165) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~