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

📄 monitor_cmd.c

📁 开放源码实时操作系统源码.
💻 C
📖 第 1 页 / 共 4 页
字号:
//==========================================================================
//
//      monitor_cmd.c
//
//      Monitor commands for the CygMON ROM monitor
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):    
// Contributors: gthomas, dmoseley
// Date:         1999-10-20
// Purpose:      Monitor commands for the CygMON ROM monitor
// Description:  
//               
//
//####DESCRIPTIONEND####
//
//=========================================================================

#ifdef HAVE_BSP
#include "cpu_info.h"
#include <bsp/bsp.h>
#include <bsp/cpu.h>
#include <bsp/hex-utils.h>
#ifdef __BOARD_HEADER__
#include __BOARD_HEADER__
#endif
#endif
#include <board.h>
#include <unistd.h>
#include <stdlib.h>
#include <monitor.h>
#include <ledit.h>
#include <string.h>
#include <ctype.h>

#ifdef HAVE_BSP
#include "fmt_util.h"
#include "tservice.h"
#endif

#ifdef __ECOS__
#include <cyg/hal/hal_stub.h>
#endif

#if USE_CYGMON_PROTOTYPES
/* Use common prototypes */
/* Some of the composed board.h files compose these
   prototypes redundently, but if they dont,
   these are the common definitions */
#include "fmt_util.h"   /* Interface to string formatting utilities */
#include "tservice.h"   /* Interface to target specific services */
#include "generic-stub.h" /* from libstub */
#endif /* USE_CYGMON_PROTOTYPES */

static int history_cmd(cmdmode_t mode) ;

#ifndef MAXLINELEN
#define MAXLINELEN 80
#endif

#define MAXLINES 23

char inbuf[MAXLINELEN] ;
static char cmd[MAXLINELEN];

#if ! defined(PROVIDE_CRASH_CMD)
#define PROVIDE_CRASH_CMD 0
#endif

#if PROVIDE_CRASH_CMD
/*
 * The crash command is used while debugging cygmon itself
 */
static int crash_cmd(cmdmode_t mode) ; /* Command to trap into cygmon */
#endif

struct cmdentry cmdtab[] = {
  {NULL, "baud",        set_serial_speed_cmd},
  {"b",  "break",       breakpoint_cmd},
#if HAVE_CACHE
  {NULL, "cache",       cache_cmd},
#endif
  {NULL, "copy",        copy_cmd},
#if PROVIDE_CRASH_CMD
  {NULL, "crash",       crash_cmd},
#endif
  {NULL, "crc",         checksumcmd},
  {"d",  "disassemble", disassemble_cmd},
  {NULL, "dump",        dump_cmd},
#if defined(NVRAM_ETH_ADDR)
  {NULL, "ethaddr",     ethaddr_cmd},
#endif
  {NULL, "fill",        fill_cmd},
  {NULL, "go",          go_cmd},
  {NULL, "help",        help_cmd},
  {"his","history",     history_cmd},
#ifdef MONITOR_CONTROL_INTERRUPTS
  {NULL, "interrupt",   int_cmd},
#endif
#if defined(NVRAM_IP_ADDR)
  {NULL, "ipaddr",      ipaddr_cmd},
#endif
  {NULL, "load",        load_cmd},
  {"m",  "memory",      mem_cmd},
#ifdef OTHERNAMES_CMD
  {"o",  "othernames",  othernames_cmd},
#endif
  {NULL, "port",        set_serial_port_cmd},
  {"r",  "register",    reg_cmd},
  {NULL, "reset",       reset_cmd},
#ifndef HAVE_BSP
  {NULL, "setargs",     set_program_args_cmd},
#endif
  {"si", "step",        step_cmd},
  {NULL, "swapmem",     swapmem_cmd},
#if defined(NVRAM_TCP_PORT)
  {NULL, "tcpport",     tcpport_cmd},
#endif
  {NULL, "terminal",    set_term_cmd},
#ifdef HAS_TIMER
  {NULL, "timer",       timer_cmd},
#endif
#if !defined(__ECOS__) || defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
  {NULL, "transfer",    transfer_cmd},
#endif
  {"u",  "unbreak",     clear_breakpoint_cmd},
#if HAVE_USAGE
  {NULL, "usage",       memusage_cmd},
#endif
  {NULL, "version",     version_cmd},
  /* Really need to redo the way commands are done--there should be a
     dynamic list (perhaps in addition to the static one). */
#ifdef TARGET_COMMANDS
  TARGET_COMMANDS
#endif

  {NULL, NULL, NULL}
};

static int 
alias_compare (char *cmd)
{
  int m = 0;
  int match = -1;
  int num_matches = 0;

  while (cmdtab[m].cmd != NULL)
    {
      if (cmdtab[m].alias != NULL && !strcmp (cmd, cmdtab[m].alias))
	{
	  match = m;
	  num_matches++;
	  /* We're expecting that aliases will be defined 
	     uniquely, but just in case, we let the user know 
	     if there is a conflict */
	  if (num_matches > 1)
	    {
	      xprintf ("Alias conflict. Executing last matching alias.\n");
	    }
	}
      m++;
    }
  return match;
}

static int
command_compare (char *cmd)
{
  int m = 0;
  int match = -1;
  int num_matches = 0;
  int cmdlen = strlen(cmd) ;
  while (cmdtab[m].cmd != NULL)
    {
      if (!(strncmp (cmd,cmdtab[m].cmd, cmdlen)))
	{
	  /* we found a match */
	  num_matches++;
	  if (num_matches == 2)  /* we found a second match */
	    {
	      xprintf ("Ambiguous command.  Possibilities are:\n%s\n%s\n",
		       cmdtab[match].cmd,
		       cmdtab[m].cmd);
	    }
	  else if (num_matches > 2)  /* we found another match */
	    {
	      /* Show the new possibility we just found */
	      xprintf ("%s\n", cmdtab[m].cmd);
	    }
          /* Point the match at the command we just looked at.
	     We have to wait until now so that the first duplicate
	     found can output the earlier match as well */
	  match = m;
	}
      m++;
    }
  return ((num_matches == 1) ? match : -1);
}

#ifdef USE_HELP
void
usage (char *string)
{
  xprintf ("Usage: %s\n", string);
}

void
short_help (char *string)
{
  xprintf ("%s\n", string);
}

void
long_help (char *string)
{
  int linecnt = 0;
  int do_leave = 0;

  for (; *string && !do_leave; string++)
    {
      xprintf ("%c", *string);
      if (*string == '\n')
	{
	  linecnt++;
	  if (linecnt == MAXLINES)
	    {
	      int i;

	      xprintf ("-More-");
	      while ((i = input_char ()) >= 0)
		{
		  if (i == '\r' || i == '\n')
		    {
		      linecnt--;
		      break;
		    }
		  else if (i == ' ')
		    {
		      linecnt = 0;
		      break;
		    }
		  else if (i == 'q' || i == 'Q')
		    {
		      do_leave = 1;
		      break;
		    }
		  else
		    beep ();
		}
	    }
	}
    }
  xprintf ("\n");
}

void
example (char *example)
{
  xprintf ("Example: %s\n", example);
}

#else
void
no_help (void)
{
  xprintf ("No help available.\n");
}

void
no_help_usage (void)
{
  xprintf ("Incorrect usage.\n");
}
#endif

int 
help_cmd (cmdmode_t mode) 
{
  int command_number = -2;

  if (mode == USAGE)
    {
      usage ("help [command]");
      return 0;
    }
  if (mode == SHORT_HELP)
    {
      short_help ("The help command");
      return 0;
    }
  if (mode == LONG_HELP)
    {
      help_cmd (USAGE);
      long_help ("\
The help command without arguments shows a list of all available commands\n\
with a short description of each one.  With a command name as an argument\n\
it shows usage for the command and a paragraph describing the command.\n\
Usage is shown as command name followed by names of extensions or arguments.\n\
Arguments in [brackets] are optional, plain text arguments are required.\n\
Note that all commands can be invoked by typing enough of the command name\n\
to uniquely specify the command.  Some commands have aliases, which are one\n\
letter abbreviations for commands which do not have unique first letters.\n\
Aliases for all commands are shown in the help screen, which displays\n\
commands in the format:\n\
command name: (alias, if any)  description of command \n");
      example("\
help foo \n\
Shows the help screen for the command foo.");
      return 0;
    }

  if (argvect[1] != NULL)
    {
      if (argvect[2] == NULL)
	{
	  command_number = command_compare (argvect[1]);
	  if (command_number < 0)
	    {
	      xprintf ("No such command as %s\n", argvect[1]);
	    }
	}
      
      if (command_number < 0)
	{
	  return help_cmd (USAGE);
	}
      else
	{
	  return cmdtab[command_number].function (LONG_HELP);
	}
    }
  else
    {
      int i;
      
      xprintf ("Available commands are:\n");
      for (i = 0; cmdtab[i].cmd != NULL; i++)
	{
	  int x = strlen (cmdtab[i].cmd) + 2;

	  xprintf ("%s: ", cmdtab[i].cmd);
	  if (cmdtab[i].alias != NULL)
	    {
	      xprintf("(%s)", cmdtab[i].alias);
	      x += 2 + strlen(cmdtab[i].alias);
	    }
	  for (; x < 20; x++)
	    {
	      xprintf (" ");
	    }
	  cmdtab[i].function (SHORT_HELP);
	  if ((i > 0) && (i % MAXLINES) == 0)
	    {
	      xprintf ("-More-");
	      input_char ();
	      xprintf ("\n");
	    }
	}
    }
  return 0;
}

#if PROVIDE_CRASH_CMD
static int crash_cmd(cmdmode_t mode)
{
  switch (mode)
    {
    case USAGE : usage("crash")  ; break ;
    case SHORT_HELP : short_help("invoke the breakpoint function");
      break ;
    case LONG_HELP :
      long_help("The crash command calls the breakpoint function() which is useful\n\
only if you are using an additional debugger to debug this software and,\n\
the general exception handler is hooked to the other debugger\n") ;
      break ;
    case INVOCATION :
      dbg_breakpoint() ;
      break ;
    }
  return 0 ;
}
#endif /* provide_crash_command */



static int history_cmd(cmdmode_t mode)
{
    switch (mode)
    {
    case USAGE : usage("history")  ; break ;
    case SHORT_HELP : short_help("Print help about line editing features.");
      break ;
    case INVOCATION :
      printHistoryList();
      break;
    case LONG_HELP :
      long_help("Cygmon line editing allows you to repeat previously entered 
commands. The line editing commands are:
        CR '\\n'  Execute the currently displayed command
        ctl-a    move to Beginning of line
        ctl-e    End of line
        ctl-f    Forward char
        ctl-b    Backward char
        ctl-k    Delete to end of line
        ctl-y    yank Character (undelete)
        ctl-d    Delete current character
        ctl-p    edit previous command
        ctl-u    Erase Line
        ctl-n    Edit next command") ;
      break ;
    }
  return 0 ;
} /* history_cmd */

#ifdef OTHERNAMES_CMD
/* Switch to using the othernames (ie alternate register names) */
int
othernames_cmd (cmdmode_t mode)
{
  if (mode == USAGE)
    {
      usage ("othernames");
      return 0;
    }
  if (mode == SHORT_HELP)
    {
      short_help ("Switch between alternate register names.");
      return 0;
    }
  if (mode == LONG_HELP)
    {
      othernames_cmd (USAGE);
      long_help ("\
The othernames command allows you to switch between alternate register
names for a given target.");
      example ("\
othernames\n\
Switches to the alternate register name set..");
      return 0;
    }
  OTHERNAMES_CMD();

  return 0;
}
#endif /* OTHERNAMES_CMD */


#if defined(NVRAM_ETH_ADDR)
int
ethaddr_cmd (cmdmode_t mode)
{
  int      i, n;
  unsigned char addr[6];
  char     *p;

  if (mode == USAGE)
    {
      usage ("ethaddr [xx:xx:xx:xx:xx:xx]");
      return 0;
    }
  if (mode == SHORT_HELP)
    {
      short_help ("get/set NVRAM backed ethernet address");
      return 0;
    }
  if (mode == LONG_HELP)
    {
      ethaddr_cmd (USAGE);
      long_help ("\
The ethaddr command is used to view and modify the non-volatile ethernet\n\
address. The address is specified by 6 colon-seperated 2 digit hexadecimal\n\
numbers. If no address is specified, the current address is displayed.\n");
      example ("ethaddr 00:00:8B:F1:36:01");
      return 0;
    }

  if (argvect[1] != NULL)
    {
      if (strlen(argvect[1]) != 17 || argvect[2] != NULL)
	{
	  return ethaddr_cmd (USAGE);
	}

      for (i = 0, p = argvect[1]; i < 6; i++, p++)
	{
	  n = __hex(*p++);
	  if (n < 0)
	    return ethaddr_cmd (USAGE);
	  addr[i] = (n << 4);
	  n = __hex(*p++);
	  if (n < 0)
	    return ethaddr_cmd (USAGE);
	  addr[i] |= n;

	  if (*p != ':' && !(i == 5 && *p == '\0'))
	    return ethaddr_cmd (USAGE);
	}
      for (i = 0; i < 6; i++)
	NVRAM_ETH_ADDR(i) = addr[i];
    }
  else
    {
      for (i = 0; i < 5; i++)
	xprintf("%02x:", NVRAM_ETH_ADDR(i));
      xprintf("%02x\n", NVRAM_ETH_ADDR(i));
    }

  return 0;
}
#endif /* NVRAM_ETH_ADDR */


#if defined(NVRAM_IP_ADDR)
int
ipaddr_cmd (cmdmode_t mode)
{
  int      i, j, n;
  unsigned char addr[4];
  char     *p;

  if (mode == USAGE)
    {
      usage ("ipaddr [n.n.n.n]");
      return 0;
    }
  if (mode == SHORT_HELP)
    {
      short_help ("get/set NVRAM backed ip address");
      return 0;
    }
  if (mode == LONG_HELP)
    {
      ipaddr_cmd (USAGE);
      long_help ("\
The ipaddr command is used to view and modify the non-volatile internet\n\
address. The address is specified by 4 dot-seperated 1-3 digit decimal\n\
numbers. If no address is specified, the current address is displayed.\n");
      example ("ipaddr 192.161.0.1");
      return 0;
    }

  if (argvect[1] != NULL)
    {
      if (argvect[2] != NULL)
	return ipaddr_cmd (USAGE);

      p = argvect[1];

      for (i = 0; i < 3; i++, p++)
	{
	  for (j = n = 0; j < 3 && isdigit(*p); j++, p++)
	    n = n*10 + (*p - '0');
	  if (j == 0 || *p != '.' || n > 255)
	    return ipaddr_cmd (USAGE);
	  addr[i] = n;
	}
      for (j = n = 0; j < 3 && isdigit(*p); j++, p++)
	n = n*10 + (*p - '0');
      if (j == 0 || *p != '\0' || n > 255)
	return ipaddr_cmd (USAGE);
      addr[i] = n;

      for (i = 0; i < 4; i++)
	NVRAM_IP_ADDR(i) = addr[i];
    }
  else
    {
      for (i = 0; i < 3; i++)
	xprintf("%d.", NVRAM_IP_ADDR(i));
      xprintf("%d\n", NVRAM_IP_ADDR(i));
    }

  return 0;
}
#endif /* NVRAM_IP_ADDR */

#if defined(NVRAM_TCP_PORT)
int
tcpport_cmd (cmdmode_t mode)
{
  int  n;
  char *p;

  if (mode == USAGE)
    {
      usage ("ethaddr [xx:xx:xx:xx:xx:xx]");
      return 0;
    }
  if (mode == SHORT_HELP)
    {
      short_help ("get/set NVRAM backed tcp port number");
      return 0;
    }
  if (mode == LONG_HELP)
    {
      tcpport_cmd (USAGE);
      long_help ("\
The tcpport command is used to view and modify the non-volatile tcp port\n\
address used for debugging. The address is specified by decimal numer in\n\
the range of 1-65535. If no port number is specified, the current port is\n\
displayed.\n");
      example ("tcpport 1000");
      return 0;

⌨️ 快捷键说明

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