Merge pull request #511 from UweBonnes/pc-stlinkv2

Pc stlinkv2
This commit is contained in:
UweBonnes 2019-09-01 13:07:35 +02:00 committed by GitHub
commit 71b8a4e081
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 210 additions and 87 deletions

View File

@ -59,8 +59,14 @@ static char morse_repeat;
void morse(const char *msg, char repeat)
{
morse_msg = morse_ptr = msg;
#if defined(PC_HOSTED)
if (msg)
DEBUG("%s\n", msg);
(void) repeat;
#else
morse_msg = morse_ptr = msg;
morse_repeat = repeat;
#endif
}
bool morse_update(void)

View File

@ -37,7 +37,8 @@
#define PLATFORM_IDENT "StlinkV2/3"
#define SET_RUN_STATE(state)
#define SET_IDLE_STATE(state)
void stlink_check_detach(int state);
#define SET_IDLE_STATE(state) stlink_check_detach(state)
//#define SET_ERROR_STATE(state)
void platform_buffer_flush(void);

View File

@ -228,7 +228,7 @@ stlink Stlink;
static void exit_function(void)
{
libusb_exit(NULL);
DEBUG_STLINK("Cleanup\n");
DEBUG("\nCleanup\n");
}
/* SIGTERM handler. */
@ -245,6 +245,46 @@ struct trans_ctx {
};
int debug_level = 0;
bool has_attached = false;
static int LIBUSB_CALL hotplug_callback_attach(
libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event,
void *user_data)
{
(void)ctx;
(void)dev;
(void)event;
(void)user_data;
has_attached = true;
return 1; /* deregister Callback*/
}
int device_detached = 0;
static int LIBUSB_CALL hotplug_callback_detach(
libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event,
void *user_data)
{
(void)ctx;
(void)dev;
(void)event;
(void)user_data;
device_detached = 1;
return 1; /* deregister Callback*/
}
void stlink_check_detach(int state)
{
if (state == 1) {
/* Check for hotplug events */
struct timeval tv = {0,0};
libusb_handle_events_timeout_completed(
Stlink.libusb_ctx, &tv, &device_detached);
if (device_detached) {
DEBUG("Dongle was detached\n");
exit(0);
}
}
}
static void LIBUSB_CALL on_trans_done(struct libusb_transfer * trans)
{
@ -319,6 +359,7 @@ static int send_recv(uint8_t *txbuf, size_t txsize,
uint8_t *rxbuf, size_t rxsize)
{
int res = 0;
stlink_check_detach(1);
if( txsize) {
int txlen = txsize;
libusb_fill_bulk_transfer(Stlink.req_trans, Stlink.handle,
@ -440,6 +481,7 @@ static int stlink_usb_error_check(uint8_t *data, bool verbose)
case STLINK_SWD_DP_ERROR:
if (verbose)
DEBUG("STLINK_SWD_DP_ERROR\n");
raise_exception(EXCEPTION_ERROR, "STLINK_SWD_DP_ERROR");
return STLINK_ERROR_FAIL;
case STLINK_SWD_DP_PARITY_ERROR:
if (verbose)
@ -487,7 +529,7 @@ static int send_recv_retry(uint8_t *txbuf, size_t txsize,
gettimeofday(&now, NULL);
timersub(&now, &start, &diff);
if ((diff.tv_sec >= 1) || (res != STLINK_ERROR_WAIT)) {
DEBUG_STLINK("Failed: ");
DEBUG("write_retry failed");
return res;
}
}
@ -510,7 +552,7 @@ static int read_retry(uint8_t *txbuf, size_t txsize,
gettimeofday(&now, NULL);
timersub(&now, &start, &diff);
if ((diff.tv_sec >= 1) || (res != STLINK_ERROR_WAIT)) {
DEBUG_STLINK("Failed: ");
DEBUG("read_retry failed");
return res;
}
}
@ -534,7 +576,6 @@ static int write_retry(uint8_t *cmdbuf, size_t cmdsize,
gettimeofday(&now, NULL);
timersub(&now, &start, &diff);
if ((diff.tv_sec >= 1) || (res != STLINK_ERROR_WAIT)) {
DEBUG_STLINK("failed");
return res;
}
}
@ -645,6 +686,7 @@ void stlink_help(char **argv)
DEBUG("\t-v[1|2]\t\t: Increasing verbosity\n");
DEBUG("\t-s \"string\"\t: Use Stlink with (partial) "
"serial number \"string\"\n");
DEBUG("\t-n\t\t: Exit immediate if no device found\n");
DEBUG("\t-h\t\t: This help.\n");
exit(0);
}
@ -659,8 +701,12 @@ void stlink_init(int argc, char **argv)
libusb_init(&Stlink.libusb_ctx);
char *serial = NULL;
int c;
while((c = getopt(argc, argv, "s:v:h")) != -1) {
bool wait_for_attach = true;
while((c = getopt(argc, argv, "ns:v:h")) != -1) {
switch(c) {
case 'n':
wait_for_attach = false;
break;
case 's':
serial = optarg;
break;
@ -676,14 +722,22 @@ void stlink_init(int argc, char **argv)
r = libusb_init(NULL);
if (r < 0)
DEBUG("Failed: %s", libusb_strerror(r));
ssize_t cnt = libusb_get_device_list(NULL, &devs);
bool hotplug = true;
if (!libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)) {
printf("Hotplug capabilites are not supported on this platform\n");
hotplug = false;
}
ssize_t cnt;
rescan:
has_attached = 0;
memset(&Stlink, 0, sizeof(Stlink));
cnt = libusb_get_device_list(NULL, &devs);
if (cnt < 0) {
libusb_exit(NULL);
DEBUG("Failed: %s", libusb_strerror(r));
goto error;
}
int i = 0;
bool multiple_devices = false;
int nr_stlinks = 0;
while ((dev = devs[i++]) != NULL) {
struct libusb_device_descriptor desc;
int r = libusb_get_device_descriptor(dev, &desc);
@ -699,10 +753,8 @@ void stlink_init(int argc, char **argv)
DEBUG("STLINKV1 not supported\n");
continue;
}
if (Stlink.handle) {
libusb_close(Stlink.handle);
multiple_devices = (serial)? false : true;
}
Stlink.vid = desc.idVendor;
Stlink.pid = desc.idProduct;
r = libusb_open(dev, &Stlink.handle);
if (r == LIBUSB_SUCCESS) {
uint8_t data[32];
@ -736,44 +788,77 @@ void stlink_init(int argc, char **argv)
}
if (serial && (!strncmp(Stlink.serial, serial, strlen(serial))))
DEBUG("Found ");
if (!serial || (!strncmp(Stlink.serial, serial, strlen(serial)))) {
if (desc.idProduct == PRODUCT_ID_STLINKV2) {
DEBUG("STLINKV20 serial %s\n", Stlink.serial);
Stlink.ver_hw = 20;
Stlink.ep_tx = 2;
} else if (desc.idProduct == PRODUCT_ID_STLINKV21) {
DEBUG("STLINKV21 serial %s\n", Stlink.serial);
Stlink.ver_hw = 21;
Stlink.ep_tx = 1;
} else if (desc.idProduct == PRODUCT_ID_STLINKV21_MSD) {
DEBUG("STLINKV21_MSD serial %s\n", Stlink.serial);
Stlink.ver_hw = 21;
Stlink.ep_tx = 1;
} else if (desc.idProduct == PRODUCT_ID_STLINKV3E) {
DEBUG("STLINKV3E serial %s\n", Stlink.serial);
Stlink.ver_hw = 30;
Stlink.ep_tx = 1;
} else if (desc.idProduct == PRODUCT_ID_STLINKV3) {
DEBUG("STLINKV3 serial %s\n", Stlink.serial);
Stlink.ver_hw = 30;
Stlink.ep_tx = 1;
if (desc.idProduct == PRODUCT_ID_STLINKV2) {
DEBUG("STLINKV20 serial %s\n", Stlink.serial);
Stlink.ver_hw = 20;
Stlink.ep_tx = 2;
} else if (desc.idProduct == PRODUCT_ID_STLINKV21) {
DEBUG("STLINKV21 serial %s\n", Stlink.serial);
Stlink.ver_hw = 21;
Stlink.ep_tx = 1;
} else if (desc.idProduct == PRODUCT_ID_STLINKV21_MSD) {
DEBUG("STLINKV21_MSD serial %s\n", Stlink.serial);
Stlink.ver_hw = 21;
Stlink.ep_tx = 1;
} else if (desc.idProduct == PRODUCT_ID_STLINKV3E) {
DEBUG("STLINKV3E serial %s\n", Stlink.serial);
Stlink.ver_hw = 30;
Stlink.ep_tx = 1;
} else if (desc.idProduct == PRODUCT_ID_STLINKV3) {
DEBUG("STLINKV3 serial %s\n", Stlink.serial);
Stlink.ver_hw = 30;
Stlink.ep_tx = 1;
} else {
DEBUG("Unknown STLINK variant, serial %s\n", Stlink.serial);
}
nr_stlinks++;
if (serial) {
if (!strncmp(Stlink.serial, serial, strlen(serial))) {
break;
} else {
DEBUG("Unknown STLINK variant, serial %s\n", Stlink.serial);
libusb_close(Stlink.handle);
Stlink.handle = 0;
}
}
if (serial && (!strncmp(Stlink.serial, serial, strlen(serial))))
break;
} else {
DEBUG("Open failed %s\n", libusb_strerror(r));
}
}
}
if (multiple_devices) {
DEBUG("Multiple Stlinks. Please specify serial number\n");
goto error_1;
}
libusb_free_device_list(devs, 1);
if (!Stlink.handle) {
DEBUG("No Stlink device found!\n");
if (nr_stlinks && serial) {
DEBUG("No Stlink with given serial number %s\n", serial);
} else if (nr_stlinks > 1) {
DEBUG("Multiple Stlinks. Please specify serial number\n");
goto error;
} else {
DEBUG("No Stlink device found!\n");
}
if (hotplug && wait_for_attach) {
libusb_hotplug_callback_handle hp;
int rc = libusb_hotplug_register_callback
(NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, 0,
VENDOR_ID_STLINK, LIBUSB_HOTPLUG_MATCH_ANY,
LIBUSB_HOTPLUG_MATCH_ANY,
hotplug_callback_attach, NULL, &hp);
if (LIBUSB_SUCCESS != rc) {
DEBUG("Error registering attach callback\n");
goto error;
}
DEBUG("Waiting for %sST device%s%s to attach\n",
(serial)? "" : "some ",
(serial)? " with serial ": "",
(serial)? serial: "");
DEBUG("Terminate with ^C\n");
while (has_attached == 0) {
rc = libusb_handle_events (NULL);
if (rc < 0)
printf("libusb_handle_events() failed: %s\n",
libusb_error_name(rc));
}
goto rescan;
}
goto error;
}
int config;
@ -797,6 +882,16 @@ void stlink_init(int argc, char **argv)
DEBUG("libusb_claim_interface failed %s\n", libusb_strerror(r));
goto error_1;
}
if (hotplug) { /* Allow gracefully exit when stlink is unplugged*/
libusb_hotplug_callback_handle hp;
int rc = libusb_hotplug_register_callback
(NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, Stlink.vid, Stlink.pid,
LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback_detach, NULL, &hp);
if (LIBUSB_SUCCESS != rc) {
DEBUG("Error registering detach callback\n");
goto error;
}
}
Stlink.req_trans = libusb_alloc_transfer(0);
Stlink.rep_trans = libusb_alloc_transfer(0);
stlink_version();
@ -827,7 +922,7 @@ void stlink_init(int argc, char **argv)
error_1:
libusb_close(Stlink.handle);
error:
libusb_free_device_list(devs, 1);
libusb_exit(Stlink.libusb_ctx);
exit(-1);
}
@ -898,14 +993,8 @@ int stlink_enter_debug_swd(void)
STLINK_DEBUG_ENTER_SWD_NO_RESET};
uint8_t data[2];
DEBUG("Enter SWD\n");
if (send_recv_retry(cmd, 16, data, 2) != STLINK_ERROR_OK)
return -1;
uint8_t cmd1[16] = {STLINK_DEBUG_COMMAND,
STLINK_DEBUG_READCOREID};
uint8_t data1[4];
send_recv(cmd1, 16, data1, 4);
stlink_usb_error_check(data, false);
return 0;
send_recv(cmd, 16, data, 2);
return stlink_usb_error_check(data, true);
}
int stlink_enter_debug_jtag(void)
@ -1077,8 +1166,7 @@ bool adiv5_ap_setup(int ap)
uint8_t data[2];
send_recv_retry(cmd, 16, data, 2);
DEBUG_STLINK("Open AP %d\n", ap);
stlink_usb_error_check(data, true);
return true;
return (stlink_usb_error_check(data, true))? false: true;
}
void adiv5_ap_cleanup(int ap)

View File

@ -32,6 +32,7 @@
# include <netinet/in.h>
# include <netinet/tcp.h>
# include <sys/select.h>
# include <fcntl.h>
#endif
#include <stdio.h>
@ -100,7 +101,33 @@ unsigned char gdb_if_getchar(void)
while(i <= 0) {
if(gdb_if_conn <= 0) {
gdb_if_conn = accept(gdb_if_serv, NULL, NULL);
#if defined(_WIN32) || defined(__CYGWIN__)
unsigned long opt = 1;
ioctlsocket(gdb_if_serv, FIONBIO, &opt);
#else
int flags = fcntl(gdb_if_serv, F_GETFL);
fcntl(gdb_if_serv, F_SETFL, flags | O_NONBLOCK);
#endif
while(1) {
gdb_if_conn = accept(gdb_if_serv, NULL, NULL);
if (gdb_if_conn == -1) {
if (errno == EWOULDBLOCK) {
SET_IDLE_STATE(1);
platform_delay(100);
} else {
DEBUG("error when accepting connection");
exit(1);
}
} else {
#if defined(_WIN32) || defined(__CYGWIN__)
unsigned long opt = 0;
ioctlsocket(gdb_if_serv, FIONBIO, &opt);
#else
fcntl(gdb_if_serv, F_SETFL, flags);
#endif
break;
}
}
DEBUG("Got connection\n");
}
i = recv(gdb_if_conn, (void*)&ret, 1, 0);

View File

@ -20,34 +20,31 @@ This flash may have been tested bad, or not have been tested at all,
or, in the best case, was tested good but market requirements made STM sell
it as F103C8.
Ignoring the chip marking and using an F103C8 blindly as a F103Cb is done
already with few problems on many china boards (e.g. blue pill). Probably
this second approach will work for many of the older STLinks.
dfu-util cares for the size and refuses to programm above the announced size:
> dfu-util -S E4D078EA -s 0x08002000:leave -D blackmagic.bin
dfu-util 0.9
...
dfu-util: Last page at 0x0801093f is not writeable
Ignoring the chip marking and using an F103C8 blindly as a F103CB is done
already with no known problems on many STM board and china boards (e.g. blue
pill) with genuine STM32. China stlinks clones with a GD32F103x8 will
probably not work. Best is to get new genuine ST hardware. The
STLINK-Vmini is < 10 $ without VAT or to resolder a genuine
STM32F103CB chip. Think also about using the pc-hosted pc-stlinkv2
platform on stlinks with revent firmware.
Flash above the announced size with recent bootloader/BMP:
==========================================================
script/stm32_mem.py does not care for the announced size:
Use either the provided python tool, as script/stm32_mem.py
does not care for the announced size and verifies:
> ../scripts/stm32_mem.py blackmagic.bin
...
USB Device Firmware Upgrade - Host Utility -- version 1.2
...
Programming memory at 0x08010800
All operations complete!
Get length of binary
> ls -l blackmagic.bin
-rwxr-xr-x 1 bon users 59712 21. Sep 22:47 blackmagic.bin
Actual file size may differ!
or compile and use the upgrade executable.
Upload binary from flash with the exact size
> dfu-util -s 0x08002000:leave:force:59712 -U blackmagic.bin.1
> cd upgrade
> make (PROBE_HOST=...)
> ./blackmagic_upgrade
Compare
> diff blackmagic.bin*
No differences should get reported!
To long to read
===============
Use the BMP provided upgrade tools:
- scripts/stm32_mem.py
- Compiled upgrade tool in upgrade
Only if mismatch is reported, think further.

View File

@ -491,7 +491,10 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
ap = adiv5_new_ap(dp, i);
if (ap == NULL) {
adiv5_ap_cleanup(i);
continue;
if (i == 0)
return;
else
continue;
}
extern void kinetis_mdm_probe(ADIv5_AP_t *);
kinetis_mdm_probe(ap);

View File

@ -451,17 +451,18 @@ static void cortexm_regs_read(target *t, void *data)
{
uint32_t *regs = data;
ADIv5_AP_t *ap = cortexm_ap(t);
unsigned i;
#if defined(STLINKV2)
uint32_t base_regs[21];
extern void stlink_regs_read(ADIv5_AP_t *ap, void *data);
extern uint32_t stlink_reg_read(ADIv5_AP_t *ap, int idx);
stlink_regs_read(ap, data);
regs += sizeof(regnum_cortex_m);
stlink_regs_read(ap, base_regs);
for(i = 0; i < sizeof(regnum_cortex_m) / 4; i++)
*regs++ = base_regs[regnum_cortex_m[i]];
if (t->target_options & TOPT_FLAVOUR_V7MF)
for(size_t t = 0; t < sizeof(regnum_cortex_mf) / 4; t++)
*regs++ = stlink_reg_read(ap, regnum_cortex_mf[t]);
#else
unsigned i;
/* FIXME: Describe what's really going on here */
adiv5_ap_write(ap, ADIV5_AP_CSW, ap->csw | ADIV5_AP_CSW_SIZE_WORD);
@ -494,14 +495,14 @@ static void cortexm_regs_write(target *t, const void *data)
ADIv5_AP_t *ap = cortexm_ap(t);
#if defined(STLINKV2)
extern void stlink_reg_write(ADIv5_AP_t *ap, int num, uint32_t val);
for(size_t z = 1; z < sizeof(regnum_cortex_m) / 4; z++) {
for(size_t z = 0; z < sizeof(regnum_cortex_m) / 4; z++) {
stlink_reg_write(ap, regnum_cortex_m[z], *regs);
regs++;
}
if (t->target_options & TOPT_FLAVOUR_V7MF)
for(size_t z = 0; z < sizeof(regnum_cortex_mf) / 4; z++) {
stlink_reg_write(ap, regnum_cortex_mf[z], *regs);
regs++;
}
}
#else
unsigned i;

View File

@ -36,7 +36,7 @@ endif
bindata.o: $(PROBE_HOST).d
$(PROBE_HOST).d: ../src/blackmagic.bin
$(PROBE_HOST).d: $(wildcard ../src/blackmagic.bin)
-rm *.d
make -C ../src $0 clean
make -C ../src $0