C Language Example | Implementing a Simple Command Line

Click the blue “Yikou Linux” in the upper left corner, and select “Set as Favorite

Get the latest technical articles first

☞【Technical】Learning Path for Embedded Driver Engineers
☞【Technical】Linux Embedded Knowledge Points - Mind Map - Free Access
☞【Employment】A Comprehensive Project Based on Linux IoT for Your Resume
☞【Employment】Resume Template







Embedded system development often requires the use of command line functionalities, such as the U-Boot command line.

The command line can increase the flexibility of program execution, facilitate debugging, and significantly improve our development efficiency.

This article teaches you how to implement a simple command line module through a straightforward example,

which can be easily ported to your own C projects.

For the complete source code, see the end of the article.

1. Design Philosophy

C Language Example | Implementing a Simple Command Line

2. Implementation

1. Structure

We use the structure struct _cmdnum to maintain the command-related information supported by the module.

typedef void (* CMDFUNC)(char [][256],int argc);   
typedef struct _cmdnum{   
    char *cmd;   
    int index;   
    int paramcount;   
    CMDFUNC callback;
    char *info;
}CMDNUM,*PCMDNUM;   
Member Meaning
char *cmd Command name
int index Command index
int paramcount Number of command parameters
CMDFUNC callback Callback function corresponding to the command

2. Supported Commands

This example adds four commands:

Function Number of Parameters Callback Function
help Displays all command information 0 showhelp()
exit Exits the current process 0 quit()
test Prints all parameter information, for testing 3 test()
send Converts the input hexadecimal string to a hexadecimal integer and stores it in an array MAX_PARAM_NUM send()

Defined as follows:

CMDNUM cmdlist[] = 
{   
    {"help",1,0,showhelp},   
    {"exit",2,0,quit},   
    {"test",3,3,test}, 
    {"send",4,MAX_PARAM_NUM,send},   
};

3. Related Functions

1. getline()

#include <stdio.h>
ssize_t getline(char **lineptr, size_t *n, FILE *stream);

Reads a line of data from the file stream stream, saving the result to *lineptr, including the terminating null character and newline character.

2. parsecmd()

void parsecmd(char *s)   

Parses the command line content, mainly implemented through the functions stripcmd/getcmdindex.

  • stripcmd
int stripcmd(char *s,char cmds[][256])   

Utilizes the library function strtok to split the parameters in the command line s by spaces, extracting parameters and storing them in the two-dimensional array **char cmds[256]**.

  • getcmdindex
int  getcmdindex(char *name)

Traverses the array cmdlist[] using the command name name to obtain the array index.

4. Core Code

CMDNUM cmdlist[] = 
{   
    {"help",1,0,showhelp,"show all cmd info"},   
    {"exit",2,0,quit,"quit application"},   
    {"test",3,3,test,"[param...]print params"}, 
    {"send",3,MAX_PARAM_NUM,senddata,"[xx...]converts data from string to hex and store to buf"},   
};   

void parsecmd(char *s)   
{   
char cmd[MAX_PARAM_NUM][256];   
int argc = 0;   
int index = -1; 
   
 argc = stripcmd(s,cmd);

//printf("argc=%d\n",argc);
 index=getcmdindex(cmd[0]);
if(index == -1)   
 {   
if(argc>0)
  {
   cprintf(RED,"\tNo such command \n");   
  }
return;   
 }   
elseif(argc>0)  
 {
  cmdlist[index].callback(cmd,argc);   
 }   
}   
   
UINT8 hex2char(UINT8 ch)
{
if ((ch >= '0') && (ch <= '9')) {return ch - '0';}
if ((ch >= 'a') && (ch <= 'f')) {return ch - 'a' + 10;}
if ((ch >= 'A') && (ch <= 'F')) {return ch - 'A' + 10;}
return (UINT8)0xff;
}

UCHAR stringToByte(char* str)
{
 UCHAR bytes = 0;

if(strlen(str)==1)
 {
  bytes= 0 << 4 | hex2char(str[0]);
 }else
 {
  bytes= hex2char(str[0]) << 4 | hex2char(str[1]);
 }

return bytes;
} 
//7e 01 02 01 00 07 07 01 00 00 00 c6 51 2a 7e 

void senddata(char argv[][256],int argc)
{
int i = 0;
int len = 0;
 UCHAR buf[256] = {0};

if(argc < 2)
 {
return;
 }
for(i=1;i<argc;i++)
 {
   buf[i-1] = stringToByte(argv[i]);
 }
cprintf(GREEN,"\n  buf:");
for(i=0;i<argc-1;i++)
 {
cprintf(GREEN,"%02x ",buf[i]);
}
putchar('\n');

}
void test(char argv[][256],int argc)
{   
int i = 0;

for(i=0;i<argc;i++)
 {
cprintf(YEL,"\targv[%d]:%s\n",i,argv[i]);
}

return;   
} 
void showsysinfo(void)   
{   
cprintf(D_GREEN_H,"---------------yikoulinux cmdline demo-----------\n");     
}   
void quit(char cmd[][256],int argc)   
{   
cprintf(RED_H,"exit to system \n");   
    exit(0);   
}   
   
void showhelp(char cmd[][256],int argc)   
{   
int i = 0;  

for(i=0;i<sizeof(cmdlist)/sizeof(CMDNUM);i++) 
 { 
    cprintf(GREEN_H,"\t%s",cmdlist[i].cmd);
  cprintf(YEL_H,"\t%s\n",cmdlist[i].info); 
 } 
return ;    
}  

int main(int argc, char* argv[])   
{   
    char *line;   
    int ret = 0;  
size_t len_line = 0;

    showsysinfo();   
    
while(1)   
 {   
  fflush( stdin );   
  cprintf(D_GREEN_H,DEV_NAME"# ");   

  ret = getline(&line, &len_line, stdin); 
if(ret == -1)
  {
   break;
  }
  parsecmd(line); 
free(line);
  line = NULL;
 }   
   
    return 0;   
}   

3. Testing

1. help

C Language Example | Implementing a Simple Command Line

2. test

C Language Example | Implementing a Simple Command Line

3. send

C Language Example | Implementing a Simple Command Line

4. exit

C Language Example | Implementing a Simple Command Line

4. Source Code Access

Reply in the public account:cmd

Or add Yikou Jun as a friend. Additionally:

All basic knowledge of C language and example codes are compiled into a PDF document【Regularly Updated

C Language Example | Implementing a Simple Command Line

end

Yikou Linux

Follow, reply 【1024】 to receive a wealth of Linux materials

Collection of Wonderful Articles

Article Recommendations

【Collection】ARM【Collection】Fan Q&A【Collection】All OriginalsCollectionLinuxGetting StartedCollectionComputer NetworksCollectionLinux Drivers【Technical】Learning Path for Embedded Driver Engineers【Technical】All Knowledge Points of Linux Embedded – Mind Map

Leave a Comment