f5abf2e5eaa304ae9e94c6dfb195811e133628a1
[openocd.git] / src / rtt / tcl.c
1 /*
2 * Copyright (C) 2019-2020 by Marc Schink <dev@zapb.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <helper/log.h>
19 #include <target/rtt.h>
20
21 #include "rtt.h"
22
23 #define CHANNEL_NAME_SIZE 128
24
25 COMMAND_HANDLER(handle_rtt_setup_command)
26 {
27 struct rtt_source source;
28
29 if (CMD_ARGC != 3)
30 return ERROR_COMMAND_SYNTAX_ERROR;
31
32 source.find_cb = &target_rtt_find_control_block;
33 source.read_cb = &target_rtt_read_control_block;
34 source.start = &target_rtt_start;
35 source.stop = &target_rtt_stop;
36 source.read = &target_rtt_read_callback;
37 source.write = &target_rtt_write_callback;
38 source.read_channel_info = &target_rtt_read_channel_info;
39
40 target_addr_t address;
41 uint32_t size;
42
43 COMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[0], address);
44 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size);
45
46 rtt_register_source(source, get_current_target(CMD_CTX));
47
48 if (rtt_setup(address, size, CMD_ARGV[2]) != ERROR_OK)
49 return ERROR_FAIL;
50
51 return ERROR_OK;
52 }
53
54 COMMAND_HANDLER(handle_rtt_start_command)
55 {
56 if (CMD_ARGC > 0)
57 return ERROR_COMMAND_SYNTAX_ERROR;
58
59 if (!rtt_configured()) {
60 command_print(CMD, "RTT is not configured");
61 return ERROR_FAIL;
62 }
63
64 return rtt_start();
65 }
66
67 COMMAND_HANDLER(handle_rtt_stop_command)
68 {
69 if (CMD_ARGC > 0)
70 return ERROR_COMMAND_SYNTAX_ERROR;
71
72 return rtt_stop();
73 }
74
75 COMMAND_HANDLER(handle_rtt_polling_interval_command)
76 {
77 if (CMD_ARGC == 0) {
78 int ret;
79 unsigned int interval;
80
81 ret = rtt_get_polling_interval(&interval);
82
83 if (ret != ERROR_OK) {
84 command_print(CMD, "Failed to get polling interval");
85 return ret;
86 }
87
88 command_print(CMD, "%u ms", interval);
89 } else if (CMD_ARGC == 1) {
90 int ret;
91 unsigned int interval;
92
93 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], interval);
94 ret = rtt_set_polling_interval(interval);
95
96 if (ret != ERROR_OK) {
97 command_print(CMD, "Failed to set polling interval");
98 return ret;
99 }
100 } else {
101 return ERROR_COMMAND_SYNTAX_ERROR;
102 }
103
104 return ERROR_OK;
105 }
106
107 COMMAND_HANDLER(handle_rtt_channels_command)
108 {
109 int ret;
110 char channel_name[CHANNEL_NAME_SIZE];
111 const struct rtt_control *ctrl;
112 struct rtt_channel_info info;
113
114 if (!rtt_found_cb()) {
115 command_print(CMD, "rtt: Control block not available");
116 return ERROR_FAIL;
117 }
118
119 ctrl = rtt_get_control();
120
121 command_print(CMD, "Channels: up=%u, down=%u", ctrl->num_up_channels,
122 ctrl->num_down_channels);
123
124 command_print(CMD, "Up-channels:");
125
126 info.name = channel_name;
127 info.name_length = sizeof(channel_name);
128
129 for (unsigned int i = 0; i < ctrl->num_up_channels; i++) {
130 ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_UP, &info);
131
132 if (ret != ERROR_OK)
133 return ret;
134
135 if (!info.size)
136 continue;
137
138 command_print(CMD, "%u: %s %u %u", i, info.name, info.size,
139 info.flags);
140 }
141
142 command_print(CMD, "Down-channels:");
143
144 for (unsigned int i = 0; i < ctrl->num_down_channels; i++) {
145 ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_DOWN, &info);
146
147 if (ret != ERROR_OK)
148 return ret;
149
150 if (!info.size)
151 continue;
152
153 command_print(CMD, "%u: %s %u %u", i, info.name, info.size,
154 info.flags);
155 }
156
157 return ERROR_OK;
158 }
159
160 static int jim_channel_list(Jim_Interp *interp, int argc,
161 Jim_Obj * const *argv)
162 {
163 Jim_Obj *list;
164 Jim_Obj *channel_list;
165 char channel_name[CHANNEL_NAME_SIZE];
166 const struct rtt_control *ctrl;
167 struct rtt_channel_info info;
168
169 if (!rtt_found_cb()) {
170 Jim_SetResultFormatted(interp, "rtt: Control block not available");
171 return ERROR_FAIL;
172 }
173
174 ctrl = rtt_get_control();
175
176 info.name = channel_name;
177 info.name_length = sizeof(channel_name);
178
179 list = Jim_NewListObj(interp, NULL, 0);
180 channel_list = Jim_NewListObj(interp, NULL, 0);
181
182 for (unsigned int i = 0; i < ctrl->num_up_channels; i++) {
183 int ret;
184 Jim_Obj *tmp;
185
186 ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_UP, &info);
187
188 if (ret != ERROR_OK)
189 return ret;
190
191 if (!info.size)
192 continue;
193
194 tmp = Jim_NewListObj(interp, NULL, 0);
195
196 Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp,
197 "name", -1));
198 Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp,
199 info.name, -1));
200
201 Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp,
202 "size", -1));
203 Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp,
204 info.size));
205
206 Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp,
207 "flags", -1));
208 Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp,
209 info.flags));
210
211 Jim_ListAppendElement(interp, channel_list, tmp);
212 }
213
214 Jim_ListAppendElement(interp, list, channel_list);
215
216 channel_list = Jim_NewListObj(interp, NULL, 0);
217
218 for (unsigned int i = 0; i < ctrl->num_down_channels; i++) {
219 int ret;
220 Jim_Obj *tmp;
221
222 ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_DOWN, &info);
223
224 if (ret != ERROR_OK)
225 return ret;
226
227 if (!info.size)
228 continue;
229
230 tmp = Jim_NewListObj(interp, NULL, 0);
231
232 Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp,
233 "name", -1));
234 Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp,
235 info.name, -1));
236
237 Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp,
238 "size", -1));
239 Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp,
240 info.size));
241
242 Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp,
243 "flags", -1));
244 Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp,
245 info.flags));
246
247 Jim_ListAppendElement(interp, channel_list, tmp);
248 }
249
250 Jim_ListAppendElement(interp, list, channel_list);
251 Jim_SetResult(interp, list);
252
253 return JIM_OK;
254 }
255
256 static const struct command_registration rtt_subcommand_handlers[] = {
257 {
258 .name = "setup",
259 .handler = handle_rtt_setup_command,
260 .mode = COMMAND_ANY,
261 .help = "setup RTT",
262 .usage = "<address> <size> <ID>"
263 },
264 {
265 .name = "start",
266 .handler = handle_rtt_start_command,
267 .mode = COMMAND_EXEC,
268 .help = "start RTT",
269 .usage = ""
270 },
271 {
272 .name = "stop",
273 .handler = handle_rtt_stop_command,
274 .mode = COMMAND_EXEC,
275 .help = "stop RTT",
276 .usage = ""
277 },
278 {
279 .name = "polling_interval",
280 .handler = handle_rtt_polling_interval_command,
281 .mode = COMMAND_EXEC,
282 .help = "show or set polling interval in ms",
283 .usage = "[interval]"
284 },
285 {
286 .name = "channels",
287 .handler = handle_rtt_channels_command,
288 .mode = COMMAND_EXEC,
289 .help = "list available channels",
290 .usage = ""
291 },
292 {
293 .name = "channellist",
294 .jim_handler = jim_channel_list,
295 .mode = COMMAND_EXEC,
296 .help = "list available channels",
297 .usage = ""
298 },
299 COMMAND_REGISTRATION_DONE
300 };
301
302 const struct command_registration rtt_target_command_handlers[] = {
303 {
304 .name = "rtt",
305 .mode = COMMAND_EXEC,
306 .help = "RTT target commands",
307 .usage = "",
308 .chain = rtt_subcommand_handlers
309 },
310 COMMAND_REGISTRATION_DONE
311 };

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)