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

📄 rwmem.c

📁 Embeded bootloader (rrload by ridgerun) for TI linux based platform v5.36
💻 C
字号:
/*************************************************************************** * rwmem.c ***************************************************************************//*************************************************************************** * Included Files ***************************************************************************/#include "util.h"/*************************************************************************** * Definitions ***************************************************************************/#define MAX_LINE 128/*************************************************************************** * Private Variables ***************************************************************************//* These describe one input line */static char line[MAX_LINE];/* These describe one command parsed from the input line */static int           cmd_code;static unsigned long cmd_address;static unsigned long cmd_value;static unsigned long cmd_write;static unsigned long cmd_count;/*************************************************************************** * In-line Functions/Macros ***************************************************************************//* These macros/inline functions allow us to precisely control how data * is accessed.  For the case of arm, for example, certain compiler options * can make 16-bit short data accessed as a pair of bytes.  Very bad * if we are trying to read/write hardware registers! */#define inb(a)      *((unsigned char  *)(a))#define outb(v,a)  (*((unsigned char  *)(a))=(v))#if 0# define inw(a)     *((unsigned short *)(a))# define outw(v,a) (*((unsigned short *)(a))=(v))#elsestatic inline unsigned short inw(unsigned int addr){  unsigned short retval;  __asm__("\tldrh %0, [%1]\n\t" : "=r"(retval) : "r"(addr));  return retval;}static inline void outw(unsigned short val, unsigned int addr){  __asm__("\tstrh %0, [%1]\n\t": : "r"(val), "r"(addr));}#endif#define inl(a)      *((unsigned long  *)(a))#define outl(v,a)  (*((unsigned long  *)(a))=(v))/*************************************************************************** * Private Functions ***************************************************************************//*************************************************************************** * show_usage ***************************************************************************/static void show_usage(void){  util_printf("< {b,w,l} <hex-address>[=<hex-value>][ <hex-byte-count>]\n"	 "<   to read/write bytes(b), short integers(w), or longs(l)\n");  util_printf("< {h,?} to print this usage information\n");  util_printf("< q to quit\n");}/*************************************************************************** * skip_spaces ***************************************************************************/static void skip_spaces(char **string){  char *ptr = *string;  while(*ptr == ' ') ptr++;  *string = ptr;}/*************************************************************************** * parse_decimal ***************************************************************************/static int parse_decimal(char **string, long *value){  char *ptr = *string;  long accumulator = 0;  int c;  /* Loop until an non-numeric character is encountered. */  for(;;)    {      /* Get the next character from the line.  Note that "ptr" is not       * incremented.  This is because we want "string" to point to       * the first non-numeric after the number on return.       */      c = *ptr;      /* Is it a numeric? */      if ((c >= '0') && (c <= '9'))	{	  /* Add the new digit to the accumulator */	  accumulator *= 10;	  accumulator += (c - '0');	  /* Now we can increment the pointer to the next character */	  ptr++;	}      else	{	  /* No, we are done here */	  break;	}    }  /* Return the decimal value and the adjusted pointer. */  *string = ptr;  *value = accumulator;  /* Always return success.  It is okay if no number is found in the   * context in which this function is called.   */  return 0;}/*************************************************************************** * parse_hex ***************************************************************************/static int parse_hex(char **string, long *value){  char *ptr = *string;  long accumulator = 0;  int nibbles = 0;  int c;  /* Loop until an non-hex character is encountered. */  for(;;)    {      /* Get the next character from the line.  Note that "ptr" is not       * incremented.  This is because we want "string" to point to       * the first non-numeric after the number on return.       */      c = *ptr;      /* Is it a numeric? */      if ((c >= '0') && (c <= '9'))	{	  /* Add the nibble to the accumulator */	  accumulator <<= 4;	  accumulator += (c - '0');	  /* Count the number of nibbles we have encounter */	  nibbles++;	  /* Now we can increment the pointer to the next character */	  ptr++;	}      /* Is it a ascii A-F? */      else if ((c >= 'A') && (c <= 'F'))	{	  /* Add the nibble to the accumulator */	  accumulator <<= 4;	  accumulator += (c - 'A' + 10);	  /* Count the number of nibbles we have encounter */	  nibbles++;	  /* Now we can increment the pointer to the next character */	  ptr++;	}      /* Is it a ascii a-f? */      else if ((c >= 'a') && (c <= 'f'))	{	  /* Add the nibble to the accumulator */	  accumulator <<= 4;	  accumulator += (c - 'a' + 10);	  /* Count the number of nibbles we have encounter */	  nibbles++;	  /* Now we can increment the pointer to the next character */	  ptr++;	}      /* Somebody might want to put an "0x" in front.  We won't complain       * in this case (even though it is not necessary).  This logic       * will also accept crazy prefixes like:  "x", "0x0x0x", "0000x",       * "xxx".  It is completely tolerant of "x"'s on the line until       * a non-zero hex character is found.  We could make this strict       * by also insisting that (nibbles == 1).       */      else if ((c == 'x') && (accumulator == 0))	{	  ptr++;	}      else	{	  break;	}    }  /* Return the hex value and the adjusted pointer. */  *string = ptr;  *value = accumulator;  /* In the context in which this function is called, it would be an   * error if no hex number were found.   */  if (nibbles)    {      return 0;    }  else    {      util_printf("< Missing hex constant\n");      return -1;    }}/*************************************************************************** * parse_line ***************************************************************************/static int parse_line(void){  char *ptr = line;  /* Initialize command variables */  cmd_code    = 0;  cmd_address = 0;  cmd_value   = 0;  cmd_write   = 0;  cmd_count   = 0;  /* Make certain that the line is not empty.  */  if (!*ptr)    {      util_printf("< No command supplied\n");      return -1;    }  /* Get the command */  skip_spaces(&ptr);  cmd_code = *ptr++;  /* Force the command to lower case */  if ((cmd_code >= 'A') && (cmd_code <= 'Z'))    cmd_code += ('a' - 'A');  /* Make sure that the command is a single lower case letter */  if ((((cmd_code < 'a') || (cmd_code > 'z')) && (cmd_code != '?')) ||      ((*ptr != ' ') && (*ptr != '\0')))    {      util_printf("< Command must be a single letter\n");      return -1;    }  /* And that that letter is our command set */  if (!util_strchr("bwlqh?", cmd_code))    {      util_printf("< Unrecognized command\n");      return -1;    }  /* These commands have arguments */  if (util_strchr("bwl", cmd_code))    {      /* Get the address */      skip_spaces(&ptr);      if (parse_hex(&ptr, &cmd_address) != 0)	{	  util_printf("< Could not parse required address\n");	  return -1;	}      /* Check for an optional write value */      skip_spaces(&ptr);      if (*ptr == '=')	{	  cmd_write = 1;	  ptr++;	  /* Get the write value */	  skip_spaces(&ptr);	  if (parse_hex(&ptr, &cmd_value) != 0)	    {	      util_printf("< Could not parse optional value\n");	      return -1;	    }	}      /* Check for an optional count */      skip_spaces(&ptr);      (void)parse_decimal(&ptr, &cmd_count);      if (cmd_count) cmd_count--;    }  /* Make sure we are at the end of the line */  skip_spaces(&ptr);  if (*ptr)    {      util_printf(" >Garbage at the end of line\n");      return -1;    }  return 0;}/*************************************************************************** * do_command * returns zero on okay * positive number if user wants to quit * negative number if error encountered ***************************************************************************/static int do_command(void){  int i;  /* Process each command by its command letter */  switch (cmd_code)    {      /* We will be transferring bytes */    case 'b':      /* Loop for the number of requested bytes (plus one) */      for (i = 0; i <= cmd_count; i++, cmd_address++)	{	  /* Print the value at the address */	  util_printf("< 0x%X = 0x%b", cmd_address, inb(cmd_address));	  /* Are we supposed to write a value to this address? */	  if (cmd_write)	    {	      /* Yes, was the supplied value within range? */	      if (cmd_value > 0x000000ff)		{		  util_printf("\n> Value to write is out of range\n");		  return -1;		}	      /* Write the value and re-read the address so that we	       * print its current value (not necessarily the value	       * written).	       */	      outb((unsigned char)cmd_value, cmd_address);	      util_printf(" -> 0x%b", inb(cmd_address));	    }	  /* Make sure we end it with a newline */	  util_putchar('\n');	}      break;            /* We will be transferring "short" values */    case 'w':      /* Loop for the number of requested bytes (plus one) */      for (i = 0; i <= cmd_count; i += 2, cmd_address += 2)	{	  /* Print the value at the address */	  util_printf("< 0x%X = 0x%x", cmd_address, inw(cmd_address));	  /* Are we supposed to write a value to this address? */	  if (cmd_write)	    {	      /* Yes, was the supplied value within range? */	      if (cmd_value > 0x0000ffff)		{		  util_printf("\n> Value to write is out of range\n");		  return -1;		}	      /* Write the value and re-read the address so that we	       * print its current value (not necessarily the value	       * written).	       */	      outw((unsigned short)cmd_value, cmd_address);	      util_printf(" -> 0x%x", inw(cmd_address));	    }	  /* Make sure we end it with a newline */	  util_putchar('\n');	}      break;      /* We will be transferring "long" values */    case 'l':      /* Loop for the number of requested bytes (plus one) */      for (i = 0; i <= cmd_count; i += 4, cmd_address += 4)	{	  /* Print the value at the address */	  util_printf("< 0x%X = 0x%X", cmd_address, inl(cmd_address));	  /* Are we supposed to write a value to this address? */	  if (cmd_write)	    {	      /* Write the value and re-read the address so that we	       * print its current value (not necessarily the value	       * written).	       */	      outl(cmd_value, cmd_address);	      util_printf(" -> 0x%X", inl(cmd_address));	    }	  /* Make sure we end it with a newline */	  util_putchar('\n');	}      break;          case 'h':    case '?':      util_printf("< Usage:\n"); show_usage();      break;    case 'q':      return 1;    default:      util_printf("< Unrecognized command\n");      return -1;    }  return 0;}/*************************************************************************** * Public Functions ***************************************************************************//*************************************************************************** * main ***************************************************************************/void modify_memory(void){  int i;  util_printf("< Usage:\n"); show_usage();  /* Loop until do_command processes a quit command.   */  for(;;)    {      /* Show a prompt.  Including <esc>[K VT100 command that erases to       * the end of the line. */      util_printf("> \033[K");      /* Read the next input line. */      util_gets(line, MAX_LINE-1);      if (line[0] != 0)	{	  /* Parse the command from the input line */	  if (!parse_line())	    {	      /* Process the command */              i=do_command();	      if (i<0)		{		  util_printf("< Could not execute command\n");		  show_usage();		}	      if (i>0)		{		  return;		}	    }	  else	    {	      util_printf("< Could not parse command line\n");	      show_usage();	    }	}    }}

⌨️ 快捷键说明

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