kopia lustrzana https://github.com/stlink-org/stlink
rodzic
42d2da531f
commit
d7e37a684a
2
Makefile
2
Makefile
|
@ -2,7 +2,7 @@
|
|||
##
|
||||
VPATH=src
|
||||
|
||||
SOURCES_LIB=stlink-common.c stlink-usb.c stlink-sg.c
|
||||
SOURCES_LIB=stlink-common.c stlink-usb.c stlink-sg.c uglylogging.c
|
||||
OBJS_LIB=$(SOURCES_LIB:.c=.o)
|
||||
TEST_PROGRAMS=test_usb #test_sg
|
||||
LDFLAGS=-lusb-1.0 -L. -lstlink
|
||||
|
|
|
@ -94,7 +94,7 @@ int main(int ac, char** av)
|
|||
}
|
||||
else /* stlinkv2 */
|
||||
{
|
||||
sl = stlink_open_usb(10);
|
||||
sl = stlink_open_usb(100);
|
||||
if (sl == NULL) goto on_error;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include "gdb-remote.h"
|
||||
|
||||
#define DEFAULT_LOGGING_LEVEL 10
|
||||
#define DEFAULT_LOGGING_LEVEL 100
|
||||
#define DEFAULT_GDB_LISTEN_PORT 4242
|
||||
|
||||
#define STRINGIFY_inner(name) #name
|
||||
|
@ -188,7 +188,7 @@ int main(int argc, char** argv) {
|
|||
memset(&state, 0, sizeof(state));
|
||||
// set defaults...
|
||||
state.stlink_version = 2;
|
||||
state.logging_level = 10;
|
||||
state.logging_level = DEFAULT_LOGGING_LEVEL;
|
||||
state.listen_port = DEFAULT_GDB_LISTEN_PORT;
|
||||
parse_options(argc, argv, &state);
|
||||
switch (state.stlink_version) {
|
||||
|
@ -234,15 +234,14 @@ int main(int argc, char** argv) {
|
|||
sl = stlink_v1_open(state.devicename, state.logging_level);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) {
|
||||
stlink_exit_dfu_mode(sl);
|
||||
}
|
||||
|
||||
if(stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) {
|
||||
stlink_enter_swd_mode(sl);
|
||||
}
|
||||
if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) {
|
||||
if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) {
|
||||
stlink_exit_dfu_mode(sl);
|
||||
}
|
||||
stlink_enter_swd_mode(sl);
|
||||
}
|
||||
|
||||
uint32_t chip_id = stlink_chip_id(sl);
|
||||
uint32_t core_id = stlink_core_id(sl);
|
||||
|
|
|
@ -13,21 +13,13 @@
|
|||
|
||||
|
||||
#include "stlink-common.h"
|
||||
#include "uglylogging.h"
|
||||
|
||||
void D(stlink_t *sl, char *txt) {
|
||||
if (sl->verbose > 1)
|
||||
fputs(txt, stderr);
|
||||
}
|
||||
|
||||
void DD(stlink_t *sl, char *format, ...) {
|
||||
if (sl->verbose > 0) {
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
vfprintf(stderr, format, list);
|
||||
va_end(list);
|
||||
}
|
||||
}
|
||||
|
||||
#define LOG_TAG __FILE__
|
||||
#define DLOG(format, args...) ugly_log(UDEBUG, LOG_TAG, format, ## args)
|
||||
#define ILOG(format, args...) ugly_log(UINFO, LOG_TAG, format, ## args)
|
||||
#define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args)
|
||||
#define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args)
|
||||
|
||||
|
||||
/* FPEC flash controller interface, pm0063 manual
|
||||
|
@ -256,38 +248,38 @@ static void disable_flash_read_protection(stlink_t *sl) {
|
|||
// Delegates to the backends...
|
||||
|
||||
void stlink_close(stlink_t *sl) {
|
||||
D(sl, "\n*** stlink_close ***\n");
|
||||
DLOG("*** stlink_close ***\n");
|
||||
sl->backend->close(sl);
|
||||
free(sl);
|
||||
}
|
||||
|
||||
void stlink_exit_debug_mode(stlink_t *sl) {
|
||||
D(sl, "\n*** stlink_exit_debug_mode ***\n");
|
||||
DLOG("*** stlink_exit_debug_mode ***\n");
|
||||
sl->backend->exit_debug_mode(sl);
|
||||
}
|
||||
|
||||
void stlink_enter_swd_mode(stlink_t *sl) {
|
||||
D(sl, "\n*** stlink_enter_swd_mode ***\n");
|
||||
DLOG("*** stlink_enter_swd_mode ***\n");
|
||||
sl->backend->enter_swd_mode(sl);
|
||||
}
|
||||
|
||||
// Force the core into the debug mode -> halted state.
|
||||
void stlink_force_debug(stlink_t *sl) {
|
||||
D(sl, "\n*** stlink_force_debug_mode ***\n");
|
||||
DLOG("*** stlink_force_debug_mode ***\n");
|
||||
sl->backend->force_debug(sl);
|
||||
}
|
||||
|
||||
void stlink_exit_dfu_mode(stlink_t *sl) {
|
||||
D(sl, "\n*** stlink_exit_dfu_mode ***\n");
|
||||
DLOG("*** stlink_exit_dfu_mode ***\n");
|
||||
sl->backend->exit_dfu_mode(sl);
|
||||
}
|
||||
|
||||
uint32_t stlink_core_id(stlink_t *sl) {
|
||||
D(sl, "\n*** stlink_core_id ***\n");
|
||||
DLOG("*** stlink_core_id ***\n");
|
||||
sl->backend->core_id(sl);
|
||||
if (sl->verbose > 2)
|
||||
stlink_print_data(sl);
|
||||
DD(sl, "core_id = 0x%08x\n", sl->core_id);
|
||||
DLOG("core_id = 0x%08x\n", sl->core_id);
|
||||
return sl->core_id;
|
||||
}
|
||||
|
||||
|
@ -314,17 +306,17 @@ void stlink_cpu_id(stlink_t *sl, cortex_m3_cpuid_t *cpuid) {
|
|||
}
|
||||
|
||||
void stlink_reset(stlink_t *sl) {
|
||||
D(sl, "\n*** stlink_reset ***\n");
|
||||
DLOG("*** stlink_reset ***\n");
|
||||
sl->backend->reset(sl);
|
||||
}
|
||||
|
||||
void stlink_run(stlink_t *sl) {
|
||||
D(sl, "\n*** stlink_run ***\n");
|
||||
DLOG("*** stlink_run ***\n");
|
||||
sl->backend->run(sl);
|
||||
}
|
||||
|
||||
void stlink_status(stlink_t *sl) {
|
||||
D(sl, "\n*** stlink_status ***\n");
|
||||
DLOG("*** stlink_status ***\n");
|
||||
sl->backend->status(sl);
|
||||
stlink_core_stat(sl);
|
||||
}
|
||||
|
@ -355,26 +347,26 @@ void _parse_version(stlink_t *sl, stlink_version_t *slv) {
|
|||
}
|
||||
|
||||
void stlink_version(stlink_t *sl) {
|
||||
D(sl, "*** looking up stlink version\n");
|
||||
DLOG("*** looking up stlink version\n");
|
||||
stlink_version_t slv;
|
||||
sl->backend->version(sl);
|
||||
_parse_version(sl, &slv);
|
||||
|
||||
DD(sl, "st vid = 0x%04x (expect 0x%04x)\n", slv.st_vid, USB_ST_VID);
|
||||
DD(sl, "stlink pid = 0x%04x\n", slv.stlink_pid);
|
||||
DD(sl, "stlink version = 0x%x\n", slv.stlink_v);
|
||||
DD(sl, "jtag version = 0x%x\n", slv.jtag_v);
|
||||
DD(sl, "swim version = 0x%x\n", slv.swim_v);
|
||||
DLOG("st vid = 0x%04x (expect 0x%04x)\n", slv.st_vid, USB_ST_VID);
|
||||
DLOG("stlink pid = 0x%04x\n", slv.stlink_pid);
|
||||
DLOG("stlink version = 0x%x\n", slv.stlink_v);
|
||||
DLOG("jtag version = 0x%x\n", slv.jtag_v);
|
||||
DLOG("swim version = 0x%x\n", slv.swim_v);
|
||||
if (slv.jtag_v == 0) {
|
||||
DD(sl, " notice: the firmware doesn't support a jtag/swd interface\n");
|
||||
DLOG(" notice: the firmware doesn't support a jtag/swd interface\n");
|
||||
}
|
||||
if (slv.swim_v == 0) {
|
||||
DD(sl, " notice: the firmware doesn't support a swim interface\n");
|
||||
DLOG(" notice: the firmware doesn't support a swim interface\n");
|
||||
}
|
||||
}
|
||||
|
||||
void stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
|
||||
D(sl, "\n*** stlink_write_mem32 ***\n");
|
||||
DLOG("*** stlink_write_mem32 ***\n");
|
||||
if (len % 4 != 0) {
|
||||
fprintf(stderr, "Error: Data length doesn't have a 32 bit alignment: +%d byte.\n", len % 4);
|
||||
return;
|
||||
|
@ -383,7 +375,7 @@ void stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
|
|||
}
|
||||
|
||||
void stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
|
||||
D(sl, "\n*** stlink_read_mem32 ***\n");
|
||||
DLOG("*** stlink_read_mem32 ***\n");
|
||||
if (len % 4 != 0) { // !!! never ever: fw gives just wrong values
|
||||
fprintf(stderr, "Error: Data length doesn't have a 32 bit alignment: +%d byte.\n",
|
||||
len % 4);
|
||||
|
@ -393,23 +385,23 @@ void stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
|
|||
}
|
||||
|
||||
void stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) {
|
||||
D(sl, "\n*** stlink_write_mem8 ***\n");
|
||||
DLOG("*** stlink_write_mem8 ***\n");
|
||||
sl->backend->write_mem8(sl, addr, len);
|
||||
}
|
||||
|
||||
void stlink_read_all_regs(stlink_t *sl, reg *regp) {
|
||||
D(sl, "\n*** stlink_read_all_regs ***\n");
|
||||
DLOG("*** stlink_read_all_regs ***\n");
|
||||
sl->backend->read_all_regs(sl, regp);
|
||||
}
|
||||
|
||||
void stlink_write_reg(stlink_t *sl, uint32_t reg, int idx) {
|
||||
D(sl, "\n*** stlink_write_reg\n");
|
||||
DLOG("*** stlink_write_reg\n");
|
||||
sl->backend->write_reg(sl, reg, idx);
|
||||
}
|
||||
|
||||
void stlink_read_reg(stlink_t *sl, int r_idx, reg *regp) {
|
||||
D(sl, "\n*** stlink_read_reg\n");
|
||||
DD(sl, " (%d) ***\n", r_idx);
|
||||
DLOG("*** stlink_read_reg\n");
|
||||
DLOG(" (%d) ***\n", r_idx);
|
||||
|
||||
if (r_idx > 20 || r_idx < 0) {
|
||||
fprintf(stderr, "Error: register index must be in [0..20]\n");
|
||||
|
@ -426,7 +418,7 @@ unsigned int is_core_halted(stlink_t *sl) {
|
|||
}
|
||||
|
||||
void stlink_step(stlink_t *sl) {
|
||||
D(sl, "\n*** stlink_step ***\n");
|
||||
DLOG("*** stlink_step ***\n");
|
||||
sl->backend->step(sl);
|
||||
}
|
||||
|
||||
|
@ -434,16 +426,16 @@ int stlink_current_mode(stlink_t *sl) {
|
|||
int mode = sl->backend->current_mode(sl);
|
||||
switch (mode) {
|
||||
case STLINK_DEV_DFU_MODE:
|
||||
DD(sl, "stlink current mode: dfu\n");
|
||||
DLOG("stlink current mode: dfu\n");
|
||||
return mode;
|
||||
case STLINK_DEV_DEBUG_MODE:
|
||||
DD(sl, "stlink current mode: debug (jtag or swd)\n");
|
||||
DLOG("stlink current mode: debug (jtag or swd)\n");
|
||||
return mode;
|
||||
case STLINK_DEV_MASS_MODE:
|
||||
DD(sl, "stlink current mode: mass\n");
|
||||
DLOG("stlink current mode: mass\n");
|
||||
return mode;
|
||||
}
|
||||
DD(sl, "stlink mode: unknown!\n");
|
||||
DLOG("stlink mode: unknown!\n");
|
||||
return STLINK_DEV_UNKNOWN_MODE;
|
||||
}
|
||||
|
||||
|
@ -496,11 +488,11 @@ void stlink_core_stat(stlink_t *sl) {
|
|||
switch (sl->q_buf[0]) {
|
||||
case STLINK_CORE_RUNNING:
|
||||
sl->core_stat = STLINK_CORE_RUNNING;
|
||||
DD(sl, " core status: running\n");
|
||||
DLOG(" core status: running\n");
|
||||
return;
|
||||
case STLINK_CORE_HALTED:
|
||||
sl->core_stat = STLINK_CORE_HALTED;
|
||||
DD(sl, " core status: halted\n");
|
||||
DLOG(" core status: halted\n");
|
||||
return;
|
||||
default:
|
||||
sl->core_stat = STLINK_CORE_STAT_UNKNOWN;
|
||||
|
|
|
@ -181,10 +181,6 @@ extern "C" {
|
|||
|
||||
};
|
||||
|
||||
// some quick and dirty logging...
|
||||
void D(stlink_t *sl, char *txt);
|
||||
void DD(stlink_t *sl, char *format, ...);
|
||||
|
||||
//stlink_t* stlink_quirk_open(const char *dev_name, const int verbose);
|
||||
|
||||
// delegated functions...
|
||||
|
|
|
@ -81,9 +81,14 @@
|
|||
#include <sys/mman.h>
|
||||
|
||||
#include "stlink-common.h"
|
||||
|
||||
#include "stlink-sg.h"
|
||||
#include "uglylogging.h"
|
||||
|
||||
#define LOG_TAG __FILE__
|
||||
#define DLOG(format, args...) ugly_log(UDEBUG, LOG_TAG, format, ## args)
|
||||
#define ILOG(format, args...) ugly_log(UINFO, LOG_TAG, format, ## args)
|
||||
#define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args)
|
||||
#define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args)
|
||||
|
||||
// Suspends execution of the calling process for
|
||||
// (at least) ms milliseconds.
|
||||
|
@ -104,7 +109,7 @@ static void clear_cdb(struct stlink_libsg *sl) {
|
|||
// E.g. make the valgrind happy.
|
||||
|
||||
static void clear_buf(stlink_t *sl) {
|
||||
DD(sl, "*** clear_buf ***\n");
|
||||
DLOG("*** clear_buf ***\n");
|
||||
for (size_t i = 0; i < sizeof (sl->q_buf); i++)
|
||||
sl->q_buf[i] = 0;
|
||||
|
||||
|
@ -142,7 +147,7 @@ static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) {
|
|||
}
|
||||
const int duration = get_scsi_pt_duration_ms(ptvp);
|
||||
if ((stl->verbose > 1) && (duration >= 0))
|
||||
DD(stl, " duration=%d ms\n", duration);
|
||||
DLOG(" duration=%d ms\n", duration);
|
||||
|
||||
// XXX stlink fw sends broken residue, so ignore it and use the known q_len
|
||||
// "usb-storage quirks=483:3744:r"
|
||||
|
@ -159,7 +164,7 @@ static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) {
|
|||
switch (cat) {
|
||||
case SCSI_PT_RESULT_GOOD:
|
||||
if (stl->verbose && (resid > 0))
|
||||
DD(stl, " notice: requested %d bytes but "
|
||||
DLOG(" notice: requested %d bytes but "
|
||||
"got %d bytes, ignore [broken] residue = %d\n",
|
||||
stl->q_len, dsize, resid);
|
||||
break;
|
||||
|
@ -168,7 +173,7 @@ static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) {
|
|||
sg_get_scsi_status_str(
|
||||
get_scsi_pt_status_response(ptvp), sizeof (buf),
|
||||
buf);
|
||||
DD(stl, " scsi status: %s\n", buf);
|
||||
DLOG(" scsi status: %s\n", buf);
|
||||
}
|
||||
return;
|
||||
case SCSI_PT_RESULT_SENSE:
|
||||
|
@ -176,11 +181,11 @@ static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) {
|
|||
if (stl->verbose) {
|
||||
sg_get_sense_str("", sl->sense_buf, slen, (stl->verbose
|
||||
> 1), sizeof (buf), buf);
|
||||
DD(stl, "%s", buf);
|
||||
DLOG("%s", buf);
|
||||
}
|
||||
if (stl->verbose && (resid > 0)) {
|
||||
if ((stl->verbose) || (stl->q_len > 0))
|
||||
DD(stl, " requested %d bytes but "
|
||||
DLOG(" requested %d bytes but "
|
||||
"got %d bytes\n", stl->q_len, dsize);
|
||||
}
|
||||
return;
|
||||
|
@ -193,13 +198,13 @@ static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) {
|
|||
// The 'host_status' field has the following values:
|
||||
// [0x07] Internal error detected in the host adapter.
|
||||
// This may not be fatal (and the command may have succeeded).
|
||||
DD(stl, " transport: %s", buf);
|
||||
DLOG(" transport: %s", buf);
|
||||
}
|
||||
return;
|
||||
case SCSI_PT_RESULT_OS_ERR:
|
||||
if (stl->verbose) {
|
||||
get_scsi_pt_os_err_str(ptvp, sizeof (buf), buf);
|
||||
DD(stl, " os: %s", buf);
|
||||
DLOG(" os: %s", buf);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
|
@ -212,10 +217,10 @@ static void stlink_confirm_inq(stlink_t *stl, struct sg_pt_base *ptvp) {
|
|||
void stlink_q(stlink_t *sl) {
|
||||
#if FINISHED_WITH_SG
|
||||
struct stlink_libsg* sg = sl->backend_data;
|
||||
DD(sl, "CDB[");
|
||||
DLOG("CDB[");
|
||||
for (int i = 0; i < CDB_SL; i++)
|
||||
DD(sl, " 0x%02x", (unsigned int) sg->cdb_cmd_blk[i]);
|
||||
DD(sl, "]\n");
|
||||
DLOG(" 0x%02x", (unsigned int) sg->cdb_cmd_blk[i]);
|
||||
DLOG("]\n");
|
||||
|
||||
// Get control command descriptor of scsi structure,
|
||||
// (one object per command!!)
|
||||
|
@ -258,13 +263,13 @@ void stlink_stat(stlink_t *stl, char *txt) {
|
|||
|
||||
switch (stl->q_buf[0]) {
|
||||
case STLINK_OK:
|
||||
DD(stl, " %s: ok\n", txt);
|
||||
DLOG(" %s: ok\n", txt);
|
||||
return;
|
||||
case STLINK_FALSE:
|
||||
DD(stl, " %s: false\n", txt);
|
||||
DLOG(" %s: false\n", txt);
|
||||
return;
|
||||
default:
|
||||
DD(stl, " %s: unknown\n", txt);
|
||||
DLOG(" %s: unknown\n", txt);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -300,7 +305,7 @@ static void parse_version(stlink_t *stl) {
|
|||
|
||||
void _stlink_sg_version(stlink_t *stl) {
|
||||
struct stlink_libsg *sl = stl->backend_data;
|
||||
D(stl, "\n*** stlink_version ***\n");
|
||||
DLOG("\n*** stlink_version ***\n");
|
||||
clear_cdb(sl);
|
||||
sl->cdb_cmd_blk[0] = STLINK_GET_VERSION;
|
||||
stl->q_len = 6;
|
||||
|
@ -339,7 +344,7 @@ void _stlink_sg_enter_swd_mode(stlink_t *sl) {
|
|||
|
||||
void _stlink_sg_enter_jtag_mode(stlink_t *sl) {
|
||||
struct stlink_libsg *sg = sl->backend_data;
|
||||
D(sl, "\n*** stlink_enter_jtag_mode ***\n");
|
||||
DLOG("\n*** stlink_enter_jtag_mode ***\n");
|
||||
clear_cdb(sg);
|
||||
sg->cdb_cmd_blk[1] = STLINK_DEBUG_ENTER;
|
||||
sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_JTAG;
|
||||
|
@ -351,7 +356,7 @@ void _stlink_sg_enter_jtag_mode(stlink_t *sl) {
|
|||
|
||||
void _stlink_sg_exit_dfu_mode(stlink_t *sl) {
|
||||
struct stlink_libsg *sg = sl->backend_data;
|
||||
D(sl, "\n*** stlink_exit_dfu_mode ***\n");
|
||||
DLOG("\n*** stlink_exit_dfu_mode ***\n");
|
||||
clear_cdb(sg);
|
||||
sg->cdb_cmd_blk[0] = STLINK_DFU_COMMAND;
|
||||
sg->cdb_cmd_blk[1] = STLINK_DFU_EXIT;
|
||||
|
@ -428,7 +433,7 @@ void _stlink_sg_reset(stlink_t *sl) {
|
|||
|
||||
void _stlink_sg_status(stlink_t *sl) {
|
||||
struct stlink_libsg *sg = sl->backend_data;
|
||||
D(sl, "\n*** stlink_status ***\n");
|
||||
DLOG("\n*** stlink_status ***\n");
|
||||
clear_cdb(sg);
|
||||
sg->cdb_cmd_blk[1] = STLINK_DEBUG_GETSTATUS;
|
||||
sl->q_len = 2;
|
||||
|
@ -440,7 +445,7 @@ void _stlink_sg_status(stlink_t *sl) {
|
|||
|
||||
void _stlink_sg_force_debug(stlink_t *sl) {
|
||||
struct stlink_libsg *sg = sl->backend_data;
|
||||
D(sl, "\n*** stlink_force_debug ***\n");
|
||||
DLOG("\n*** stlink_force_debug ***\n");
|
||||
clear_cdb(sg);
|
||||
sg->cdb_cmd_blk[1] = STLINK_DEBUG_FORCEDEBUG;
|
||||
sl->q_len = 2;
|
||||
|
@ -471,7 +476,7 @@ void _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) {
|
|||
for (int i = 0; i < 16; i++) {
|
||||
sg->reg.r[i] = read_uint32(sl->q_buf, 4 * i);
|
||||
if (sl->verbose > 1)
|
||||
DD(sl, "r%2d = 0x%08x\n", i, sg->reg.r[i]);
|
||||
DLOG("r%2d = 0x%08x\n", i, sg->reg.r[i]);
|
||||
}
|
||||
sg->reg.xpsr = read_uint32(sl->q_buf, 64);
|
||||
sg->reg.main_sp = read_uint32(sl->q_buf, 68);
|
||||
|
@ -481,11 +486,11 @@ void _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) {
|
|||
if (sl->verbose < 2)
|
||||
return;
|
||||
|
||||
DD(sl, "xpsr = 0x%08x\n", sg->reg.xpsr);
|
||||
DD(sl, "main_sp = 0x%08x\n", sg->reg.main_sp);
|
||||
DD(sl, "process_sp = 0x%08x\n", sg->reg.process_sp);
|
||||
DD(sl, "rw = 0x%08x\n", sg->reg.rw);
|
||||
DD(sl, "rw2 = 0x%08x\n", sg->reg.rw2);
|
||||
DLOG("xpsr = 0x%08x\n", sg->reg.xpsr);
|
||||
DLOG("main_sp = 0x%08x\n", sg->reg.main_sp);
|
||||
DLOG("process_sp = 0x%08x\n", sg->reg.process_sp);
|
||||
DLOG("rw = 0x%08x\n", sg->reg.rw);
|
||||
DLOG("rw2 = 0x%08x\n", sg->reg.rw2);
|
||||
}
|
||||
|
||||
// Read an arm-core register, the index must be in the range 0..20.
|
||||
|
@ -506,7 +511,7 @@ void _stlink_sg_read_reg(stlink_t *sl, int r_idx, reg *regp) {
|
|||
stlink_print_data(sl);
|
||||
|
||||
uint32_t r = read_uint32(sl->q_buf, 0);
|
||||
DD(sl, "r_idx (%2d) = 0x%08x\n", r_idx, r);
|
||||
DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r);
|
||||
|
||||
switch (r_idx) {
|
||||
case 16:
|
||||
|
@ -553,7 +558,7 @@ void _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int idx) {
|
|||
|
||||
void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) {
|
||||
struct stlink_libsg *sg = sl->backend_data;
|
||||
D(sl, "\n*** stlink_write_dreg ***\n");
|
||||
DLOG("\n*** stlink_write_dreg ***\n");
|
||||
clear_cdb(sg);
|
||||
sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEDEBUGREG;
|
||||
// 2-5: address of reg of the debug module
|
||||
|
@ -570,7 +575,7 @@ void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) {
|
|||
|
||||
void _stlink_sg_run(stlink_t *sl) {
|
||||
struct stlink_libsg *sg = sl->backend_data;
|
||||
D(sl, "\n*** stlink_run ***\n");
|
||||
DLOG("\n*** stlink_run ***\n");
|
||||
clear_cdb(sg);
|
||||
sg->cdb_cmd_blk[1] = STLINK_DEBUG_RUNCORE;
|
||||
sl->q_len = 2;
|
||||
|
@ -595,7 +600,7 @@ void _stlink_sg_step(stlink_t *sl) {
|
|||
// see Cortex-M3 Technical Reference Manual
|
||||
// TODO make delegate!
|
||||
void stlink_set_hw_bp(stlink_t *sl, int fp_nr, uint32_t addr, int fp) {
|
||||
D(sl, "\n*** stlink_set_hw_bp ***\n");
|
||||
DLOG("\n*** stlink_set_hw_bp ***\n");
|
||||
struct stlink_libsg *sg = sl->backend_data;
|
||||
clear_cdb(sg);
|
||||
sg->cdb_cmd_blk[1] = STLINK_DEBUG_SETFP;
|
||||
|
@ -616,7 +621,7 @@ void stlink_set_hw_bp(stlink_t *sl, int fp_nr, uint32_t addr, int fp) {
|
|||
// TODO make delegate!
|
||||
void stlink_clr_hw_bp(stlink_t *sl, int fp_nr) {
|
||||
struct stlink_libsg *sg = sl->backend_data;
|
||||
D(sl, "\n*** stlink_clr_hw_bp ***\n");
|
||||
DLOG("\n*** stlink_clr_hw_bp ***\n");
|
||||
clear_cdb(sg);
|
||||
sg->cdb_cmd_blk[1] = STLINK_DEBUG_CLEARFP;
|
||||
sg->cdb_cmd_blk[2] = fp_nr;
|
||||
|
@ -805,7 +810,7 @@ stlink_t* stlink_open(const char *dev_name, const int verbose) {
|
|||
|
||||
|
||||
stlink_t* stlink_v1_open(const char *dev_name, const int verbose) {
|
||||
|
||||
ugly_init(verbose);
|
||||
stlink_t *sl = stlink_open(dev_name, verbose);
|
||||
if (sl == NULL) {
|
||||
fputs("Error: could not open stlink device\n", stderr);
|
||||
|
@ -825,7 +830,7 @@ stlink_t* stlink_v1_open(const char *dev_name, const int verbose) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
D(sl, "\n*** stlink_force_open ***\n");
|
||||
DLOG("\n*** stlink_force_open ***\n");
|
||||
switch (stlink_current_mode(sl)) {
|
||||
case STLINK_DEV_MASS_MODE:
|
||||
return sl;
|
||||
|
@ -833,10 +838,10 @@ stlink_t* stlink_v1_open(const char *dev_name, const int verbose) {
|
|||
// TODO go to mass?
|
||||
return sl;
|
||||
}
|
||||
DD(sl, "\n*** switch the stlink to mass mode ***\n");
|
||||
DLOG("\n*** switch the stlink to mass mode ***\n");
|
||||
_stlink_sg_exit_dfu_mode(sl);
|
||||
// exit the dfu mode -> the device is gone
|
||||
DD(sl, "\n*** reopen the stlink device ***\n");
|
||||
DLOG("\n*** reopen the stlink device ***\n");
|
||||
delay(1000);
|
||||
stlink_close(sl);
|
||||
delay(5000);
|
||||
|
|
|
@ -5,8 +5,17 @@
|
|||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <libusb-1.0/libusb.h>
|
||||
|
||||
#include "stlink-common.h"
|
||||
#include "stlink-usb.h"
|
||||
#include "uglylogging.h"
|
||||
|
||||
#define LOG_TAG __FILE__
|
||||
#define DLOG(format, args...) ugly_log(UDEBUG, LOG_TAG, format, ## args)
|
||||
#define ILOG(format, args...) ugly_log(UINFO, LOG_TAG, format, ## args)
|
||||
#define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args)
|
||||
#define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args)
|
||||
|
||||
|
||||
enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80};
|
||||
|
||||
|
@ -472,11 +481,11 @@ void _stlink_usb_read_all_regs(stlink_t *sl, reg *regp) {
|
|||
if (sl->verbose < 2)
|
||||
return;
|
||||
|
||||
DD(sl, "xpsr = 0x%08x\n", read_uint32(sl->q_buf, 64));
|
||||
DD(sl, "main_sp = 0x%08x\n", read_uint32(sl->q_buf, 68));
|
||||
DD(sl, "process_sp = 0x%08x\n", read_uint32(sl->q_buf, 72));
|
||||
DD(sl, "rw = 0x%08x\n", read_uint32(sl->q_buf, 76));
|
||||
DD(sl, "rw2 = 0x%08x\n", read_uint32(sl->q_buf, 80));
|
||||
DLOG("xpsr = 0x%08x\n", read_uint32(sl->q_buf, 64));
|
||||
DLOG("main_sp = 0x%08x\n", read_uint32(sl->q_buf, 68));
|
||||
DLOG("process_sp = 0x%08x\n", read_uint32(sl->q_buf, 72));
|
||||
DLOG("rw = 0x%08x\n", read_uint32(sl->q_buf, 76));
|
||||
DLOG("rw2 = 0x%08x\n", read_uint32(sl->q_buf, 80));
|
||||
}
|
||||
|
||||
void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) {
|
||||
|
@ -499,7 +508,7 @@ void _stlink_usb_read_reg(stlink_t *sl, int r_idx, reg *regp) {
|
|||
sl->q_len = (size_t) size;
|
||||
stlink_print_data(sl);
|
||||
r = read_uint32(sl->q_buf, 0);
|
||||
DD(sl, "r_idx (%2d) = 0x%08x\n", r_idx, r);
|
||||
DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r);
|
||||
|
||||
switch (r_idx) {
|
||||
case 16:
|
||||
|
@ -584,7 +593,7 @@ stlink_t* stlink_open_usb(const int verbose) {
|
|||
memset(sl, 0, sizeof (stlink_t));
|
||||
memset(slu, 0, sizeof (struct stlink_libusb));
|
||||
|
||||
sl->verbose = verbose;
|
||||
ugly_init(verbose);
|
||||
sl->backend = &_stlink_usb_backend;
|
||||
sl->backend_data = slu;
|
||||
|
||||
|
@ -604,15 +613,15 @@ stlink_t* stlink_open_usb(const int verbose) {
|
|||
sl->sram_size = STM32L_SRAM_SIZE;
|
||||
|
||||
if (libusb_init(&(slu->libusb_ctx))) {
|
||||
fprintf(stderr, "failed to init libusb context, wrong version of libraries?\n");
|
||||
goto on_error;
|
||||
WLOG("failed to init libusb context, wrong version of libraries?\n");
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
slu->usb_handle = libusb_open_device_with_vid_pid(slu->libusb_ctx, USB_ST_VID, USB_STLINK_32L_PID);
|
||||
if (slu->usb_handle == NULL) {
|
||||
// TODO - free usb context too...
|
||||
free(slu);
|
||||
fprintf(stderr, "Couldn't find any ST-Link/V2 devices");
|
||||
WLOG("Couldn't find any ST-Link/V2 devices");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -620,14 +629,15 @@ stlink_t* stlink_open_usb(const int verbose) {
|
|||
int r;
|
||||
|
||||
r = libusb_detach_kernel_driver(slu->usb_handle, 0);
|
||||
if (r<0)
|
||||
printf("libusb_detach_kernel_driver(() error %s\n", strerror(-r));
|
||||
if (r<0) {
|
||||
WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-r));
|
||||
}
|
||||
goto on_libusb_error;
|
||||
}
|
||||
|
||||
if (libusb_get_configuration(slu->usb_handle, &config)) {
|
||||
/* this may fail for a previous configured device */
|
||||
printf("libusb_get_configuration()\n");
|
||||
WLOG("libusb_get_configuration()\n");
|
||||
goto on_libusb_error;
|
||||
}
|
||||
|
||||
|
@ -635,25 +645,25 @@ stlink_t* stlink_open_usb(const int verbose) {
|
|||
printf("setting new configuration (%d -> 1)\n", config);
|
||||
if (libusb_set_configuration(slu->usb_handle, 1)) {
|
||||
/* this may fail for a previous configured device */
|
||||
printf("libusb_set_configuration()\n");
|
||||
WLOG("libusb_set_configuration() failed\n");
|
||||
goto on_libusb_error;
|
||||
}
|
||||
}
|
||||
|
||||
if (libusb_claim_interface(slu->usb_handle, 0)) {
|
||||
printf("libusb_claim_interface()\n");
|
||||
WLOG("libusb_claim_interface() failed\n");
|
||||
goto on_libusb_error;
|
||||
}
|
||||
|
||||
slu->req_trans = libusb_alloc_transfer(0);
|
||||
if (slu->req_trans == NULL) {
|
||||
printf("libusb_alloc_transfer\n");
|
||||
WLOG("libusb_alloc_transfer failed\n");
|
||||
goto on_libusb_error;
|
||||
}
|
||||
|
||||
slu->rep_trans = libusb_alloc_transfer(0);
|
||||
if (slu->rep_trans == NULL) {
|
||||
printf("libusb_alloc_transfer\n");
|
||||
WLOG("libusb_alloc_transfer failed\n");
|
||||
goto on_libusb_error;
|
||||
}
|
||||
// TODO - could use the scanning techniq from stm8 code here...
|
||||
|
@ -666,7 +676,7 @@ stlink_t* stlink_open_usb(const int verbose) {
|
|||
|
||||
/* success */
|
||||
if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) {
|
||||
printf("-- exit_dfu_mode\n");
|
||||
ILOG("-- exit_dfu_mode\n");
|
||||
stlink_exit_dfu_mode(sl);
|
||||
}
|
||||
stlink_version(sl);
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* UglyLogging. Slow, yet another wheel reinvented, but enough to make the
|
||||
* rest of our code pretty enough.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "uglylogging.h"
|
||||
|
||||
static int max_level;
|
||||
|
||||
int ugly_init(int maximum_threshold) {
|
||||
max_level = maximum_threshold;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ugly_log(int level, const char *tag, const char *format, ...) {
|
||||
if (level > max_level) {
|
||||
return 0;
|
||||
}
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
time_t mytt = time(NULL);
|
||||
struct tm *tt;
|
||||
tt = localtime(&mytt);
|
||||
fprintf(stderr, "%d-%02d-%02dT%02d:%02d:%02d ", tt->tm_year + 1900, tt->tm_mon + 1, tt->tm_mday, tt->tm_hour, tt->tm_min, tt->tm_sec);
|
||||
switch (level) {
|
||||
case UDEBUG:
|
||||
fprintf(stderr, "DEBUG %s: ", tag);
|
||||
break;
|
||||
case UINFO:
|
||||
fprintf(stderr, "INFO %s: ", tag);
|
||||
break;
|
||||
case UWARN:
|
||||
fprintf(stderr, "WARN %s: ", tag);
|
||||
break;
|
||||
case UERROR:
|
||||
fprintf(stderr, "ERROR %s: ", tag);
|
||||
break;
|
||||
case UFATAL:
|
||||
fprintf(stderr, "FATAL %s: ", tag);
|
||||
vfprintf(stderr, format, args);
|
||||
exit(EXIT_FAILURE);
|
||||
// NEVER GETS HERE!!!
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%d %s: ", level, tag);
|
||||
break;
|
||||
}
|
||||
vfprintf(stderr, format, args);
|
||||
va_end(args);
|
||||
return 1;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Ugly, low performance, configurable level, logging "framework"
|
||||
*/
|
||||
|
||||
#ifndef UGLYLOGGING_H
|
||||
#define UGLYLOGGING_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define UDEBUG 90
|
||||
#define UINFO 50
|
||||
#define UWARN 30
|
||||
#define UERROR 20
|
||||
#define UFATAL 10
|
||||
|
||||
int ugly_init(int maximum_threshold);
|
||||
int ugly_log(int level, const char *tag, const char *format, ...);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* UGLYLOGGING_H */
|
||||
|
Ładowanie…
Reference in New Issue