Hosted: Add Stlink, remove old pc-stlinkv2 platform

This commit is contained in:
Uwe Bonnes 2020-04-19 15:50:50 +02:00
parent 09602a9e74
commit 13c3c934d2
16 changed files with 340 additions and 2226 deletions

View File

@ -9,4 +9,5 @@ LDFLAGS += -lws2_32
endif
VPATH += platforms/pc
SRC += timing.c cl_utils.c utils.c libusb_utils.c
SRC += stlinkv2.c
PC_HOSTED = 1

View File

@ -24,9 +24,14 @@
#include "general.h"
#include "swdptap.h"
#include "jtagtap.h"
#include "target.h"
#include "target_internal.h"
#include "adiv5.h"
#include "timing.h"
#include "cl_utils.h"
#include "gdb_if.h"
#include <signal.h>
#include "stlinkv2.h"
#define VENDOR_ID_BMP 0x1d50
#define PRODUCT_ID_BMP 0x6018
@ -48,8 +53,20 @@ jtag_proc_t jtag_proc;
static void exit_function(void)
{
libusb_exit(info.libusb_ctx);
fprintf(stderr, "INFO: Cleanup\n");
if(info.usb_link) {
libusb_free_transfer(info.usb_link->req_trans);
libusb_free_transfer(info.usb_link->rep_trans);
if (info.usb_link->ul_libusb_device_handle) {
libusb_release_interface (
info.usb_link->ul_libusb_device_handle, 0);
libusb_close(info.usb_link->ul_libusb_device_handle);
}
}
switch (info.bmp_type) {
default:
break;
}
fflush(stdout);
}
/* SIGTERM handler. */
@ -82,7 +99,7 @@ static int find_debuggers( BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info)
if (res < 0) {
fprintf(stderr, "WARN: libusb_get_device_descriptor() failed: %s",
libusb_strerror(res));
libusb_free_device_list(devs, 0);
libusb_free_device_list(devs, 1);
continue;
}
libusb_device_handle *handle;
@ -119,13 +136,13 @@ static int find_debuggers( BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info)
continue;
}
}
libusb_close(handle);
if (cl_opts->opt_ident_string) {
char *match_manu = NULL;
char *match_product = NULL;
match_manu = strstr(manufacturer, cl_opts->opt_ident_string);
match_product = strstr(product, cl_opts->opt_ident_string);
if (!match_manu && !match_product) {
libusb_close(handle);
continue;
}
}
@ -135,16 +152,16 @@ static int find_debuggers( BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info)
(desc.idProduct == PRODUCT_ID_BMP)) {
type = BMP_TYPE_BMP;
} else if (desc.idVendor == VENDOR_ID_STLINK) {
if (desc.idProduct == PRODUCT_ID_STLINKV1) {
fprintf(stderr, "INFO: STLINKV1 not supported\n");
continue;
}
if ((desc.idProduct == PRODUCT_ID_STLINKV2) ||
(desc.idProduct == PRODUCT_ID_STLINKV21) ||
(desc.idProduct == PRODUCT_ID_STLINKV21_MSD) ||
(desc.idProduct == PRODUCT_ID_STLINKV3) ||
(desc.idProduct == PRODUCT_ID_STLINKV3E)) {
type = BMP_TYPE_STLINKV2;
} else {
if (desc.idProduct == PRODUCT_ID_STLINKV1)
fprintf(stderr, "INFO: STLINKV1 not supported\n");
continue;
}
} else {
continue;
@ -176,8 +193,8 @@ static int find_debuggers( BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info)
goto rescan;
}
}
libusb_free_device_list(devs, 0);
return 0;
libusb_free_device_list(devs, 1);
return (found_debuggers == 1) ? 0 : -1;
}
void platform_init(int argc, char **argv)
@ -202,38 +219,97 @@ void platform_init(int argc, char **argv)
printf("Using %s %s %s\n", info.serial,
info.manufacturer,
info.product);
switch (info.bmp_type) {
case BMP_TYPE_STLINKV2:
if (stlink_init( &info))
exit(-1);
break;
default:
exit(-1);
}
int ret = -1;
if (cl_opts.opt_mode != BMP_MODE_DEBUG) {
ret = cl_execute(&cl_opts);
} else {
gdb_if_init();
return;
}
exit(ret);
}
int platform_adiv5_swdp_scan(void)
{
return -1;
switch (info.bmp_type) {
case BMP_TYPE_STLINKV2:
{
target_list_free();
ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
if (!stlink_enter_debug_swd(&info, dp)) {
adiv5_dp_init(dp);
if (target_list)
return 1;
}
free(dp);
break;
}
default:
return 0;
}
return 0;
}
int platform_swdptap_init(void)
{
switch (info.bmp_type) {
case BMP_TYPE_STLINKV2:
return 0;
break;
default:
return -1;
}
return -1;
}
int platform_jtag_scan(const uint8_t *lrlens)
{
(void) lrlens;
switch (info.bmp_type) {
case BMP_TYPE_STLINKV2:
return jtag_scan_stlinkv2(&info, lrlens);
default:
return -1;
}
return -1;
}
int platform_jtagtap_init(void)
{
switch (info.bmp_type) {
case BMP_TYPE_STLINKV2:
return 0;
}
int platform_adiv5_dp_defaults(void *arg)
{
(void)arg;
default:
return -1;
}
return -1;
}
int platform_jtag_dp_init()
void platform_adiv5_dp_defaults(ADIv5_DP_t *dp)
{
switch (info.bmp_type) {
case BMP_TYPE_STLINKV2:
return stlink_adiv5_dp_defaults(dp);
default:
break;
}
}
int platform_jtag_dp_init(ADIv5_DP_t *dp)
{
switch (info.bmp_type) {
case BMP_TYPE_STLINKV2:
return stlink_jtag_dp_init(dp);
default:
return -1;
}
return 0;
}
@ -258,10 +334,34 @@ char *platform_ident(void)
const char *platform_target_voltage(void)
{
switch (info.bmp_type) {
case BMP_TYPE_STLINKV2:
return stlink_target_voltage(&info);
default:
break;;
}
return NULL;
}
void platform_srst_set_val(bool assert) {(void) assert;}
void platform_srst_set_val(bool assert)
{
switch (info.bmp_type) {
case BMP_TYPE_STLINKV2:
return stlink_srst_set_val(&info, assert);
default:
break;
}
}
bool platform_srst_get_val(void)
{
switch (info.bmp_type) {
case BMP_TYPE_STLINKV2:
return stlink_srst_get_val();
default:
break;
}
return false;
}
bool platform_srst_get_val(void) { return false;}
void platform_buffer_flush(void) {}

View File

@ -1,6 +1,8 @@
#ifndef __PLATFORM_H
#define __PLATFORM_H
#include <libusb-1.0/libusb.h>
#include "libusb_utils.h"
#include "timing.h"
char *platform_ident(void);
@ -22,6 +24,8 @@ typedef enum bmp_type_s {
typedef struct bmp_info_s {
bmp_type_t bmp_type;
libusb_context *libusb_ctx;
struct ftdi_context *ftdic;
usb_link_t *usb_link;
unsigned int vid;
unsigned int pid;
char dev;
@ -30,4 +34,6 @@ typedef struct bmp_info_s {
char product[128];
} bmp_info_t;
extern bmp_info_t info;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -24,28 +24,18 @@
#define STLINK_DEBUG_PORT_ACCESS 0xffff
void stlink_init(int argc, char **argv);
int stlink_init(bmp_info_t *info);
int stlink_hwversion(void);
void stlink_leave_state(void);
const char *stlink_target_voltage(void);
void stlink_srst_set_val(bool assert);
int stlink_enter_debug_swd(void);
int stlink_enter_debug_jtag(void);
int stlink_read_idcodes(uint32_t *);
uint32_t stlink_read_coreid(void);
int stlink_read_dp_register(uint16_t port, uint16_t addr, uint32_t *res);
int stlink_write_dp_register(uint16_t port, uint16_t addr, uint32_t val);
const char *stlink_target_voltage(bmp_info_t *info);
void stlink_srst_set_val(bmp_info_t *info, bool assert);
bool stlink_srst_get_val(void);
int stlink_enter_debug_swd(bmp_info_t *info, ADIv5_DP_t *dp);
uint32_t stlink_dp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
uint16_t addr, uint32_t value);
uint32_t stlink_dp_read(ADIv5_DP_t *dp, uint16_t addr);
uint32_t stlink_dp_error(ADIv5_DP_t *dp);
void stlink_dp_abort(ADIv5_DP_t *dp, uint32_t abort);
int stlink_open_ap(uint8_t ap);
void stlink_close_ap(uint8_t ap);
void stlink_regs_read(ADIv5_AP_t *ap, void *data);
uint32_t stlink_reg_read(ADIv5_AP_t *ap, int idx);
void stlink_reg_write(ADIv5_AP_t *ap, int num, uint32_t val);
const char *stlink_target_voltage(bmp_info_t *info);
void stlink_adiv5_dp_defaults(ADIv5_DP_t *dp);
int stlink_jtag_dp_init(ADIv5_DP_t *dp);
int jtag_scan_stlinkv2(bmp_info_t *info, const uint8_t *irlens);
void stlink_exit_function(bmp_info_t *info);
extern int debug_level;
# define DEBUG_STLINK if (debug_level > 0) printf
# define DEBUG_USB if (debug_level > 1) printf

View File

@ -1,14 +0,0 @@
TARGET=blackmagic_stlinkv2
SYS = $(shell $(CC) -dumpmachine)
CFLAGS += -DSTLINKV2 -DJTAG_HL -DENABLE_DEBUG
CFLAGS +=-I ./target -I./platforms/pc
LDFLAGS += -lusb-1.0
ifneq (, $(findstring mingw, $(SYS)))
LDFLAGS += -lws2_32
else ifneq (, $(findstring cygwin, $(SYS)))
LDFLAGS += -lws2_32
endif
VPATH += platforms/pc
SRC += timing.c stlinkv2.c cl_utils.c utils.c
OWN_HL = 1
PC_HOSTED = 1

View File

@ -1,25 +0,0 @@
ST-Link V2/3 with original STM firmware as Blackmagic Debug Probes
Recent STM ST-LINK firmware revision (V3 and V2 >= J32) expose all
functionality that BMP needs. This platform implements blackmagic debug
probe for the STM ST-LINK.
Use at your own risk, but report or better fix problems.
Compile with "make PROBE_HOST=pc-stlinkv2"
Run the resulting blackmagic_stlinkv2 executable to start the gdb server.
You can also use on the command line alone, e.g
- "blackmagic_stlinkv2 -t" to scan and display the results of the scan
- "blackmagic_stlinkv2 <file.bin>" to flash <file.bin> at 0x08000000
- "blackmagic_stlinkv2 -h" for more options
Cross-compling for windows with mingw succeeds.
Drawback:
- JTAG does not work for chains with multiple devices.
- ST-LINKV3 seem to only work on STM32 devices.
- St-LINKV3 needs connect under reset on more devices than V2
ToDo:
- Implement an SWO server

View File

@ -1,115 +0,0 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2019 2019 Uwe Bonnes
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* 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 <http://www.gnu.org/licenses/>.
*/
#include "general.h"
#include "gdb_if.h"
#include "version.h"
#include "platform.h"
#include "target.h"
#include "target_internal.h"
#include "swdptap.h"
#include <assert.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include "adiv5.h"
#include "stlinkv2.h"
int platform_hwversion(void)
{
return stlink_hwversion();
}
const char *platform_target_voltage(void)
{
return stlink_target_voltage();
}
int platform_swdptap_init(void)
{
return 0;
}
swd_proc_t swd_proc;
jtag_proc_t jtag_proc;
static int adiv5_swdp_scan_stlinkv2(void)
{
target_list_free();
ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
if (stlink_enter_debug_swd())
return 0;
dp->idcode = stlink_read_coreid();
dp->dp_read = stlink_dp_read;
dp->error = stlink_dp_error;
dp->low_access = stlink_dp_low_access;
dp->abort = stlink_dp_abort;
stlink_dp_error(dp);
adiv5_dp_init(dp);
return target_list?1:0;
return 0;
}
int platform_adiv5_swdp_scan(void)
{
return adiv5_swdp_scan_stlinkv2();
}
int platform_jtag_scan(const uint8_t *lrlens)
{
return jtag_scan_stlinkv2(lrlens);
}
void platform_init(int argc, char **argv)
{
stlink_init(argc, argv);
}
static bool srst_status = false;
void platform_srst_set_val(bool assert)
{
stlink_srst_set_val(assert);
srst_status = assert;
}
bool platform_srst_get_val(void) { return srst_status; }
void platform_buffer_flush(void)
{
}
int platform_buffer_write(const uint8_t *data, int size)
{
(void) data;
(void) size;
return size;
}
int platform_buffer_read(uint8_t *data, int size)
{
(void) data;
return size;
}
int platform_jtagtap_init(void)
{
return 0;
}

View File

@ -1,46 +0,0 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2011 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __PLATFORM_H
#define __PLATFORM_H
#include <libusb-1.0/libusb.h>
#include "timing.h"
#ifndef _WIN32
# include <alloca.h>
#else
# ifndef alloca
# define alloca __builtin_alloca
# endif
#endif
#define PLATFORM_IDENT() "StlinkV2/3"
#define SET_RUN_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);
int platform_buffer_write(const uint8_t *data, int size);
int platform_buffer_read(uint8_t *data, int size);
int jtag_scan_stlinkv2(const uint8_t *irlens);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,52 +0,0 @@
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2019 Uwe Bonnes
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* 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 <http://www.gnu.org/licenses/>.
*/
#if !defined(__STLINKV2_H_)
#define STLINK_ERROR_FAIL -1
#define STLINK_ERROR_OK 0
#define STLINK_ERROR_WAIT 1
#define STLINK_DEBUG_PORT_ACCESS 0xffff
void stlink_init(int argc, char **argv);
int stlink_hwversion(void);
void stlink_leave_state(void);
const char *stlink_target_voltage(void);
void stlink_srst_set_val(bool assert);
int stlink_enter_debug_swd(void);
int stlink_enter_debug_jtag(void);
int stlink_read_idcodes(uint32_t *);
uint32_t stlink_read_coreid(void);
int stlink_read_dp_register(uint16_t port, uint16_t addr, uint32_t *res);
int stlink_write_dp_register(uint16_t port, uint16_t addr, uint32_t val);
uint32_t stlink_dp_low_access(ADIv5_DP_t *dp, uint8_t RnW,
uint16_t addr, uint32_t value);
uint32_t stlink_dp_read(ADIv5_DP_t *dp, uint16_t addr);
uint32_t stlink_dp_error(ADIv5_DP_t *dp);
void stlink_dp_abort(ADIv5_DP_t *dp, uint32_t abort);
int stlink_open_ap(uint8_t ap);
void stlink_close_ap(uint8_t ap);
void stlink_regs_read(ADIv5_AP_t *ap, void *data);
uint32_t stlink_reg_read(ADIv5_AP_t *ap, int idx);
void stlink_reg_write(ADIv5_AP_t *ap, int num, uint32_t val);
extern int debug_level;
# define DEBUG_STLINK if (debug_level > 0) printf
# define DEBUG_USB if (debug_level > 1) printf
#endif

View File

@ -120,27 +120,29 @@ static void cl_help(char **argv, BMP_CL_OPTIONS_t *opt)
printf("\t-h\t\t: This help.\n");
printf("\t-v[1|2]\t\t: Increasing verbosity\n");
printf("\t-d \"path\"\t: Use serial device at \"path\"\n");
printf("\t-P <num>\t: Use device found as <num>");
printf("\t-P <num>\t: Use debugger found at position <num>\n");
printf("\t-n <num>\t: Use target device found at position <num>\n");
printf("\t-s \"string\"\t: Use dongle with (partial) "
"serial number \"string\"\n");
printf("\t-c \"string\"\t: Use ftdi dongle with type \"string\"\n");
printf("\t-n\t\t: Exit immediate if no device found\n");
printf("\tRun mode related options:\n");
printf("\tDefault mode is to start the debug server at :2000\n");
printf("\t-j\t\t: Use JTAG. SWD is default.\n");
printf("\t-C\t\t: Connect under reset\n");
printf("\t-t\t\t: Scan SWD, with no target found scan jtag and exit\n");
printf("\t-t\t\t: Scan SWD and display information about connected"
"devices\n");
printf("\t-E\t\t: Erase flash until flash end or for given size\n");
printf("\t-V\t\t: Verify flash against binary file\n");
printf("\t-r\t\t: Read flash and write to binary file\n");
printf("\t-p\t\t: Supplies power to the target (where applicable)\n");
printf("\t-R\t\t: Reset device\n");
printf("\t\tDefault mode is starting the debug server\n");
printf("\tFlash operation modifiers options:\n");
printf("\t-a <num>\t: Start flash operation at flash address <num>\n"
"\t\t\tDefault start is 0x08000000\n");
"\t\t\t Default start is 0x08000000\n");
printf("\t-S <num>\t: Read <num> bytes. Default is until read fails.\n");
printf("\t-j\t\t: Use JTAG. SWD is default.\n");
printf("\t <file>\t\t: Use (binary) file <file> for flash operation\n"
"\t\t\tGiven <file> writes to flash if neither -r or -V is given\n");
"\t\t\t Given <file> writes to flash if neither -r or -V is "
"given\n");
exit(0);
}
@ -150,7 +152,7 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
opt->opt_target_dev = 1;
opt->opt_flash_start = 0x08000000;
opt->opt_flash_size = 16 * 1024 *1024;
while((c = getopt(argc, argv, "Ehv::d:s:I:c:CnN:tVta:S:jpP:rR")) != -1) {
while((c = getopt(argc, argv, "Ehv::d:s:I:c:Cn:tVta:S:jpP:rR")) != -1) {
switch(c) {
case 'c':
if (optarg)
@ -171,9 +173,6 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
case 'C':
opt->opt_connect_under_reset = true;
break;
case 'n':
opt->opt_no_wait = true;
break;
case 'd':
if (optarg)
opt->opt_device = optarg;
@ -208,7 +207,7 @@ void cl_init(BMP_CL_OPTIONS_t *opt, int argc, char **argv)
if (optarg)
opt->opt_flash_start = strtol(optarg, NULL, 0);
break;
case 'N':
case 'n':
if (optarg)
opt->opt_target_dev = strtol(optarg, NULL, 0);
break;

View File

@ -39,7 +39,6 @@ enum bmp_cl_mode {
typedef struct BMP_CL_OPTIONS_s {
enum bmp_cl_mode opt_mode;
bool opt_usejtag;
bool opt_no_wait;
bool opt_tpwr;
bool opt_connect_under_reset;
char *opt_flash_file;

View File

@ -18,7 +18,6 @@
*/
#include "general.h"
#include "cl_utils.h"
#include <libusb_utils.h>
static void LIBUSB_CALL on_trans_done(struct libusb_transfer *trans)
{