stlink: Use callback to increase frequency of trace data sampling 61/1661/5
authorAndreas Fritiofson <andreas.fritiofson@gmail.com>
Fri, 7 Mar 2014 19:08:31 +0000 (20:08 +0100)
committerAndreas Fritiofson <andreas.fritiofson@gmail.com>
Fri, 7 Mar 2014 21:19:12 +0000 (21:19 +0000)
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
src/jtag/drivers/stlink_usb.c
src/target/target.c
src/target/target.h

index e9d13d566da44ca389864f3991dff28de6c24e91..06ec4b7028ef3cf788cca9be452c077fd9684e26 100644 (file)
@@ -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;
 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);
 
        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;
                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);
                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.");
                }
        } 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 */
                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
                        if (stlink_usb_trace_enable(handle) == ERROR_OK)
                                LOG_DEBUG("Tracing: enabled\n");
                        else
index b2af96a3144d188cb3d9056c7c67e85b9ee4ef32..1557c72d97047f49ecee4374d2f6ae03ad9b9f5b 100644 (file)
@@ -1361,7 +1361,7 @@ int target_unregister_event_callback(int (*callback)(struct target *target,
        return ERROR_OK;
 }
 
        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;
 {
        struct target_timer_callback **p = &target_timer_callbacks;
        struct target_timer_callback *c = target_timer_callbacks;
index 21b94eea8a583fd5f84d8c8159a60542ab180bf8..3ce164a2052115222a2f0c3b5ab3e69302500175 100644 (file)
@@ -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_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
 int target_call_timer_callbacks(void);
 /**
  * Invoke this to ensure that e.g. polling timer callbacks happen before

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)