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

📄 jp-io.c

📁 嵌入式开发板连接程序源码
💻 C
字号:
/* jp-io.c -- Low level JTAG communications   Copyright (C) 2001 Marko Mlinar, markom@opencores.org   Copyright (C) 2004 Gy鰎gy Jeney, nog@sdf.lonestar.org   Code for TCP/IP copied from gdb, by Chris ZiomkowskiThis file is part of OpenRISC 1000 Architectural Simulator.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* This handles all the low-level io with the selected cable */#include <stdio.h>#include <stdint.h>#include <string.h>#include <sys/io.h>#include <sys/types.h>#include <unistd.h>#include <errno.h>#include <stdlib.h>#include <sys/socket.h>#include <sys/un.h>#include "jp.h"static int jp_parallel_init();static void jp_parallel_out(uint8_t value);static uint8_t jp_parallel_in();static int jp_parallel_opt(int c, char *str);static void jp_phys_wait();static int jp_rtl_sim_init();static void jp_rtl_sim_out(uint8_t value);static uint8_t jp_rtl_sim_in();static void jp_rtl_sim_wait();static int jp_rtl_sim_opt(int c, char *str);static int jp_vpi_init();static void jp_vpi_out(uint8_t value);static uint8_t jp_vpi_in();static void jp_vpi_wait();static int jp_vpi_opt(int c, char *str);static uint8_t jp_xpc3_in();static void jp_xpc3_out(uint8_t value);static uint8_t jp_xess_in();static void jp_xess_out(uint8_t value);static struct jtag_cable {  const char *name;  uint8_t (*in_func)();  void (*out_func)(uint8_t);  int (*init_func)();  void (*wait_func)();  int (*opt_func)(int c, char *str);  const char *opts;  const char *help;} jtag_cables[] = {  { "rtl_sim", jp_rtl_sim_in, jp_rtl_sim_out, jp_rtl_sim_init, jp_rtl_sim_wait,    jp_rtl_sim_opt, "d:",    "-d [directory] Directory in which gdb_in.dat/gdb_out.dat may be found\n" },  { "vpi", jp_vpi_in, jp_vpi_out, jp_vpi_init, jp_vpi_wait, jp_vpi_opt, "s:",    "-s [socket] Location of socket that the vpi module created\n" },  { "xpc3", jp_xpc3_in, jp_xpc3_out, jp_parallel_init, jp_phys_wait,    jp_parallel_opt, "p:",    "-p [port] Which port to use when communicateing with the parport hardware (eg. 0x378)\n" },  { "xess", jp_xess_in, jp_xess_out, jp_parallel_init, jp_phys_wait,    jp_parallel_opt, "p:",    "-p [port] Which port to use when communicateing with the parport hardware (eg. 0x378)\n" },  { NULL, NULL, NULL, NULL } };static struct jtag_cable *jtag_cable_in_use = NULL; /* The current selected cable *//* Only used for the parport */static int base = 0x378;/* Only used in the vpi */static int vpi_comm;static char *sock_loc = "/tmp/jp-vpi";/* Only used for the rtl_sim */static char *gdb_in = "gdb_in.dat";static char *gdb_out = "gdb_out.dat";void jp_out (uint8_t value){  /* finally call the cable-specific out-function */  jtag_cable_in_use->out_func(value);  if(!(value & 1))    debug("[%x%c]", (value & TDI_BIT) != 0, (value & TMS_BIT) ? '^' : '_');  flush_debug();}/* Receive a byte from the board.  */uint8_t jp_in(){  int data;  /* Get the data from the board */  data = jtag_cable_in_use->in_func();  debug(" R%01X ", data);  flush_debug();  return data;}/* waits */void jp_wait(){  jtag_cable_in_use->wait_func();}/* Selects a cable for use, returns non-null on success */int jp_select_cable(const char *cable){  int i;  for(i = 0; jtag_cables[i].name; i++) {    if(!strcmp(cable, jtag_cables[i].name)) {      jtag_cable_in_use = &jtag_cables[i];      return 1;    }  }  return 0;}/* Calls the init-fucntion of the cable */int jp_init_cable(){  return jtag_cable_in_use->init_func();}/* Parses command-line options specific to the selected cable */int jp_cable_opt(int c, char *str){  return jtag_cable_in_use->opt_func(c, str);}const char *jp_get_cable_args(){  return jtag_cable_in_use->opts;}/* Prints a (short) useage message for each availible cable */void jp_print_cable_help(){  int i;  printf("Availible cables: ");  for(i = 0; jtag_cables[i].name; i++) {    if(i)      printf(", ");    printf(jtag_cables[i].name);  }  printf("\n\nOptions availible for the cables:\n");  for(i = 0; jtag_cables[i].name; i++) {    if(!jtag_cables[i].help)      continue;    printf("  %s:\n    %s", jtag_cables[i].name, jtag_cables[i].help);  }}/*-------------------------------------[ Parallel port specific functions ]---*/static int jp_parallel_init(){  if (ioperm(base, 3, 1)) {    fprintf(stderr, "Couldn't get the port at %x\n", base);    perror("Root privileges are required.\n");    return 0;  }  printf("Connected to parallel port at %x\n", base);  printf("Dropping root privileges.\n");  setreuid(getuid(), getuid());  return 1;}static void jp_parallel_out(uint8_t value){  outb(value, LPT_WRITE);}static uint8_t jp_parallel_in(){  return inb(LPT_READ);}static int jp_parallel_opt(int c, char *str){  switch(c) {  case 'p':    if(!sscanf(str, "%x", &base)) {      fprintf(stderr, "p parameter must have a hex number as parameter\n");      return 0;    }    break;  default:    fprintf(stderr, "Unknown parameter '%c'\n", c);    return 0;  }  return 1;}/*-----------------------------------------[ Physical board wait function ]---*/static void jp_phys_wait(){  /* FIXME: this needs some real TLC */  int i;  volatile int j;  for(i = 0; i < 1000; i++)    j = i;}/*----------------------------------------------[ xpc3 specific functions ]---*/static void jp_xpc3_out(uint8_t value){  uint8_t out = 0;  /* First convert the bits in value byte to the ones that the cable wants */  if(value & TCLK_BIT)    out |= 0x02; /* D1 pin 3 */  if(value & TRST_BIT)    out |= 0x10; /* Not used */  if(value & TDI_BIT)    out |= 0x01; /* D0 pin 2 */  if(value & TMS_BIT)    out |= 0x04; /* D2 pin 4 */  jp_parallel_out(out);}static uint8_t jp_xpc3_in(){  uint8_t in;  in = jp_parallel_in();  if(in & 0x10) /* S6 pin 13 */    return 1;  return 0;}/*----------------------------------------------[ xess specific functions ]---*/static void jp_xess_out(uint8_t value){  uint8_t out = 0;  /* First convert the bits in value byte to the ones that the cable wants */  if(value & TCLK_BIT)    out |= 0x04; /* D2 pin 4 */  if(value & TRST_BIT)    out |= 0x08; /* D3 pin 5 */  if(value & TDI_BIT)    out |= 0x10; /* D4 pin 6 */  if(value & TMS_BIT)    out |= 0x20; /* D3 pin 5 */  jp_parallel_out(out);}static uint8_t jp_xess_in(){  uint8_t in;  in = jp_parallel_in();  if(in & 0x20) /* S5 pin 12*/    return 1;  return 0;}/*-------------------------------------------[ rtl_sim specific functions ]---*/static int jp_rtl_sim_init(){  FILE *fin = fopen (gdb_in, "wt+");  if(!fin) {    fprintf(stderr, "Can not open %s\n", gdb_in);    return 0;  }  fclose(fin);  return 1;}static void jp_rtl_sim_out(uint8_t value){  FILE *fout;  int num_read;  int r;  fout = fopen(gdb_in, "wt+");  fprintf(fout, "F\n");  fclose(fout);  fout = fopen(gdb_out, "wt+");  fprintf(fout, "%02X\n", value);  fclose(fout);  do {    fout = fopen(gdb_out, "rt");    r = fscanf(fout,"%x", &num_read);    fclose(fout);  } while(!r || (num_read != (0x10 | value)));}static uint8_t jp_rtl_sim_in(){  FILE *fin = 0;  char ch;  uint8_t data;  while(1) {    fin = fopen(gdb_in, "rt");    if(!fin)      continue;    ch = fgetc(fin);    fclose(fin);    if((ch != '0') && (ch != '1'))      continue;    else      break;  }  data = ch == '1' ? 1 : 0;  return data;}static void jp_rtl_sim_wait(){  usleep(1000);}static int jp_rtl_sim_opt(int c, char *str){  switch(c) {  case 'd':    if(!(gdb_in = malloc(strlen(str) + 12))) { /* 12 == strlen("gdb_in.dat") + 2 */      fprintf(stderr, "Unable to allocate enough memory\n");      return 0;    }    if(!(gdb_out = malloc(strlen(str) + 13))) { /* 13 == strlen("gdb_out.dat") + 2 */      fprintf(stderr, "Unable to allocate enough memory\n");      free(gdb_in);      return 0;    }    sprintf(gdb_in, "%s/gdb_in.dat", str);    sprintf(gdb_out, "%s/gdb_out.dat", str);    break;  default:    fprintf(stderr, "Unknown parameter '%c'\n", c);    return 0;  }  return 1;}/*-----------------------------------------------[ VPI specific functions ]---*/static int jp_vpi_init(){  struct sockaddr_un addr;  if((vpi_comm = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {    fprintf(stderr, "Unable to create socket (%s)\n", strerror(errno));    return 0;  }  addr.sun_family = AF_UNIX;  strcpy(addr.sun_path, sock_loc);  if(connect(vpi_comm, (struct sockaddr *)&addr, sizeof(addr)) == -1) {    fprintf(stderr, "Unable to connect to %s (%s)\n", addr.sun_path,            strerror(errno));    return 0;  }  return 1;}static void jp_vpi_out(uint8_t value){  uint8_t ack;  /* Send the data to the socket */  write(vpi_comm, &value, 1);  do {    /* Ok, read the data */    read(vpi_comm, &ack, 1);  } while(ack != (value | 0x10));}static uint8_t jp_vpi_in(){  uint8_t dat;  /* ask vpi to send us the out-bit */  dat = 0x80;  write(vpi_comm, &dat, 1);  /* Wait and read the data */  read(vpi_comm, &dat, 1);  if(dat > 1)    fprintf(stderr, "Unexpected value: %i\n", dat);  return dat;}static void jp_vpi_wait(){  uint8_t dat = 0x81;  /* Get the sim to reply when the timeout has been reached */  write(vpi_comm, &dat, 1);  /* block, waiting for the data */  read(vpi_comm, &dat, 1);}static int jp_vpi_opt(int c, char *str){  switch(c) {  case 's':    if(!(sock_loc = strdup(str))) {      fprintf(stderr, "Unable to allocate memory\n");      return 0;    }    break;  default:    fprintf(stderr, "Unknown parameter '%c'\n", c);    return 0;  }  return 1;}

⌨️ 快捷键说明

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