X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Farmv7m_trace.c;h=c1e4f5baac33d7f2b8a5c282c7c56f605bddfc59;hb=e9493cc20a0c2160696b24757274ec4ee302ac39;hp=b1bbb31c5ad75fa13811f658dc7c8e09738f2384;hpb=a09a75653dbe7ad99da6349285ab6622b80fdc15;p=openocd.git diff --git a/src/target/armv7m_trace.c b/src/target/armv7m_trace.c index b1bbb31c5a..c1e4f5baac 100644 --- a/src/target/armv7m_trace.c +++ b/src/target/armv7m_trace.c @@ -10,6 +10,9 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -20,6 +23,34 @@ #include #include #include +#include + +#define TRACE_BUF_SIZE 4096 + +static int armv7m_poll_trace(void *target) +{ + struct armv7m_common *armv7m = target_to_armv7m(target); + uint8_t buf[TRACE_BUF_SIZE]; + size_t size = sizeof(buf); + int retval; + + retval = adapter_poll_trace(buf, &size); + if (retval != ERROR_OK || !size) + return retval; + + target_call_trace_callbacks(target, size, buf); + + if (armv7m->trace_config.trace_file != NULL) { + if (fwrite(buf, 1, size, armv7m->trace_config.trace_file) == size) + fflush(armv7m->trace_config.trace_file); + else { + LOG_ERROR("Error writing to the trace destination file"); + return ERROR_FAIL; + } + } + + return ERROR_OK; +} int armv7m_trace_tpiu_config(struct target *target) { @@ -28,19 +59,38 @@ int armv7m_trace_tpiu_config(struct target *target) int prescaler; int retval; + target_unregister_timer_callback(armv7m_poll_trace, target); + + + retval = adapter_config_trace(trace_config->config_type == INTERNAL, + trace_config->pin_protocol, + trace_config->port_size, + &trace_config->trace_freq); + if (retval != ERROR_OK) + return retval; + if (!trace_config->trace_freq) { LOG_ERROR("Trace port frequency is 0, can't enable TPIU"); return ERROR_FAIL; } + prescaler = trace_config->traceclkin_freq / trace_config->trace_freq; + if (trace_config->traceclkin_freq % trace_config->trace_freq) { - LOG_ERROR("Can not calculate an integer divisor to get %u trace port frequency from %u TRACECLKIN frequency", - trace_config->trace_freq, trace_config->traceclkin_freq); - return ERROR_FAIL; + prescaler++; + int trace_freq = trace_config->traceclkin_freq / prescaler; + LOG_INFO("Can not obtain %u trace port frequency from %u TRACECLKIN frequency, using %u instead", + trace_config->trace_freq, trace_config->traceclkin_freq, + trace_freq); + trace_config->trace_freq = trace_freq; + retval = adapter_config_trace(trace_config->config_type == INTERNAL, + trace_config->pin_protocol, + trace_config->port_size, + &trace_config->trace_freq); + if (retval != ERROR_OK) + return retval; } - prescaler = trace_config->traceclkin_freq / trace_config->trace_freq; - retval = target_write_u32(target, TPIU_CSPSR, 1 << trace_config->port_size); if (retval != ERROR_OK) return retval; @@ -65,6 +115,9 @@ int armv7m_trace_tpiu_config(struct target *target) if (retval != ERROR_OK) return retval; + if (trace_config->config_type == INTERNAL) + target_register_timer_callback(armv7m_poll_trace, 1, 1, target); + target_call_event_callbacks(target, TARGET_EVENT_TRACE_CONFIG); return ERROR_OK; @@ -137,10 +190,13 @@ COMMAND_HANDLER(handle_tpiu_config_command) return ERROR_COMMAND_SYNTAX_ERROR; armv7m->trace_config.config_type = INTERNAL; - armv7m->trace_config.trace_file = fopen(CMD_ARGV[cmd_idx], "ab"); - if (!armv7m->trace_config.trace_file) { - LOG_ERROR("Can't open trace destination file"); - return ERROR_FAIL; + + if (strcmp(CMD_ARGV[cmd_idx], "-") != 0) { + armv7m->trace_config.trace_file = fopen(CMD_ARGV[cmd_idx], "ab"); + if (!armv7m->trace_config.trace_file) { + LOG_ERROR("Can't open trace destination file"); + return ERROR_FAIL; + } } } cmd_idx++;