1897 views|1 replies

501

Posts

4

Resources
The OP
 

[RTT & Infineon PSoC6 evaluation board (with touch)] CLI command line implementation [Copy link]

Preface

We have tested the serial port before, refer to

https://en.eeworld.com/bbs/thread-1247060-1-1.html

https://en.eeworld.com/bbs/thread-1247447-1-1.html

To facilitate subsequent debugging, we will now implement a simple SHELL command line.

process

First, you need to implement the serial port transceiver interface

intuart_read(uint8_t* buffer, uint32_tlen)

{

if(cyhal_uart_getc(&cy_retarget_io_uart_obj, buffer, len)

== CY_RSLT_SUCCESS)

{

returnlen;

}

else

{

return0;

}

}

intuart_write(uint8_t* buffer, uint32_tlen)

{

while(len--)

{

cyhal_uart_putc(&cy_retarget_io_uart_obj, *buffer++);

}

}

Implemented in Shell.c and putchar, putchar has been redirected so it does not need to be implemented, otherwise it can be changed to uart_write

/**

*****************************************************************************

* \fnstatic intshell_getchar(unsigned char *data)

* \brief reads a character.

* \note .

* \ param [out] data stores the read data.

* retval 0 Success.

* retval -1 failed.

*****************************************************************************

*/

staticintshell_getchar(unsignedchar*data)

{

int error=0;

//driver_uart_recv(getstdiouart(), data, 1,10,&erro);

if(0 == uart_read(data, 1))

{

error = 1;

}

else

{

uart_write(data,1);

}

if (error!=0)

{

return-1;

}

return0;

}

Core data structures

typedef void ( * CommandFunc )( void *); /**< shell command callback function*/

/**

* \structshell_cmd_cfg

* SHELL command structure.

*/

typedefstruct

{

unsigned char const * name; /**< shell command name*/

CommandFunc func; /**< shell command callback function*/

char const * helpstr; /**< Help string*/

}shell_cmd_cfg;

Defining a table

constshell_cmd_cfgshell_cmd_list[ ] =

{

/*1. Help related*/

{ ( const uint8_t*)"help", HelpFun, "help"}, /*Print help information*/

{ 0, 0 },

};

When receiving a command line, shell_cmd_list is searched for the command name. If a match is found, the function func is called to execute.

Read a line of command key code

staticunsignedintshell_read_line(intget(unsignedchar* tmp))

{

unsignedcharch = '\r';

unsignedintcount;

unsignedchartmp;

/*Start printing once " sh >"*/

if(cmd_buf[0]=='\r')

{

printf("sh>\r\n");

memset(cmd_buf,0x00,sizeof(cmd_buf));

}

/*If a character is received, go down, otherwise return*/

if(get(&tmp)==0)

{

ch = tmp;

}

else

{

return0;

}

/*If a non-printing character is received and the current receive buffer is not 0, it is considered that a frame is received, otherwise "SH>" is printed*/

if((ch == '\r'|| ch == '\n'|| ch < ' '|| ch > '~') && (ch != '\b'))

{

if(cmd_buf_index==0)

{

printf("sh>\r\n");

}

else

{

count = cmd_buf_index;

cmd_buf[cmd_buf_index]=0;

cmd_buf_index =0;

printf("\r\n");

returncount;

}

}

else

{

if(ch == '\b')

{

if(cmd_buf_index != 0)

{

cmd_buf_index--;

putchar('\b');

putchar(' ');

putchar('\b');

cmd_buf[cmd_buf_index]= '\0';

}

}

else

{

/*If a print character is received and the current receive buffer is full, it is considered that one frame has been received"*/

putchar(ch);

cmd_buf[cmd_buf_index++] = ch;

if(cmd_buf_index>=(sizeof(cmd_buf)-1))

{

count = cmd_buf_index;

cmd_buf[cmd_buf_index]=0;

cmd_buf_index =0;

printf("\r\n");

returncount;

}

}

}

return0;

}

test

Compile and run, you can enter help to view the command list

Code

shell.c

/**
*****************************************************************************
* \brief Platform related (PLATFORM) SHELL module (SHELL) related interface implementation.
* \details
* All rights reserved.
* \file shell.c
* \author
* \version 1.0
* \date
* \note Please refer to the notes before use.\n
* \since Newly created
* \par Revision record
* - Initial version
* \par Resource description
* - RAM:
* - ROM:
**************************************************************************
*/

#include <stdio.h>
#include <string.h>
#include "shell.h"
#include "cy_retarget_io.h"

extern int uart_read(uint8_t* buffer, uint32_t len);
extern int uart_write(uint8_t* buffer, uint32_t len);
/********************************************************************************
*
* Internal data
*
****************************************************************************/
#define SHELL_CMD_LEN 64 /**< Shell command buffer length */
extern const shell_cmd_cfg shell_cmd_list[ ]; /**< Defined in shell_fun */
extern const shell_cmd_cfg shell_cmd_list_app[ ]; /**< Defined in app_shellfun */
static int shellpassed = 1; /**< Whether the shell password is verified: 0: verified, 1: not verified */
static unsigned char cmd_buf[SHELL_CMD_LEN]="\r";
static int cmd_buf_index=0; /**< Number of characters of the command currently received */

/********************************************************************************
*
* Internal interface function implementation
*
****************************************************************************/

/**
**************************************************************************
* \fn static int shell_getchar(unsigned char *data)
* \brief Read a character.
* \note .
* \param[out] data stores the read data.
* retval 0 success.
* retval -1 failure.
*****************************************************************************
*/
static int shell_getchar(unsigned char *data)
{
int erro=0;
//driver_uart_recv(getstdiouart(), data, 1,10,&erro);
if(0 == uart_read(data, 1))
{
erro = 1;
}
else
{
uart_write(data,1);
}
if(erro!=0)
{
return -1;
}
return 0;
}


/**
**************************************************************************
* \fn static unsigned int shell_cmd_len(char const *cmd)
* \brief Get the command character length.
* \note End with space or \0.
* \param[in] cmd string
* return unsigned int command character length
************************************************************************
*/
static unsigned int shell_cmd_len(unsigned char const *cmd)
{
unsigned char const *p = cmd;
unsigned int len = 0;
while((*p != ' ') && (*p != 0))
{
p++;
len++;
}
return len;
}

/**
**************************************************************************
* \fn static void shell_check_passwd(void)
* \brief Shell password confirmation.
* \note End with space or \0.
*****************************************************************************
*/
static void shell_check_passwd(void)
{
unsigned int i;
unsigned char ch[6] = {0};
unsigned char pw[7] = SHELL_PASSWORD_STR;

while(1)
{
printf("\r\nPassword:");
memset(ch, 0, sizeof(ch));
for (i = 0; i < sizeof(ch); i++)
{
ch = getchar();
putchar('\b');
putchar('*');
}
if (memcmp(pw, ch, sizeof(ch)) == 0)
{
printf("\r\n");
break;
}
printf("\r\nAccess denied\r\n");
}
}

/**
**************************************************************************
* \fn static int shell_cmd_check(unsigned char *cmd, char const *str)
* \brief Match command characters.
* \note .
* \param[in] cmd string
* \param[in] str Matching character
* retval 0 Match successful
* retval 1 Match failed
********************************************************************************
*/
static int shell_cmd_check(unsigned char *cmd, unsigned char const *str)
{
unsigned int len1 = shell_cmd_len((unsigned char const *)cmd);
unsigned int len2 = shell_cmd_len(str);
if(len1 != len2)
{
return 1;
}
return memcmp(cmd, str, len1);
}

/**
*****************************************************************************
* \fn static unsigned int shell_read_line(int get(void), unsigned int len)
* \brief Shell reads command line.
* \note Enter ends, you can use the Backspace key to clear the input.
* \param[in] get Input interface function
* \param[in] p Receive buffer
* \param[in] len Length to be received
* return unsigned int Actual length received
****************************************************************************
*/
static unsigned int shell_read_line(int get(unsigned char* tmp))
{
unsigned char ch = '\r';
unsigned int count;
unsigned char tmp;
/*Start printing "sh>" once*/
if(cmd_buf[0]=='\r')
{
printf("sh>\r\n");
memset(cmd_buf,0x00,sizeof(cmd_buf));
}
/*If a character is received, go down, otherwise return*/
if(get(&tmp)==0)
{
ch = tmp;
}
else
{
return 0;
}
/*If a non-printing character is received and the current receive buffer is not 0, it is considered that a frame is received, otherwise print "SH>"*/
if((ch == '\r' || ch == '\n' || ch < ' ' || ch > '~') && (ch != '\b'))
{
if(cmd_buf_index==0)
{
printf("sh>\r\n");
}
else
{
count = cmd_buf_index;
cmd_buf[cmd_buf_index]=0;
cmd_buf_index =0;
printf("\r\n");
return count;
}
}
else
{
if(ch == '\b')
{
if(cmd_buf_index != 0)
{
cmd_buf_index--;
putchar('\b');
putchar(' ');
putchar('\b');
cmd_buf[cmd_buf_index]= '\0';
}
}
else
{
/*If a print character is received and the current receive buffer is full, it is considered that a frame has been received"*/
putchar(ch);
cmd_buf[cmd_buf_index++] = ch;
if(cmd_buf_index>=(sizeof(cmd_buf)-1))
{
count = cmd_buf_index;
cmd_buf[cmd_buf_index]=0;
cmd_buf_index =0;
printf("\r\n");
return count;
}
}
}
return 0;
}

/**
**************************************************************************
* \fn int shell_exec_cmdlist(unsigned char* cmd)
* \brief Search for command list and execute.
* retval 0 success
* retval -1 failure
* \note .
*****************************************************************************
*/
int shell_exec_cmdlist(unsigned char* cmd)
{
int i;
/*Platform related commands*/
for (i=0; shell_cmd_list.name != 0; i++)
{
if (shell_cmd_check(cmd, shell_cmd_list.name) == 0)
{
shell_cmd_list.func(cmd);
return 0;
}
}
// /*Application related commands*/
// for (i=0; shell_cmd_list_app.name != 0; i++)
// {
// if (shell_cmd_check(cmd, shell_cmd_list_app.name) == 0)
// {
// shell_cmd_list_app.func(cmd);
// return 0;
// }
// }
if(shell_cmd_list.name == NULL)
{
printf("unkown command\r\n");
return -1;
}
return 0;
}

/********************************************************************************
*
* External interface function implementation
*
****************************************************************************/
/**
*************************************************************************
* \fn void shell_exec_shellcmd(void)
* \brief Execute shell command.
* \note The task cycle calls this function.
*****************************************************************************
*/
void shell_exec_shellcmd(void)
{
if (!shellpassed)
{
shell_check_passwd();
shellpassed = 1;
}
if(shell_read_line(shell_getchar))
{
shell_exec_cmdlist(cmd_buf);
}
}

shell.h

/**
*****************************************************************************
* \brief Platform related (PLATFORM) SHELL module (SHELL) related data structure and interface description.
* \details
* All rights reserved.
* \file shell.h
* \author
* \version 1.0
* \date
* \note Please refer to the notes before use.\n
* \since Newly created
* \par Revision record
* - Initial version
* \par Resource description
* - RAM:
* - ROM:
**************************************************************************
*/

#ifndef _SHELL_H_
#define _SHELL_H_

#ifdef __cplusplus
extern "C" {
#endif

/** \addtogroup PLATFORM PLATFORM
* \{
*/

/** \addtogroup PLATFORM_SHELL PLATFORM_SHELL
* \{
*/
/*****************************************************************************
* *
* Data structure description *
* *
****************************************************************************/

/** \defgroup PLATFORM_SHELL_data PLATFORM_SHELL_data
* \{
*/

typedef void ( * CommandFunc )( void *); /**< shell command callback function*/

/**
* \struct shell_cmd_cfg
* SHELL command structure.
*/
typedef struct
{
unsigned char const* name; /**< shell command name*/
CommandFunc func; /**< shell command callback function*/
char const* helpstr; /**< help string*/
}shell_cmd_cfg;

#define SHELL_PASSWORD_STR "DSWYBS" /**< The shell password is fixed to 6 characters */
#define SHELL_CMDBUF_SIZE 64 /**< The shell command buffer size */


/**
* \}
*/

/*********************************************************************************
*
* Interface function description
*
*************************************************************************/

/** \defgroup PLATFORM_SHELL_if PLATFORM_SHELL_if
* \{
*/

/**
*************************************************************************
* \fn void shell_exec_shellcmd(void)
* \brief Execute shell command.
* \note The task cycle calls this function.
*****************************************************************************
*/
void shell_exec_shellcmd(void);
/**
*****************************************************************************
* \fn int shell_exec_cmdlist(unsigned char* cmd)
* \brief Search for command list and execute.
* retval 0 success
* retval -11 failure
* \note .
*****************************************************************************
*/
int shell_exec_cmdlist(unsigned char* cmd);
/**
* \}
*/

/**
* \}
*/

/**
* \}
*/

#ifdef __cplusplus
}
#endif

#endif

shell_func.c

/**
*****************************************************************************
* \brief Platform layer (PLATFORM) SHELL command module (SHELL_FUN) related interface implementation.
* \details
* All rights reserved.
* \file shell_fun.c
* \author
* \version 1.0
* \date
* \note Platform related commands.\n
* \since Newly created
* \par Revision record
* - Initial version
* \par Resource description
* - RAM:
* - ROM:
**************************************************************************
*/

#include <stdio.h>
#include <time.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include "shell_fun.h"
#include "shell.h"


/********************************************************************************
*
* Internal data
*
****************************************************************************/

const shell_cmd_cfg shell_cmd_list[ ] =
{
/*1. Help related*/
{ (const uint8_t*)"help", HelpFun, "help"}, /*Print help information*/
{ 0, 0 },
};

/********************************************************************************
*
* Internal interface function implementation
*
****************************************************************************/

/********************************************************************************
*
* External interface function implementation
*
****************************************************************************/

/********************************************************************************
*
* Help related
*
****************************************************************************/

void HelpFun(void* param)
{
unsigned int i;
printf("\r\n");
printf("**************\r\n");
printf("* SHELL *\r\n");
printf("* V1.0 *\r\n");
printf("**************\r\n");
printf("\r\n");
for (i=0; shell_cmd_list.name != 0; i++)
{
printf("%02d.",i);
printf("%-16s",shell_cmd_list.name);
printf("%s\r\n",shell_cmd_list.helpstr);
}
}

shell_func.h

/**
*****************************************************************************
* \brief Platform layer (PLATFORM) SHELL command module (SHELL_FUN) related data structure and interface description.
* \details
* All rights reserved.
* \file shell_fun.h
* \author
* \version 1.0
* \date
* \note Platform related commands.\n
* \since Newly created
* \par Revision record
* -
* \par Resource description
* - RAM:
* - ROM:
**************************************************************************
*/

#ifndef __SHELL_FUN_H
#define __SHELL_FUN_H

#ifdef __cplusplus
extern "C" {
#endif

/*****************************************************************************
*
* 帮助相关
*
****************************************************************************/
void HelpFun(void* param);
void DeadTimeFun(void* param);
void DirFun(void* param);
void SpeedFun(void* param);

#ifdef __cplusplus
}
#endif

#endif

Summarize

The above implements a simple eSHELL command line, which can be used for interaction later.

This post is from ARM Technology

Latest reply

This CLI command line implementation, the code is long enough   Details Published on 2023-6-24 21:25
 

1663

Posts

0

Resources
2
 

This CLI command line implementation, the code is long enough

This post is from ARM Technology
 
 
 

Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list