|
From: Richard S. U. <ru...@mi...> - 2011-09-02 16:15:54
|
Updated remote_bitbang jtag driver patch is attached with config option
changed to --enable-remote-bitbang and copyright notice added.
Thanks,
Richard
On Thu, Aug 25, 2011 at 08:34:11PM +0000, Uhler, Richard wrote:
>
> ________________________________________
> From: ope...@li... [ope...@li...] on behalf of Uhler, Richard [ru...@qu...]
> Sent: Thursday, June 30, 2011 3:24 PM
> To: Øyvind Harboe
> Cc: ope...@li...
> Subject: Re: [Openocd-development] [PATCH] Implementation of a remote bitbang jtag driver
>
> I have been instructed we can only make the contribution if no explicit copyright claim is required. Is that acceptable?
>
> Richard
> ________________________________________
> From: Øyvind Harboe [oyv...@zy...]
> Sent: Sunday, June 26, 2011 8:42 AM
> To: Uhler, Richard
> Cc: ope...@li...
> Subject: Re: [Openocd-development] [PATCH] Implementation of a remote bitbang jtag driver
>
> Hi,
>
> some comments:
>
> - new files, except for config and macro files, must have the
> gpl 2 or later license header and it must state the copyright
> holder(you in this case).
> - the option should be --enable-remote-bitbang, not --enable-remote_bitbang
> to be more consistent with other options.
>
>
>
>
> --
> Øyvind Harboe - Can Zylin Consulting help on your project?
> US toll free 1-866-980-3434 / International +47 51 87 40 27
> http://www.zylin.com/
> _______________________________________________
> Openocd-development mailing list
> Ope...@li...
> https://lists.berlios.de/mailman/listinfo/openocd-development
> From 9a06645e11c5a1623ed3fff5261014143502cad3 Mon Sep 17 00:00:00 2001
> From: Richard Uhler <ru...@mi...>
> Date: Thu, 25 Aug 2011 13:29:33 -0700
> Subject: [PATCH] Implementation of a new jtag remote_bitbang driver.
>
> The driver sends ascii encoded bitbang commands over unix sockets or TCP to
> another process. This driver is useful for debugging software running on
> processors which are being simulated.
> ---
> configure.ac | 12 ++
> doc/manual/jtag/drivers/remote_bitbang.txt | 53 +++++
> doc/openocd.texi | 37 ++++
> src/jtag/drivers/Makefile.am | 3 +
> src/jtag/drivers/remote_bitbang.c | 286 ++++++++++++++++++++++++++++
> src/jtag/interfaces.c | 6 +
> 6 files changed, 397 insertions(+), 0 deletions(-)
> create mode 100644 doc/manual/jtag/drivers/remote_bitbang.txt
> create mode 100644 src/jtag/drivers/remote_bitbang.c
>
> diff --git a/configure.ac b/configure.ac
> index b6c04ab..ec51bd7 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -498,6 +498,10 @@ if test $build_zy1000 = yes; then
> fi
> AC_MSG_RESULT($build_zy1000)
>
> +AC_ARG_ENABLE(remote-bitbang,
> + AS_HELP_STRING([--enable-remote-bitbang], [Enable building support for the Remote Bitbang jtag driver]),
> + [build_remote_bitbang=$enableval], [build_remote_bitbang=no])
> +
>
> AC_MSG_CHECKING([whether to enable dummy minidriver])
> if test $build_minidriver_dummy = yes; then
> @@ -778,6 +782,13 @@ if test "$use_internal_jimtcl" = yes; then
> fi
> fi
>
> +if test $build_remote_bitbang = yes; then
> + build_bitbang=yes
> + AC_DEFINE(BUILD_REMOTE_BITBANG, 1, [1 if you want the Remote Bitbang JTAG driver.])
> +else
> + AC_DEFINE(BUILD_REMOTE_BITBNAG, 0, [0 if you don't want the Remote Bitbang JTAG driver.])
> +fi
> +
> #-- Deal with MingW/Cygwin FTD2XX issues
>
> if test $is_win32 = yes; then
> @@ -1075,6 +1086,7 @@ AM_CONDITIONAL(VSLLINK, test $build_vsllink = yes)
> AM_CONDITIONAL(RLINK, test $build_rlink = yes)
> AM_CONDITIONAL(ULINK, test $build_ulink = yes)
> AM_CONDITIONAL(ARMJTAGEW, test $build_armjtagew = yes)
> +AM_CONDITIONAL(REMOTE_BITBANG, test $build_remote_bitbang = yes)
> AM_CONDITIONAL(BUSPIRATE, test $build_buspirate = yes)
> AM_CONDITIONAL(USB, test $build_usb = yes)
> AM_CONDITIONAL(IS_CYGWIN, test $is_cygwin = yes)
> diff --git a/doc/manual/jtag/drivers/remote_bitbang.txt b/doc/manual/jtag/drivers/remote_bitbang.txt
> new file mode 100644
> index 0000000..5a80047
> --- /dev/null
> +++ b/doc/manual/jtag/drivers/remote_bitbang.txt
> @@ -0,0 +1,53 @@
> +/** @remote_bitbangpage OpenOCD Developer's Guide
> +
> +The remote_bitbang JTAG driver is used to drive JTAG from a remote process. The
> +remote_bitbang driver communicates via TCP or UNIX sockets with some remote
> +process using an ASCII encoding of the bitbang interface. The remote process
> +presumably then drives the JTAG however it pleases. The remote process should
> +act as a server, listening for connections from the openocd remote_bitbang
> +driver.
> +
> +The remote bitbang driver is useful for debugging software running on
> +processors which are being simulated.
> +
> +The bitbang interface consists of the following functions.
> +
> +blink on
> + Blink a light somewhere. The argument on is either 1 or 0.
> +
> +read
> + Sample the value of tdo.
> +
> +write tck tms tdi
> + Set the value of tck, tms, and tdi.
> +
> +reset trst srst
> + Set the value of trst, srst.
> +
> +An additional function, quit, is added to the remote_bitbang interface to
> +indicate there will be no more requests and the connection with the remote
> +driver should be closed.
> +
> +These five functions are encoded in ascii by assigning a single character to
> +each possible request. The assignments are:
> +
> + B - Blink on
> + b - Blink off
> + R - Read request
> + Q - Quit request
> + 0 - Write 0 0 0
> + 1 - Write 0 0 1
> + 2 - Write 0 1 0
> + 3 - Write 0 1 1
> + 4 - Write 1 0 0
> + 5 - Write 1 0 1
> + 6 - Write 1 1 0
> + 7 - Write 1 1 1
> + r - Reset 0 0
> + s - Reset 0 1
> + t - Reset 1 0
> + u - Reset 1 1
> +
> +The read response is encoded in ascii as either digit 0 or 1.
> +
> + */
> diff --git a/doc/openocd.texi b/doc/openocd.texi
> index 8b7e588..05c06b8 100644
> --- a/doc/openocd.texi
> +++ b/doc/openocd.texi
> @@ -2321,6 +2321,43 @@ ft2232_vid_pid 0x0403 0xbdc8
> @end example
> @end deffn
>
> +@deffn {Interface Driver} {remote_bitbang}
> +Drive JTAG from a remote process. This sets up a UNIX or TCP socket connection
> +with a remote process and sends ASCII encoded bitbang requests to that process
> +instead of directly driving JTAG.
> +
> +The remote_bitbang driver is useful for debugging software running on
> +processors which are being simulated.
> +
> +@deffn {Config Command} {remote_bitbang_port} number
> +Specifies the TCP port of the remote process to connect to or 0 to use UNIX
> +sockets instead of TCP.
> +@end deffn
> +
> +@deffn {Config Command} {remote_bitbang_host} hostname
> +Specifies the hostname of the remote process to connect to using TCP, or the
> +name of the UNIX socket to use if remote_bitbang_port is 0.
> +@end deffn
> +
> +For example, to connect remotely via TCP to the host foobar you might have
> +something like:
> +
> +@example
> +interface remote_bitbang
> +remote_bitbang_port 3335
> +remote_bitbang_host foobar
> +@end example
> +
> +To connect to another process running locally via UNIX sockets with socket
> +named mysocket:
> +
> +@example
> +interface remote_bitbang
> +remote_bitbang_port 0
> +remote_bitbang_host mysocket
> +@end example
> +@end deffn
> +
> @deffn {Interface Driver} {usb_blaster}
> USB JTAG/USB-Blaster compatibles over one of the userspace libraries
> for FTDI chips. These interfaces have several commands, used to
> diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am
> index 805d1a4..408ea81 100644
> --- a/src/jtag/drivers/Makefile.am
> +++ b/src/jtag/drivers/Makefile.am
> @@ -81,6 +81,9 @@ endif
> if BUSPIRATE
> DRIVERFILES += buspirate.c
> endif
> +if REMOTE_BITBANG
> +DRIVERFILES += remote_bitbang.c
> +endif
>
> noinst_HEADERS = \
> bitbang.h \
> diff --git a/src/jtag/drivers/remote_bitbang.c b/src/jtag/drivers/remote_bitbang.c
> new file mode 100644
> index 0000000..d3ab1b1
> --- /dev/null
> +++ b/src/jtag/drivers/remote_bitbang.c
> @@ -0,0 +1,286 @@
> +/***************************************************************************
> + * Copyright (C) 2011 by Richard Uhler *
> + * ru...@mi... *
> + * *
> + * This program 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 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 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 this program; if not, write to the *
> + * Free Software Foundation, Inc., *
> + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
> + ***************************************************************************/
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#include <sys/socket.h>
> +#include <sys/un.h>
> +#include <netdb.h>
> +#include <jtag/interface.h>
> +#include "bitbang.h"
> +
> +// from unix man page and sys/un.h:
> +#define UNIX_PATH_MAX 108
> +
> +// arbitrary limit on host name length:
> +#define REMOTE_BITBANG_HOST_MAX 255
> +
> +#define REMOTE_BITBANG_RAISE_ERROR(expr ...) \
> + LOG_ERROR(expr); LOG_ERROR("Terminating openocd."); exit(-1);
> +
> +static char remote_bitbang_host[REMOTE_BITBANG_HOST_MAX] = "openocd";
> +static uint16_t remote_bitbang_port = 0;
> +
> +FILE* remote_bitbang_in;
> +FILE* remote_bitbang_out;
> +
> +static void remote_bitbang_putc(int c)
> +{
> + if (EOF == fputc(c, remote_bitbang_out)) {
> + REMOTE_BITBANG_RAISE_ERROR("remote_bitbang_putc: %s", strerror(errno));
> + }
> +}
> +
> +static int remote_bitbang_quit(void)
> +{
> + if (EOF == fputc('Q', remote_bitbang_out)) {
> + LOG_ERROR("fputs: %s", strerror(errno));
> + return ERROR_FAIL;
> + }
> +
> + if (EOF == fflush(remote_bitbang_out)) {
> + LOG_ERROR("fflush: %s", strerror(errno));
> + return ERROR_FAIL;
> + }
> +
> + // We only need to close one of the FILE*s, because they both use the same
> + // underlying file descriptor.
> + if (EOF == fclose(remote_bitbang_out)) {
> + LOG_ERROR("fclose: %s", strerror(errno));
> + return ERROR_FAIL;
> + }
> +
> + LOG_INFO("remote_bitbang interface quit");
> + return ERROR_OK;
> +}
> +
> +// Get the next read response.
> +static int remote_bitbang_rread(void)
> +{
> + if (EOF == fflush(remote_bitbang_out)) {
> + remote_bitbang_quit();
> + REMOTE_BITBANG_RAISE_ERROR("fflush: %s", strerror(errno));
> + }
> +
> + int c = fgetc(remote_bitbang_in);
> + switch (c) {
> + case '0': return 0;
> + case '1': return 1;
> + default:
> + remote_bitbang_quit();
> + REMOTE_BITBANG_RAISE_ERROR(
> + "remote_bitbang: invalid read response: %c(%i)", c, c);
> + }
> +}
> +
> +static int remote_bitbang_read(void)
> +{
> + remote_bitbang_putc('R');
> + return remote_bitbang_rread();
> +}
> +
> +static void remote_bitbang_write(int tck, int tms, int tdi)
> +{
> + char c = '0' + ((tck ? 0x4 : 0x0) | (tms ? 0x2 : 0x0) | (tdi ? 0x1 : 0x0));
> + remote_bitbang_putc(c);
> +}
> +
> +static void remote_bitbang_reset(int trst, int srst)
> +{
> + char c = 'r' + ((trst ? 0x2 : 0x0) | (srst ? 0x1 : 0x0));
> + remote_bitbang_putc(c);
> +}
> +
> +static void remote_bitbang_blink(int on)
> +{
> + char c = on ? 'B' : 'b';
> + remote_bitbang_putc(c);
> +}
> +
> +static struct bitbang_interface remote_bitbang_bitbang = {
> + .read = &remote_bitbang_read,
> + .write = &remote_bitbang_write,
> + .reset = &remote_bitbang_reset,
> + .blink = &remote_bitbang_blink,
> +};
> +
> +static int remote_bitbang_speed(int speed)
> +{
> + return ERROR_OK;
> +}
> +
> +static int remote_bitbang_init_tcp(void)
> +{
> + LOG_INFO("Connecting to %s:%i", remote_bitbang_host, remote_bitbang_port);
> + int fd = socket(PF_INET, SOCK_STREAM, 0);
> + if (fd < 0) {
> + LOG_ERROR("socket: %s", strerror(errno));
> + return ERROR_FAIL;
> + }
> +
> + struct hostent* hent = gethostbyname(remote_bitbang_host);
> + if (hent == NULL) {
> + char* errorstr = "???";
> + switch (h_errno) {
> + case HOST_NOT_FOUND: errorstr = "host not found"; break;
> + case NO_ADDRESS: errorstr = "no address"; break;
> + case NO_RECOVERY: errorstr = "no recovery"; break;
> + case TRY_AGAIN: errorstr = "try again"; break;
> + }
> + LOG_ERROR("gethostbyname: %s", errorstr);
> + return ERROR_FAIL;
> + }
> +
> + struct sockaddr_in addr;
> + addr.sin_family = AF_INET;
> + addr.sin_port = htons(remote_bitbang_port);
> + addr.sin_addr = *(struct in_addr*)hent->h_addr;
> + if (connect(fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) < 0) {
> + LOG_ERROR("connect: %s", strerror(errno));
> + return ERROR_FAIL;
> + }
> +
> + remote_bitbang_in = fdopen(fd, "r");
> + if (remote_bitbang_in == NULL) {
> + LOG_ERROR("fdopen: failed to open read stream");
> + return ERROR_FAIL;
> + }
> +
> + remote_bitbang_out = fdopen(fd, "w");
> + if (remote_bitbang_out == NULL) {
> + LOG_ERROR("fdopen: failed to open write stream");
> + return ERROR_FAIL;
> + }
> +
> + LOG_INFO("remote_bitbang driver initialized");
> + return ERROR_OK;
> +}
> +
> +static int remote_bitbang_init_unix(void)
> +{
> + LOG_INFO("Connecting to unix socket %s", remote_bitbang_host);
> + int fd = socket(PF_UNIX, SOCK_STREAM, 0);
> + if (fd < 0) {
> + LOG_ERROR("socket: %s", strerror(errno));
> + return ERROR_FAIL;
> + }
> +
> + struct sockaddr_un addr;
> + addr.sun_family = AF_UNIX;
> + strncpy(addr.sun_path, remote_bitbang_host, UNIX_PATH_MAX);
> + addr.sun_path[UNIX_PATH_MAX-1] = '\0';
> +
> + if (connect(fd, (struct sockaddr*)&addr, sizeof(struct sockaddr_un)) < 0) {
> + LOG_ERROR("connect: %s", strerror(errno));
> + return ERROR_FAIL;
> + }
> +
> + remote_bitbang_in = fdopen(fd, "r");
> + if (remote_bitbang_in == NULL) {
> + LOG_ERROR("fdopen: failed to open read stream");
> + return ERROR_FAIL;
> + }
> +
> + remote_bitbang_out = fdopen(fd, "w");
> + if (remote_bitbang_out == NULL) {
> + LOG_ERROR("fdopen: failed to open write stream");
> + return ERROR_FAIL;
> + }
> +
> + LOG_INFO("remote_bitbang driver initialized");
> + return ERROR_OK;
> +}
> +
> +static int remote_bitbang_init(void)
> +{
> + bitbang_interface = &remote_bitbang_bitbang;
> +
> + LOG_INFO("Initializing remote_bitbang driver");
> + if (remote_bitbang_port == 0) {
> + return remote_bitbang_init_unix();
> + }
> + return remote_bitbang_init_tcp();
> +}
> +
> +static int remote_bitbang_khz(int khz, int* jtag_speed)
> +{
> + *jtag_speed = 0;
> + return ERROR_OK;
> +}
> +
> +static int remote_bitbang_speed_div(int speed, int* khz)
> +{
> + // I don't think this really matters any.
> + *khz = 1;
> + return ERROR_OK;
> +}
> +
> +
> +COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_port_command)
> +{
> + if (CMD_ARGC == 1) {
> + COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], remote_bitbang_port);
> + return ERROR_OK;
> + }
> + return ERROR_COMMAND_SYNTAX_ERROR;
> +}
> +
> +COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_host_command)
> +{
> + if (CMD_ARGC == 1) {
> + strncpy(remote_bitbang_host, CMD_ARGV[0], REMOTE_BITBANG_HOST_MAX);
> + remote_bitbang_host[REMOTE_BITBANG_HOST_MAX-1] = '\0';
> + return ERROR_OK;
> + }
> + return ERROR_COMMAND_SYNTAX_ERROR;
> +}
> +
> +
> +static const struct command_registration remote_bitbang_command_handlers[] = {
> + {
> + .name = "remote_bitbang_port",
> + .handler = remote_bitbang_handle_remote_bitbang_port_command,
> + .mode = COMMAND_CONFIG,
> + .help = "Set the port to use to connect to the remote jtag.\n"
> + " if 0, use unix sockets to connect to the remote jtag.",
> + .usage = "port_number",
> + },
> + {
> + .name = "remote_bitbang_host",
> + .handler = remote_bitbang_handle_remote_bitbang_host_command,
> + .mode = COMMAND_CONFIG,
> + .help = "Set the host to use to connect to the remote jtag.\n"
> + " if port is 0, this is the name of the unix socket to use.",
> + .usage = "host_name",
> + },
> + COMMAND_REGISTRATION_DONE,
> +};
> +
> +struct jtag_interface remote_bitbang_interface = {
> + .name = "remote_bitbang",
> + .execute_queue = &bitbang_execute_queue,
> + .speed = &remote_bitbang_speed,
> + .commands = remote_bitbang_command_handlers,
> + .init = &remote_bitbang_init,
> + .quit = &remote_bitbang_quit,
> + .khz = &remote_bitbang_khz,
> + .speed_div = &remote_bitbang_speed_div,
> +};
> diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c
> index dbc69d0..76a4e8d 100644
> --- a/src/jtag/interfaces.c
> +++ b/src/jtag/interfaces.c
> @@ -97,6 +97,9 @@ extern struct jtag_interface armjtagew_interface;
> #if BUILD_BUSPIRATE == 1
> extern struct jtag_interface buspirate_interface;
> #endif
> +#if BUILD_REMOTE_BITBANG == 1
> +extern struct jtag_interface remote_bitbang_interface;
> +#endif
> #endif // standard drivers
>
> /**
> @@ -163,6 +166,9 @@ struct jtag_interface *jtag_interfaces[] = {
> #if BUILD_BUSPIRATE == 1
> &buspirate_interface,
> #endif
> +#if BUILD_REMOTE_BITBANG == 1
> + &remote_bitbang_interface,
> +#endif
> #endif // standard drivers
> NULL,
> };
> --
> 1.7.5
>
|