⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 call.c

📁 umon bootloader source code, support mips cpu.
💻 C
字号:
/* call.c:
 *	This code is part of the DEBUG code that allows the monitor to do
 *	some basic debug stuff (go,resume, set breakpoints, etc...).
 *
 *	General notice:
 *	This code is part of a boot-monitor package developed as a generic base
 *	platform for embedded system designs.  As such, it is likely to be
 *	distributed to various projects beyond the control of the original
 *	author.  Please notify the author of any enhancements made or bugs found
 *	so that all may benefit from the changes.  In addition, notification back
 *	to the author will allow the new user to pick up changes that may have
 *	been made by other users after this version of the code was distributed.
 *
 *	Note1: the majority of this code was edited with 4-space tabs.
 *	Note2: as more and more contributions are accepted, the term "author"
 *		   is becoming a mis-representation of credit.
 *
 *	Original author:	Ed Sutter
 *	Email:				esutter@lucent.com
 *	Phone:				908-582-2351
 */
#include "config.h"
#include "cpuio.h"
#include "cpu.h"
#include "genlib.h"
#include "stddefs.h"
#include "cli.h"
#include "warmstart.h"
#include "ctype.h"

#define sizeof	(int)sizeof

char	*ArgvAry[32];	/* Used for passing args to application */


/* Call():
 *	This function is called when the user wants to execute an 
 *	embedded function. 
 *  The the argument is preceded by an ampersand, then a pointer
 *  to the argument is passed to the function instead of a 
 *	strtol() conversion.
 */
char *CallHelp[] = {
	"Call embedded function",
	"-[aqv:] {address} [arg1] [arg2] ...",
#if INCLUDE_VERBOSEHELP
	" -a       pass (argc,argv) function",
	" -q       quiet mode",
	" -v {var} put return val in varname",
#endif
	0,
};

int
Call(int argc,char *argv[])
{
	char	*varname;
	long	args[10];
	int		i, j, ret, opt, useargc, quiet;
	int		(*func)(long,long,long,long,long,long,long,long,long,long);

	quiet = 0;
	useargc = 0;
	varname = (char *)0;
	while((opt=getopt(argc,argv,"aqv:")) != -1) {
		switch(opt) {
		case 'a':
			useargc = 1;
			break;
		case 'q':
			quiet = 1;
			break;
		case 'v':
			varname = optarg;
			break;
		default:
			return(CMD_PARAM_ERROR);
		}
	}

	if ((argc < optind+1) || (argc > optind+11))
		return(CMD_PARAM_ERROR);

	func = (int(*)(long,long,long,long,long,long,long,long,long,long))
			strtol(argv[optind],(char **)0,0);

	if ((func == 0) && (isdigit(argv[optind][0]) == 0)) {
		return(CMD_PARAM_ERROR);
	}

	/* If useargc flag is not set, then retrieve and convert
	 * args from command line.  If the first character of the
	 * argument is an ampersand (&), then a pointer to the argument
	 * is passed; otherwise, the argument is converted to a long
	 * integer using strtol()...
	 */
	if (!useargc) {
		for(j=0,i=optind+1;i<argc;i++,j++) {
			if (argv[i][0] == '&')
				args[j] = (ulong)&argv[i][1];
			else
				args[j] = strtol(argv[i],(char **)0,0);
		}
	}

	ctxAPP();
	EnableBreakInterrupt();
	if (useargc) {
		ret = func(argc-optind,(long)&argv[optind],0,0,0,0,0,0,0,0);
	}
	else {
		ret = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],
			args[7],args[8],args[9]);
	}
	DisableBreakInterrupt();
	ctxMON();

	if (varname)
		shell_sprintf(varname,"0x%x",ret);
	if (!quiet)
		printf("Returned: %d (0x%x)\n",ret,ret);
	return(CMD_SUCCESS);
}

/* Reset():
 *	Used to re-initialize the monitor through the command interface.
 */

char *ResetHelp[] = {
	"Reset monitor firmware",
	"-[xt:]",
#if INCLUDE_VERBOSEHELP
	" -x      app_exit",
	" -t ##   warmstart type",
#endif
	0,
};

int
Reset(int argc,char *argv[])
{
	extern	void appexit(int);
	int	opt;
	volatile int i;

	intsoff();

	/* For some systems, the reset occurs while characters are in the
	 * UART FIFO (so they don't get printed).  Adding this delay will
	 * hopefully allow the characters in the FIFO to drain...
	 */
	for(i=0;i<LoopsPerSecond;i++);

	while((opt=getopt(argc,argv,"xt:")) != -1) {
		switch(opt) {
		case 'x':
			appexit(0);
			break;
		case 't':
			monrestart(atoi(optarg));
			break;
		default:	
			return(CMD_PARAM_ERROR);
		}
	}
	monrestart(INITIALIZE);
	return(CMD_SUCCESS);
}

#if (INCLUDE_TFS | INCLUDE_ARGV)

static void
clearArgVars(void)
{
	int	i;
	char	buf[8];

	for(i=0;i<(sizeof(ArgvAry)/sizeof(char *));i++) {
		sprintf(buf,"ARG%d",i);
		setenv(buf,0);
	}
	setenv("ARGC",0);
}

/* Argv():
 *	Used to display/modify the current argv list that is accessed by
 *	the application through the jump table or through command options.
 */
char *ArgvHelp[] = {
	"Build argv list",
	"-[cilv] [arg0] [arg1] ...",
#if INCLUDE_VERBOSEHELP
	" -c   copy argc to $ARGC (only)",
	" -i   initialize (clear) arglist",
	" -l   list argv strings",
	" -v   copy arglist to $ARG{0-N} and $ARGC",
#endif
	0,
};


int
Argv(int argc,char *argv[])
{
	char	*cp, buf[16];
	int	i, opt;

	while((opt=getopt(argc,argv,"cilv")) != -1) {
		switch(opt) {
		case 'i':
			clearArgVars();
			ArgvAry[0] = (char *)0;
			break;
		case 'c':
			for(i=0;(i<(sizeof(ArgvAry)/sizeof(char *)) && ArgvAry[i]);i++);
			shell_sprintf("ARGC","%d",i);
			break;
		case 'v':
			clearArgVars();
			for(i=0;(i<(sizeof(ArgvAry)/sizeof(char *)) && ArgvAry[i]);i++) {
				sprintf(buf,"ARG%d",i);
				setenv(buf,ArgvAry[i]);
			}
			shell_sprintf("ARGC","%d",i);
			break;
		case 'l':		/* List args */
			for(i=0;(i<(sizeof(ArgvAry)/sizeof(char *)) && ArgvAry[i]);i++)
				printf("\targv[%d]: '%s'\n", i,ArgvAry[i]);
			break;
		default:
			return(CMD_PARAM_ERROR);
		}
	}
	if (optind != 1)
		return(CMD_SUCCESS);

	cp = ((char *)&ArgvAry[0] + (argc-optind+1)*4);
	for(i=optind;i<argc;i++) {
		ArgvAry[i-1] = cp;
		strcpy(cp,argv[i]);
		cp += (strlen(cp) + 1);
	}
	ArgvAry[i-1] = 0;	/* Null terminate the list */
	return(CMD_SUCCESS);
}

int
putargv(int argnum,char *argptr)
{
	if (argnum >= (sizeof(ArgvAry)/sizeof(char *)))
		return(-1);

	ArgvAry[argnum] = argptr;
	return(0);
}

/* getargv():
 *	Provides a hook allowing the downloaded application code to 
 *	handle main(argc,argv) in a painless way.  The Argv[] array
 *	location is returned by get_argv() and is assumed to contain
 *	the NULL terminated list of argv pointers...  Immediately
 *	after the NULL termination is the data that the argv pointers
 *	are referencing.  
 *	This provides a total of 64*4 bytes of space to accomodate
 *	the needs of argv.
 */

void
getargv(int *argc,char ***argv)
{
	int	i;

	if (argv)
		*argv = &ArgvAry[0];
	for(i=0;;i++)
		if (ArgvAry[i] == 0)
			break;
	if (argc)
		*argc = i;
}
#else
void
getargv(int *argc,char ***argv)
{
	if (argc)
		*argc = -1;
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -