finsh.h 9.7 KB
Newer Older
B
bernard.xiong 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * File      : finsh.h
 * This file is part of RT-Thread RTOS
 * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://www.rt-thread.org/license/LICENSE
 *
 * Change Logs:
 * Date           Author       Notes
 * 2010-03-22     Bernard      first version
 */
14 15 16 17 18 19
#ifndef __FINSH_H__
#define __FINSH_H__

#include <rtthread.h>

/* -- the beginning of option -- */
20 21
#define FINSH_NAME_MAX          16      /* max length of identifier */
#define FINSH_NODE_MAX          16      /* max number of node */
22

23 24 25
#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 */
26

B
bernard.xiong 已提交
27
#define FINSH_STACK_MAX         64      /* max stack size */
28
#define FINSH_TEXT_MAX          128     /* max text segment size */
29

30
#define HEAP_ALIGNMENT          4       /* heap alignment */
31 32

#define FINSH_GET16(x)    (*(x)) | (*((x)+1) << 8)
33 34
#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)
35

36 37 38 39 40
#define FINSH_SET16(x, v)           \
    do                              \
    {                               \
        *(x)     = (v) & 0x00ff;    \
        (*((x)+1)) = (v) >> 8;      \
41 42
    } while ( 0 )

43 44 45 46
#define FINSH_SET32(x, v)                                       \
    do                                                          \
    {                                                           \
        *(x)     = (rt_uint32_t)(v)  & 0x000000ff;              \
47 48 49
        (*((x)+1)) = ((rt_uint32_t)(v) >> 8) & 0x000000ff;      \
        (*((x)+2)) = ((rt_uint32_t)(v) >> 16) & 0x000000ff;     \
        (*((x)+3)) = ((rt_uint32_t)(v) >> 24);                  \
50 51 52 53 54
    } while ( 0 )

/* -- the end of option -- */

#if defined(RT_USING_NEWLIB) || defined (RT_USING_MINILIBC)
55
#include <sys/types.h>
56 57 58 59 60
#include <string.h>
#else
typedef unsigned char  u_char;
typedef unsigned short u_short;
typedef unsigned long  u_long;
61

62
#if !defined(__CC_ARM) && !defined(__IAR_SYSTEMS_ICC__)
63
typedef unsigned int size_t;
64 65 66

#ifndef NULL
#define NULL RT_NULL
67
#endif
68 69 70 71 72 73 74 75 76 77 78

#define memset	rt_memset
#define strlen	rt_strlen
#define strncpy	rt_strncpy
#define strncmp	rt_strncmp

int strcmp (const char *s1, const char *s2);
char *strdup(const char *s);

int isalpha( int ch );
int atoi(const char* s);
79 80 81
#else
/* use libc of armcc */
#include <ctype.h>
B
bernard.xiong 已提交
82
#include <stdlib.h>
qiuyiuestc's avatar
qiuyiuestc 已提交
83 84
#include <string.h>
#endif
85 86 87 88 89
#endif

#define FINSH_VERSION_MAJOR			0
#define FINSH_VERSION_MINOR			5

B
bernard.xiong@gmail.com 已提交
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
/**
 * @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 			*/
/*@}*/
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157

typedef long (*syscall_func)();

/* system call table */
struct finsh_syscall
{
	const char*		name;		/* the name of system call */
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
	const char*		desc;		/* description of system call */
#endif
	syscall_func func;		/* the function address of system call */
};
/* system call item */
struct finsh_syscall_item
{
	struct finsh_syscall_item* next;	/* next item */
	struct finsh_syscall syscall;		/* syscall */
};
extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end;
extern struct finsh_syscall_item *global_syscall_list;

/* find out system call, which should be implemented in user program */
struct finsh_syscall* finsh_syscall_lookup(const char* name);

/* 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
	u_char		 type;		/* the type of variable */
	void*		 var ;		/* the address of variable */
};
/* 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);

#ifdef FINSH_USING_SYMTAB
	#ifdef FINSH_USING_DESCRIPTION
B
bernard.xiong@gmail.com 已提交
158 159 160 161 162 163 164 165
		/**
		 * @ingroup finsh
		 *
		 * This macro exports a system function to finsh shell.
		 *
		 * @param name the name of function.
		 * @param desc the description of function, which will show in help.
		 */
166 167 168 169 170 171 172 173 174 175
		#define FINSH_FUNCTION_EXPORT(name, desc)					 \
		const char __fsym_##name##_name[] = #name;					 \
		const char __fsym_##name##_desc[] = #desc;					 \
		const struct finsh_syscall __fsym_##name SECTION("FSymTab")= \
		{							\
			__fsym_##name##_name,	\
			__fsym_##name##_desc,	\
			(syscall_func)&name		\
		};

B
bernard.xiong@gmail.com 已提交
176 177 178 179 180 181 182 183 184
		/**
		 * @ingroup finsh
		 *
		 * This macro exports a variable to finsh shell.
		 *
		 * @param name the name of function.
		 * @param type the type of variable.
		 * @param desc the description of function, which will show in help.
		 */
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
		#define FINSH_VAR_EXPORT(name, type, desc)					\
		const char __vsym_##name##_name[] = #name;					\
		const char __vsym_##name##_desc[] = #desc;					\
		const struct finsh_sysvar __vsym_##name SECTION("VSymTab")=	\
		{							\
			__vsym_##name##_name,	\
			__vsym_##name##_desc,	\
			type, 					\
			(void*)&name			\
		};
	#else
		#define FINSH_FUNCTION_EXPORT(name, desc)					 \
		const char __fsym_##name##_name[] = #name;					 \
		const struct finsh_syscall __fsym_##name SECTION("FSymTab")= \
		{							\
			__fsym_##name##_name,	\
			(syscall_func)&name		\
		};

		#define FINSH_VAR_EXPORT(name, type, desc)					\
		const char __vsym_##name##_name[] = #name;					\
		const struct finsh_sysvar __vsym_##name SECTION("VSymTab")=	\
		{							\
			__vsym_##name##_name,	\
			type, 					\
			(void*)&name			\
		};
	#endif
#else
	#define FINSH_FUNCTION_EXPORT(name, desc)
	#define FINSH_VAR_EXPORT(name, type, desc)
#endif

struct finsh_token
{
	char eof;
	char replay;

	int  position;
	u_char current_token;

	union {
		char char_value;
		int int_value;
		long long_value;
	} value;
	u_char string[128];

	u_char* line;
};

#define FINSH_IDTYPE_VAR		0x01
#define FINSH_IDTYPE_SYSVAR		0x02
#define FINSH_IDTYPE_SYSCALL	0x04
#define FINSH_IDTYPE_ADDRESS	0x08
struct finsh_node
{
	u_char node_type;	/* node node_type */
	u_char data_type;	/* node data node_type */
	u_char 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
{
	u_char* parser_string;

    struct finsh_token token;
	struct finsh_node* root;
};

/**
B
bernard.xiong@gmail.com 已提交
274 275 276
 * @ingroup finsh
 *
 * The basic data type in finsh shell
277
 */
B
bernard.xiong@gmail.com 已提交
278

279
enum finsh_type {
B
bernard.xiong@gmail.com 已提交
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
	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 	*/
295 296 297 298 299 300 301 302
};

/* 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);
303
#ifdef RT_USING_DEVICE
304
void finsh_set_device(const char* device_name);
305
#endif
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325

/* 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 */
u_char finsh_errno(void);
/* get error string */
const char* finsh_error_string(u_char type);

#ifdef RT_USING_HEAP
/**
B
bernard.xiong@gmail.com 已提交
326 327 328
 * @ingroup finsh
 *
 * This function appends a system call to finsh runtime environment
329 330 331 332
 * @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);
B
bernard.xiong@gmail.com 已提交
333

334
/**
B
bernard.xiong@gmail.com 已提交
335 336 337
 * @ingroup finsh
 *
 * This function appends a system variable to finsh runtime environment
338 339 340 341 342 343 344 345
 * @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, u_char type, void* addr);
#endif

#endif