aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/jtag/drivers/stlink_usb.c20
-rw-r--r--src/target/target.c2
-rw-r--r--src/target/target.h2
3 files changed, 20 insertions, 4 deletions
diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c
index e9d13d56..06ec4b70 100644
--- a/src/jtag/drivers/stlink_usb.c
+++ b/src/jtag/drivers/stlink_usb.c
@@ -830,6 +830,12 @@ static void stlink_usb_trace_read(void *handle)
}
}
+static int stlink_usb_trace_read_callback(void *handle)
+{
+ stlink_usb_trace_read(handle);
+ return ERROR_OK;
+}
+
static enum target_state stlink_usb_v2_get_status(void *handle)
{
int result;
@@ -1006,8 +1012,10 @@ static void stlink_usb_trace_disable(void *handle)
h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_STOP_TRACE_RX;
res = stlink_usb_xfer(handle, h->databuf, 2);
- if (res == ERROR_OK)
+ if (res == ERROR_OK) {
h->trace.enabled = false;
+ target_unregister_timer_callback(stlink_usb_trace_read_callback, handle);
+ }
}
@@ -1044,6 +1052,14 @@ static int stlink_usb_trace_enable(void *handle)
if (res == ERROR_OK) {
h->trace.enabled = true;
LOG_DEBUG("Tracing: recording at %" PRIu32 "Hz\n", trace_hz);
+ /* We need the trace read function to be called at a
+ * high-enough frequency to ensure reasonable
+ * "timeliness" in processing ITM/DWT data.
+ * TODO: An alternative could be using the asynchronous
+ * features of the libusb-1.0 API to queue up one or more
+ * reads in advance and requeue them once they are
+ * completed. */
+ target_register_timer_callback(stlink_usb_trace_read_callback, 1, 1, handle);
}
} else {
LOG_ERROR("Tracing is not supported by this version.");
@@ -1065,7 +1081,7 @@ static int stlink_usb_run(void *handle)
res = stlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_DEBUGEN);
/* Try to start tracing, if requested */
- if (res == ERROR_OK && h->trace.source_hz) {
+ if (res == ERROR_OK && h->trace.source_hz && !h->trace.enabled) {
if (stlink_usb_trace_enable(handle) == ERROR_OK)
LOG_DEBUG("Tracing: enabled\n");
else
diff --git a/src/target/target.c b/src/target/target.c
index b2af96a3..1557c72d 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -1361,7 +1361,7 @@ int target_unregister_event_callback(int (*callback)(struct target *target,
return ERROR_OK;
}
-static int target_unregister_timer_callback(int (*callback)(void *priv), void *priv)
+int target_unregister_timer_callback(int (*callback)(void *priv), void *priv)
{
struct target_timer_callback **p = &target_timer_callbacks;
struct target_timer_callback *c = target_timer_callbacks;
diff --git a/src/target/target.h b/src/target/target.h
index 21b94eea..3ce164a2 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -328,7 +328,7 @@ int target_call_event_callbacks(struct target *target, enum target_event event);
*/
int target_register_timer_callback(int (*callback)(void *priv),
int time_ms, int periodic, void *priv);
-
+int target_unregister_timer_callback(int (*callback)(void *priv), void *priv);
int target_call_timer_callbacks(void);
/**
* Invoke this to ensure that e.g. polling timer callbacks happen before