浅析redboot如何格式化serial输入和script脚本是怎么被读出来的.docx

上传人:b****8 文档编号:10655430 上传时间:2023-02-22 格式:DOCX 页数:18 大小:19.47KB
下载 相关 举报
浅析redboot如何格式化serial输入和script脚本是怎么被读出来的.docx_第1页
第1页 / 共18页
浅析redboot如何格式化serial输入和script脚本是怎么被读出来的.docx_第2页
第2页 / 共18页
浅析redboot如何格式化serial输入和script脚本是怎么被读出来的.docx_第3页
第3页 / 共18页
浅析redboot如何格式化serial输入和script脚本是怎么被读出来的.docx_第4页
第4页 / 共18页
浅析redboot如何格式化serial输入和script脚本是怎么被读出来的.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

浅析redboot如何格式化serial输入和script脚本是怎么被读出来的.docx

《浅析redboot如何格式化serial输入和script脚本是怎么被读出来的.docx》由会员分享,可在线阅读,更多相关《浅析redboot如何格式化serial输入和script脚本是怎么被读出来的.docx(18页珍藏版)》请在冰豆网上搜索。

浅析redboot如何格式化serial输入和script脚本是怎么被读出来的.docx

浅析redboot如何格式化serial输入和script脚本是怎么被读出来的

浅析redboot如何格式化serial输入和script脚本是怎么被读出来的

浅析redboot如何格式化serial输入和script脚本是怎么被读出来的

 redboot的交互过程类似于linux中的shell,redboot中设计的交互快捷键,i

完全参照了linux下terminal中的快捷键:

       ctrl+a将光标移动到输入的所有数据的开头

       ctrl+e将光标移动到输入的所有数据的末尾

       ctrl+b将光标向后移动

       ctrl+f将光标向前移动

       ctrl+d删除光标所在字符

       ctrl+k将光标之后的所有内容删除掉

       还有一个快捷键redboot没有实现,即:

ctrl+u,它是将光标之前的所有数据清除

       ctrl+p查询前一个历史命令

       ctrl+n查询下一个历史命令

来看看源码实现:

void

cyg_start(void)

{

   ......

   staticcharline[CYGPKG_REDBOOT_MAX_CMD_LINE];

   ......

   unsignedchar*hold_script=script;

   script=(unsignedchar*)0;//下面的_rb_gets()函数将因为script为0,而跳过读取script操作[luther.gliethttp]

   res=_rb_gets(line,sizeof(line),CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);

   if(res==_GETS_CTRLC){//如果用户从serial串口输入了ctrl+c组合

       script=(unsignedchar*)0; //Disablescript

   }else{

       script=hold_script; //Re-enablescript,这样再次执行_rb_gets()时,就会读取script脚本,然后执行它了

   }

   ......

}

int

_rb_gets(char*buf,intbuflen,inttimeout)

{

   *buf='\0'; //Emptybuffer

   return_rb_gets_preloaded(buf,buflen,timeout);

}

//如下对_rb_gets_preloaded返回值含义进行了描述

//Readalineofinputfromtheuser

//Return:

//       _GETS_OK:

'n'validcharactersreceived

//      _GETS_GDB:

'$'(GDBlead-in)

//  _GETS_TIMEOUT:

Noinputbeforetimeout

//    _GETS_CTRLC:

^Ctyped

//

int

_rb_gets_preloaded(char*buf,intbuflen,inttimeout)

{

   char*ip=buf;  //Insertionpoint

   char*eol=buf; //Endofline

   charc;

   boolres=false;

   staticcharlast_ch='\0';

   int_timeout;

#ifCYGNUM_REDBOOT_CMD_LINE_EDITING!

=0//我们定义该值为16

//

//Commandlinehistorysupport

//   ^P-Selectpreviouslinefromhistory

//   ^N-Selectnextlinefromhistory

//   ^A-Moveinsertion[cursor]tostartofline

//   ^E-Movecursortoendofline

//   ^B-Movecursorback[previouscharacter]

//   ^F-Movecursorforward[nextcharacter]

//

//我们定义CYGNUM_REDBOOT_CMD_LINE_EDITING该值为16

#define_CL_NUM_LINESCYGNUM_REDBOOT_CMD_LINE_EDITING      //Numberoflinestokeep

   //保持16行数据,类似history

   //CYGPKG_REDBOOT_MAX_CMD_LINE我们定义为256字节

   staticchar_cl_lines[_CL_NUM_LINES][CYGPKG_REDBOOT_MAX_CMD_LINE];

   //循环缓冲区指针

   staticint _cl_index=-1;     //Lastknowncommandline

   staticint _cl_max_index=-1; //Lastcommandinbuffers

   int_index=_cl_index; //Lastsavedline

   char*xp;

#endif

   //Displaycurrentbufferdata

   while(*eol){

       //先drain空buf中的内容,如果有的话

       mon_write_char(*eol++);

   }

   ip=eol;//insertpoint插入点指针

   while(true){

#ifdefCYGFUN_REDBOOT_BOOT_SCRIPT

       //我们定义了该宏

       if(getc_script(&c))//从script脚本中读取一个字节数据,同时script++,源码见后

           do_idle(false);//执行定义的idle函数,源码见后

       else

#endif

       if((timeout>0)&&(eol==buf)){//所以如果我们只是输入了几个字符串在minicom中,而并不按回车,那么程序将

       //永远停留在下面的mon_read_char(&c);上

#defineMIN_TIMEOUT50

           _timeout=timeout>MIN_TIMEOUT?

MIN_TIMEOUT:

timeout;

           mon_set_read_char_timeout(_timeout);

           while(timeout>0){

               //最大超时_timeout,等待serial串口数据到来

               res=mon_read_char_with_timeout(&c);

               if(res){

                   //Gotacharacter

                   //从serail读到一个字符

                   do_idle(false);//再次尝试执行idle函数

                   break;

               }

               timeout-=_timeout;

           }

           if(res==false){

               do_idle(true);

               return_GETS_TIMEOUT; //Inputtimedout

           }

       }else{

           mon_read_char(&c);//读一个字符

       }

       *eol='\0';

       switch(c){

#defineCTRL(c)((c)&0x1F)

#ifCYGNUM_REDBOOT_CMD_LINE_EDITING!

=0

       caseCTRL('P'):

           //Fetchthepreviouslineintothebuffer

           if(_index>=0){

               //Erasethepreviousline[crude]

               //发送'\b'让minicom向后退格一个字符,然后退格

               while(ip!

=buf){

               //删除上面mon_write_char(*eol++);发送出去的字符,如果发送了的话.

                   mon_write_char('\b');

                   mon_write_char('');//发送''覆盖原有数据,所以这样看上去minicom就删除了一个字符

                   mon_write_char('\b');

                   ip--;

               }

               //现在ip等于buf了

               strcpy(buf,_cl_lines[_index]);//将前一个cmd从_cl_lines[]取出来

               while(*ip){

                   mon_write_char(*ip++);//将命令通过serial发送给minicom.

               }

               eol=ip;//eol等于当前插入缓冲区指针ip

               //Movetopreviousline

               _index--;//调整到前一个命令行历史记录

               if(_index<0){

                   _index=_cl_max_index;//循环到最大处,不保证此处有有效命令

               }

           }else{

               //发送bell铃声数据,minicom会让pc的bios发声

               mon_write_char(0x07); //Audiblebellonmostdevices

           }

           break;

       caseCTRL('N'):

           //Fetchthenextlineintothebuffer

           //操作和上面的'P'操作一致

           if(_index>=0){

               if(++_index>_cl_max_index)_index=0;

               //Erasethepreviousline[crude]

               while(ip!

=buf){

                   mon_write_char('\b');

                   mon_write_char('');

                   mon_write_char('\b');

                   ip--;

               }

               strcpy(buf,_cl_lines[_index]);

               while(*ip){

                   mon_write_char(*ip++);

               }

               eol=ip;

           }else{

               mon_write_char(0x07); //Audiblebellonmostdevices

           }

           break;

       caseCTRL('B'):

 

           //Moveinsertionpointbackwards

           //向后移动光标,ip当前insertpoint减减,eof不变

           if(ip!

=buf){

               mon_write_char('\b');

               ip--;

           }

           break;

       caseCTRL('F'):

           //Moveinsertionpointforwards

           //如果当前ip还没有到eol,那么前移,即,再在此处输出一次同样的字符[luther.gliethttp]

           if(ip!

=eol){

               mon_write_char(*ip++);

           }

           break;

       caseCTRL('E'):

           //Moveinsertionpointtoendofline

           //原理同上

           while(ip!

=eol){

               mon_write_char(*ip++);

           }

           break;

       caseCTRL('A'):

           //Moveinsertionpointtobeginningofline

           //原理同上

           if(ip!

=buf){

               xp=eol;//这里是个bug,应该改为xp=ip;才正常

               while(xp--!

=buf){

                   mon_write_char('\b');

               }

           }

           ip=buf;

           break;

       caseCTRL('K'):

           //从当前位置一直删除到结尾字符

           //Killtotheendofline

           if(ip!

=eol){

               xp=ip;

               while(xp++!

=eol){

                   //从当前插入指针所在出ip开始输出''空格,一直到eol

                   //这样原有的数据都因为''而看上去像是被删除了似的

                   mon_write_char('');

               }

               while(--xp!

=ip){

                   mon_write_char('\b');//退格在退到原来的ip处

               }

               eol=ip;//因为当前ip后的数据已经全部清空,所以当前ip就是eol.

           }

           break;

       caseCTRL('D'):

           //Erasethecharacterunderthecursor

           if(ip!

=eol){

               xp=ip;

               eol--;//彻底删除当前ip所指字符,所以eol少1.

               while(xp!

=eol){

                   *xp=*(xp+1);

                   mon_write_char(*xp++);

               }

               mon_write_char(''); //Eraseslastcharacter

               mon_write_char('\b');

               while(xp--!

=ip){

                   mon_write_char('\b');

               }

           }

           break;

#endif//CYGNUM_REDBOOT_CMD_LINE_EDITING

       caseCTRL('C'):

//^C

           //Abortcurrentinput

           diag_printf("^C\n");

           *buf='\0'; //Nothingusefulinbuffer

           return_GETS_CTRLC;//ok,收到了ctrl+c组合.

       case'\n':

       case'\r':

           //Ifpreviouscharacterwasthe"other"end-of-line,ignorethisone

           if(((c=='\n')&&(last_ch=='\r'))||

               ((c=='\r')&&(last_ch=='\n'))){

               //如果前一个是与其配对的另外一个字符,那么退出

               c='\0';//追加'\0'字符串结尾符号

               break;

           }

           //Endofline

           if(console_echo){

                   //发送回车换行给console,这样console也才能出现回车换行[luther.gliethttp]

                   mon_write_char('\r');

                   mon_write_char('\n');

           }

           last_ch=c;//记录当前输入

#ifCYGNUM_REDBOOT_CMD_LINE_EDITING!

=0

           if(cmd_history&&(buf!

=eol)){

               //Savecurrentline-onlywhenenabled

               //允许作history时,才执行如下操作,将当前serial获得的命令行,存入_cl_lines[]历史记录缓冲区.

               if(++_cl_index==_CL_NUM_LINES)_cl_index=0;

               if(_cl_index>_cl_max_index)_cl_max_index=_cl_index;

               strcpy(_cl_lines[_cl_index],buf);

           }

#endif

           return_GETS_OK;

       case'\b':

       case0x7F:

 //DEL

           if(ip!

=buf){

#ifCYGNUM_REDBOOT_CMD_LINE_EDITING!

=0

               if(ip!

=eol){

                   ip--;

                   mon_write_char('\b');

                   xp=ip;

                   while(xp!

=(eol-1)){

                       *xp=*(xp+1);

                       mon_write_char(*xp++);

                   }

                   mon_write_char(''); //Eraseslastcharacter

                   mon_write_char('\b');

                   while(xp--!

=ip){

                       mon_write_char('\b');

       

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1