当前位置: 编程技术>c/c++/嵌入式
基于C语言实现shell指令的详解
来源: 互联网 发布时间:2014-10-15
本文导语: 源代码来自于TI开发板在ARM上实现shell命令解析第一步:构建命令实现函数和命令表1,定义结构体 和命令表 代码如下:typedef int (*pfnCmdLine)(int argc, char *argv[]);//*****************************************************************************////! Structu...
源代码来自于TI开发板
在ARM上实现shell命令解析
第一步:构建命令实现函数和命令表
1,定义结构体 和命令表
typedef int (*pfnCmdLine)(int argc, char *argv[]);
//*****************************************************************************
//
//! Structure for an entry in the command list table.
//
//*****************************************************************************
typedef struct
{
//
//! A pointer to a string containing the name of the command.
//
const char *pcCmd;
//
//! A function pointer to the implementation of the command.
//
pfnCmdLine pfnCmd;
//
//! A pointer to a string of brief help text for the command.
//
const char *pcHelp;
}
tCmdLineEntry;
//*****************************************************************************
//
//! This is the command table that must be provided by the application.
//
//*****************************************************************************
extern tCmdLineEntry g_sCmdTable[];
2,编写命令执行函数 实现命令表
int
Cmd_help(int argc, char *argv[])
{
tCmdLineEntry *pEntry;
//
// Print some header text.
//
UARTprintf("nAvailable commandsn");
UARTprintf("------------------n");
//
// Point at the beginning of the command table.
//
pEntry = &g_sCmdTable[0];
//
// Enter a loop to read each entry from the command table. The
// end of the table has been reached when the command name is NULL.
//
while(pEntry->pcCmd)
{
//
// Print the command name and the brief description.
//
UARTprintf("%s%sn", pEntry->pcCmd, pEntry->pcHelp);
//
// Advance to the next entry in the table.
//
pEntry++;
}
//
// Return success.
//
return(0);
}
int
Cmd_ls(int argc, char *argv[])
{
unsigned long ulTotalSize;
unsigned long ulFileCount;
unsigned long ulDirCount;
FRESULT fresult;
FATFS *pFatFs;
//
// Open the current directory for access.
//
fresult = f_opendir(&g_sDirObject, g_cCwdBuf);
//
// Check for error and return if there is a problem.
//
if(fresult != FR_OK)
{
return(fresult);
}
ulTotalSize = 0;
ulFileCount = 0;
ulDirCount = 0;
//
// Give an extra blank line before the listing.
//
UARTprintf("n");
//
// Enter loop to enumerate through all directory entries.
//
for(;;)
{
//
// Read an entry from the directory.
//
fresult = f_readdir(&g_sDirObject, &g_sFileInfo);
//
// Check for error and return if there is a problem.
//
if(fresult != FR_OK)
{
return(fresult);
}
//
// If the file name is blank, then this is the end of the
// listing.
//
if(!g_sFileInfo.fname[0])
{
break;
}
//
// If the attribue is directory, then increment the directory count.
//
if(g_sFileInfo.fattrib & AM_DIR)
{
ulDirCount++;
}
//
// Otherwise, it is a file. Increment the file count, and
// add in the file size to the total.
//
else
{
ulFileCount++;
ulTotalSize += g_sFileInfo.fsize;
}
//
// Print the entry information on a single line with formatting
// to show the attributes, date, time, size, and name.
//
UARTprintf("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9u %sn",
(g_sFileInfo.fattrib & AM_DIR) ? 'D' : '-',
(g_sFileInfo.fattrib & AM_RDO) ? 'R' : '-',
(g_sFileInfo.fattrib & AM_HID) ? 'H' : '-',
(g_sFileInfo.fattrib & AM_SYS) ? 'S' : '-',
(g_sFileInfo.fattrib & AM_ARC) ? 'A' : '-',
(g_sFileInfo.fdate >> 9) + 1980,
(g_sFileInfo.fdate >> 5) & 15,
g_sFileInfo.fdate & 31,
(g_sFileInfo.ftime >> 11),
(g_sFileInfo.ftime >> 5) & 63,
g_sFileInfo.fsize,
g_sFileInfo.fname);
// tcp_write(Rpcb,g_sFileInfo.fname,sizeof(g_sFileInfo.fname),0);
} // endfor
//
// Print summary lines showing the file, dir, and size totals.
//
UARTprintf("n%4u File(s),%10u bytes totaln%4u Dir(s)",
ulFileCount, ulTotalSize, ulDirCount);
//
// Get the free space.
//
fresult = f_getfree("/", &ulTotalSize, &pFatFs);
//
// Check for error and return if there is a problem.
//
if(fresult != FR_OK)
{
return(fresult);
}
//
// Display the amount of free space that was calculated.
//
UARTprintf(", %10uK bytes freen", ulTotalSize * pFatFs->sects_clust / 2);
//
// Made it to here, return with no errors.
//
return(0);
}
tCmdLineEntry g_sCmdTable[] =
{
{ "help", Cmd_help, " : Display list of commands" },
{ "h", Cmd_help, " : alias for help" },
{ "?", Cmd_help, " : alias for help" },
{ "ls", Cmd_ls, " : Display list of files" },
{ "chdir", Cmd_cd, ": Change directory" },
{ "cd", Cmd_cd, " : alias for chdir" },
{ "pwd", Cmd_pwd, " : Show current working directory" },
{ "cat", Cmd_cat, " : Show contents of a text file" },
{ "rm", CMD_Delete, " : Delete a file or a folder" },
{ 0, 0, 0 }
};
第二步:编写命令解析 执行函数
//*****************************************************************************
//
// cmdline.c - Functions to help with processing command lines.
//
// Copyright (c) 2007-2010 Texas Instruments Incorporated. All rights reserved.
// Software License Agreement
//
// Texas Instruments (TI) is supplying this software for use solely and
// exclusively on TI's microcontroller products. The software is owned by
// TI and/or its suppliers, and is protected under applicable copyright
// laws. You may not combine this software with "viral" open-source
// software in order to form a larger program.
//
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
//
// This is part of revision 6594 of the Stellaris Firmware Development Package.
//
//*****************************************************************************
//*****************************************************************************
//
//! addtogroup cmdline_api
//! @{
//
//*****************************************************************************
#include
#include "cmdline.h"
//*****************************************************************************
//
// Defines the maximum number of arguments that can be parsed.
//
//*****************************************************************************
#ifndef CMDLINE_MAX_ARGS
#define CMDLINE_MAX_ARGS 8
#endif
//*****************************************************************************
//
//! Process a command line string into arguments and execute the command.
//!
//! param pcCmdLine points to a string that contains a command line that was
//! obtained by an application by some means.
//!
//! This function will take the supplied command line string and break it up
//! into individual arguments. The first argument is treated as a command and
//! is searched for in the command table. If the command is found, then the
//! command function is called and all of the command line arguments are passed
//! in the normal argc, argv form.
//!
//! The command table is contained in an array named g_sCmdTable which
//! must be provided by the application.
//!
//! return Returns b CMDLINE_BAD_CMD if the command is not found,
//! b CMDLINE_TOO_MANY_ARGS if there are more arguments than can be parsed.
//! Otherwise it returns the code that was returned by the command function.
//
//*****************************************************************************
int
CmdLineProcess(char *pcCmdLine)
{
static char *argv[CMDLINE_MAX_ARGS + 1];
char *pcChar;
int argc;
int bFindArg = 1;
tCmdLineEntry *pCmdEntry;
//
// Initialize the argument counter, and point to the beginning of the
// command line string.
//
argc = 0;
pcChar = pcCmdLine;
//
// Advance through the command line until a zero character is found.
//
while(*pcChar)
{
//
// If there is a space, then replace it with a zero, and set the flag
// to search for the next argument.
//
if(*pcChar == ' ')
{
*pcChar = 0;
bFindArg = 1;
}
//
// Otherwise it is not a space, so it must be a character that is part
// of an argument.
//
else
{
//
// If bFindArg is set, then that means we are looking for the start
// of the next argument.
//
if(bFindArg)
{
//
// As long as the maximum number of arguments has not been
// reached, then save the pointer to the start of this new arg
// in the argv array, and increment the count of args, argc.
//
if(argc < CMDLINE_MAX_ARGS)
{
argv[argc] = pcChar;
argc++;
bFindArg = 0;
}
//
// The maximum number of arguments has been reached so return
// the error.
//
else
{
return(CMDLINE_TOO_MANY_ARGS);
}
}
}
//
// Advance to the next character in the command line.
//
pcChar++;
}
//
// If one or more arguments was found, then process the command.
//
if(argc)
{
//
// Start at the beginning of the command table, to look for a matching
// command.
//
pCmdEntry = &g_sCmdTable[0];
//
// Search through the command table until a null command string is
// found, which marks the end of the table.
//
while(pCmdEntry->pcCmd)
{
//
// If this command entry command string matches argv[0], then call
// the function for this command, passing the command line
// arguments.
//
if(!strcmp(argv[0], pCmdEntry->pcCmd))
{
return(pCmdEntry->pfnCmd(argc, argv));
}
//
// Not found, so advance to the next entry.
//
pCmdEntry++;
}
}
//
// Fall through to here means that no matching command was found, so return
// an error.
//
return(CMDLINE_BAD_CMD);
}
第三步:收到命令 调用解析函数
接收可用串口 网口等
假如收到的吗,命令为 ls -l
*cmd="ls -l";
CmdLineProcess(cmd);
在ARM上实现shell命令解析
第一步:构建命令实现函数和命令表
1,定义结构体 和命令表
代码如下:
typedef int (*pfnCmdLine)(int argc, char *argv[]);
//*****************************************************************************
//
//! Structure for an entry in the command list table.
//
//*****************************************************************************
typedef struct
{
//
//! A pointer to a string containing the name of the command.
//
const char *pcCmd;
//
//! A function pointer to the implementation of the command.
//
pfnCmdLine pfnCmd;
//
//! A pointer to a string of brief help text for the command.
//
const char *pcHelp;
}
tCmdLineEntry;
//*****************************************************************************
//
//! This is the command table that must be provided by the application.
//
//*****************************************************************************
extern tCmdLineEntry g_sCmdTable[];
2,编写命令执行函数 实现命令表
代码如下:
int
Cmd_help(int argc, char *argv[])
{
tCmdLineEntry *pEntry;
//
// Print some header text.
//
UARTprintf("nAvailable commandsn");
UARTprintf("------------------n");
//
// Point at the beginning of the command table.
//
pEntry = &g_sCmdTable[0];
//
// Enter a loop to read each entry from the command table. The
// end of the table has been reached when the command name is NULL.
//
while(pEntry->pcCmd)
{
//
// Print the command name and the brief description.
//
UARTprintf("%s%sn", pEntry->pcCmd, pEntry->pcHelp);
//
// Advance to the next entry in the table.
//
pEntry++;
}
//
// Return success.
//
return(0);
}
代码如下:
int
Cmd_ls(int argc, char *argv[])
{
unsigned long ulTotalSize;
unsigned long ulFileCount;
unsigned long ulDirCount;
FRESULT fresult;
FATFS *pFatFs;
//
// Open the current directory for access.
//
fresult = f_opendir(&g_sDirObject, g_cCwdBuf);
//
// Check for error and return if there is a problem.
//
if(fresult != FR_OK)
{
return(fresult);
}
ulTotalSize = 0;
ulFileCount = 0;
ulDirCount = 0;
//
// Give an extra blank line before the listing.
//
UARTprintf("n");
//
// Enter loop to enumerate through all directory entries.
//
for(;;)
{
//
// Read an entry from the directory.
//
fresult = f_readdir(&g_sDirObject, &g_sFileInfo);
//
// Check for error and return if there is a problem.
//
if(fresult != FR_OK)
{
return(fresult);
}
//
// If the file name is blank, then this is the end of the
// listing.
//
if(!g_sFileInfo.fname[0])
{
break;
}
//
// If the attribue is directory, then increment the directory count.
//
if(g_sFileInfo.fattrib & AM_DIR)
{
ulDirCount++;
}
//
// Otherwise, it is a file. Increment the file count, and
// add in the file size to the total.
//
else
{
ulFileCount++;
ulTotalSize += g_sFileInfo.fsize;
}
//
// Print the entry information on a single line with formatting
// to show the attributes, date, time, size, and name.
//
UARTprintf("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9u %sn",
(g_sFileInfo.fattrib & AM_DIR) ? 'D' : '-',
(g_sFileInfo.fattrib & AM_RDO) ? 'R' : '-',
(g_sFileInfo.fattrib & AM_HID) ? 'H' : '-',
(g_sFileInfo.fattrib & AM_SYS) ? 'S' : '-',
(g_sFileInfo.fattrib & AM_ARC) ? 'A' : '-',
(g_sFileInfo.fdate >> 9) + 1980,
(g_sFileInfo.fdate >> 5) & 15,
g_sFileInfo.fdate & 31,
(g_sFileInfo.ftime >> 11),
(g_sFileInfo.ftime >> 5) & 63,
g_sFileInfo.fsize,
g_sFileInfo.fname);
// tcp_write(Rpcb,g_sFileInfo.fname,sizeof(g_sFileInfo.fname),0);
} // endfor
//
// Print summary lines showing the file, dir, and size totals.
//
UARTprintf("n%4u File(s),%10u bytes totaln%4u Dir(s)",
ulFileCount, ulTotalSize, ulDirCount);
//
// Get the free space.
//
fresult = f_getfree("/", &ulTotalSize, &pFatFs);
//
// Check for error and return if there is a problem.
//
if(fresult != FR_OK)
{
return(fresult);
}
//
// Display the amount of free space that was calculated.
//
UARTprintf(", %10uK bytes freen", ulTotalSize * pFatFs->sects_clust / 2);
//
// Made it to here, return with no errors.
//
return(0);
}
代码如下:
tCmdLineEntry g_sCmdTable[] =
{
{ "help", Cmd_help, " : Display list of commands" },
{ "h", Cmd_help, " : alias for help" },
{ "?", Cmd_help, " : alias for help" },
{ "ls", Cmd_ls, " : Display list of files" },
{ "chdir", Cmd_cd, ": Change directory" },
{ "cd", Cmd_cd, " : alias for chdir" },
{ "pwd", Cmd_pwd, " : Show current working directory" },
{ "cat", Cmd_cat, " : Show contents of a text file" },
{ "rm", CMD_Delete, " : Delete a file or a folder" },
{ 0, 0, 0 }
};
第二步:编写命令解析 执行函数
代码如下:
//*****************************************************************************
//
// cmdline.c - Functions to help with processing command lines.
//
// Copyright (c) 2007-2010 Texas Instruments Incorporated. All rights reserved.
// Software License Agreement
//
// Texas Instruments (TI) is supplying this software for use solely and
// exclusively on TI's microcontroller products. The software is owned by
// TI and/or its suppliers, and is protected under applicable copyright
// laws. You may not combine this software with "viral" open-source
// software in order to form a larger program.
//
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
//
// This is part of revision 6594 of the Stellaris Firmware Development Package.
//
//*****************************************************************************
//*****************************************************************************
//
//! addtogroup cmdline_api
//! @{
//
//*****************************************************************************
#include
#include "cmdline.h"
//*****************************************************************************
//
// Defines the maximum number of arguments that can be parsed.
//
//*****************************************************************************
#ifndef CMDLINE_MAX_ARGS
#define CMDLINE_MAX_ARGS 8
#endif
//*****************************************************************************
//
//! Process a command line string into arguments and execute the command.
//!
//! param pcCmdLine points to a string that contains a command line that was
//! obtained by an application by some means.
//!
//! This function will take the supplied command line string and break it up
//! into individual arguments. The first argument is treated as a command and
//! is searched for in the command table. If the command is found, then the
//! command function is called and all of the command line arguments are passed
//! in the normal argc, argv form.
//!
//! The command table is contained in an array named g_sCmdTable which
//! must be provided by the application.
//!
//! return Returns b CMDLINE_BAD_CMD if the command is not found,
//! b CMDLINE_TOO_MANY_ARGS if there are more arguments than can be parsed.
//! Otherwise it returns the code that was returned by the command function.
//
//*****************************************************************************
int
CmdLineProcess(char *pcCmdLine)
{
static char *argv[CMDLINE_MAX_ARGS + 1];
char *pcChar;
int argc;
int bFindArg = 1;
tCmdLineEntry *pCmdEntry;
//
// Initialize the argument counter, and point to the beginning of the
// command line string.
//
argc = 0;
pcChar = pcCmdLine;
//
// Advance through the command line until a zero character is found.
//
while(*pcChar)
{
//
// If there is a space, then replace it with a zero, and set the flag
// to search for the next argument.
//
if(*pcChar == ' ')
{
*pcChar = 0;
bFindArg = 1;
}
//
// Otherwise it is not a space, so it must be a character that is part
// of an argument.
//
else
{
//
// If bFindArg is set, then that means we are looking for the start
// of the next argument.
//
if(bFindArg)
{
//
// As long as the maximum number of arguments has not been
// reached, then save the pointer to the start of this new arg
// in the argv array, and increment the count of args, argc.
//
if(argc < CMDLINE_MAX_ARGS)
{
argv[argc] = pcChar;
argc++;
bFindArg = 0;
}
//
// The maximum number of arguments has been reached so return
// the error.
//
else
{
return(CMDLINE_TOO_MANY_ARGS);
}
}
}
//
// Advance to the next character in the command line.
//
pcChar++;
}
//
// If one or more arguments was found, then process the command.
//
if(argc)
{
//
// Start at the beginning of the command table, to look for a matching
// command.
//
pCmdEntry = &g_sCmdTable[0];
//
// Search through the command table until a null command string is
// found, which marks the end of the table.
//
while(pCmdEntry->pcCmd)
{
//
// If this command entry command string matches argv[0], then call
// the function for this command, passing the command line
// arguments.
//
if(!strcmp(argv[0], pCmdEntry->pcCmd))
{
return(pCmdEntry->pfnCmd(argc, argv));
}
//
// Not found, so advance to the next entry.
//
pCmdEntry++;
}
}
//
// Fall through to here means that no matching command was found, so return
// an error.
//
return(CMDLINE_BAD_CMD);
}
第三步:收到命令 调用解析函数
接收可用串口 网口等
假如收到的吗,命令为 ls -l
*cmd="ls -l";
CmdLineProcess(cmd);