From 17fddb4289cb632a414d9780b3c2e60e368fa083 Mon Sep 17 00:00:00 2001 From: Andreas Fritiofson Date: Fri, 7 Mar 2014 20:08:31 +0100 Subject: [PATCH] stlink: Use callback to increase frequency of trace data sampling The ST-LINK/V2 has limited internal buffering, such that trace data can be missed if the target is generating data at a rate quicker than the OpenOCD trace sampling. The issue of lost data is compounded since individual TPIU packets may be split across individual STLINK_TRACE_EP reads, and misleading results can occur if mid-packet loss occurs. This patch increases the frequency of checking for pending trace data with the aim of minimising such losses. Note: With the limited (I/O and memory) bandwidth of the ST-LINK/V2 there cannot, however, be a guarantee against trace data loss. The timer callback is only added when enabling tracing, and is removed when tracing is disabled. Change-Id: Ibde9794b77793d3068f88cb5c1a26f9ceadcbd8a Signed-off-by: James G. Smith Signed-off-by: Andreas Fritiofson Reviewed-on: http://openocd.zylin.com/1661 Tested-by: jenkins --- src/jtag/drivers/stlink_usb.c | 20 ++++++++++++++++++-- src/target/target.c | 2 +- src/target/target.h | 2 +- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index e9d13d566d..06ec4b7028 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 b2af96a314..1557c72d97 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 21b94eea8a..3ce164a205 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 -- 2.30.2