X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Farmv7m_trace.c;h=6170119d9effc698daca348233bac183e70a48b8;hb=5fbf4d4cc3f67ec8b2fb3d8a789117583a84e1a1;hp=b1bbb31c5ad75fa13811f658dc7c8e09738f2384;hpb=a09a75653dbe7ad99da6349285ab6622b80fdc15;p=openocd.git diff --git a/src/target/armv7m_trace.c b/src/target/armv7m_trace.c index b1bbb31c5a..6170119d9e 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 == TRACE_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 == TRACE_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,10 @@ int armv7m_trace_tpiu_config(struct target *target) if (retval != ERROR_OK) return retval; + if (trace_config->config_type == TRACE_CONFIG_TYPE_INTERNAL) + target_register_timer_callback(armv7m_poll_trace, 1, + TARGET_TIMER_TYPE_PERIODIC, target); + target_call_event_callbacks(target, TARGET_EVENT_TRACE_CONFIG); return ERROR_OK; @@ -120,7 +174,7 @@ COMMAND_HANDLER(handle_tpiu_config_command) if (CMD_ARGC == cmd_idx + 1) { close_trace_file(armv7m); - armv7m->trace_config.config_type = DISABLED; + armv7m->trace_config.config_type = TRACE_CONFIG_TYPE_DISABLED; if (CMD_CTX->mode == COMMAND_EXEC) return armv7m_trace_tpiu_config(target); else @@ -130,17 +184,20 @@ COMMAND_HANDLER(handle_tpiu_config_command) !strcmp(CMD_ARGV[cmd_idx], "internal")) { close_trace_file(armv7m); - armv7m->trace_config.config_type = EXTERNAL; + armv7m->trace_config.config_type = TRACE_CONFIG_TYPE_EXTERNAL; if (!strcmp(CMD_ARGV[cmd_idx], "internal")) { cmd_idx++; if (CMD_ARGC == cmd_idx) 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; + armv7m->trace_config.config_type = TRACE_CONFIG_TYPE_INTERNAL; + + 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++; @@ -148,7 +205,7 @@ COMMAND_HANDLER(handle_tpiu_config_command) return ERROR_COMMAND_SYNTAX_ERROR; if (!strcmp(CMD_ARGV[cmd_idx], "sync")) { - armv7m->trace_config.pin_protocol = SYNC; + armv7m->trace_config.pin_protocol = TPIU_PIN_PROTOCOL_SYNC; cmd_idx++; if (CMD_ARGC == cmd_idx) @@ -157,9 +214,9 @@ COMMAND_HANDLER(handle_tpiu_config_command) COMMAND_PARSE_NUMBER(u32, CMD_ARGV[cmd_idx], armv7m->trace_config.port_size); } else { if (!strcmp(CMD_ARGV[cmd_idx], "manchester")) - armv7m->trace_config.pin_protocol = ASYNC_MANCHESTER; + armv7m->trace_config.pin_protocol = TPIU_PIN_PROTOCOL_ASYNC_MANCHESTER; else if (!strcmp(CMD_ARGV[cmd_idx], "uart")) - armv7m->trace_config.pin_protocol = ASYNC_UART; + armv7m->trace_config.pin_protocol = TPIU_PIN_PROTOCOL_ASYNC_UART; else return ERROR_COMMAND_SYNTAX_ERROR; @@ -181,7 +238,7 @@ COMMAND_HANDLER(handle_tpiu_config_command) COMMAND_PARSE_NUMBER(uint, CMD_ARGV[cmd_idx], armv7m->trace_config.trace_freq); cmd_idx++; } else { - if (armv7m->trace_config.config_type != INTERNAL) { + if (armv7m->trace_config.config_type != TRACE_CONFIG_TYPE_INTERNAL) { LOG_ERROR("Trace port frequency can't be omitted in external capture mode"); return ERROR_COMMAND_SYNTAX_ERROR; }