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 <jsmith@ecoscentric.com> Signed-off-by: Andreas Fritiofson <andreas.fritiofson@gmail.com> Reviewed-on: http://openocd.zylin.com/1661 Tested-by: jenkins
This commit is contained in:
parent
d82490adfb
commit
17fddb4289
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue