}
static struct transport jtag_transport = {
- .name = "jtag",
+ .id = TRANSPORT_JTAG,
.select = jtag_select,
.init = jtag_init,
};
transport_is_swim()) {
if (trst == TRST_ASSERT) {
LOG_ERROR("transport %s has no trst signal",
- get_current_transport()->name);
+ get_current_transport_name());
return ERROR_FAIL;
}
return ERROR_OK;
LOG_ERROR("reset is not supported on transport %s",
- get_current_transport()->name);
+ get_current_transport_name());
return ERROR_FAIL;
}
return adapter_system_reset(1);
else if (get_current_transport())
LOG_ERROR("reset is not supported on %s",
- get_current_transport()->name);
+ get_current_transport_name());
else
LOG_ERROR("transport is not selected");
return ERROR_FAIL;
return adapter_system_reset(0);
else if (get_current_transport())
LOG_ERROR("reset is not supported on %s",
- get_current_transport()->name);
+ get_current_transport_name());
else
LOG_ERROR("transport is not selected");
return ERROR_FAIL;
return ERROR_FAIL;
}
- LOG_DEBUG("current transport %s", transport->name);
+ LOG_DEBUG("current transport %s", get_current_transport_name());
/* get selected transport as enum */
- tr = HL_TRANSPORT_UNKNOWN;
-
- if (strcmp(transport->name, "hla_swd") == 0)
+ switch (transport->id) {
+ case TRANSPORT_HLA_SWD:
tr = HL_TRANSPORT_SWD;
- else if (strcmp(transport->name, "hla_jtag") == 0)
+ break;
+ case TRANSPORT_HLA_JTAG:
tr = HL_TRANSPORT_JTAG;
+ break;
+ default:
+ tr = HL_TRANSPORT_UNKNOWN;
+ break;
+ }
int retval = hl_interface_open(tr);
}
static struct transport hl_swd_transport = {
- .name = "hla_swd",
+ .id = TRANSPORT_HLA_SWD,
.select = hl_swd_transport_select,
.init = hl_transport_init,
.override_target = hl_interface_override_target,
};
static struct transport hl_jtag_transport = {
- .name = "hla_jtag",
+ .id = TRANSPORT_HLA_JTAG,
.select = hl_jtag_transport_select,
.init = hl_transport_init,
.override_target = hl_interface_override_target,
* messaging and error handling.
*/
+#include <helper/align.h>
+#include <helper/bits.h>
#include <helper/log.h>
#include <helper/replacements.h>
#include <transport/transport.h>
*/
/** List of transports known to OpenOCD. */
+static const struct {
+ unsigned int id;
+ const char *name;
+} transport_names[] = {
+ { TRANSPORT_JTAG, "jtag", },
+ { TRANSPORT_SWD, "swd", },
+ { TRANSPORT_HLA_JTAG, "hla_jtag", },
+ { TRANSPORT_HLA_SWD, "hla_swd", },
+ { TRANSPORT_DAPDIRECT_JTAG, "dapdirect_jtag", },
+ { TRANSPORT_DAPDIRECT_SWD, "dapdirect_swd", },
+ { TRANSPORT_SWIM, "swim", },
+};
+
+/** List of transports registered in OpenOCD. */
static struct transport *transport_list;
/**
/** * The transport being used for the current OpenOCD session. */
static struct transport *session;
+static const char *transport_name(unsigned int id)
+{
+ for (unsigned int i = 0; i < ARRAY_SIZE(transport_names); i++)
+ if (id == transport_names[i].id)
+ return transport_names[i].name;
+
+ return NULL;
+}
+
+static bool is_transport_id_valid(unsigned int id)
+{
+ return (id != 0) && ((id & ~TRANSPORT_VALID_MASK) == 0) && IS_PWR_OF_2(id);
+}
+
static int transport_select(struct command_context *ctx, const char *name)
{
/* name may only identify a known transport;
* caller guarantees session's transport isn't yet set.*/
for (struct transport *t = transport_list; t; t = t->next) {
- if (strcmp(t->name, name) == 0) {
+ if (!strcmp(transport_name(t->id), name)) {
int retval = t->select(ctx);
/* select() registers commands specific to this
* transport, and may also reset the link, e.g.
if (retval == ERROR_OK)
session = t;
else
- LOG_ERROR("Error selecting '%s' as transport", t->name);
+ LOG_ERROR("Error selecting '%s' as transport", name);
return retval;
}
}
{
struct transport *t;
+ if (!is_transport_id_valid(new_transport->id)) {
+ LOG_ERROR("invalid transport ID 0x%x", new_transport->id);
+ return ERROR_FAIL;
+ }
+
for (t = transport_list; t; t = t->next) {
- if (strcmp(t->name, new_transport->name) == 0) {
- LOG_ERROR("transport name already used");
+ if (t->id == new_transport->id) {
+ LOG_ERROR("transport '%s' already registered",
+ transport_name(t->id));
return ERROR_FAIL;
}
}
if (!new_transport->select || !new_transport->init)
- LOG_ERROR("invalid transport %s", new_transport->name);
+ LOG_ERROR("invalid transport %s",
+ transport_name(new_transport->id));
/* splice this into the list */
new_transport->next = transport_list;
transport_list = new_transport;
- LOG_DEBUG("register '%s'", new_transport->name);
+ LOG_DEBUG("register '%s' (ID %d)",
+ transport_name(new_transport->id), new_transport->id);
return ERROR_OK;
}
return session;
}
+const char *get_current_transport_name(void)
+{
+ if (!session || !is_transport_id_valid(session->id))
+ NULL;
+
+ return transport_name(session->id);
+}
+
/*-----------------------------------------------------------------------*/
/*
if (transport_single_is_autoselected)
LOG_WARNING("DEPRECATED: auto-selecting transport \"%s\". "
"Use 'transport select %s' to suppress this message.",
- session->name, session->name);
+ transport_name(session->id), transport_name(session->id));
return session->init(CMD_CTX);
}
command_print(CMD, "The following transports are available:");
for (struct transport *t = transport_list; t; t = t->next)
- command_print(CMD, "\t%s", t->name);
+ command_print(CMD, "\t%s", transport_name(t->id));
return ERROR_OK;
}
if (retval != ERROR_OK)
return retval;
}
- command_print(CMD, "%s", session->name);
+ command_print(CMD, "%s", transport_name(session->id));
return ERROR_OK;
}
/* assign transport */
if (session) {
- if (!strcmp(session->name, CMD_ARGV[0])) {
+ if (!strcmp(transport_name(session->id), CMD_ARGV[0])) {
if (transport_single_is_autoselected) {
/* Nothing to do, but also nothing to complain */
transport_single_is_autoselected = false;
return ERROR_OK;
}
- LOG_WARNING("Transport \"%s\" was already selected", session->name);
+ LOG_WARNING("Transport \"%s\" was already selected", CMD_ARGV[0]);
return ERROR_OK;
}
command_print(CMD, "Can't change session's transport after the initial selection was made");
#include "config.h"
#endif
+#include "helper/bits.h"
#include "helper/command.h"
+#define TRANSPORT_JTAG BIT(0)
+#define TRANSPORT_SWD BIT(1)
+#define TRANSPORT_HLA_JTAG BIT(2)
+#define TRANSPORT_HLA_SWD BIT(3)
+#define TRANSPORT_DAPDIRECT_JTAG BIT(4)
+#define TRANSPORT_DAPDIRECT_SWD BIT(5)
+#define TRANSPORT_SWIM BIT(6)
+
+/* mask for valid ID */
+#define TRANSPORT_VALID_MASK \
+ (TRANSPORT_JTAG | \
+ TRANSPORT_SWD | \
+ TRANSPORT_HLA_JTAG | \
+ TRANSPORT_HLA_SWD | \
+ TRANSPORT_DAPDIRECT_JTAG | \
+ TRANSPORT_DAPDIRECT_SWD | \
+ TRANSPORT_SWIM)
+
/**
* Wrapper for transport lifecycle operations.
*
*/
struct transport {
/**
- * Each transport has a unique name, used to select it
- * from among the alternatives. Examples might include
- * "jtag", * "swd", "AVR_ISP" and more.
+ * Each transport has a unique ID, used to select it
+ * from among the alternatives.
*/
- const char *name;
+ unsigned int id;
/**
* When a transport is selected, this method registers
struct transport *get_current_transport(void);
+const char *get_current_transport_name(void);
+
int transport_register_commands(struct command_context *ctx);
int allow_transports(struct command_context *ctx, const char * const *vector);