1 /***************************************************************************
2 * Copyright (C) 2011 by Richard Uhler *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
25 #include <sys/socket.h>
28 #include <jtag/interface.h>
31 /* from unix man page and sys/un.h: */
32 #define UNIX_PATH_MAX 108
34 /* arbitrary limit on host name length: */
35 #define REMOTE_BITBANG_HOST_MAX 255
37 #define REMOTE_BITBANG_RAISE_ERROR(expr ...) \
40 LOG_ERROR("Terminating openocd."); \
44 static char remote_bitbang_host
[REMOTE_BITBANG_HOST_MAX
] = "openocd";
45 static uint16_t remote_bitbang_port
;
47 FILE *remote_bitbang_in
;
48 FILE *remote_bitbang_out
;
50 static void remote_bitbang_putc(int c
)
52 if (EOF
== fputc(c
, remote_bitbang_out
))
53 REMOTE_BITBANG_RAISE_ERROR("remote_bitbang_putc: %s", strerror(errno
));
56 static int remote_bitbang_quit(void)
58 if (EOF
== fputc('Q', remote_bitbang_out
)) {
59 LOG_ERROR("fputs: %s", strerror(errno
));
63 if (EOF
== fflush(remote_bitbang_out
)) {
64 LOG_ERROR("fflush: %s", strerror(errno
));
68 /* We only need to close one of the FILE*s, because they both use the same */
69 /* underlying file descriptor. */
70 if (EOF
== fclose(remote_bitbang_out
)) {
71 LOG_ERROR("fclose: %s", strerror(errno
));
75 LOG_INFO("remote_bitbang interface quit");
79 /* Get the next read response. */
80 static int remote_bitbang_rread(void)
82 if (EOF
== fflush(remote_bitbang_out
)) {
83 remote_bitbang_quit();
84 REMOTE_BITBANG_RAISE_ERROR("fflush: %s", strerror(errno
));
87 int c
= fgetc(remote_bitbang_in
);
94 remote_bitbang_quit();
95 REMOTE_BITBANG_RAISE_ERROR(
96 "remote_bitbang: invalid read response: %c(%i)", c
, c
);
100 static int remote_bitbang_read(void)
102 remote_bitbang_putc('R');
103 return remote_bitbang_rread();
106 static void remote_bitbang_write(int tck
, int tms
, int tdi
)
108 char c
= '0' + ((tck
? 0x4 : 0x0) | (tms
? 0x2 : 0x0) | (tdi
? 0x1 : 0x0));
109 remote_bitbang_putc(c
);
112 static void remote_bitbang_reset(int trst
, int srst
)
114 char c
= 'r' + ((trst
? 0x2 : 0x0) | (srst
? 0x1 : 0x0));
115 remote_bitbang_putc(c
);
118 static void remote_bitbang_blink(int on
)
120 char c
= on
? 'B' : 'b';
121 remote_bitbang_putc(c
);
124 static struct bitbang_interface remote_bitbang_bitbang
= {
125 .read
= &remote_bitbang_read
,
126 .write
= &remote_bitbang_write
,
127 .reset
= &remote_bitbang_reset
,
128 .blink
= &remote_bitbang_blink
,
131 static int remote_bitbang_speed(int speed
)
136 static int remote_bitbang_init_tcp(void)
138 LOG_INFO("Connecting to %s:%i", remote_bitbang_host
, remote_bitbang_port
);
139 int fd
= socket(PF_INET
, SOCK_STREAM
, 0);
141 LOG_ERROR("socket: %s", strerror(errno
));
145 struct hostent
*hent
= gethostbyname(remote_bitbang_host
);
147 char *errorstr
= "???";
150 errorstr
= "host not found";
153 errorstr
= "no address";
156 errorstr
= "no recovery";
159 errorstr
= "try again";
162 LOG_ERROR("gethostbyname: %s", errorstr
);
166 struct sockaddr_in addr
;
167 addr
.sin_family
= AF_INET
;
168 addr
.sin_port
= htons(remote_bitbang_port
);
169 addr
.sin_addr
= *(struct in_addr
*)hent
->h_addr
;
170 if (connect(fd
, (struct sockaddr
*)&addr
, sizeof(struct sockaddr_in
)) < 0) {
171 LOG_ERROR("connect: %s", strerror(errno
));
175 remote_bitbang_in
= fdopen(fd
, "r");
176 if (remote_bitbang_in
== NULL
) {
177 LOG_ERROR("fdopen: failed to open read stream");
181 remote_bitbang_out
= fdopen(fd
, "w");
182 if (remote_bitbang_out
== NULL
) {
183 LOG_ERROR("fdopen: failed to open write stream");
187 LOG_INFO("remote_bitbang driver initialized");
191 static int remote_bitbang_init_unix(void)
193 LOG_INFO("Connecting to unix socket %s", remote_bitbang_host
);
194 int fd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
196 LOG_ERROR("socket: %s", strerror(errno
));
200 struct sockaddr_un addr
;
201 addr
.sun_family
= AF_UNIX
;
202 strncpy(addr
.sun_path
, remote_bitbang_host
, UNIX_PATH_MAX
);
203 addr
.sun_path
[UNIX_PATH_MAX
-1] = '\0';
205 if (connect(fd
, (struct sockaddr
*)&addr
, sizeof(struct sockaddr_un
)) < 0) {
206 LOG_ERROR("connect: %s", strerror(errno
));
210 remote_bitbang_in
= fdopen(fd
, "r");
211 if (remote_bitbang_in
== NULL
) {
212 LOG_ERROR("fdopen: failed to open read stream");
216 remote_bitbang_out
= fdopen(fd
, "w");
217 if (remote_bitbang_out
== NULL
) {
218 LOG_ERROR("fdopen: failed to open write stream");
222 LOG_INFO("remote_bitbang driver initialized");
226 static int remote_bitbang_init(void)
228 bitbang_interface
= &remote_bitbang_bitbang
;
230 LOG_INFO("Initializing remote_bitbang driver");
231 if (remote_bitbang_port
== 0)
232 return remote_bitbang_init_unix();
233 return remote_bitbang_init_tcp();
236 static int remote_bitbang_khz(int khz
, int *jtag_speed
)
242 static int remote_bitbang_speed_div(int speed
, int *khz
)
244 /* I don't think this really matters any. */
249 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_port_command
)
252 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0], remote_bitbang_port
);
255 return ERROR_COMMAND_SYNTAX_ERROR
;
258 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_host_command
)
261 strncpy(remote_bitbang_host
, CMD_ARGV
[0], REMOTE_BITBANG_HOST_MAX
);
262 remote_bitbang_host
[REMOTE_BITBANG_HOST_MAX
-1] = '\0';
265 return ERROR_COMMAND_SYNTAX_ERROR
;
268 static const struct command_registration remote_bitbang_command_handlers
[] = {
270 .name
= "remote_bitbang_port",
271 .handler
= remote_bitbang_handle_remote_bitbang_port_command
,
272 .mode
= COMMAND_CONFIG
,
273 .help
= "Set the port to use to connect to the remote jtag.\n"
274 " if 0, use unix sockets to connect to the remote jtag.",
275 .usage
= "port_number",
278 .name
= "remote_bitbang_host",
279 .handler
= remote_bitbang_handle_remote_bitbang_host_command
,
280 .mode
= COMMAND_CONFIG
,
281 .help
= "Set the host to use to connect to the remote jtag.\n"
282 " if port is 0, this is the name of the unix socket to use.",
283 .usage
= "host_name",
285 COMMAND_REGISTRATION_DONE
,
288 struct jtag_interface remote_bitbang_interface
= {
289 .name
= "remote_bitbang",
290 .execute_queue
= &bitbang_execute_queue
,
291 .speed
= &remote_bitbang_speed
,
292 .commands
= remote_bitbang_command_handlers
,
293 .init
= &remote_bitbang_init
,
294 .quit
= &remote_bitbang_quit
,
295 .khz
= &remote_bitbang_khz
,
296 .speed_div
= &remote_bitbang_speed_div
,
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)