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

📄 mbxtcl.c

📁 CMX990 demonstration board (DE9901)
💻 C
📖 第 1 页 / 共 4 页
字号:
"Reads data from the upper half of the flash memory. It is 1 MB in size.\n\
Syntax:\n\
    flread pos ?length?\n\
Reads 32-bits data from byte position pos (0-1048575)\n\
Number of data read is length (1-32) and is default to 1.";
static int MbxTclFlashRead(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) {
  int data[32];
  char str[50];
  Cyg_ErrNo err;
  cyg_io_handle_t flash;
  int length, len, pos, i;

  if (argc < 2 || argc > 3) {
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                     " pos ?length?\"", (char *)NULL);
    return TCL_ERROR;
  }

  if (Tcl_GetUInt(interp, argv[1], &pos) != TCL_OK) {
    return TCL_ERROR;
  }
  if (pos < 0 || pos > 1048575) {
    Tcl_AppendResult(interp, "wrong value for pos: should be 0-1048575", (char *)NULL);
    return TCL_ERROR;
  }
  if (argc == 3) {
    if (Tcl_GetUInt(interp, argv[2], &length) != TCL_OK) {
      return TCL_ERROR;
    }
    if (length < 1 || length > 32) {
      Tcl_AppendResult(interp, "wrong value for length: should be 1-32", (char *)NULL);
      return TCL_ERROR;
    }
  } else {
    length = 1;
  }

  err = cyg_io_lookup("/dev/flash1", &flash);
  if (err) {
    sprintf(str, "Error opening /dev/flash1: %d", err);
    Tcl_SetResult(interp, str, TCL_VOLATILE);
    return TCL_ERROR;
  }
  len = length*sizeof(int);
  err = cyg_io_bread(flash, data, &len, pos);
  if (err) {
    sprintf(str, "Error reading /dev/flash1: %d", err);
    Tcl_SetResult(interp, str, TCL_VOLATILE);
    return TCL_ERROR;
  }
  for (i=0; i<length; i++) {
    sprintf(str, "%d", data[i]);
    Tcl_AppendResult(interp, str, (i == length-1 ? "" : " "), (char*)NULL);
  }
  return TCL_OK;
}

/****f* MBXTCL/MbxTclFlashWrite
* DESCRIPTION
* Writes data to the flash.
***/
static const char MbxTclFlashWriteHelp[] = 
"Writes data to the upper half of the flash memory. It is 1 MB in size.\n\
Syntax:\n\
    flwrite pos data\n\
Writes 32-bits data to byte position pos (0-1048575)\n\
Data is a list of words to write. Maximum of 32 words.";
static int MbxTclFlashWrite(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) {
  int data[32];
  char str[50];
  Cyg_ErrNo err;
  cyg_io_handle_t flash;
  int len, i;
  int pos;
  char *first, *next;
  char temp;

  if (argc != 3) {
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                     " pos data\"", (char *)NULL);
    return TCL_ERROR;
  }

  if (Tcl_GetUInt(interp, argv[1], &pos) != TCL_OK) {
    return TCL_ERROR;
  }
  if (pos < 0 || pos > 1048575) {
    Tcl_AppendResult(interp, "wrong value for pos: should be 0-1048575", (char *)NULL);
    return TCL_ERROR;
  }

  i = 0;
  first = argv[2];
  while ((i < 32) && (first[0] != '\0')) {
    if (TclFindElement(interp, first, &first, &next, &len, NULL) != TCL_OK) {
      Tcl_AppendResult(interp, "data is not a list", (char *)NULL);
      return TCL_ERROR;
    }
    if (len == 0) {
      Tcl_AppendResult(interp, "empty list?", (char *)NULL);
      return TCL_ERROR;
    }
    temp = first[len];
    first[len] = '\0';
    if (Tcl_GetInt(interp, first, &(data[i])) != TCL_OK) {
      return TCL_ERROR;
    }
    first[len] = temp;
    i++;
    first = next;
  }
  
  err = cyg_io_lookup("/dev/flash1", &flash);
  if (err) {
    sprintf(str, "Error opening /dev/flash1: %d", err);
    Tcl_SetResult(interp, str, TCL_VOLATILE);
    return TCL_ERROR;
  }
  len = i*sizeof(int);
  err = cyg_io_bwrite(flash, data, &len, pos);
  if (err) {
    sprintf(str, "Error writing /dev/flash1: %d", err);
    Tcl_SetResult(interp, str, TCL_VOLATILE);
    return TCL_ERROR;
  }
  return TCL_OK;
}

/****f* MBXTCL/MbxTclShowThreads
* DESCRIPTION
* Show all threads in the system.
***/
static const char MbxTclShowThreadsHelp[] = "Show all threads in the system.";
static int MbxTclShowThreads(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) {
  cyg_handle_t thread = 0;
  cyg_uint16 id = 0;
  char str[80];
  
  if (argc != 1) {
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                     "\"", (char *)NULL);
    return TCL_ERROR;
  }

  Tcl_AppendResult(interp, "                              Stack Stack      Stack\n", (char *)NULL);
  Tcl_AppendResult(interp, "ID:        Name: Prio: State: size: used:      base:\n", (char *)NULL);

  while(cyg_thread_get_next(&thread, &id)) {
    cyg_thread_info info;
    
    if(!cyg_thread_get_info(thread, id, &info))
      break;
    
    sprintf(str, "%3d %12s %5d %6d %5d %5d 0x%08x\n",
            info.id, info.name?info.name:"----", info.set_pri, info.state,
            info.stack_size, info.stack_used, info.stack_base);
    Tcl_AppendResult(interp, str, (char *)NULL);
  }
  return TCL_OK;
}


/*************************************************************************************/
/* A data structure that pair a Tcl command with the implementation in a C function */
/* and a help string for the command. */
typedef struct {
  char *name;			/* Name of command. */
  Tcl_CmdProc *proc;		/* Procedure that executes command. */
  const char *help;             /* Help text that describes the command. */
} cmdInfo_t;

/* A list of all Mobitex TCL commands implemented. */
static const cmdInfo_t mbxCmds[] = {
  {"rev",             MbxTclRev,          MbxTclRevHelp},
  {"hw",              MbxTclHw,           MbxTclHwHelp},
  {"time",            MbxTclTime,         MbxTclTimeHelp},
  {"print",           MbxTclPrint,        MbxTclPrintHelp},
  {"cpuload",         MbxTclCpuLoad,      MbxTclCpuLoadHelp},
  {"exit",            MbxTclExit,         MbxTclExitHelp},
  {"pio",             MbxTclPio,          MbxTclPioHelp},
  {"adc",             MbxTclAdc,          MbxTclAdcHelp},
  {"dac",             MbxTclDac,          MbxTclDacHelp},
  {"pll",             MbxTclPll,          MbxTclPllHelp},
  {"cmx",             MbxTclCmx,          MbxTclCmxHelp},
  {"prbs",            MbxTclPrbs,         MbxTclPrbsHelp},
  {"rx",              MbxTclRx,           MbxTclRxHelp},
  {"tx",              MbxTclTx,           MbxTclTxHelp},
  {"band",            MbxTclBand,         MbxTclBandHelp},
  {"freqpar",         MbxTclFreqPar,      MbxTclFreqParHelp},
  {"peek8",           MbxTclPeek8,        MbxTclPeek8Help},
  {"peek",            MbxTclPeek32,       MbxTclPeek32Help},
  {"poke8",           MbxTclPoke8,        MbxTclPoke8Help},
  {"poke",            MbxTclPoke32,       MbxTclPoke32Help},
  {"wd",              MbxTclWd,           MbxTclWdHelp},
  {"flashload",       MbxTclFlashLoad,    MbxTclFlashLoadHelp},
  {"flread",          MbxTclFlashRead,    MbxTclFlashReadHelp},
  {"flwrite",         MbxTclFlashWrite,   MbxTclFlashWriteHelp},
  {"ps",              MbxTclShowThreads,  MbxTclShowThreadsHelp},
  
  /* End list with NULL pointers */
  {NULL,              (Tcl_CmdProc *) NULL, NULL}
};

/****f* MBXTCL/MbxTclHelp
* DESCRIPTION
* Prints the help string for a command.
***/
static int MbxTclHelp(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) {
  cmdInfo_t *cmdInfoPtr;

  if (argc > 2) {
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
                     " [command]\"", (char *)NULL);
    return TCL_ERROR;
  }
  if (argc == 1) {
    /* Return a list of all commands. */
    Tcl_AppendResult(interp, "Type \"help <command>\" for specific help on a command.\n", 
                      "See a Tcl user guide for general tcl commands.\n", "This is a list of DE9901 specific commands:\n", (char *)NULL);
    for (cmdInfoPtr = (cmdInfo_t *)mbxCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {
      Tcl_AppendResult(interp, cmdInfoPtr->name, " ", (char *)NULL);
    }
    return TCL_OK;
  }
  /* Search for the command. */
  for (cmdInfoPtr = (cmdInfo_t *)mbxCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {
    if (strcmp(cmdInfoPtr->name, argv[1]) == 0) {
      if (cmdInfoPtr->help == NULL) {
        Tcl_SetResult(interp, "No help available", TCL_STATIC);
        return TCL_ERROR;
      }
      Tcl_SetResult(interp, (char*)cmdInfoPtr->help, TCL_STATIC);
      return TCL_OK;
    }
  }
  Tcl_SetResult(interp, "Command not found", TCL_STATIC);
  return TCL_ERROR;
}


/****f* MBXTCL/InitCommands
* DESCRIPTION
* This function installs all new TCL commands in a Tcl interpreter.
***/
static void InitCommands(Tcl_Interp *iPtr) {
  cmdInfo_t *cmdInfoPtr;
  
  for (cmdInfoPtr = (cmdInfo_t *)mbxCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {
    Tcl_CreateCommand(iPtr, cmdInfoPtr->name, cmdInfoPtr->proc, (ClientData) 0,
                      (Tcl_CmdDeleteProc *) NULL);
  }
  Tcl_CreateCommand(iPtr, "help", MbxTclHelp, (ClientData) 0,
                    (Tcl_CmdDeleteProc *) NULL);
}

/* A pointer to the default TCL interpreter. */
extern Tcl_Interp *interp;
/* TCL function to run as a thread. */
void TclMain(cyg_addrword_t lData);

/****f* MBXTCL/MbxTclInit
* DESCRIPTION
* This function shall be called when the system is started. The console port is opened
* and setup for used by Tcl.
* The Tcl thread is started and the Tcl system is initialized.
* The Tcl thread stops automatically after the initialization is ready.
* The user application can start the Tcl thread later. See MbxTclStartCheck.
***/
void MbxTclInit(void) {
  int err;
  cyg_tty_info_t ttyInfo;
  cyg_serial_info_t serInfo;
  cyg_uint32 block;
  cyg_uint32 len;

  // Open console serial port.
  err = cyg_io_lookup("/dev/con", &portHandl[0]);
  if (err) {
    diag_printf("ERROR opening /dev/con\n");
  }

  // Open console TTY.
  err = cyg_io_lookup("/dev/tty1", &portHandl[1]);
  if (err) {
    diag_printf("ERROR opening device tty1\n");
  }

  // Setup serial port config.
  len = sizeof(serInfo);
  cyg_io_get_config(portHandl[0], CYG_IO_GET_CONFIG_SERIAL_INFO, &serInfo, &len);
  // Change speed to 9600 since 38400 seems to be too much for the system,
  // characters are lost.
  serInfo.baud = CYGNUM_SERIAL_BAUD_9600;
  len = sizeof(serInfo);
  cyg_io_set_config(portHandl[0], CYG_IO_SET_CONFIG_SERIAL_INFO, &serInfo, &len);

  // Setup tty console port for use by tcl.
  ttyInfo.tty_in_flags = CYG_TTY_IN_FLAGS_ECHO | CYG_TTY_IN_FLAGS_CRLF;
  ttyInfo.tty_out_flags = CYG_TTY_OUT_FLAGS_CRLF;
  len = sizeof(ttyInfo);
  cyg_io_set_config(portHandl[1], CYG_IO_SET_CONFIG_TTY_INFO, &ttyInfo, &len);

  // Setup console port to be non-blocking until tcl is started.
  block = 0;
  len = sizeof(block);
  cyg_io_set_config(portHandl[0], CYG_IO_SET_CONFIG_SERIAL_READ_BLOCKING, &block, &len);

  // Create the TCL thread.
  // It will run immediately and initialize itself and then suspend.
  cyg_thread_create(1, TclMain, (cyg_addrword_t) 0,
                    "Tcl", (void *)&tclStack, TCL_STACK_SIZE,
                    &tclThread, &tclThreadPCB);
  cyg_thread_resume(tclThread);
  // When resume is executed this thread will stop and this function
  // will execute again after tcl has been initialized.

  // Now it is time to install Mobitex specific commands.
  InitCommands(interp);

  // Set the priority for TCL thread to the lowest.
  // It will not run again until the user starts it.
  cyg_thread_set_priority(tclThread, TCL_THREAD_PRIO);
  printf("TCL thread initialized.\n");
  printf("Enter password to start TCL.\n");
}

/****f* MBXTCL/MbxTclStartCheck
* DESCRIPTION
* This function checks for a password to be entered on the console port.
* When the right word is read the Tcl thread is started and the user has
* a command interface to DE9901.
***/
void MbxTclStartCheck(void) {
  static char buffer[20]; /* The length must be at least 10 + sizeof(password). */
  static const char password[] = "tcl";
  static cyg_uint32 pi = 0;
  char str[10];
  char *p;
  cyg_uint32 len, block, i;

  len = 10;
  cyg_io_read(portHandl[0], str, &len);
  if (len > 0) {
    /* Copy characters to password buffer and check if the right word is entered. */
    for (i=0; i<len; i++) {
      buffer[pi] = str[i];
      pi++;
    }
    buffer[pi] = 0;
    p = strstr(buffer, password);
    if (p != NULL) {
      /* The right password was found. */
      pi = 0;
      buffer[0] = 0;
      /* Setup console port to have read blocking when tcl is started. */
      block = 1;
      len = sizeof(block);
      cyg_io_set_config(portHandl[0], CYG_IO_SET_CONFIG_SERIAL_READ_BLOCKING, &block, &len);
      mbxTclRun = TRUE;
      fputs("\n", stdout);
      fputs("Welcome to Mobitex embedded TCL (R1A) for eCos\n", stdout);
      fputs("running on a DE9901 demonstration board!\n", stdout);
      fputs("(Type \"help\" for a list of DE9901 specific commands.)\n", stdout);
      cyg_thread_resume(tclThread);
    } else {
      if (pi > sizeof(password)) {
        /* Shift the last password characters down for the next check. */
        for (i=0; i<sizeof(password); i++) {
          buffer[i] = buffer[pi-sizeof(password)+i];
        }
        pi = i;
      }
    }
  }
}

⌨️ 快捷键说明

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