2 * Copyright (C) 2016-2020 by Marc Schink <dev@zapb.de>
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.
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.
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/>.
24 #include <helper/log.h>
25 #include <helper/binarybuffer.h>
26 #include <helper/command.h>
31 static int read_rtt_channel(struct target
*target
,
32 const struct rtt_control
*ctrl
, unsigned int channel_index
,
33 enum rtt_channel_type type
, struct rtt_channel
*channel
)
36 uint8_t buf
[RTT_CHANNEL_SIZE
];
37 target_addr_t address
;
39 address
= ctrl
->address
+ RTT_CB_SIZE
+ (channel_index
* RTT_CHANNEL_SIZE
);
41 if (type
== RTT_CHANNEL_TYPE_DOWN
)
42 address
+= ctrl
->num_up_channels
* RTT_CHANNEL_SIZE
;
44 ret
= target_read_buffer(target
, address
, RTT_CHANNEL_SIZE
, buf
);
49 channel
->address
= address
;
50 channel
->name_addr
= buf_get_u32(buf
+ 0, 0, 32);
51 channel
->buffer_addr
= buf_get_u32(buf
+ 4, 0, 32);
52 channel
->size
= buf_get_u32(buf
+ 8, 0, 32);
53 channel
->write_pos
= buf_get_u32(buf
+ 12, 0, 32);
54 channel
->read_pos
= buf_get_u32(buf
+ 16, 0, 32);
55 channel
->flags
= buf_get_u32(buf
+ 20, 0, 32);
60 int target_rtt_start(struct target
*target
, const struct rtt_control
*ctrl
,
66 int target_rtt_stop(struct target
*target
, void *user_data
)
71 static int read_channel_name(struct target
*target
, target_addr_t address
,
72 char *name
, size_t length
)
78 while (offset
< length
) {
82 read_length
= MIN(32, length
- offset
);
83 ret
= target_read_buffer(target
, address
+ offset
, read_length
,
84 (uint8_t *)name
+ offset
);
89 if (memchr(name
+ offset
, '\0', read_length
))
92 offset
+= read_length
;
95 name
[length
- 1] = '\0';
100 static int write_to_channel(struct target
*target
,
101 const struct rtt_channel
*channel
, const uint8_t *buffer
,
110 if (channel
->write_pos
== channel
->read_pos
) {
111 uint32_t first_length
;
113 len
= MIN(*length
, channel
->size
- 1);
114 first_length
= MIN(len
, channel
->size
- channel
->write_pos
);
116 ret
= target_write_buffer(target
,
117 channel
->buffer_addr
+ channel
->write_pos
, first_length
,
123 ret
= target_write_buffer(target
, channel
->buffer_addr
,
124 len
- first_length
, buffer
+ first_length
);
128 } else if (channel
->write_pos
< channel
->read_pos
) {
129 len
= MIN(*length
, channel
->read_pos
- channel
->write_pos
- 1);
136 ret
= target_write_buffer(target
,
137 channel
->buffer_addr
+ channel
->write_pos
, len
, buffer
);
142 uint32_t first_length
;
145 channel
->size
- channel
->write_pos
+ channel
->read_pos
- 1);
152 first_length
= MIN(len
, channel
->size
- channel
->write_pos
);
154 ret
= target_write_buffer(target
,
155 channel
->buffer_addr
+ channel
->write_pos
, first_length
,
161 buffer
= buffer
+ first_length
;
163 ret
= target_write_buffer(target
, channel
->buffer_addr
,
164 len
- first_length
, buffer
);
170 ret
= target_write_u32(target
, channel
->address
+ 12,
171 (channel
->write_pos
+ len
) % channel
->size
);
181 static bool channel_is_active(const struct rtt_channel
*channel
)
192 int target_rtt_write_callback(struct target
*target
, struct rtt_control
*ctrl
,
193 unsigned int channel_index
, const uint8_t *buffer
, size_t *length
,
197 struct rtt_channel channel
;
199 ret
= read_rtt_channel(target
, ctrl
, channel_index
,
200 RTT_CHANNEL_TYPE_DOWN
, &channel
);
202 if (ret
!= ERROR_OK
) {
203 LOG_ERROR("rtt: Failed to read down-channel %u description",
208 if (!channel_is_active(&channel
)) {
209 LOG_WARNING("rtt: Down-channel %u is not active", channel_index
);
213 if (channel
.size
< RTT_CHANNEL_BUFFER_MIN_SIZE
) {
214 LOG_WARNING("rtt: Down-channel %u is not large enough",
219 ret
= write_to_channel(target
, &channel
, buffer
, length
);
224 LOG_DEBUG("rtt: Wrote %zu bytes into down-channel %u", *length
,
230 int target_rtt_read_control_block(struct target
*target
,
231 target_addr_t address
, struct rtt_control
*ctrl
, void *user_data
)
234 uint8_t buf
[RTT_CB_SIZE
];
236 ret
= target_read_buffer(target
, address
, RTT_CB_SIZE
, buf
);
241 memcpy(ctrl
->id
, buf
, RTT_CB_MAX_ID_LENGTH
);
242 ctrl
->id
[RTT_CB_MAX_ID_LENGTH
- 1] = '\0';
243 ctrl
->num_up_channels
= buf_get_u32(buf
+ RTT_CB_MAX_ID_LENGTH
+ 0,
245 ctrl
->num_down_channels
= buf_get_u32(buf
+ RTT_CB_MAX_ID_LENGTH
+ 4,
251 int target_rtt_find_control_block(struct target
*target
,
252 target_addr_t
*address
, size_t size
, const char *id
, bool *found
,
260 size_t cb_offset
= 0;
261 const size_t id_length
= strlen(id
);
263 LOG_INFO("rtt: Searching for control block '%s'", id
);
265 for (target_addr_t addr
= 0; addr
< size
; addr
= addr
+ sizeof(buf
)) {
268 const size_t buf_size
= MIN(sizeof(buf
), size
- addr
);
269 ret
= target_read_buffer(target
, *address
+ addr
, buf_size
, buf
);
277 while (i
< buf_size
) {
278 if (buf
[i
] != id
[j
]) {
290 if (j
== id_length
) {
291 *address
= *address
+ cb_offset
;
301 int target_rtt_read_channel_info(struct target
*target
,
302 const struct rtt_control
*ctrl
, unsigned int channel_index
,
303 enum rtt_channel_type type
, struct rtt_channel_info
*info
,
307 struct rtt_channel channel
;
309 ret
= read_rtt_channel(target
, ctrl
, channel_index
, type
, &channel
);
311 if (ret
!= ERROR_OK
) {
312 LOG_ERROR("rtt: Failed to read channel %u description",
317 ret
= read_channel_name(target
, channel
.name_addr
, info
->name
,
323 info
->size
= channel
.size
;
324 info
->flags
= channel
.flags
;
329 static int read_from_channel(struct target
*target
,
330 const struct rtt_channel
*channel
, uint8_t *buffer
,
339 if (channel
->read_pos
== channel
->write_pos
) {
341 } else if (channel
->read_pos
< channel
->write_pos
) {
342 len
= MIN(*length
, channel
->write_pos
- channel
->read_pos
);
344 ret
= target_read_buffer(target
,
345 channel
->buffer_addr
+ channel
->read_pos
, len
, buffer
);
350 uint32_t first_length
;
353 channel
->size
- channel
->read_pos
+ channel
->write_pos
);
354 first_length
= MIN(len
, channel
->size
- channel
->read_pos
);
356 ret
= target_read_buffer(target
,
357 channel
->buffer_addr
+ channel
->read_pos
, first_length
, buffer
);
362 ret
= target_read_buffer(target
, channel
->buffer_addr
,
363 len
- first_length
, buffer
+ first_length
);
370 ret
= target_write_u32(target
, channel
->address
+ 16,
371 (channel
->read_pos
+ len
) % channel
->size
);
382 int target_rtt_read_callback(struct target
*target
,
383 const struct rtt_control
*ctrl
, struct rtt_sink_list
**sinks
,
384 size_t num_channels
, void *user_data
)
386 num_channels
= MIN(num_channels
, ctrl
->num_up_channels
);
388 for (size_t i
= 0; i
< num_channels
; i
++) {
390 struct rtt_channel channel
;
391 uint8_t buffer
[1024];
397 ret
= read_rtt_channel(target
, ctrl
, i
, RTT_CHANNEL_TYPE_UP
,
400 if (ret
!= ERROR_OK
) {
401 LOG_ERROR("rtt: Failed to read up-channel %zu description", i
);
405 if (!channel_is_active(&channel
)) {
406 LOG_WARNING("rtt: Up-channel %zu is not active", i
);
410 if (channel
.size
< RTT_CHANNEL_BUFFER_MIN_SIZE
) {
411 LOG_WARNING("rtt: Up-channel %zu is not large enough", i
);
415 length
= sizeof(buffer
);
416 ret
= read_from_channel(target
, &channel
, buffer
, &length
);
418 if (ret
!= ERROR_OK
) {
419 LOG_ERROR("rtt: Failed to read from up-channel %zu", i
);
423 for (struct rtt_sink_list
*sink
= sinks
[i
]; sink
; sink
= sink
->next
)
424 sink
->read(i
, buffer
, length
, sink
->user_data
);
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)