杨屹的《为uCOS51增加Shell界面》<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
https://static.assets-stash.eet-china.com/album/old-resources/2009/10/16/25edb564-a2f9-4cd3-bc44-bd0c2408bdfd.rar我的shell工程,智林STM32下使用,实现了四个命令:help-用于显示其他可用命令,cls-用于清屏,ledon-点亮开发板上的绿色指示灯,ledoff-关闭指示灯。有智林STM32板的朋友可以下载使用。
<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />2009年10月14日星期三 19:51:18
人机交互程序编写过程
一、参考的文献
上次的计划里已经说明了此次编写的目标,这个人机交互程序实际上就是一个简单的Command Shell。参考的文献主要是杨屹的《为uCOS51增加Shell界面》这篇文章,写得很好。我会把我编写过程中的一些想法记录在此,然后也会上传杨屹的这篇文章,有兴趣的朋友可以阅读参考。
二、编写Shell的准备工作
1、我这个命令界面要在开发板的按键和液晶显示的基础上实现,而杨屹的Shell是在串口上实现。这里共同的地方是:不管字符来自按键还是来自串口,都是通过同样的函数接口将字符先存储到缓冲区,这样使得Shell接口的可移植性提高。我这里使用KB_GetChar(),以后在使用串口的时候,这个函数可以更名为Uart_GetChar(),对于上层程序来说,它提供了近似的接口。
2、shell任务采用软件状态机实现,以下是已详细注释的源代码:
switch(CmdState) //根据状态机进行散转
{ case StateInput: //如果处于输入状态
{ CharIn=(char)KB_GetChar(); //读取输入按键
if(CharIn=='\n') // 如果按下了Enter键,它是触发软件状态机从输入态
{ // 进入命令解释执行态的关键。
CmdBuf[CharCount]='\0'; //CharCount=输入字符的数字,命令缓冲区以0结束
Shell_PutChar( CharIn ); //显示器上回显换行
if (CharCount==0) //之前没有输入字符,就是平白按了一下Enter { Shell_PutString("sh>"); //重新显示命令提示符,仍在输入态下循环 }
else
{ CmdState="StateExe"; //如果输入过字符,进入命令解释态
CharCount=0;
}
}
else if (CharIn=='\b') //如果输入退格键
{
if (CharCount==0) //之前没有输入字符,按退格不能理他
{ Buzzer_Beep(); //警告,已经退回提示符了,再退就:>了。
}
else
{
CharCount -=1; //有效字符数减去1.
Shell_PutChar(CharIn); //让字符界面自己处理退格键
}
}
else //如果是其他键
{
CmdBuf[CharCount]=CharIn; //将字符存入缓冲区当前位置
CharCount +=1; //缓冲区位置向前移动
if (CharCount>=CharMaxCount+1) //如果超过了,这个字符现在占据最后一个位置
{ CharCount="CharMaxCount"; //使当前位置保持为最后一个,等待Enter。
Buzzer_Beep(); //这个字符也不向字符界面输出,而是产生警告
}
else
{
Shell_PutChar(CharIn);//将有效字符输出。
}
}
}
break;
case StateExe: //如果处于命令执行态
{ CmdStr="ParseCmdBuf"(CmdBuf); //解析命令缓冲区,得到命令结构信息,我这里还只支持简单命令
//所以处理很简单,直接获得命令字符串,以后可以扩展。
for(CmdIndex=0; CmdIndex<4; CmdIndex++ )
{ // 在命令表里搜索对应命令字符串
CompResult=strcmp( CmdStr,CmdStrTable[CmdIndex]);
//命令字符串比较的结果
if (CompResult==0) //如果在字符串表里找到。返回0.
break; //此时CmdIndex对应的值为命令在命令表里的索引。
}
if ( CmdIndex<4)
{
CmdTable[CmdIndex].CmdFunc();
} //找到对应命令,调用相应函数处理
else
{ Shell_PutString("Bad Command!\n");
} //没有找到对应命令,输出信息。
CmdState=StateInput;
Shell_PutString("Sh>");
}
break;
三、实际效果
最终实现的四个命令是:help-用于显示其他可用命令,cls-用于清屏,ledon-点亮开发板上的绿色指示灯,ledoff-关闭指示灯。
命令都能正确执行,也能识别不正确的命令,但是每次执行一次正确命令,获取按键的程序就进入死循环,再不能输入新的命令。问题正在调试过程中————————————。
文章评论(0条评论)
登录后参与讨论