/** * \file Ifx_Shell.h * \brief Shell functions. * \ingroup library_srvsw_sysse_comm_shell * * \version disabled * \copyright Copyright (c) 2013 Infineon Technologies AG. All rights reserved. * * * IMPORTANT NOTICE * * * Use of this file is subject to the terms of use agreed between (i) you or * the company in which ordinary course of business you are acting and (ii) * Infineon Technologies AG or its licensees. If and as long as no such * terms of use are agreed, use of this file is subject to following: * Boost Software License - Version 1.0 - August 17th, 2003 * Permission is hereby granted, free of charge, to any person or * organization obtaining a copy of the software and accompanying * documentation covered by this license (the "Software") to use, reproduce, * display, distribute, execute, and transmit the Software, and to prepare * derivative works of the Software, and to permit third-parties to whom the * Software is furnished to do so, all subject to the following: * The copyright notices in the Software and this entire statement, including * the above license grant, this restriction and the following disclaimer, must * be included in all copies of the Software, in whole or in part, and all * derivative works of the Software, unless such copies or derivative works are * solely in the form of machine-executable object code generated by a source * language processor. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * \defgroup library_srvsw_sysse_comm_shell Shell * This module implements the Shell functions. * It parses a command line and call the corresponding command execution. * Multiple command list can be used in parallel. * * Only full command match is accepted. * * New feature / change: * - Prefix can be defined for each command list * - Help for a single command is displayed with "help " * - help for a command list is displayed with "help " * - command short cut is not allowed * - command with identical start option "opt1 opt2" and "opt1 opt3" are accepted, and root to different handlers * - Enhanced help info print * * Help text xyntax: * - /p indicates a parameter description, can be multi-line, lines must be separated with ENDL * - /s Indicates a syntax help * * Example of help list: * \code * Ifx_Shell_Command Ifx_g_OsciShell_commands[] = * { * {IFX_OSCI_SHELL_PREFIX, " : Oscilloscope functions" * , NULL_PTR, NULL_PTR }, * {"run", " : run the oscilloscope"ENDL * "/s run [single|auto|normal]" * , NULL_PTR, &Ifx_OsciShell_run }, * {"stop", " : stop oscilloscope" * , NULL_PTR, &Ifx_OsciShell_stop }, * {"trigger", " : trigger settings"ENDL * "/s trigger [force|single|level |raising|falling|source |interval ]"ENDL * "/p force: Force the trigger"ENDL * "/p single: Single the trigger"ENDL * "/p level : Set trigger level to value"ENDL * "/p [raising|falling]: Set trigger to raising or falling edges"ENDL * "/p source : Set trigger channel number"ENDL * " can be obtained with 'channel' command"ENDL * "/p interval : Set sampling interval to value" * * , NULL_PTR, &Ifx_OsciShell_trigger }, * {"status", " : display status" * , NULL_PTR, &Ifx_OsciShell_status }, * {"channel", " : channel information"ENDL * "/s channel: Show the channels information"ENDL * "/s channel : Assign a signal to a channel" * , NULL_PTR, &Ifx_OsciShell_channel }, * {"analyze", " : signal analysis of a ch"ENDL * "/s analyze : analyze the input channel " * , NULL_PTR, &Ifx_OsciShell_analyze }, * {"simulate", " : simulate a signal"ENDL * "/s simulate : Simulate a signal generation"ENDL * "/p : {0 .. Channel count}"ENDL * "/p : {add,sub,mul,clr}"ENDL * "/p : {sine,square}"ENDL * "/p : -INF .. INF"ENDL * "/p : -INF .. INF"ENDL * "/p : -INF .. INF"ENDL * "/p : 0 .. 360 [degree]"ENDL * "/s simulate atan : Compute atan(ych/xch) and store in channel " * , NULL_PTR, &Ifx_OsciShell_simulate}, * {"dump", " : dump values (all channels)"ENDL * "/s dump [hex]"ENDL * "/p : Dump the values of the channel "ENDL * "/p hex: If hex is specified, values will be in hexadecimal" * , NULL_PTR, &Ifx_OsciShell_dump }, * IFX_SHELL_COMMAND_LIST_END, * }; * \endcode * * To enable help command, include the below command in the main command list * {"help", SHELL_HELP_DESCRIPTION_TEXT , &\, &Ifx_Shell_showHelp, }, * * \ingroup library_srvsw_sysse_comm * */ #ifndef IFX_SHELL_H #define IFX_SHELL_H 1 //---------------------------------------------------------------------------------------- #include "StdIf/IfxStdIf_DPipe.h" #include "Ifx_Cfg.h" //---------------------------------------------------------------------------------------- #define IFX_SHELL_NULL_CHAR '\0' #ifndef IFX_CFG_SHELL_CMD_HISTORY_SIZE #define IFX_CFG_SHELL_CMD_HISTORY_SIZE (10) /**<\brief Number of commands to store in history */ #endif #ifndef IFX_CFG_SHELL_CMD_LINE_SIZE #define IFX_CFG_SHELL_CMD_LINE_SIZE (128) /**<\brief max command line IFX_CFG_SHELL_CMD_LINE_SIZE - 1 */ #endif #ifndef IFX_CFG_SHELL_COMMAND_LISTS #define IFX_CFG_SHELL_COMMAND_LISTS (1) /**<\brief Number of command lists */ #endif #ifndef IFX_CFG_SHELL_PROMPT #define IFX_CFG_SHELL_PROMPT "Shell>" /**<\brief Shell prompt */ #endif #define SHELL_HELP_DESCRIPTION_TEXT \ " : Display command list, and command help."ENDL \ "/s help: show all commands"ENDL \ "/s help : show the command details" /** \brief Marker for end of command list, the end of list is detected by commandLine=NULL */ #define IFX_SHELL_COMMAND_LIST_END {0, 0, 0, 0} /** \brief Marker for end of syntax list */ #define IFX_SHELL_SYNTAX_LIST_END {0, 0} /** \brief Signifies no item in use in command history list */ #define IFX_SHELL_CMD_HISTORY_NO_ITEM (-1) //---------------------------------------------------------------------------------------- /** \brief Result code definition used after each executed Shell command */ typedef enum { Ifx_Shell_ResultCode_unknown = (128), Ifx_Shell_ResultCode_nok = (129), Ifx_Shell_ResultCode_undefined = (130), Ifx_Shell_ResultCode_ok = (255) } Ifx_Shell_ResultCode; /** \brief Definition of a callback function which handles a Shell command */ typedef boolean (*Ifx_Shell_Call)(pchar args, void *data, IfxStdIf_DPipe *io); /** \brief Shell command object */ typedef struct { pchar commandLine; pchar help; void *data; Ifx_Shell_Call call; } Ifx_Shell_Command; /** \brief Command line editing state */ typedef struct { char *cmdStr; /**< \brief Pointer to current string containing command line as so far processed */ Ifx_SizeT cursor; /**< \brief Pointer to variable containing position of cursor in so-far-processed command line */ Ifx_SizeT length; /**< \brief Pointer to variable containing total length of command line */ boolean historyAdd; /**< \brief If TRUE, when Enter is pressed, the current cmdLine should be added to the command history (in parent) */ Ifx_SizeT historyItem; /**< \brief Item ID in command history list, or IFX_SHELL_CMD_HISTORY_NO_ITEM if not using list (e.g. new command) */ } Ifx_Shell_CmdLine; /** \brief Shell command processing state */ typedef enum { IFX_SHELL_CMD_STATE_NORMAL, /**< \brief Normal - no special sequences being processed */ IFX_SHELL_CMD_STATE_ESCAPE, /**< \brief Escape character has been pressed */ IFX_SHELL_CMD_STATE_ESCAPE_BRACKET, /**< \brief ESC [ pressed */ IFX_SHELL_CMD_STATE_ESCAPE_BRACKET_NUMBER /**< \brief ESC [ (number) pressed */ } Ifx_Shell_CmdState; /** \brief Shell protocol configuration */ typedef struct { boolean (*start)(void *protocol, IfxStdIf_DPipe *io); void (*execute)(void *protocol); void (*onStart)(void *protocol, void *data); void *onStartData; void *object; boolean started; } Ifx_Shell_Protocol; /** \brief Shell control flags */ typedef struct { uint16 showPrompt : 1; uint16 enabled : 1; uint16 sendResultCode : 1; uint16 echo : 1; uint16 echoError : 1; } Ifx_Shell_Flags; /** \brief internal Shell run-time data */ typedef struct { char echo[2]; char inputbuffer[IFX_CFG_SHELL_CMD_LINE_SIZE + 1]; char cmdStr[IFX_CFG_SHELL_CMD_LINE_SIZE]; Ifx_Shell_CmdState cmdState; char escBracketNum; } Ifx_Shell_Runtime; typedef Ifx_Shell_Command *Ifx_Shell_CommandList; typedef const Ifx_Shell_Command *Ifx_Shell_CommandListConst; /** * \brief Shell object definition */ typedef struct { IfxStdIf_DPipe *io; /**< \brief Pointer to IfxStdIf_DPipe object used by the Shell */ Ifx_Shell_Flags control; /**< \brief control flags */ /** \brief Array of pointers to the history entries */ char *cmdHistory[IFX_CFG_SHELL_CMD_HISTORY_SIZE]; /** \brief Current status of command line editing (saves passing many parameters around) */ Ifx_Shell_CmdLine cmd; Ifx_Shell_Runtime locals; /**< \brief Runtime data */ /** \brief Array of pointers to command list. The pointed location shall be constant * during Shell lifetime, e.g. stored in non-volatile memory or as global variable * * The 1st item in the list is use as a group command prefix if its "call" parameter is NULL pointer, else it is use as other entries. * In case "call" is NULL, the corresponding 'data' is ignored, and the 'help' is displayed. * **/ Ifx_Shell_CommandListConst commandList[IFX_CFG_SHELL_COMMAND_LISTS]; Ifx_Shell_Protocol protocol; /**< \brief Protocol handler data */ } Ifx_Shell; /** * \brief Shell configuration. */ typedef struct { IfxStdIf_DPipe *standardIo; /**<\brief Pointer to a IfxStdIf_DPipe object used by the Shell */ boolean echo; /**<\brief Specifies whether each command shall be echoed back to user */ boolean showPrompt; /**<\brief Specifies whether the IFX_CFG_SHELL_PROMPT shall be displayed after each command */ boolean sendResultCode; /**<\brief Specifies whether the Ifx_Shell_ResultCode shall be sent to user */ Ifx_Shell_CommandListConst commandList[IFX_CFG_SHELL_COMMAND_LISTS]; /**< \brief Specifies pointer to the command list */ Ifx_Shell_Protocol protocol; /**<\brief Configuration for the Ifx_Shell_Protocol */ } Ifx_Shell_Config; /** * \brief Shell Syntax Description. */ typedef struct { pchar syntax; /**<\brief syntax */ pchar description; /**<\brief description */ } Ifx_Shell_Syntax; //---------------------------------------------------------------------------------------- /** \addtogroup library_srvsw_sysse_comm_shell * \{ */ /** \name Basic functionality * \{ */ /** Set the config default parameter * * \param config Pointer to the configuration structure to be initialized */ void Ifx_Shell_initConfig(Ifx_Shell_Config *config); /** * \brief Initialize the shell * \param shell Pointer to the \ref Ifx_Shell object * \param config Pointer to the configuration structure */ IFX_EXTERN boolean Ifx_Shell_init(Ifx_Shell *shell, const Ifx_Shell_Config *config); /** * \brief Deinitialise the shell * \param shell Pointer to the \ref Ifx_Shell object */ IFX_EXTERN void Ifx_Shell_deinit(Ifx_Shell *shell); /** * \brief Clear the receive buffer and enable the shell * \param shell Pointer to the \ref Ifx_Shell object */ IFX_EXTERN void Ifx_Shell_enable(Ifx_Shell *shell); /** * \brief Disable the shell * \param shell Pointer to the \ref Ifx_Shell object */ IFX_EXTERN void Ifx_Shell_disable(Ifx_Shell *shell); /** * \brief Process the shell. * * This function shall be called within a loop or periodic timer to guarantee the correct * processing of the incoming/received data. * * \param shell Pointer to the \ref Ifx_Shell object */ IFX_EXTERN void Ifx_Shell_process(Ifx_Shell *shell); /** \} */ //---------------------------------------------------------------------------------------- /** \name Parsing functions * \{ */ /** * \brief Within the context of Shell.call, skip the whitespaces of the args string. * \param args Pointer to the original string * \return Pointer to the string after skipping the whitespaces */ IFX_EXTERN pchar Ifx_Shell_skipWhitespace(pchar args); /** * \brief Match string pointed by the *argsPtr with a given token * \param argsPtr Pointer to the argument null-terminated string * \param token Pointer to the token string to match * \retval TRUE if the given token match with the string pointed by argsPtr */ IFX_EXTERN boolean Ifx_Shell_matchToken(pchar *argsPtr, pchar token); /** * \brief Parse a token * Return the next token in tokenBuffer and move the argsPtr pointer after this token * \param argsPtr Pointer to the argument null-terminated string * \param tokenBuffer Pointer to the value storage * \param bufferLength Maximum parsing length */ IFX_EXTERN boolean Ifx_Shell_parseToken(pchar *argsPtr, char *tokenBuffer, int bufferLength); /** * \brief Parse an address * \param argsPtr Pointer to the argument null-terminated string * \param address Pointer to the value storage */ IFX_EXTERN boolean Ifx_Shell_parseAddress(pchar *argsPtr, void **address); /** * \brief Parse a signed 32-bit integer value * \param argsPtr Pointer to the argument null-terminated string * \param value Pointer to the value storage */ IFX_EXTERN boolean Ifx_Shell_parseSInt32(pchar *argsPtr, sint32 *value); /** * \brief Parse an unsigned 32-bit integer value * \param argsPtr Pointer to the argument null-terminated string * \param value Pointer to the value storage * \param hex if TRUE, hex parsing will be done, else decimal parsing */ IFX_EXTERN boolean Ifx_Shell_parseUInt32(pchar *argsPtr, uint32 *value, boolean hex); /** * \brief Parse a signed 64-bit integer value * \param argsPtr Pointer to the argument null-terminated string * \param value Pointer to the value storage */ IFX_EXTERN boolean Ifx_Shell_parseSInt64(pchar *argsPtr, sint64 *value); /** * \brief Parse an unsigned 64-bit integer value * \param argsPtr Pointer to the argument null-terminated string * \param value Pointer to the value storage * \param hex if TRUE, hex parsing will be done, else decimal parsing */ IFX_EXTERN boolean Ifx_Shell_parseUInt64(pchar *argsPtr, uint64 *value, boolean hex); /** * \brief Parse a 64-bit (double precision) floating-point value * \param argsPtr Pointer to the argument null-terminated string * \param value Pointer to the value storage */ IFX_EXTERN boolean Ifx_Shell_parseFloat64(pchar *argsPtr, float64 *value); /** * \brief Parse a 32-bit (single precision) floating-point value * \param argsPtr Pointer to the argument null-terminated string * \param value Pointer to the value storage */ IFX_EXTERN boolean Ifx_Shell_parseFloat32(pchar *argsPtr, float32 *value); /** \} */ //---------------------------------------------------------------------------------------- /** \name Command list functions * \{ */ /** * \brief Find command in command List * \param commandList Pointer to the first entry of an array of \ref Ifx_Shell_Command * \param commandLine Pointer to null-terminated string containings the command to search. * \param args Pointer to the argument null-terminated string * \param match Return the number of arguments that matches */ IFX_EXTERN const Ifx_Shell_Command *Ifx_Shell_commandFind(Ifx_Shell_CommandListConst commandList, pchar commandLine, pchar *args, uint32 *match); /** * \brief Implementation of \ref Ifx_Shell_Call. Show the help menu from single command list. * \param commandList Pointer to an array of Ifx_Shell_Command * \param io Pointer to the IfxStdIf_DPipe object * \param briefOnly if TRUE, show only the brief description, else show the full description * \param singleCommand If TRUE, only show the 1st command pointed by commandList, else show the full list */ IFX_EXTERN boolean Ifx_Shell_showHelpSingle(Ifx_Shell_CommandListConst commandList, IfxStdIf_DPipe *io, boolean briefOnly, boolean singleCommand); /** * \brief Implementation of \ref Ifx_Shell_Call. Show the help menu and list of commands. * \param args The argument null-terminated string * \param shellPtr Pointer to a Shell object * \param io Pointer to \ref IfxStdIf_DPipe object */ IFX_EXTERN boolean Ifx_Shell_showHelp(pchar args, void *shellPtr, IfxStdIf_DPipe *io); /** * \brief Implementation of \ref Ifx_Shell_Call. print the syntax. * \param syntaxList Pointer to syntax list * \param io Pointer to \ref IfxStdIf_DPipe object */ IFX_EXTERN void Ifx_Shell_printSyntax(const Ifx_Shell_Syntax *syntaxList, IfxStdIf_DPipe *io); /** \} */ //---------------------------------------------------------------------------------------- /** \name Sub protocol functions * \{ */ /** * \brief Implementation of \ref Ifx_Shell_Call. Start the Shell protocol. * \param args The argument null-terminated string * \param data Pointer to \ref Ifx_Shell object * \param io Pointer to \ref IfxStdIf_DPipe object */ IFX_EXTERN boolean Ifx_Shell_protocolStart(pchar args, void *data, IfxStdIf_DPipe *io); /** * \brief Implementation of \ref Ifx_Shell_Call. Start the ShellBb protocol. * \param args The argument null-terminated string * \param data Pointer to \ref Ifx_Shell object * \param io Pointer to \ref IfxStdIf_DPipe object */ IFX_EXTERN boolean Ifx_Shell_bbProtocolStart(pchar args, void *data, IfxStdIf_DPipe *io); /** \} */ //---------------------------------------------------------------------------------------- /** \} */ #endif