250 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			250 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Copyright (c) 2006-2021, RT-Thread Development Team
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * SPDX-License-Identifier: Apache-2.0
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Change Logs:
							 | 
						||
| 
								 | 
							
								 * Date           Author       Notes
							 | 
						||
| 
								 | 
							
								 * 2010-03-22     Bernard      first version
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								#ifndef __FINSH_H__
							 | 
						||
| 
								 | 
							
								#define __FINSH_H__
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <rtthread.h>
							 | 
						||
| 
								 | 
							
								#include "finsh_api.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* -- the beginning of option -- */
							 | 
						||
| 
								 | 
							
								#define FINSH_NAME_MAX          16      /* max length of identifier */
							 | 
						||
| 
								 | 
							
								#define FINSH_NODE_MAX          16      /* max number of node */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define FINSH_HEAP_MAX          128     /* max length of heap */
							 | 
						||
| 
								 | 
							
								#define FINSH_STRING_MAX        128     /* max length of string */
							 | 
						||
| 
								 | 
							
								#define FINSH_VARIABLE_MAX      8       /* max number of variable */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define FINSH_STACK_MAX         64      /* max stack size */
							 | 
						||
| 
								 | 
							
								#define FINSH_TEXT_MAX          128     /* max text segment size */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define HEAP_ALIGNMENT          4       /* heap alignment */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define FINSH_GET16(x)    (*(x)) | (*((x)+1) << 8)
							 | 
						||
| 
								 | 
							
								#define FINSH_GET32(x)    (rt_uint32_t)(*(x)) | ((rt_uint32_t)*((x)+1) << 8) | \
							 | 
						||
| 
								 | 
							
								    ((rt_uint32_t)*((x)+2) << 16) | ((rt_uint32_t)*((x)+3) << 24)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define FINSH_SET16(x, v)           \
							 | 
						||
| 
								 | 
							
								    do                              \
							 | 
						||
| 
								 | 
							
								    {                               \
							 | 
						||
| 
								 | 
							
								        *(x)     = (v) & 0x00ff;    \
							 | 
						||
| 
								 | 
							
								        (*((x)+1)) = (v) >> 8;      \
							 | 
						||
| 
								 | 
							
								    } while ( 0 )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define FINSH_SET32(x, v)                                       \
							 | 
						||
| 
								 | 
							
								    do                                                          \
							 | 
						||
| 
								 | 
							
								    {                                                           \
							 | 
						||
| 
								 | 
							
								        *(x)     = (rt_uint32_t)(v)  & 0x000000ff;              \
							 | 
						||
| 
								 | 
							
								        (*((x)+1)) = ((rt_uint32_t)(v) >> 8) & 0x000000ff;      \
							 | 
						||
| 
								 | 
							
								        (*((x)+2)) = ((rt_uint32_t)(v) >> 16) & 0x000000ff;     \
							 | 
						||
| 
								 | 
							
								        (*((x)+3)) = ((rt_uint32_t)(v) >> 24);                  \
							 | 
						||
| 
								 | 
							
								    } while ( 0 )
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* -- the end of option -- */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* std header file */
							 | 
						||
| 
								 | 
							
								#include <stdio.h>
							 | 
						||
| 
								 | 
							
								#include <ctype.h>
							 | 
						||
| 
								 | 
							
								#include <stdlib.h>
							 | 
						||
| 
								 | 
							
								#include <stdint.h>
							 | 
						||
| 
								 | 
							
								#include <string.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define FINSH_VERSION_MAJOR         1
							 | 
						||
| 
								 | 
							
								#define FINSH_VERSION_MINOR         0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @addtogroup finsh
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								/*@{*/
							 | 
						||
| 
								 | 
							
								#define FINSH_ERROR_OK              0   /**< No error           */
							 | 
						||
| 
								 | 
							
								#define FINSH_ERROR_INVALID_TOKEN   1   /**< Invalid token      */
							 | 
						||
| 
								 | 
							
								#define FINSH_ERROR_EXPECT_TYPE     2   /**< Expect a type      */
							 | 
						||
| 
								 | 
							
								#define FINSH_ERROR_UNKNOWN_TYPE    3   /**< Unknown type       */
							 | 
						||
| 
								 | 
							
								#define FINSH_ERROR_VARIABLE_EXIST  4   /**< Variable exist     */
							 | 
						||
| 
								 | 
							
								#define FINSH_ERROR_EXPECT_OPERATOR 5   /**< Expect a operator  */
							 | 
						||
| 
								 | 
							
								#define FINSH_ERROR_MEMORY_FULL     6   /**< Memory full        */
							 | 
						||
| 
								 | 
							
								#define FINSH_ERROR_UNKNOWN_OP      7   /**< Unknown operator   */
							 | 
						||
| 
								 | 
							
								#define FINSH_ERROR_UNKNOWN_NODE    8   /**< Unknown node       */
							 | 
						||
| 
								 | 
							
								#define FINSH_ERROR_EXPECT_CHAR     9   /**< Expect a character */
							 | 
						||
| 
								 | 
							
								#define FINSH_ERROR_UNEXPECT_END    10  /**< Unexpect end       */
							 | 
						||
| 
								 | 
							
								#define FINSH_ERROR_UNKNOWN_TOKEN   11  /**< Unknown token      */
							 | 
						||
| 
								 | 
							
								#define FINSH_ERROR_NO_FLOAT        12  /**< Float not supported */
							 | 
						||
| 
								 | 
							
								#define FINSH_ERROR_UNKNOWN_SYMBOL  13  /**< Unknown symbol     */
							 | 
						||
| 
								 | 
							
								#define FINSH_ERROR_NULL_NODE       14  /**< Null node          */
							 | 
						||
| 
								 | 
							
								/*@}*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* system call item */
							 | 
						||
| 
								 | 
							
								struct finsh_syscall_item
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    struct finsh_syscall_item* next;    /* next item */
							 | 
						||
| 
								 | 
							
								    struct finsh_syscall syscall;       /* syscall */
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								extern struct finsh_syscall_item *global_syscall_list;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* system variable table */
							 | 
						||
| 
								 | 
							
								struct finsh_sysvar
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    const char*     name;       /* the name of variable */
							 | 
						||
| 
								 | 
							
								#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
							 | 
						||
| 
								 | 
							
								    const char*     desc;       /* description of system variable */
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								    uint8_t      type;      /* the type of variable */
							 | 
						||
| 
								 | 
							
								    void*        var ;      /* the address of variable */
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
							 | 
						||
| 
								 | 
							
								struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call);
							 | 
						||
| 
								 | 
							
								struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call);
							 | 
						||
| 
								 | 
							
								#define FINSH_NEXT_SYSCALL(index)  index=finsh_syscall_next(index)
							 | 
						||
| 
								 | 
							
								#define FINSH_NEXT_SYSVAR(index)   index=finsh_sysvar_next(index)
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								#define FINSH_NEXT_SYSCALL(index)  index++
							 | 
						||
| 
								 | 
							
								#define FINSH_NEXT_SYSVAR(index)   index++
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* system variable item */
							 | 
						||
| 
								 | 
							
								struct finsh_sysvar_item
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    struct finsh_sysvar_item *next;     /* next item */
							 | 
						||
| 
								 | 
							
								    struct finsh_sysvar sysvar;         /* system variable */
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								extern struct finsh_sysvar *_sysvar_table_begin, *_sysvar_table_end;
							 | 
						||
| 
								 | 
							
								extern struct finsh_sysvar_item* global_sysvar_list;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* find out system variable, which should be implemented in user program */
							 | 
						||
| 
								 | 
							
								struct finsh_sysvar* finsh_sysvar_lookup(const char* name);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct finsh_token
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    char eof;
							 | 
						||
| 
								 | 
							
								    char replay;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    int  position;
							 | 
						||
| 
								 | 
							
								    uint8_t current_token;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    union {
							 | 
						||
| 
								 | 
							
								        char char_value;
							 | 
						||
| 
								 | 
							
								        int int_value;
							 | 
						||
| 
								 | 
							
								        long long_value;
							 | 
						||
| 
								 | 
							
								    } value;
							 | 
						||
| 
								 | 
							
								    uint8_t string[FINSH_STRING_MAX];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    uint8_t* line;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define FINSH_IDTYPE_VAR        0x01
							 | 
						||
| 
								 | 
							
								#define FINSH_IDTYPE_SYSVAR     0x02
							 | 
						||
| 
								 | 
							
								#define FINSH_IDTYPE_SYSCALL    0x04
							 | 
						||
| 
								 | 
							
								#define FINSH_IDTYPE_ADDRESS    0x08
							 | 
						||
| 
								 | 
							
								struct finsh_node
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t node_type;  /* node node_type */
							 | 
						||
| 
								 | 
							
								    uint8_t data_type;  /* node data node_type */
							 | 
						||
| 
								 | 
							
								    uint8_t idtype;     /* id node information */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    union {         /* value node */
							 | 
						||
| 
								 | 
							
								        char    char_value;
							 | 
						||
| 
								 | 
							
								        short   short_value;
							 | 
						||
| 
								 | 
							
								        int     int_value;
							 | 
						||
| 
								 | 
							
								        long    long_value;
							 | 
						||
| 
								 | 
							
								        void*   ptr;
							 | 
						||
| 
								 | 
							
								    } value;
							 | 
						||
| 
								 | 
							
								    union
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        /* point to variable identifier or function identifier */
							 | 
						||
| 
								 | 
							
								        struct finsh_var    *var;
							 | 
						||
| 
								 | 
							
								        struct finsh_sysvar *sysvar;
							 | 
						||
| 
								 | 
							
								        struct finsh_syscall*syscall;
							 | 
						||
| 
								 | 
							
								    }id;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* sibling and child node */
							 | 
						||
| 
								 | 
							
								    struct finsh_node *sibling, *child;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct finsh_parser
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    uint8_t* parser_string;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    struct finsh_token token;
							 | 
						||
| 
								 | 
							
								    struct finsh_node* root;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @ingroup finsh
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * The basic data type in finsh shell
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								enum finsh_type {
							 | 
						||
| 
								 | 
							
								    finsh_type_unknown = 0, /**< unknown data type */
							 | 
						||
| 
								 | 
							
								    finsh_type_void,        /**< void           */
							 | 
						||
| 
								 | 
							
								    finsh_type_voidp,       /**< void pointer   */
							 | 
						||
| 
								 | 
							
								    finsh_type_char,        /**< char           */
							 | 
						||
| 
								 | 
							
								    finsh_type_uchar,       /**< unsigned char  */
							 | 
						||
| 
								 | 
							
								    finsh_type_charp,       /**< char pointer   */
							 | 
						||
| 
								 | 
							
								    finsh_type_short,       /**< short          */
							 | 
						||
| 
								 | 
							
								    finsh_type_ushort,      /**< unsigned short */
							 | 
						||
| 
								 | 
							
								    finsh_type_shortp,      /**< short pointer  */
							 | 
						||
| 
								 | 
							
								    finsh_type_int,         /**< int            */
							 | 
						||
| 
								 | 
							
								    finsh_type_uint,        /**< unsigned int   */
							 | 
						||
| 
								 | 
							
								    finsh_type_intp,        /**< int pointer    */
							 | 
						||
| 
								 | 
							
								    finsh_type_long,        /**< long           */
							 | 
						||
| 
								 | 
							
								    finsh_type_ulong,       /**< unsigned long  */
							 | 
						||
| 
								 | 
							
								    finsh_type_longp        /**< long pointer   */
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* init finsh environment */
							 | 
						||
| 
								 | 
							
								int finsh_init(struct finsh_parser* parser);
							 | 
						||
| 
								 | 
							
								/* flush finsh node, text segment */
							 | 
						||
| 
								 | 
							
								int finsh_flush(struct finsh_parser* parser);
							 | 
						||
| 
								 | 
							
								/* reset all of finsh */
							 | 
						||
| 
								 | 
							
								int finsh_reset(struct finsh_parser* parser);
							 | 
						||
| 
								 | 
							
								#ifdef RT_USING_DEVICE
							 | 
						||
| 
								 | 
							
								void finsh_set_device(const char* device_name);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* run finsh parser to generate abstract synatx tree */
							 | 
						||
| 
								 | 
							
								void finsh_parser_run (struct finsh_parser* parser, const unsigned char* string);
							 | 
						||
| 
								 | 
							
								/* run compiler to compile abstract syntax tree */
							 | 
						||
| 
								 | 
							
								int finsh_compiler_run(struct finsh_node* node);
							 | 
						||
| 
								 | 
							
								/* run finsh virtual machine */
							 | 
						||
| 
								 | 
							
								void finsh_vm_run(void);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* get variable value */
							 | 
						||
| 
								 | 
							
								struct finsh_var* finsh_var_lookup(const char* name);
							 | 
						||
| 
								 | 
							
								/* get bottom value of stack */
							 | 
						||
| 
								 | 
							
								long finsh_stack_bottom(void);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* get error number of finsh */
							 | 
						||
| 
								 | 
							
								uint8_t finsh_errno(void);
							 | 
						||
| 
								 | 
							
								/* get error string */
							 | 
						||
| 
								 | 
							
								const char* finsh_error_string(uint8_t type);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef RT_USING_HEAP
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @ingroup finsh
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This function appends a system call to finsh runtime environment
							 | 
						||
| 
								 | 
							
								 * @param name the name of system call
							 | 
						||
| 
								 | 
							
								 * @param func the function pointer of system call
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								void finsh_syscall_append(const char* name, syscall_func func);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @ingroup finsh
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * This function appends a system variable to finsh runtime environment
							 | 
						||
| 
								 | 
							
								 * @param name the name of system variable
							 | 
						||
| 
								 | 
							
								 * @param type the data type of system variable
							 | 
						||
| 
								 | 
							
								 * @param addr the address of system variable
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								void finsh_sysvar_append(const char* name, uint8_t type, void* addr);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								#endif
							 |