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 ***************************************************************************/
29 #include <jtag/interface.h>
33 #define UNIX_PATH_LEN 108
36 /* arbitrary limit on host name length: */
37 #define REMOTE_BITBANG_HOST_MAX 255
39 #define REMOTE_BITBANG_RAISE_ERROR(expr ...) \
42 LOG_ERROR("Terminating openocd."); \
46 static char remote_bitbang_host
[REMOTE_BITBANG_HOST_MAX
] = "openocd";
47 static uint16_t remote_bitbang_port
;
49 FILE *remote_bitbang_in
;
50 FILE *remote_bitbang_out
;
52 static void remote_bitbang_putc(int c
)
54 if (EOF
== fputc(c
, remote_bitbang_out
))
55 REMOTE_BITBANG_RAISE_ERROR("remote_bitbang_putc: %s", strerror(errno
));
58 static int remote_bitbang_quit(void)
60 if (EOF
== fputc('Q', remote_bitbang_out
)) {
61 LOG_ERROR("fputs: %s", strerror(errno
));
65 if (EOF
== fflush(remote_bitbang_out
)) {
66 LOG_ERROR("fflush: %s", strerror(errno
));
70 /* We only need to close one of the FILE*s, because they both use the same */
71 /* underlying file descriptor. */
72 if (EOF
== fclose(remote_bitbang_out
)) {
73 LOG_ERROR("fclose: %s", strerror(errno
));
77 LOG_INFO("remote_bitbang interface quit");
81 /* Get the next read response. */
82 static int remote_bitbang_rread(void)
84 if (EOF
== fflush(remote_bitbang_out
)) {
85 remote_bitbang_quit();
86 REMOTE_BITBANG_RAISE_ERROR("fflush: %s", strerror(errno
));
89 int c
= fgetc(remote_bitbang_in
);
96 remote_bitbang_quit();
97 REMOTE_BITBANG_RAISE_ERROR(
98 "remote_bitbang: invalid read response: %c(%i)", c
, c
);
102 static int remote_bitbang_read(void)
104 remote_bitbang_putc('R');
105 return remote_bitbang_rread();
108 static void remote_bitbang_write(int tck
, int tms
, int tdi
)
110 char c
= '0' + ((tck
? 0x4 : 0x0) | (tms
? 0x2 : 0x0) | (tdi
? 0x1 : 0x0));
111 remote_bitbang_putc(c
);
114 static void remote_bitbang_reset(int trst
, int srst
)
116 char c
= 'r' + ((trst
? 0x2 : 0x0) | (srst
? 0x1 : 0x0));
117 remote_bitbang_putc(c
);
120 static void remote_bitbang_blink(int on
)
122 char c
= on
? 'B' : 'b';
123 remote_bitbang_putc(c
);
126 static struct bitbang_interface remote_bitbang_bitbang
= {
127 .read
= &remote_bitbang_read
,
128 .write
= &remote_bitbang_write
,
129 .reset
= &remote_bitbang_reset
,
130 .blink
= &remote_bitbang_blink
,
133 static int remote_bitbang_speed(int speed
)
138 static int remote_bitbang_init_tcp(void)
140 LOG_INFO("Connecting to %s:%i", remote_bitbang_host
, remote_bitbang_port
);
141 int fd
= socket(PF_INET
, SOCK_STREAM
, 0);
143 LOG_ERROR("socket: %s", strerror(errno
));
147 struct hostent
*hent
= gethostbyname(remote_bitbang_host
);
149 char *errorstr
= "???";
152 errorstr
= "host not found";
155 errorstr
= "no address";
158 errorstr
= "no recovery";
161 errorstr
= "try again";
164 LOG_ERROR("gethostbyname: %s", errorstr
);
168 struct sockaddr_in addr
;
169 addr
.sin_family
= AF_INET
;
170 addr
.sin_port
= htons(remote_bitbang_port
);
171 addr
.sin_addr
= *(struct in_addr
*)hent
->h_addr
;
172 if (connect(fd
, (struct sockaddr
*)&addr
, sizeof(struct sockaddr_in
)) < 0) {
173 LOG_ERROR("connect: %s", strerror(errno
));
177 remote_bitbang_in
= fdopen(fd
, "r");
178 if (remote_bitbang_in
== NULL
) {
179 LOG_ERROR("fdopen: failed to open read stream");
183 remote_bitbang_out
= fdopen(fd
, "w");
184 if (remote_bitbang_out
== NULL
) {
185 LOG_ERROR("fdopen: failed to open write stream");
189 LOG_INFO("remote_bitbang driver initialized");
193 static int remote_bitbang_init_unix(void)
195 LOG_INFO("Connecting to unix socket %s", remote_bitbang_host
);
196 int fd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
198 LOG_ERROR("socket: %s", strerror(errno
));
202 struct sockaddr_un addr
;
203 addr
.sun_family
= AF_UNIX
;
204 strncpy(addr
.sun_path
, remote_bitbang_host
, UNIX_PATH_LEN
);
205 addr
.sun_path
[UNIX_PATH_LEN
-1] = '\0';
207 if (connect(fd
, (struct sockaddr
*)&addr
, sizeof(struct sockaddr_un
)) < 0) {
208 LOG_ERROR("connect: %s", strerror(errno
));
212 remote_bitbang_in
= fdopen(fd
, "r");
213 if (remote_bitbang_in
== NULL
) {
214 LOG_ERROR("fdopen: failed to open read stream");
218 remote_bitbang_out
= fdopen(fd
, "w");
219 if (remote_bitbang_out
== NULL
) {
220 LOG_ERROR("fdopen: failed to open write stream");
224 LOG_INFO("remote_bitbang driver initialized");
228 static int remote_bitbang_init(void)
230 bitbang_interface
= &remote_bitbang_bitbang
;
232 LOG_INFO("Initializing remote_bitbang driver");
233 if (remote_bitbang_port
== 0)
234 return remote_bitbang_init_unix();
235 return remote_bitbang_init_tcp();
238 static int remote_bitbang_khz(int khz
, int *jtag_speed
)
244 static int remote_bitbang_speed_div(int speed
, int *khz
)
246 /* I don't think this really matters any. */
251 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_port_command
)
254 COMMAND_PARSE_NUMBER(u16
, CMD_ARGV
[0], remote_bitbang_port
);
257 return ERROR_COMMAND_SYNTAX_ERROR
;
260 COMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_host_command
)
263 strncpy(remote_bitbang_host
, CMD_ARGV
[0], REMOTE_BITBANG_HOST_MAX
);
264 remote_bitbang_host
[REMOTE_BITBANG_HOST_MAX
-1] = '\0';
267 return ERROR_COMMAND_SYNTAX_ERROR
;
270 static const struct command_registration remote_bitbang_command_handlers
[] = {
272 .name
= "remote_bitbang_port",
273 .handler
= remote_bitbang_handle_remote_bitbang_port_command
,
274 .mode
= COMMAND_CONFIG
,
275 .help
= "Set the port to use to connect to the remote jtag.\n"
276 " if 0, use unix sockets to connect to the remote jtag.",
277 .usage
= "port_number",
280 .name
= "remote_bitbang_host",
281 .handler
= remote_bitbang_handle_remote_bitbang_host_command
,
282 .mode
= COMMAND_CONFIG
,
283 .help
= "Set the host to use to connect to the remote jtag.\n"
284 " if port is 0, this is the name of the unix socket to use.",
285 .usage
= "host_name",
287 COMMAND_REGISTRATION_DONE
,
290 struct jtag_interface remote_bitbang_interface
= {
291 .name
= "remote_bitbang",
292 .execute_queue
= &bitbang_execute_queue
,
293 .speed
= &remote_bitbang_speed
,
294 .commands
= remote_bitbang_command_handlers
,
295 .init
= &remote_bitbang_init
,
296 .quit
= &remote_bitbang_quit
,
297 .khz
= &remote_bitbang_khz
,
298 .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)