cli.c
来自「基于ARM和uC/OS-II实现的串口控制台」· C语言 代码 · 共 1,153 行 · 第 1/3 页
C
1,153 行
pParaBuf[i] = CurBuf[offset + i];
}
pParaBuf[i] = '\0';
return TRUE;
}
/*******************************************************************************
* Function: SearchCmd()
* Description: 在当前命令集中查找输入的命令字串
* Calls:
* Called By:
* Input: CurBuf 要查找的命令字串
* CmdID 用于存放返回的命令ID号的地址
* err 错误码返回地址
* Return: ERR_CLI_SEARCHOK 命令搜索成功
* ERR_CLI_SEARCHERR 命令搜索失败
*******************************************************************************/
int SearchCmd(char *CurBuf, uint8 *CmdID, uint8 *err)
{
uint8 i, len, index, index2, offset, cnt = 0;
CmdInfo *CurCmdDB = NULL;
/* 计算字符串长度,以0或空格键作为结尾。以此计算出输入的主命令长度 */
for(len = 0; *(CurBuf + len) != '\0'; len++)
{
if(*(CurBuf + len) == SPACE) break;
}
/* 获取当前命令状态,用以决定查找命令的数据库及库中的命令数量 */
switch(GetCmdStatus())
{
case USER:
CurCmdDB = CmdDBUser;
break;
case PRIVATE:
CurCmdDB = CmdDBPrivate;
break;
case CONFIG:
CurCmdDB = CmdDBConfig;
break;
case CONFIG_LINE:
CurCmdDB = CmdDBLine;
break;
}
for(cnt = 0; CurCmdDB[cnt].name[0] != NULL;cnt++);
/* 当有命令字符串输入时,在对应命令数据库中进行查找 */
for(index = 0; (index < cnt) && (len > 0); index++)
{
for(i = 0, offset = 0; i < len; i++)
{
/* 输入的命令与数据库中的命令串进行逐字符比较 */
if(CurBuf[i] == CurCmdDB[index].name[i])
{
offset++;
}
else
{
break;
}
}
/* 如果输入的命令字符串在命令数据库中能够全部匹配,则查找成功 */
if(i == len && offset == len)
{
/* 查找是否有相同索引的命令 */
i = 0;
offset = 0;
for(index2 = index + 1; (index2 < cnt) && (len > 0); index2++)
{
for(i = 0, offset = 0; i < len; i++)
{
if(CurBuf[i] == CurCmdDB[index2].name[i])
{
offset++;
}
else
{
break;
}
}
/* 如果输入的命令字符串在命令数据库中后面部分能够全部匹配,
则命令索引在该数据库中不唯一 */
if(i == len && offset == len)
{
return ERR_CLI_CMD_NOT_UNIQUE;
}
}
*CmdID = index;
return ERR_CLI_SEARCHOK;
}
}
return ERR_CLI_SEARCHERR;
}
/*******************************************************************************
* Function: SearchPara()
* Description:
* Calls:
* Called By:
* Input:
* Return:
*******************************************************************************/
int SearchPara(char *CurBuf, uint8 ParaNum, CmdInfo *CurDB, uint8 *ParaID
, uint8 *err)
{
uint8 i, len, index, index2, spcnt = 0, offset = 0, cnt;
while(1)
{
/* 计算所要搜索参数在整个输入命令中的偏移量 */
if(*(CurBuf + offset) == SPACE)
{
/* 消除连续空格影响 */
if(*(CurBuf + offset + 1) == SPACE)
{
offset++;
continue;
}
else
{
offset++;
spcnt++;
if(spcnt == ParaNum)
{
break;
}
}
}
else
{
offset++;
/* 如果已搜索到输入命令的末尾,则结束搜索 */
if(offset >= strlen(CurBuf))
{
return ERR_CLI_SEARCH_PARA_ERR;
}
}
}
/* 计算参数字符串长度,以0或空格键作为结尾 */
for(len = 0; *(CurBuf + offset + len) != '\0'; len++)
{
if(*(CurBuf + offset + len) == SPACE) break;
}
for(cnt = 0; CurDB[cnt].name[0] != NULL;cnt++);
/* 当有命令字符串输入时,在对应命令数据库中进行查找 */
for(index = 0; (index < cnt) && (len > 0); index++)
{
for(i = 0, spcnt = 0; i < len; i++)
{
/* 输入的命令与数据库中的命令串进行逐字符比较 */
if(CurBuf[i + offset] == CurDB[index].name[i])
{
spcnt++;
}
else
{
break;
}
}
/* 如果输入的命令字符串在命令数据库中能够全部匹配,则查找成功 */
if(i == len && spcnt == len)
{
/* 查找是否有相同索引的命令 */
i = 0;
spcnt = 0;
for(index2 = index + 1; (index2 < cnt) && (len > 0); index2++)
{
for(i = 0, spcnt = 0; i < len; i++)
{
if(CurBuf[i] == CurDB[index2].name[i])
{
spcnt++;
}
else
{
break;
}
}
/* 如果输入的命令字符串在命令数据库中后面部分能够全部匹配,
则命令索引在该数据库中不唯一 */
if(i == len && spcnt == len)
{
return ERR_CLI_CMD_NOT_UNIQUE;
}
}
*ParaID = index;
return ERR_CLI_PARA_OK;
}
}
return ERR_CLI_SEARCH_PARA_ERR;
}
/*******************************************************************************
* Function: CmdRun()
* Description: 执行当前命令模式下CmdID对应的命令函数
* Calls: GetCmdStatus()
* Called By: TaskCLI()
* Input: CmdID 命令在命令库中的编号
*******************************************************************************/
void CmdRun(uint8 CmdID)
{
switch(GetCmdStatus()) // 建立一个状态类,
{
case USER:
CmdDBUser[CmdID].func();
break;
case PRIVATE:
CmdDBPrivate[CmdID].func();
break;
case CONFIG:
CmdDBConfig[CmdID].func();
break;
case CONFIG_LINE:
CmdDBLine[CmdID].func();
break;
default:
break;
}
}
/*******************************************************************************
* Function: CmdErr()
* Description: 命令错误提示
* Calls: U0Send()/strlen()/PrintBuf()/CurPrompt()
* Called By: TaskCLI()/CmdShow()/CmdConf()/CmdHostname()
*******************************************************************************/
void CmdErr(void)
{
SendStr(BLANKROW);
PrintBuf();
SendStr(CMD_ERR_INVALID);
CurPrompt();
PrintBuf();
}
/*******************************************************************************
* Function: CmdNotUnique()
* Description: 命令索引不唯一
* Calls: SendStr()/PrintBuf()/CurPrompt()
* Called By: TaskCLI()
*******************************************************************************/
void CmdNotUnique(void)
{
SendStr(BLANKROW);
PrintBuf();
SendStr(CMD_ERR_NOT_UNIQUE);
CurPrompt();
PrintBuf();
}
/*******************************************************************************
* Function: CmdIncomplate()
* Description: 命令错误提示
* Calls: U0Send()/strlen()/PrintBuf()/CurPrompt()
* Called By:
*******************************************************************************/
void CmdIncomplate(void)
{
SendStr(BLANKROW);
PrintBuf();
SendStr(CMD_ERR_INCOMPLETE);
CurPrompt();
PrintBuf();
}
/*******************************************************************************
* Function: CLIInit()
* Description: Command Line Interface Init.
* Calls: Init_Timer1()
* Called By: TaskCLI()
*******************************************************************************/
void CLIInit(void)
{
PINSEL0 |= UART0_RXD;
/* 初始化EXEC超时定时器 */
Init_Timer1(EXECTO / 60, EXECTO % 60);
}
/*******************************************************************************
* Function: RecInHisBuf()
* Description: Save the history command in HISTORY-COMMAND-BUFFER.
* Calls:
* Called By: TaskCLI()
*******************************************************************************/
void RecInHisBuf(char *CurCmdBuf)
{
uint8 i;
for(i = 0; *(CurCmdBuf + i) != 0; i++)
{
CmdHisBuf[CmdHisBufUsage][i] = *(CurCmdBuf + i);
}
if(CmdHisBufUsage == MAX_HIS_BUF)
{
CmdHisBufUsage = 0;
if(CurCmdHisBuf == MAX_HIS_BUF)
{
CurCmdHisBuf = 0;
}
return;
}
CmdHisBufUsage++;
CurCmdHisBuf++;
return;
}
/*******************************************************************************
* Function: TaskCLI()
* Description: Task of Command Line Interface
* Calls: CLIInit()/OSSemCreate()/GetCmd()/SearchCmd()/CmdRun()/CmdErr()
* Called By: main()
*******************************************************************************/
void TaskCLI(void *pdata)
{
uint8 err, CmdID;
char CurCmdBuf[256];
CLIInit();
sem_cmd = OSSemCreate(0);
while(1)
{
OSSemPend(sem_cmd, 0, &err);
GetCmd(CurCmdBuf);
RecInHisBuf(CurCmdBuf);
switch(SearchCmd(CurCmdBuf, &CmdID, &err))
{
case ERR_CLI_SEARCHOK:
CmdRun(CmdID);
break;
case ERR_CLI_SEARCHERR:
CmdErr();
break;
case ERR_CLI_CMD_NOT_UNIQUE:
CmdNotUnique();
break;
default:
break;
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?