armv7m_trace: get rid of the old tpiu code

Remove all the old tpiu code and replace it with a wrapper that
uses the new commands, prints-out the new commands and informs
about the deprecation.

All the code that handles the deprecated tpiu commands is enclosed
between the comments
	/* START_DEPRECATED_TPIU */
and
	/* END_DEPRECATED_TPIU */
so will be easy to remove it in the future.

Change-Id: I70b0486770128203b923346382d9a90b8ec08439
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: http://openocd.zylin.com/6030
Tested-by: jenkins
Reviewed-by: Adrian M Negreanu <adrian.negreanu@nxp.com>
This commit is contained in:
Antonio Borneo 2020-11-13 23:36:24 +01:00
parent c945d6e616
commit dc7b32ea4a
9 changed files with 223 additions and 432 deletions

View File

@ -9642,54 +9642,6 @@ Disable the TPIU or the SWO, terminating the receiving of the trace data.
@end deffn
TODO: remove the old tpiu commands
@deffn Command {tpiu config} (@option{disable} | ((@option{external} | @option{internal (@var{filename} | @var{:port} | -)}) @
(@option{sync @var{port_width}} | ((@option{manchester} | @option{uart}) @var{formatter_enable})) @
@var{TRACECLKIN_freq} [@var{trace_freq}]))
ARMv7-M architecture provides several modules to generate debugging
information internally (ITM, DWT and ETM). Their output is directed
through TPIU to be captured externally either on an SWO pin (this
configuration is called SWV) or on a synchronous parallel trace port.
This command configures the TPIU module of the target and, if internal
capture mode is selected, starts to capture trace output by using the
debugger adapter features.
Some targets require additional actions to be performed in the
@b{trace-config} handler for trace port to be activated.
Command options:
@itemize @minus
@item @option{disable} disable TPIU handling;
@item @option{external} configure TPIU to let user capture trace
output externally (with an additional UART or logic analyzer hardware).
@item @option{internal (@var{filename} | @var{:port} | -)} configure TPIU and debug adapter to
gather trace data then:
@itemize @minus
@item append it to a regular file or a named pipe if @var{filename} is specified.
@item listen to a TCP/IP port if @var{:port} is specified, then broadcast the trace data over this port.
@item if '-' is specified, OpenOCD will forward trace data to @command{tcl_trace} command.
@*@b{Note:} while broadcasting to file or TCP, the forwarding to @command{tcl_trace} will remain active.
@end itemize
@item @option{sync @var{port_width}} use synchronous parallel trace output
mode, and set port width to @var{port_width}.
@item @option{manchester} use asynchronous SWO mode with Manchester
coding.
@item @option{uart} use asynchronous SWO mode with NRZ (same as
regular UART 8N1) coding.
@item @var{formatter_enable} is @option{on} or @option{off} to enable
or disable TPIU formatter which needs to be used when both ITM and ETM
data is to be output via SWO.
@item @var{TRACECLKIN_freq} this should be specified to match target's
current TRACECLKIN frequency (usually the same as HCLK).
@item @var{trace_freq} trace port frequency. Can be omitted in
internal mode to let the adapter driver select the maximum supported
rate automatically.
@end itemize
Example usage:
@enumerate
@ -9725,7 +9677,6 @@ openocd -f interface/stlink.cfg \
-c "stm32l1.tpiu enable"
@end example
@end enumerate
@end deffn
@subsection ARMv7-M specific commands
@cindex tracing

View File

@ -27,7 +27,7 @@
#include <jtag/jtag.h>
#include <jtag/swim.h>
#include <target/armv7m_trace.h>
#include <target/arm_tpiu_swo.h>
/* @file
* The "Cable Helper API" is what the cable drivers can use to help

View File

@ -38,6 +38,12 @@
#include <transport/transport.h>
#include "arm_tpiu_swo.h"
/* START_DEPRECATED_TPIU */
#include <target/cortex_m.h>
#include <target/target_type.h>
#define MSG "DEPRECATED \'tpiu config\' command: "
/* END_DEPRECATED_TPIU */
#define TCP_SERVICE_NAME "tpiu_swo_trace"
/* default for Cortex-M3 and Cortex-M4 specific TPIU */
@ -53,9 +59,9 @@
#define TPIU_DEVID_OFFSET 0xfc8
#define TPIU_ACPR_MAX_PRESCALER 0x1fff
#define TPIU_SPPR_PROTOCOL_SYNC 0x0 /**< synchronous trace output */
#define TPIU_SPPR_PROTOCOL_MANCHESTER 0x1 /**< asynchronous output with NRZ coding */
#define TPIU_SPPR_PROTOCOL_UART 0x2 /**< asynchronous output with Manchester coding */
#define TPIU_SPPR_PROTOCOL_SYNC (TPIU_PIN_PROTOCOL_SYNC)
#define TPIU_SPPR_PROTOCOL_MANCHESTER (TPIU_PIN_PROTOCOL_ASYNC_MANCHESTER)
#define TPIU_SPPR_PROTOCOL_UART (TPIU_PIN_PROTOCOL_ASYNC_UART)
#define TPIU_DEVID_NOSUPPORT_SYNC BIT(9)
#define TPIU_DEVID_SUPPORT_MANCHESTER BIT(10)
#define TPIU_DEVID_SUPPORT_UART BIT(11)
@ -106,6 +112,9 @@ struct arm_tpiu_swo_object {
char *out_filename;
/** track TCP connections */
struct list_head connections;
/* START_DEPRECATED_TPIU */
bool recheck_ap_cur_target;
/* END_DEPRECATED_TPIU */
};
struct arm_tpiu_swo_connection {
@ -612,6 +621,31 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const
struct target *target = get_current_target(cmd_ctx);
/* START_DEPRECATED_TPIU */
if (obj->recheck_ap_cur_target) {
if (strcmp(target->type->name, "cortex_m") &&
strcmp(target->type->name, "hla_target")) {
LOG_ERROR(MSG "Current target is not a Cortex-M nor a HLA");
return JIM_ERR;
}
if (!target_was_examined(target)) {
LOG_ERROR(MSG "Current target not examined yet");
return JIM_ERR;
}
struct cortex_m_common *cm = target_to_cm(target);
obj->recheck_ap_cur_target = false;
obj->spot.ap_num = cm->armv7m.debug_ap->ap_num;
tpiu_ap = dap_ap(obj->spot.dap, obj->spot.ap_num);
if (obj->spot.ap_num == 0)
LOG_INFO(MSG "Confirmed TPIU %s is on AP 0", obj->name);
else
LOG_INFO(MSG "Target %s is on AP %d. Revised command is "
"\'tpiu create %s -dap %s -ap-num %d\'",
target_name(target), obj->spot.ap_num,
obj->name, adiv5_dap_name(obj->spot.dap), obj->spot.ap_num);
}
/* END_DEPRECATED_TPIU */
/* trigger the event before any attempt to R/W in the TPIU/SWO */
arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_ENABLE);
@ -951,6 +985,163 @@ static int jim_arm_tpiu_swo_init(Jim_Interp *interp, int argc, Jim_Obj *const *a
return retval;
}
/* START_DEPRECATED_TPIU */
/* DEPRECATED: emulation of old command 'tpiu config' */
COMMAND_HANDLER(handle_tpiu_deprecated_config_command)
{
struct target *target = get_current_target(CMD_CTX);
struct arm_tpiu_swo_object *obj = NULL;
int retval;
if (strcmp(target->type->name, "cortex_m") &&
strcmp(target->type->name, "hla_target")) {
LOG_ERROR(MSG "Current target is not a Cortex-M nor a HLA");
return ERROR_FAIL;
}
if (!list_empty(&all_tpiu_swo)) {
obj = list_first_entry(&all_tpiu_swo, typeof(*obj), lh);
LOG_INFO(MSG "Using %s", obj->name);
} else {
struct cortex_m_common *cm = target_to_cm(target);
struct adiv5_private_config *pc = target->private_config;
struct adiv5_dap *dap = pc->dap;
int ap_num = pc->ap_num;
bool set_recheck_ap_cur_target = false;
LOG_INFO(MSG "Adding a TPIU \'%s.tpiu\' in the configuration", target_name(target));
if (ap_num == DP_APSEL_INVALID && transport_is_hla())
ap_num = 0; /* HLA should only support AP 0 */
if (ap_num == DP_APSEL_INVALID && target_was_examined(target))
ap_num = cm->armv7m.debug_ap->ap_num;
if (ap_num == DP_APSEL_INVALID) {
LOG_INFO(MSG "Target %s uses AP autodetection. Adding TPIU on AP 0; can be revised later",
target_name(target));
ap_num = 0;
set_recheck_ap_cur_target = true;
}
LOG_INFO(MSG "Running: \'tpiu create %s.tpiu -dap %s -ap-num %d\'",
target_name(target), adiv5_dap_name(dap), ap_num);
retval = command_run_linef(CMD_CTX, "tpiu create %s.tpiu -dap %s -ap-num %d",
target_name(target), adiv5_dap_name(dap), ap_num);
if (retval != ERROR_OK)
return retval;
obj = list_first_entry(&all_tpiu_swo, typeof(*obj), lh);
if (set_recheck_ap_cur_target)
obj->recheck_ap_cur_target = true;
}
unsigned int cmd_idx = 0;
if (CMD_ARGC == cmd_idx)
return ERROR_COMMAND_SYNTAX_ERROR;
if (!strcmp(CMD_ARGV[cmd_idx], "disable")) {
if (CMD_ARGC != cmd_idx + 1)
return ERROR_COMMAND_SYNTAX_ERROR;
LOG_INFO(MSG "Running: \'%s disable\'", obj->name);
return command_run_linef(CMD_CTX, "%s disable", obj->name);
}
const char *output = NULL;
const char *protocol;
const char *formatter = NULL;
const char *port_width = NULL;
const char *trace_clk;
const char *pin_clk = NULL;
if (!strcmp(CMD_ARGV[cmd_idx], "internal")) {
cmd_idx++;
if (CMD_ARGC == cmd_idx)
return ERROR_COMMAND_SYNTAX_ERROR;
output = CMD_ARGV[cmd_idx];
} else if (strcmp(CMD_ARGV[cmd_idx], "external"))
return ERROR_COMMAND_SYNTAX_ERROR;
cmd_idx++;
if (CMD_ARGC == cmd_idx)
return ERROR_COMMAND_SYNTAX_ERROR;
if (!strcmp(CMD_ARGV[cmd_idx], "sync")) {
protocol = CMD_ARGV[cmd_idx];
cmd_idx++;
if (CMD_ARGC == cmd_idx)
return ERROR_COMMAND_SYNTAX_ERROR;
port_width = CMD_ARGV[cmd_idx];
} else {
if (strcmp(CMD_ARGV[cmd_idx], "manchester") && strcmp(CMD_ARGV[cmd_idx], "uart"))
return ERROR_COMMAND_SYNTAX_ERROR;
protocol = CMD_ARGV[cmd_idx];
cmd_idx++;
if (CMD_ARGC == cmd_idx)
return ERROR_COMMAND_SYNTAX_ERROR;
formatter = CMD_ARGV[cmd_idx];
}
cmd_idx++;
if (CMD_ARGC == cmd_idx)
return ERROR_COMMAND_SYNTAX_ERROR;
trace_clk = CMD_ARGV[cmd_idx];
cmd_idx++;
if (CMD_ARGC != cmd_idx) {
pin_clk = CMD_ARGV[cmd_idx];
cmd_idx++;
}
if (CMD_ARGC != cmd_idx)
return ERROR_COMMAND_SYNTAX_ERROR;
LOG_INFO(MSG "Running: \'%s configure -protocol %s -traceclk %s" "%s%s" "%s%s" "%s%s" "%s%s\'",
obj->name, protocol, trace_clk,
pin_clk ? " -pin-freq " : "", pin_clk ? pin_clk : "",
output ? " -output " : "", output ? output : "",
formatter ? " -formatter " : "", formatter ? formatter : "",
port_width ? " -port-width " : "", port_width ? port_width : "");
retval = command_run_linef(CMD_CTX,
"%s configure -protocol %s -traceclk %s" "%s%s" "%s%s" "%s%s" "%s%s",
obj->name, protocol, trace_clk,
pin_clk ? " -pin-freq " : "", pin_clk ? pin_clk : "",
output ? " -output " : "", output ? output : "",
formatter ? " -formatter " : "", formatter ? formatter : "",
port_width ? " -port-width " : "", port_width ? port_width : "");
if (retval != ERROR_OK)
return retval;
LOG_INFO(MSG "Running: \'%s enable\'", obj->name);
retval = command_run_linef(CMD_CTX, "%s enable", obj->name);
if (retval != ERROR_OK)
return retval;
target_handle_event(target, TARGET_EVENT_TRACE_CONFIG);
return ERROR_OK;
}
static const struct command_registration arm_tpiu_deprecated_subcommand_handlers[] = {
{
.name = "config",
.handler = handle_tpiu_deprecated_config_command,
.mode = COMMAND_ANY,
.help = "Configure TPIU features, DEPRECATED, use \'tpiu create\'",
.usage = "(disable | "
"((external | internal (<filename> | <:port> | -)) "
"(sync <port width> | ((manchester | uart) <formatter enable>)) "
"<TRACECLKIN freq> [<trace freq>]))",
},
COMMAND_REGISTRATION_DONE
};
const struct command_registration arm_tpiu_deprecated_command_handlers[] = {
{
.name = "tpiu",
.chain = arm_tpiu_deprecated_subcommand_handlers,
.usage = "",
.help = "tpiu command group",
},
COMMAND_REGISTRATION_DONE
};
/* END_DEPRECATED_TPIU */
static const struct command_registration arm_tpiu_swo_subcommand_handlers[] = {
{
.name = "create",

View File

@ -3,6 +3,18 @@
#ifndef OPENOCD_TARGET_ARM_TPIU_SWO_H
#define OPENOCD_TARGET_ARM_TPIU_SWO_H
/* Values should match TPIU_SPPR_PROTOCOL_xxx */
enum tpiu_pin_protocol {
TPIU_PIN_PROTOCOL_SYNC = 0, /**< synchronous trace output */
TPIU_PIN_PROTOCOL_ASYNC_MANCHESTER = 1, /**< asynchronous output with Manchester coding */
TPIU_PIN_PROTOCOL_ASYNC_UART = 2, /**< asynchronous output with NRZ coding */
};
/* START_DEPRECATED_TPIU */
/* DEPRECATED: emulation of old command 'tpiu config' */
extern const struct command_registration arm_tpiu_deprecated_command_handlers[];
/* END_DEPRECATED_TPIU */
int arm_tpiu_swo_register_commands(struct command_context *cmd_ctx);
int arm_tpiu_swo_cleanup_all(void);

View File

@ -26,133 +26,6 @@
#include <jtag/interface.h>
#include <helper/time_support.h>
#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);
switch (armv7m->trace_config.internal_channel) {
case TRACE_INTERNAL_CHANNEL_FILE:
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;
}
}
break;
case TRACE_INTERNAL_CHANNEL_TCP:
if (armv7m->trace_config.trace_service != NULL) {
/* broadcast to all service connections */
struct connection *connection = armv7m->trace_config.trace_service->connections;
retval = ERROR_OK;
while (connection) {
if (connection_write(connection, buf, size) != (int) size)
retval = ERROR_FAIL;
connection = connection->next;
}
if (retval != ERROR_OK) {
LOG_ERROR("Error streaming the trace to TCP/IP port");
return ERROR_FAIL;
}
}
break;
case TRACE_INTERNAL_CHANNEL_TCL_ONLY:
/* nothing to do :
* the trace data is sent to TCL by calling the target_call_trace_callbacks
**/
break;
default:
LOG_ERROR("unsupported trace internal channel");
return ERROR_FAIL;
}
return ERROR_OK;
}
int armv7m_trace_tpiu_config(struct target *target)
{
struct armv7m_common *armv7m = target_to_armv7m(target);
struct armv7m_trace_config *trace_config = &armv7m->trace_config;
uint16_t prescaler = TPIU_ACPR_MAX_SWOSCALER + 1;
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, trace_config->traceclkin_freq, &prescaler);
if (retval != ERROR_OK)
return retval;
if (trace_config->config_type == TRACE_CONFIG_TYPE_EXTERNAL) {
prescaler = trace_config->traceclkin_freq / trace_config->trace_freq;
if (trace_config->traceclkin_freq % trace_config->trace_freq) {
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;
}
}
if (!trace_config->trace_freq) {
LOG_ERROR("Trace port frequency is 0, can't enable TPIU");
return ERROR_FAIL;
}
retval = target_write_u32(target, TPIU_CSPSR, 1 << trace_config->port_size);
if (retval != ERROR_OK)
return retval;
retval = target_write_u32(target, TPIU_ACPR, prescaler - 1);
if (retval != ERROR_OK)
return retval;
retval = target_write_u32(target, TPIU_SPPR, trace_config->pin_protocol);
if (retval != ERROR_OK)
return retval;
uint32_t ffcr;
retval = target_read_u32(target, TPIU_FFCR, &ffcr);
if (retval != ERROR_OK)
return retval;
if (trace_config->formatter)
ffcr |= (1 << 1);
else
ffcr &= ~(1 << 1);
retval = target_write_u32(target, TPIU_FFCR, ffcr);
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;
}
int armv7m_trace_itm_config(struct target *target)
{
struct armv7m_common *armv7m = target_to_armv7m(target);
@ -210,182 +83,6 @@ int armv7m_trace_itm_config(struct target *target)
return ERROR_OK;
}
static void close_trace_channel(struct armv7m_common *armv7m)
{
switch (armv7m->trace_config.internal_channel) {
case TRACE_INTERNAL_CHANNEL_FILE:
if (armv7m->trace_config.trace_file)
fclose(armv7m->trace_config.trace_file);
armv7m->trace_config.trace_file = NULL;
break;
case TRACE_INTERNAL_CHANNEL_TCP:
if (armv7m->trace_config.trace_service)
remove_service(armv7m->trace_config.trace_service->name, armv7m->trace_config.trace_service->port);
armv7m->trace_config.trace_service = NULL;
break;
case TRACE_INTERNAL_CHANNEL_TCL_ONLY:
/* nothing to do:
* the trace polling is disabled in the beginning of armv7m_trace_tpiu_config
**/
break;
default:
LOG_ERROR("unsupported trace internal channel");
}
}
static int trace_new_connection(struct connection *connection)
{
/* nothing to do */
return ERROR_OK;
}
static int trace_input(struct connection *connection)
{
/* create a dummy buffer to check if the connection is still active */
const int buf_len = 100;
unsigned char buf[buf_len];
int bytes_read = connection_read(connection, buf, buf_len);
if (bytes_read == 0)
return ERROR_SERVER_REMOTE_CLOSED;
else if (bytes_read == -1) {
LOG_ERROR("error during read: %s", strerror(errno));
return ERROR_SERVER_REMOTE_CLOSED;
}
return ERROR_OK;
}
static int trace_connection_closed(struct connection *connection)
{
/* nothing to do, no connection->priv to free */
return ERROR_OK;
}
extern struct command_context *global_cmd_ctx;
int armv7m_trace_tpiu_exit(struct target *target)
{
struct armv7m_common *armv7m = target_to_armv7m(target);
if (global_cmd_ctx->mode == COMMAND_CONFIG ||
armv7m->trace_config.config_type == TRACE_CONFIG_TYPE_DISABLED)
return ERROR_OK;
close_trace_channel(armv7m);
armv7m->trace_config.config_type = TRACE_CONFIG_TYPE_DISABLED;
return armv7m_trace_tpiu_config(target);
}
COMMAND_HANDLER(handle_tpiu_config_command)
{
struct target *target = get_current_target(CMD_CTX);
struct armv7m_common *armv7m = target_to_armv7m(target);
unsigned int cmd_idx = 0;
if (CMD_ARGC == cmd_idx)
return ERROR_COMMAND_SYNTAX_ERROR;
if (!strcmp(CMD_ARGV[cmd_idx], "disable")) {
if (CMD_ARGC == cmd_idx + 1) {
close_trace_channel(armv7m);
armv7m->trace_config.config_type = TRACE_CONFIG_TYPE_DISABLED;
if (CMD_CTX->mode == COMMAND_EXEC)
return armv7m_trace_tpiu_config(target);
else
return ERROR_OK;
}
} else if (!strcmp(CMD_ARGV[cmd_idx], "external") ||
!strcmp(CMD_ARGV[cmd_idx], "internal")) {
close_trace_channel(armv7m);
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 = TRACE_CONFIG_TYPE_INTERNAL;
armv7m->trace_config.internal_channel = TRACE_INTERNAL_CHANNEL_TCL_ONLY;
if (strcmp(CMD_ARGV[cmd_idx], "-") != 0) {
if (CMD_ARGV[cmd_idx][0] == ':') {
armv7m->trace_config.internal_channel = TRACE_INTERNAL_CHANNEL_TCP;
int ret = add_service("armv7m_trace", &(CMD_ARGV[cmd_idx][1]),
CONNECTION_LIMIT_UNLIMITED, trace_new_connection, trace_input,
trace_connection_closed, NULL, &armv7m->trace_config.trace_service);
if (ret != ERROR_OK) {
LOG_ERROR("Can't configure trace TCP port");
return ERROR_FAIL;
}
} else {
armv7m->trace_config.internal_channel = TRACE_INTERNAL_CHANNEL_FILE;
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++;
if (CMD_ARGC == cmd_idx)
return ERROR_COMMAND_SYNTAX_ERROR;
if (!strcmp(CMD_ARGV[cmd_idx], "sync")) {
armv7m->trace_config.pin_protocol = TPIU_PIN_PROTOCOL_SYNC;
cmd_idx++;
if (CMD_ARGC == cmd_idx)
return ERROR_COMMAND_SYNTAX_ERROR;
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 = TPIU_PIN_PROTOCOL_ASYNC_MANCHESTER;
else if (!strcmp(CMD_ARGV[cmd_idx], "uart"))
armv7m->trace_config.pin_protocol = TPIU_PIN_PROTOCOL_ASYNC_UART;
else
return ERROR_COMMAND_SYNTAX_ERROR;
cmd_idx++;
if (CMD_ARGC == cmd_idx)
return ERROR_COMMAND_SYNTAX_ERROR;
COMMAND_PARSE_ON_OFF(CMD_ARGV[cmd_idx], armv7m->trace_config.formatter);
}
cmd_idx++;
if (CMD_ARGC == cmd_idx)
return ERROR_COMMAND_SYNTAX_ERROR;
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[cmd_idx], armv7m->trace_config.traceclkin_freq);
cmd_idx++;
if (CMD_ARGC != cmd_idx) {
COMMAND_PARSE_NUMBER(uint, CMD_ARGV[cmd_idx], armv7m->trace_config.trace_freq);
cmd_idx++;
} else {
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;
}
armv7m->trace_config.trace_freq = 0;
}
if (CMD_ARGC == cmd_idx) {
if (CMD_CTX->mode == COMMAND_EXEC)
return armv7m_trace_tpiu_config(target);
else
return ERROR_OK;
}
}
return ERROR_COMMAND_SYNTAX_ERROR;
}
COMMAND_HANDLER(handle_itm_port_command)
{
struct target *target = get_current_target(CMD_CTX);
@ -433,20 +130,6 @@ COMMAND_HANDLER(handle_itm_ports_command)
return ERROR_OK;
}
static const struct command_registration tpiu_command_handlers[] = {
{
.name = "config",
.handler = handle_tpiu_config_command,
.mode = COMMAND_ANY,
.help = "Configure TPIU features",
.usage = "(disable | "
"((external | internal (<filename> | <:port> | -)) "
"(sync <port width> | ((manchester | uart) <formatter enable>)) "
"<TRACECLKIN freq> [<trace freq>]))",
},
COMMAND_REGISTRATION_DONE
};
static const struct command_registration itm_command_handlers[] = {
{
.name = "port",
@ -466,13 +149,6 @@ static const struct command_registration itm_command_handlers[] = {
};
const struct command_registration armv7m_trace_command_handlers[] = {
{
.name = "tpiu",
.mode = COMMAND_ANY,
.help = "tpiu command group",
.usage = "",
.chain = tpiu_command_handlers,
},
{
.name = "itm",
.mode = COMMAND_ANY,

View File

@ -18,33 +18,14 @@
#ifndef OPENOCD_TARGET_ARMV7M_TRACE_H
#define OPENOCD_TARGET_ARMV7M_TRACE_H
#include <server/server.h>
#include <target/target.h>
#include <command.h>
/**
* @file
* Holds the interface to TPIU, ITM and DWT configuration functions.
* Holds the interface to ITM and DWT configuration functions.
*/
enum trace_config_type {
TRACE_CONFIG_TYPE_DISABLED, /**< tracing is disabled */
TRACE_CONFIG_TYPE_EXTERNAL, /**< trace output is captured externally */
TRACE_CONFIG_TYPE_INTERNAL /**< trace output is handled by OpenOCD adapter driver */
};
enum trace_internal_channel {
TRACE_INTERNAL_CHANNEL_TCL_ONLY, /** trace data is sent only to 'tcl_trace' */
TRACE_INTERNAL_CHANNEL_FILE, /** trace data is appended to a file */
TRACE_INTERNAL_CHANNEL_TCP /** trace data is appended to a TCP/IP port*/
};
enum tpiu_pin_protocol {
TPIU_PIN_PROTOCOL_SYNC, /**< synchronous trace output */
TPIU_PIN_PROTOCOL_ASYNC_MANCHESTER, /**< asynchronous output with Manchester coding */
TPIU_PIN_PROTOCOL_ASYNC_UART /**< asynchronous output with NRZ coding */
};
enum itm_ts_prescaler {
ITM_TS_PRESCALE1, /**< no prescaling for the timestamp counter */
ITM_TS_PRESCALE4, /**< refclock divided by 4 for the timestamp counter */
@ -53,19 +34,6 @@ enum itm_ts_prescaler {
};
struct armv7m_trace_config {
/** Currently active trace capture mode */
enum trace_config_type config_type;
/** The used channel when internal mode is selected */
enum trace_internal_channel internal_channel;
/** Currently active trace output mode */
enum tpiu_pin_protocol pin_protocol;
/** TPIU formatter enable/disable (in async mode) */
bool formatter;
/** Synchronous output port width */
uint32_t port_size;
/** Bitmask of currently enabled ITM stimuli */
uint32_t itm_ter[8];
/** Identifier for multi-source trace stream formatting */
@ -80,27 +48,10 @@ struct armv7m_trace_config {
bool itm_synchro_packets;
/** Config ITM after target examine */
bool itm_deferred_config;
/** Current frequency of TRACECLKIN (usually matches HCLK) */
unsigned int traceclkin_freq;
/** Current frequency of trace port */
unsigned int trace_freq;
/** Handle to output trace data in INTERNAL capture mode via file */
FILE *trace_file;
/** Handle to output trace data in INTERNAL capture mode via tcp */
struct service *trace_service;
};
extern const struct command_registration armv7m_trace_command_handlers[];
/**
* Configure hardware accordingly to the current TPIU target settings
*/
int armv7m_trace_tpiu_config(struct target *target);
/**
* Disable TPIU data gathering at exit
*/
int armv7m_trace_tpiu_exit(struct target *target);
/**
* Configure hardware accordingly to the current ITM target settings
*/

View File

@ -1648,8 +1648,6 @@ void cortex_m_deinit_target(struct target *target)
{
struct cortex_m_common *cortex_m = target_to_cm(target);
armv7m_trace_tpiu_exit(target);
free(cortex_m->fp_comparator_list);
cortex_m_dwt_free(target);
@ -2082,9 +2080,6 @@ int cortex_m_examine(struct target *target)
if (retval != ERROR_OK)
return retval;
if (armv7m->trace_config.config_type != TRACE_CONFIG_TYPE_DISABLED)
armv7m_trace_tpiu_config(target);
if (armv7m->trace_config.itm_deferred_config)
armv7m_trace_itm_config(target);
@ -2486,6 +2481,11 @@ static const struct command_registration cortex_m_command_handlers[] = {
{
.chain = armv7m_trace_command_handlers,
},
/* START_DEPRECATED_TPIU */
{
.chain = arm_tpiu_deprecated_command_handlers,
},
/* END_DEPRECATED_TPIU */
{
.name = "cortex_m",
.mode = COMMAND_EXEC,

View File

@ -630,6 +630,11 @@ static const struct command_registration adapter_command_handlers[] = {
{
.chain = rtt_target_command_handlers,
},
/* START_DEPRECATED_TPIU */
{
.chain = arm_tpiu_deprecated_command_handlers,
},
/* END_DEPRECATED_TPIU */
COMMAND_REGISTRATION_DONE
};

View File

@ -4945,6 +4945,11 @@ no_params:
}
if (goi->isconfigure) {
/* START_DEPRECATED_TPIU */
if (n->value == TARGET_EVENT_TRACE_CONFIG)
LOG_INFO("DEPRECATED target event %s", n->name);
/* END_DEPRECATED_TPIU */
bool replace = true;
if (teap == NULL) {
/* create new */