Initial commit of workable stm32l debug

Move towards a standard libstlink, with backends for libusb (stm32l discovery) and scsi
passthrough (stm32vl discovery) and a common front end.

Verified that stm32l branch works much the same, but more to go for stm32vl.
pull/29/head
Karl Palsson 2011-10-06 23:22:33 +00:00
rodzic 8be7cea215
commit d060c3c040
15 zmienionych plików z 2963 dodań i 2140 usunięć

44
Makefile 100644
Wyświetl plik

@ -0,0 +1,44 @@
VPATH=src
SOURCES_LIB=stlink-common.c stlink-usb.c #stlink-sg.c
OBJS_LIB=$(SOURCES_LIB:.c=.o)
CFLAGS+=-DCONFIG_USE_LIBUSB
#CFLAGS+=-DCONFIG_USE_LIBSG
CFLAGS+= -std=gnu99
CFLAGS+=-Wall -Wextra
LDFLAGS=-lstlink -lusb-1.0 -L.
LIBRARY=libstlink.a
all: $(LIBRARY) test_usb #test_sg
$(LIBRARY): $(OBJS_LIB)
@echo "objs are $(OBJS_LIB)"
$(AR) -cr $@ $^
@echo "done making library"
test_sg: test_sg.o $(LIBRARY)
@echo "building test_sg"
$(CC) $(LDFLAGS) -o $@
test_usb: test_usb.o $(LIBRARY)
@echo "building test_usb"
$(CC) test_usb.o $(LDFLAGS) -o $@
@echo "done linking"
%.o: %.c
@echo "building $^ into $@"
$(CC) $(CFLAGS) -c $^ -o $@
@echo "done compiling"
clean:
rm -rf $(OBJS_LIB)
rm -rf $(LIBRARY)
rm -rf test_usb*
rm -rf test_sg*
.PHONY: clean all

Wyświetl plik

@ -1,22 +0,0 @@
PRG := st-util
DEBUG := #-DDEBUG
all: $(PRG)
LIBS := \
-lsgutils2
OBJS += \
stlink-hw.o gdb-remote.o gdb-server.o
$(PRG): $(OBJS)
gcc -o $(PRG) $(OBJS) $(LIBS)
%.o: ../src/%.c
gcc -O3 -g3 -Wall -Werror -c -std=gnu99 -MMD -MP \
-fno-strict-aliasing -Wno-unused $(DEBUG) \
-MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)"\
-o "$@" "$<"
clean:
@rm -vf *.d *.o $(PRG)

351
src/stlink-common.c 100644
Wyświetl plik

@ -0,0 +1,351 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include "stlink-common.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);
}
}
// Delegates to the backends...
void stlink_close(stlink_t *sl) {
D(sl, "\n*** 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");
sl->backend->exit_debug_mode(sl);
}
void stlink_enter_swd_mode(stlink_t *sl) {
D(sl, "\n*** stlink_enter_swd_mode ***\n");
sl->backend->enter_swd_mode(sl);
}
void stlink_exit_dfu_mode(stlink_t *sl) {
D(sl, "\n*** stlink_exit_duf_mode ***\n");
sl->backend->exit_dfu_mode(sl);
}
void stlink_core_id(stlink_t *sl) {
D(sl, "\n*** stlink_core_id ***\n");
sl->backend->core_id(sl);
DD(sl, "core_id = 0x%08x\n", sl->core_id);
}
void stlink_reset(stlink_t *sl) {
D(sl, "\n*** stlink_reset ***\n");
sl->backend->reset(sl);
}
void stlink_run(stlink_t *sl) {
D(sl, "\n*** stlink_core_id ***\n");
sl->backend->run(sl);
DD(sl, "core_id = 0x%08x\n", sl->core_id);
}
void stlink_status(stlink_t *sl) {
D(sl, "\n*** stlink_core_id ***\n");
sl->backend->status(sl);
stlink_core_stat(sl);
DD(sl, "core_id = 0x%08x\n", sl->core_id);
}
void stlink_version(stlink_t *sl) {
D(sl, "*** looking up stlink version\n");
sl->backend->version(sl);
}
void stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
D(sl, "\n*** 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;
}
sl->backend->write_mem32(sl, addr, len);
}
void stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) {
D(sl, "\n*** stlink_write_mem8 ***\n");
sl->backend->write_mem8(sl, addr, len);
}
// End of delegates.... Common code below here...
// Endianness
// http://www.ibm.com/developerworks/aix/library/au-endianc/index.html
// const int i = 1;
// #define is_bigendian() ( (*(char*)&i) == 0 )
static inline unsigned int is_bigendian(void) {
static volatile const unsigned int i = 1;
return *(volatile const char*) &i == 0;
}
uint16_t read_uint16(const unsigned char *c, const int pt) {
uint32_t ui;
char *p = (char *) &ui;
if (!is_bigendian()) { // le -> le (don't swap)
p[0] = c[pt];
p[1] = c[pt + 1];
} else {
p[0] = c[pt + 1];
p[1] = c[pt];
}
return ui;
}
void stlink_core_stat(stlink_t *sl) {
if (sl->q_len <= 0)
return;
stlink_print_data(sl);
switch (sl->q_buf[0]) {
case STLINK_CORE_RUNNING:
sl->core_stat = STLINK_CORE_RUNNING;
DD(sl, " core status: running\n");
return;
case STLINK_CORE_HALTED:
sl->core_stat = STLINK_CORE_HALTED;
DD(sl, " core status: halted\n");
return;
default:
sl->core_stat = STLINK_CORE_STAT_UNKNOWN;
fprintf(stderr, " core status: unknown\n");
}
}
void stlink_print_data(stlink_t *sl) {
if (sl->q_len <= 0 || sl->verbose < 2)
return;
if (sl->verbose > 2)
fprintf(stdout, "data_len = %d 0x%x\n", sl->q_len, sl->q_len);
for (int i = 0; i < sl->q_len; i++) {
if (i % 16 == 0) {
/*
if (sl->q_data_dir == Q_DATA_OUT)
fprintf(stdout, "\n<- 0x%08x ", sl->q_addr + i);
else
fprintf(stdout, "\n-> 0x%08x ", sl->q_addr + i);
*/
}
fprintf(stdout, " %02x", (unsigned int) sl->q_buf[i]);
}
fputs("\n\n", stdout);
}
/* memory mapped file */
typedef struct mapped_file {
uint8_t* base;
size_t len;
} mapped_file_t;
#define MAPPED_FILE_INITIALIZER { NULL, 0 }
static int map_file(mapped_file_t* mf, const char* path) {
int error = -1;
struct stat st;
const int fd = open(path, O_RDONLY);
if (fd == -1) {
fprintf(stderr, "open(%s) == -1\n", path);
return -1;
}
if (fstat(fd, &st) == -1) {
fprintf(stderr, "fstat() == -1\n");
goto on_error;
}
mf->base = (uint8_t*) mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
if (mf->base == MAP_FAILED) {
fprintf(stderr, "mmap() == MAP_FAILED\n");
goto on_error;
}
mf->len = st.st_size;
/* success */
error = 0;
on_error:
close(fd);
return error;
}
static void unmap_file(mapped_file_t* mf) {
munmap((void*) mf->base, mf->len);
mf->base = (unsigned char*) MAP_FAILED;
mf->len = 0;
}
static int check_file
(stlink_t* sl, mapped_file_t* mf, stm32_addr_t addr) {
size_t off;
for (off = 0; off < mf->len; off += sl->flash_pgsz) {
size_t aligned_size;
/* adjust last page size */
size_t cmp_size = sl->flash_pgsz;
if ((off + sl->flash_pgsz) > mf->len)
cmp_size = mf->len - off;
aligned_size = cmp_size;
if (aligned_size & (4 - 1))
aligned_size = (cmp_size + 4) & ~(4 - 1);
stlink_read_mem32(sl, addr + off, aligned_size);
if (memcmp(sl->q_buf, mf->base + off, cmp_size))
return -1;
}
return 0;
}
int stlink_fwrite_sram
(stlink_t * sl, const char* path, stm32_addr_t addr) {
/* write the file in sram at addr */
int error = -1;
size_t off;
mapped_file_t mf = MAPPED_FILE_INITIALIZER;
if (map_file(&mf, path) == -1) {
fprintf(stderr, "map_file() == -1\n");
return -1;
}
/* check addr range is inside the sram */
if (addr < sl->sram_base) {
fprintf(stderr, "addr too low\n");
goto on_error;
} else if ((addr + mf.len) < addr) {
fprintf(stderr, "addr overruns\n");
goto on_error;
} else if ((addr + mf.len) > (sl->sram_base + sl->sram_size)) {
fprintf(stderr, "addr too high\n");
goto on_error;
} else if ((addr & 3) || (mf.len & 3)) {
/* todo */
fprintf(stderr, "unaligned addr or size\n");
goto on_error;
}
/* do the copy by 1k blocks */
for (off = 0; off < mf.len; off += 1024) {
size_t size = 1024;
if ((off + size) > mf.len)
size = mf.len - off;
memcpy(sl->q_buf, mf.base + off, size);
/* round size if needed */
if (size & 3)
size += 2;
stlink_write_mem32(sl, addr + off, size);
}
/* check the file ha been written */
if (check_file(sl, &mf, addr) == -1) {
fprintf(stderr, "check_file() == -1\n");
goto on_error;
}
/* success */
error = 0;
on_error:
unmap_file(&mf);
return error;
}
int stlink_fread(stlink_t* sl, const char* path, stm32_addr_t addr, size_t size) {
/* read size bytes from addr to file */
int error = -1;
size_t off;
const int fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 00700);
if (fd == -1) {
fprintf(stderr, "open(%s) == -1\n", path);
return -1;
}
/* do the copy by 1k blocks */
for (off = 0; off < size; off += 1024) {
size_t read_size = 1024;
if ((off + read_size) > size)
read_size = off + read_size;
/* round size if needed */
if (read_size & 3)
read_size = (read_size + 4) & ~(3);
stlink_read_mem32(sl, addr + off, read_size);
if (write(fd, sl->q_buf, read_size) != (ssize_t) read_size) {
fprintf(stderr, "write() != read_size\n");
goto on_error;
}
}
/* success */
error = 0;
on_error:
close(fd);
return error;
}
typedef struct flash_loader {
stm32_addr_t loader_addr; /* loader sram adddr */
stm32_addr_t buf_addr; /* buffer sram address */
} flash_loader_t;
int write_buffer_to_sram
(stlink_t *sl, flash_loader_t* fl, const uint8_t* buf, size_t size) {
/* write the buffer right after the loader */
memcpy(sl->q_buf, buf, size);
stlink_write_mem8(sl, fl->buf_addr, size);
return 0;
}

190
src/stlink-common.h 100644
Wyświetl plik

@ -0,0 +1,190 @@
/*
* File: stlink-common.h
* Bulk import from stlink-hw.h
*
* This should contain all the common top level stlink interfaces, regardless
* of how the backend does the work....
*/
#ifndef STLINK_COMMON_H
#define STLINK_COMMON_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
// Max data transfer size.
// 6kB = max mem32_read block, 8kB sram
//#define Q_BUF_LEN 96
#define Q_BUF_LEN 1024 * 100
// st-link vendor cmd's
#define USB_ST_VID 0x0483
#define USB_STLINK_PID 0x3744
// STLINK_DEBUG_RESETSYS, etc:
#define STLINK_OK 0x80
#define STLINK_FALSE 0x81
#define STLINK_CORE_RUNNING 0x80
#define STLINK_CORE_HALTED 0x81
#define STLINK_CORE_STAT_UNKNOWN -1
#define STLINK_GET_VERSION 0xf1
#define STLINK_GET_CURRENT_MODE 0xf5
#define STLINK_DEBUG_COMMAND 0xF2
#define STLINK_DFU_COMMAND 0xF3
#define STLINK_DFU_EXIT 0x07
// STLINK_GET_CURRENT_MODE
#define STLINK_DEV_DFU_MODE 0x00
#define STLINK_DEV_MASS_MODE 0x01
#define STLINK_DEV_DEBUG_MODE 0x02
#define STLINK_DEV_UNKNOWN_MODE -1
// jtag mode cmds
#define STLINK_DEBUG_ENTER 0x20
#define STLINK_DEBUG_EXIT 0x21
#define STLINK_DEBUG_READCOREID 0x22
#define STLINK_DEBUG_GETSTATUS 0x01
#define STLINK_DEBUG_FORCEDEBUG 0x02
#define STLINK_DEBUG_RESETSYS 0x03
#define STLINK_DEBUG_READALLREGS 0x04
#define STLINK_DEBUG_READREG 0x05
#define STLINK_DEBUG_WRITEREG 0x06
#define STLINK_DEBUG_READMEM_32BIT 0x07
#define STLINK_DEBUG_WRITEMEM_32BIT 0x08
#define STLINK_DEBUG_RUNCORE 0x09
#define STLINK_DEBUG_STEPCORE 0x0a
#define STLINK_DEBUG_SETFP 0x0b
#define STLINK_DEBUG_WRITEMEM_8BIT 0x0d
#define STLINK_DEBUG_CLEARFP 0x0e
#define STLINK_DEBUG_WRITEDEBUGREG 0x0f
#define STLINK_DEBUG_ENTER_SWD 0xa3
#define STLINK_DEBUG_ENTER_JTAG 0x00
typedef struct {
uint32_t r[16];
uint32_t xpsr;
uint32_t main_sp;
uint32_t process_sp;
uint32_t rw;
uint32_t rw2;
} reg;
typedef uint32_t stm32_addr_t;
enum transport_type {
TRANSPORT_TYPE_ZERO = 0,
TRANSPORT_TYPE_LIBSG,
TRANSPORT_TYPE_LIBUSB,
TRANSPORT_TYPE_INVALID
};
typedef struct _stlink stlink_t;
typedef struct _stlink_backend {
void (*close) (stlink_t* sl);
void (*exit_debug_mode) (stlink_t *sl);
void (*enter_swd_mode) (stlink_t *sl);
void (*enter_jtag_mode) (stlink_t *stl);
void (*exit_dfu_mode) (stlink_t *stl);
void (*core_id) (stlink_t *stl);
void (*reset) (stlink_t *stl);
void (*run) (stlink_t *stl);
void (*status) (stlink_t *stl);
void (*version) (stlink_t *stl);
void (*write_mem32) (stlink_t *sl, uint32_t addr, uint16_t len);
void (*write_mem8) (stlink_t *sl, uint32_t addr, uint16_t len);
} stlink_backend_t;
struct _stlink {
struct _stlink_backend *backend;
void *backend_data;
// Data transferred from or to device
unsigned char q_buf[Q_BUF_LEN];
int q_len;
// transport layer verboseness: 0 for no debug info, 10 for lots
int verbose;
uint32_t core_id;
int core_stat;
/* medium density stm32 flash settings */
#define STM32_FLASH_BASE 0x08000000
#define STM32_FLASH_SIZE (128 * 1024)
#define STM32_FLASH_PGSZ 1024
stm32_addr_t flash_base;
size_t flash_size;
size_t flash_pgsz;
/* in flash system memory */
#define STM32_SYSTEM_BASE 0x1ffff000
#define STM32_SYSTEM_SIZE (2 * 1024)
stm32_addr_t sys_base;
size_t sys_size;
/* sram settings */
#define STM32_SRAM_BASE 0x20000000
#define STM32_SRAM_SIZE (8 * 1024)
stm32_addr_t sram_base;
size_t sram_size;
};
// 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...
void stlink_enter_swd_mode(stlink_t *sl);
void stlink_enter_jtag_mode(stlink_t *sl);
void stlink_exit_debug_mode(stlink_t *sl);
void stlink_exit_dfu_mode(stlink_t *sl);
void stlink_close(stlink_t *sl);
void stlink_core_id(stlink_t *sl);
void stlink_reset(stlink_t *sl);
void stlink_run(stlink_t *sl);
void stlink_status(stlink_t *sl);
void stlink_version(stlink_t *sl);
void stlink_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len);
void stlink_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len);
// unprocessed
int stlink_current_mode(stlink_t *sl);
void stlink_force_debug(stlink_t *sl);
void stlink_step(stlink_t *sl);
void stlink_read_all_regs(stlink_t *sl);
void stlink_read_reg(stlink_t *sl, int r_idx);
void stlink_write_reg(stlink_t *sl, uint32_t reg, int idx);
void stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len);
int stlink_erase_flash_page(stlink_t* sl, stm32_addr_t page);
int stlink_erase_flash_mass(stlink_t* sl);
int stlink_write_flash(stlink_t* sl, stm32_addr_t address, uint8_t* data, unsigned length);
// privates....
uint16_t read_uint16(const unsigned char *c, const int pt);
void stlink_core_stat(stlink_t *sl);
void stlink_print_data(stlink_t *sl);
#include "stlink-sg.h"
#include "stlink-usb.h"
#ifdef __cplusplus
}
#endif
#endif /* STLINK_COMMON_H */

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,203 +0,0 @@
#ifndef _STLINK_HW_H_
#define _STLINK_HW_H_
#include <stdint.h>
// device access
#define RDWR 0
#define RO 1
#define SG_TIMEOUT_SEC 1 // actually 1 is about 2 sec
// Each CDB can be a total of 6, 10, 12, or 16 bytes, later version
// of the SCSI standard also allow for variable-length CDBs (min. CDB is 6).
// the stlink needs max. 10 bytes.
#define CDB_6 6
#define CDB_10 10
#define CDB_12 12
#define CDB_16 16
#define CDB_SL 10
// Query data flow direction.
#define Q_DATA_OUT 0
#define Q_DATA_IN 1
// The SCSI Request Sense command is used to obtain sense data
// (error information) from a target device.
// http://en.wikipedia.org/wiki/SCSI_Request_Sense_Command
#define SENSE_BUF_LEN 32
// Max data transfer size.
// 6kB = max mem32_read block, 8kB sram
//#define Q_BUF_LEN 96
#define Q_BUF_LEN 1024 * 100
// st-link vendor cmd's
#define USB_ST_VID 0x0483
#define USB_STLINK_PID 0x3744
// STLINK_DEBUG_RESETSYS, etc:
#define STLINK_OK 0x80
#define STLINK_FALSE 0x81
#define STLINK_CORE_RUNNING 0x80
#define STLINK_CORE_HALTED 0x81
#define STLINK_CORE_STAT_UNKNOWN -1
#define STLINK_GET_VERSION 0xf1
#define STLINK_GET_CURRENT_MODE 0xf5
#define STLINK_DEBUG_COMMAND 0xF2
#define STLINK_DFU_COMMAND 0xF3
#define STLINK_DFU_EXIT 0x07
// STLINK_GET_CURRENT_MODE
#define STLINK_DEV_DFU_MODE 0x00
#define STLINK_DEV_MASS_MODE 0x01
#define STLINK_DEV_DEBUG_MODE 0x02
#define STLINK_DEV_UNKNOWN_MODE -1
// jtag mode cmds
#define STLINK_DEBUG_ENTER 0x20
#define STLINK_DEBUG_EXIT 0x21
#define STLINK_DEBUG_READCOREID 0x22
#define STLINK_DEBUG_GETSTATUS 0x01
#define STLINK_DEBUG_FORCEDEBUG 0x02
#define STLINK_DEBUG_RESETSYS 0x03
#define STLINK_DEBUG_READALLREGS 0x04
#define STLINK_DEBUG_READREG 0x05
#define STLINK_DEBUG_WRITEREG 0x06
#define STLINK_DEBUG_READMEM_32BIT 0x07
#define STLINK_DEBUG_WRITEMEM_32BIT 0x08
#define STLINK_DEBUG_RUNCORE 0x09
#define STLINK_DEBUG_STEPCORE 0x0a
#define STLINK_DEBUG_SETFP 0x0b
#define STLINK_DEBUG_WRITEMEM_8BIT 0x0d
#define STLINK_DEBUG_CLEARFP 0x0e
#define STLINK_DEBUG_WRITEDEBUGREG 0x0f
#define STLINK_DEBUG_ENTER_SWD 0xa3
#define STLINK_DEBUG_ENTER_JTAG 0x00
typedef struct {
uint32_t r[16];
uint32_t xpsr;
uint32_t main_sp;
uint32_t process_sp;
uint32_t rw;
uint32_t rw2;
} reg;
typedef uint32_t stm32_addr_t;
enum transport_type
{
TRANSPORT_TYPE_ZERO = 0,
#if CONFIG_USE_LIBSG
TRANSPORT_TYPE_LIBSG,
#endif /* CONFIG_USE_LIBSG */
#if CONFIG_USE_LIBUSB
TRANSPORT_TYPE_LIBUSB,
#endif /* CONFIG_USE_LIBUSB */
TRANSPORT_TYPE_INVALID
};
struct stlink_libusb
{
libusb_device_handle* usb_handle;
struct libusb_transfer* req_trans;
struct libusb_transfer* rep_trans;
unsigned int ep_req;
unsigned int ep_rep;
};
struct stlink_libsg {
int sg_fd;
int do_scsi_pt_err;
// sg layer verboseness: 0 for no debug info, 10 for lots
int verbose;
unsigned char cdb_cmd_blk[CDB_SL];
// Data transferred from or to device
unsigned char q_buf[Q_BUF_LEN];
int q_len;
int q_data_dir; // Q_DATA_IN, Q_DATA_OUT
// the start of the query data in the device memory space
uint32_t q_addr;
// Sense (error information) data
unsigned char sense_buf[SENSE_BUF_LEN];
uint32_t st_vid;
uint32_t stlink_pid;
uint32_t stlink_v;
uint32_t jtag_v;
uint32_t swim_v;
uint32_t core_id;
reg reg;
int core_stat;
/* medium density stm32 flash settings */
#define STM32_FLASH_BASE 0x08000000
#define STM32_FLASH_SIZE (128 * 1024)
#define STM32_FLASH_PGSZ 1024
stm32_addr_t flash_base;
size_t flash_size;
size_t flash_pgsz;
/* in flash system memory */
#define STM32_SYSTEM_BASE 0x1ffff000
#define STM32_SYSTEM_SIZE (2 * 1024)
stm32_addr_t sys_base;
size_t sys_size;
/* sram settings */
#define STM32_SRAM_BASE 0x20000000
#define STM32_SRAM_SIZE (8 * 1024)
stm32_addr_t sram_base;
size_t sram_size;
};
struct stlink
{
enum transport_type tt;
union {
#if CONFIG_USE_LIBUSB
struct stlink_libusb *libusb;
#endif /* CONFIG_USE_LIBUSB */
#if CONFIG_USE_LIBSG
struct stlink_libsg *libsg;
#endif /* CONFIG_USE_LIBSG */
} transport;
unsigned char q_buf[64];
size_t q_len;
/* layer independant */
uint32_t core_id;
};
struct stlink* stlink_quirk_open(enum transport_type tt, const char *dev_name, const int verbose);
int stlink_current_mode(struct stlink *sl);
void stlink_enter_swd_mode(struct stlink *sl);
void stlink_enter_jtag_mode(struct stlink *sl);
void stlink_exit_debug_mode(struct stlink *sl);
void stlink_core_id(struct stlink *sl);
void stlink_status(struct stlink *sl);
void stlink_force_debug(struct stlink *sl);
void stlink_reset(struct stlink *sl);
void stlink_run(struct stlink *sl);
void stlink_step(struct stlink *sl);
void stlink_read_all_regs(struct stlink *sl);
void stlink_read_reg(struct stlink *sl, int r_idx);
void stlink_write_reg(struct stlink *sl, uint32_t reg, int idx);
void stlink_read_mem32(struct stlink *sl, uint32_t addr, uint16_t len);
void stlink_write_mem8(struct stlink *sl, uint32_t addr, uint16_t len);
void stlink_write_mem32(struct stlink *sl, uint32_t addr, uint16_t len);
void stlink_close(struct stlink *sl);
int stlink_erase_flash_page(struct stlink* sl, stm32_addr_t page);
int stlink_erase_flash_mass(struct stlink* sl);
int stlink_write_flash(struct stlink* sl, stm32_addr_t address, uint8_t* data, unsigned length);
#endif

1436
src/stlink-sg.c 100644

Plik diff jest za duży Load Diff

75
src/stlink-sg.h 100644
Wyświetl plik

@ -0,0 +1,75 @@
/*
* File: stlink-sg.h
* Author: karl
*
* Created on October 1, 2011, 11:29 PM
*/
#ifndef STLINK_SG_H
#define STLINK_SG_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stlink-common.h"
// device access
#define RDWR 0
#define RO 1
#define SG_TIMEOUT_SEC 1 // actually 1 is about 2 sec
// Each CDB can be a total of 6, 10, 12, or 16 bytes, later version
// of the SCSI standard also allow for variable-length CDBs (min. CDB is 6).
// the stlink needs max. 10 bytes.
#define CDB_6 6
#define CDB_10 10
#define CDB_12 12
#define CDB_16 16
#define CDB_SL 10
// Query data flow direction.
#define Q_DATA_OUT 0
#define Q_DATA_IN 1
// The SCSI Request Sense command is used to obtain sense data
// (error information) from a target device.
// http://en.wikipedia.org/wiki/SCSI_Request_Sense_Command
#define SENSE_BUF_LEN 32
#if defined(CONFIG_USE_LIBUSB)
struct stlink_libsg {
int sg_fd;
int do_scsi_pt_err;
unsigned char cdb_cmd_blk[CDB_SL];
int q_data_dir; // Q_DATA_IN, Q_DATA_OUT
// the start of the query data in the device memory space
uint32_t q_addr;
// Sense (error information) data
unsigned char sense_buf[SENSE_BUF_LEN];
uint32_t st_vid;
uint32_t stlink_pid;
uint32_t stlink_v;
uint32_t jtag_v;
uint32_t swim_v;
uint32_t core_id;
reg reg;
};
#else
struct stlink_libsg {};
#endif
#ifdef __cplusplus
}
#endif
#endif /* STLINK_SG_H */

552
src/stlink-usb.c 100644
Wyświetl plik

@ -0,0 +1,552 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <time.h>
#include <sys/types.h>
#include <libusb-1.0/libusb.h>
#include "stlink-common.h"
#include "stlink-usb.h"
/* endianess related */
static inline unsigned int is_bigendian(void) {
static volatile const unsigned int i = 1;
return *(volatile const char*) &i == 0;
}
void _stlink_usb_close(stlink_t* sl) {
struct stlink_libusb * const handle = sl->backend_data;
// maybe we couldn't even get the usb device?
if (handle != NULL) {
if (handle->req_trans != NULL)
libusb_free_transfer(handle->req_trans);
if (handle->rep_trans != NULL)
libusb_free_transfer(handle->rep_trans);
if (handle->usb_handle != NULL)
libusb_close(handle->usb_handle);
libusb_exit(handle->libusb_ctx);
free(handle);
}
}
static void write_uint32(unsigned char* buf, uint32_t ui) {
if (!is_bigendian()) { // le -> le (don't swap)
buf[0] = ((unsigned char*) &ui)[0];
buf[1] = ((unsigned char*) &ui)[1];
buf[2] = ((unsigned char*) &ui)[2];
buf[3] = ((unsigned char*) &ui)[3];
} else {
buf[0] = ((unsigned char*) &ui)[3];
buf[1] = ((unsigned char*) &ui)[2];
buf[2] = ((unsigned char*) &ui)[1];
buf[3] = ((unsigned char*) &ui)[0];
}
}
static void write_uint16(unsigned char* buf, uint16_t ui) {
if (!is_bigendian()) { // le -> le (don't swap)
buf[0] = ((unsigned char*) &ui)[0];
buf[1] = ((unsigned char*) &ui)[1];
} else {
buf[0] = ((unsigned char*) &ui)[1];
buf[1] = ((unsigned char*) &ui)[0];
}
}
static uint32_t read_uint32(const unsigned char *c, const int pt) {
uint32_t ui;
char *p = (char *) &ui;
if (!is_bigendian()) { // le -> le (don't swap)
p[0] = c[pt];
p[1] = c[pt + 1];
p[2] = c[pt + 2];
p[3] = c[pt + 3];
} else {
p[0] = c[pt + 3];
p[1] = c[pt + 2];
p[2] = c[pt + 1];
p[3] = c[pt];
}
return ui;
}
struct trans_ctx {
#define TRANS_FLAGS_IS_DONE (1 << 0)
#define TRANS_FLAGS_HAS_ERROR (1 << 1)
volatile unsigned long flags;
};
static void on_trans_done(struct libusb_transfer * trans) {
struct trans_ctx * const ctx = trans->user_data;
if (trans->status != LIBUSB_TRANSFER_COMPLETED)
ctx->flags |= TRANS_FLAGS_HAS_ERROR;
ctx->flags |= TRANS_FLAGS_IS_DONE;
}
int submit_wait(struct stlink_libusb *slu, struct libusb_transfer * trans) {
struct timeval start;
struct timeval now;
struct timeval diff;
struct trans_ctx trans_ctx;
enum libusb_error error;
trans_ctx.flags = 0;
/* brief intrusion inside the libusb interface */
trans->callback = on_trans_done;
trans->user_data = &trans_ctx;
if ((error = libusb_submit_transfer(trans))) {
printf("libusb_submit_transfer(%d)\n", error);
return -1;
}
gettimeofday(&start, NULL);
while (trans_ctx.flags == 0) {
struct timeval timeout;
timeout.tv_sec = 3;
timeout.tv_usec = 0;
if (libusb_handle_events_timeout(slu->libusb_ctx, &timeout)) {
printf("libusb_handle_events()\n");
return -1;
}
gettimeofday(&now, NULL);
timersub(&now, &start, &diff);
if (diff.tv_sec >= 3) {
printf("libusb_handle_events() timeout\n");
return -1;
}
}
if (trans_ctx.flags & TRANS_FLAGS_HAS_ERROR) {
printf("libusb_handle_events() | has_error\n");
return -1;
}
return 0;
}
ssize_t send_recv(struct stlink_libusb* handle,
unsigned char* txbuf, size_t txsize,
unsigned char* rxbuf, size_t rxsize) {
/* note: txbuf and rxbuf can point to the same area */
libusb_fill_bulk_transfer(handle->req_trans, handle->usb_handle,
handle->ep_req,
txbuf, txsize,
NULL, NULL,
0
);
printf("submit_wait(req)\n");
if (submit_wait(handle, handle->req_trans)) return -1;
/* send_only */
if (rxsize == 0) return 0;
/* read the response */
libusb_fill_bulk_transfer(handle->rep_trans, handle->usb_handle,
handle->ep_rep, rxbuf, rxsize, NULL, NULL, 0);
printf("submit_wait(rep)\n");
if (submit_wait(handle, handle->rep_trans)) return -1;
return handle->rep_trans->actual_length;
}
static inline int send_only
(struct stlink_libusb* handle, unsigned char* txbuf, size_t txsize) {
return send_recv(handle, txbuf, txsize, NULL, 0);
}
// KARL - fixme, common code! (or, one per backend)
// candidate for common code...
static int is_stlink_device(libusb_device * dev) {
struct libusb_device_descriptor desc;
if (libusb_get_device_descriptor(dev, &desc))
return 0;
printf("device: 0x%04x, 0x%04x\n", desc.idVendor, desc.idProduct);
if (desc.idVendor != 0x0483)
return 0;
if (desc.idProduct != 0x3748)
return 0;
return 1;
}
void _stlink_usb_version(stlink_t * sl) {
struct stlink_libusb * const slu = sl->backend_data;
unsigned char* const buf = sl->q_buf;
ssize_t size;
memset(buf, 0, sizeof (sl->q_buf));
buf[0] = STLINK_GET_VERSION;
buf[1] = 0x80;
size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf));
if (size == -1) {
printf("[!] send_recv\n");
return;
}mkdir g
#if 1 /* DEBUG */
{
unsigned int i;
for (i = 0; i < size; ++i) printf("%02x", buf[i]);
printf("\n");
}
#endif /* DEBUG */
}
void _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
D(sl, "oops! no write32 support yet ;)\n");
}
void _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) {
D(sl, "oops! no write8 support yet ;)\n");
}
int stlink_current_mode(stlink_t * sl) {
int mode = -1;
struct stlink_libusb * const slu = sl->backend_data;
unsigned char* const buf = sl->q_buf;
ssize_t size;
memset(buf, 0, sizeof (sl->q_buf));
buf[0] = STLINK_GET_CURRENT_MODE;
size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf));
if (size == -1) {
printf("[!] send_recv\n");
return -1;
}
/* mode = (int)read_uint16(buf, 0); */
mode = (int) buf[0];
#if 1 /* DEBUG */
printf("mode == 0x%x\n", mode);
#endif /* DEBUG */
return mode;
}
void _stlink_usb_core_id(stlink_t * sl) {
struct stlink_libusb * const slu = sl->backend_data;
unsigned char* const buf = sl->q_buf;
ssize_t size;
memset(buf, 0, sizeof (sl->q_buf));
buf[0] = STLINK_DEBUG_COMMAND;
buf[1] = STLINK_DEBUG_READCOREID;
size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf));
if (size == -1) {
printf("[!] send_recv\n");
return;
}
sl->core_id = read_uint32(buf, 0);
}
void _stlink_usb_status(stlink_t * sl) {
struct stlink_libusb * const slu = sl->backend_data;
unsigned char* const buf = sl->q_buf;
ssize_t size;
memset(buf, 0, sizeof (sl->q_buf));
buf[0] = STLINK_DEBUG_COMMAND;
buf[1] = STLINK_DEBUG_GETSTATUS;
size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf));
if (size == -1) {
printf("[!] send_recv\n");
return;
}
/* todo: stlink_core_stat */
// FIXME - decode into sl->core_stat
#if 1 /* DEBUG */
printf("status == 0x%x\n", buf[0]);
#endif /* DEBUG */
}
void _stlink_enter_swd_mode(stlink_t * sl) {
struct stlink_libusb * const slu = sl->backend_data;
unsigned char* const buf = sl->q_buf;
ssize_t size;
memset(buf, 0, sizeof (sl->q_buf));
buf[0] = STLINK_DEBUG_COMMAND;
buf[1] = 0x30; /* needed byte */
buf[2] = STLINK_DEBUG_ENTER_JTAG;
size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf));
if (size == -1) {
printf("[!] send_recv\n");
return;
}
}
void _stlink_usb_exit_dfu_mode(stlink_t* sl) {
struct stlink_libusb * const slu = sl->backend_data;
unsigned char* const buf = sl->q_buf;
ssize_t size;
memset(buf, 0, sizeof (sl->q_buf));
buf[0] = STLINK_DFU_COMMAND;
buf[1] = STLINK_DFU_EXIT;
size = send_only(slu, buf, 16);
if (size == -1) {
printf("[!] send_recv\n");
return;
}
}
void _stlink_usb_reset(stlink_t * sl) {
struct stlink_libusb * const slu = sl->backend_data;
unsigned char* const buf = sl->q_buf;
ssize_t size;
memset(buf, 0, sizeof (sl->q_buf));
buf[0] = STLINK_DEBUG_COMMAND;
buf[1] = STLINK_DEBUG_RESETSYS;
size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf));
if (size == -1) {
printf("[!] send_recv\n");
return;
}
}
void stlink_step(stlink_t* sl) {
struct stlink_libusb * const slu = sl->backend_data;
unsigned char* const buf = sl->q_buf;
ssize_t size;
memset(buf, 0, sizeof (sl->q_buf));
buf[0] = STLINK_DEBUG_COMMAND;
buf[1] = STLINK_DEBUG_STEPCORE;
size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf));
if (size == -1) {
printf("[!] send_recv\n");
return;
}
}
void _stlink_usb_run(stlink_t* sl) {
struct stlink_libusb * const slu = sl->backend_data;
unsigned char* const buf = sl->q_buf;
ssize_t size;
memset(buf, 0, sizeof (sl->q_buf));
buf[0] = STLINK_DEBUG_COMMAND;
buf[1] = STLINK_DEBUG_RUNCORE;
size = send_recv(slu, buf, 16, buf, sizeof (sl->q_buf));
if (size == -1) {
printf("[!] send_recv\n");
return;
}
}
void _stlink_usb_exit_debug_mode(stlink_t *sl) {
struct stlink_libusb * const slu = sl->backend_data;
unsigned char* const buf = sl->q_buf;
ssize_t size;
memset(buf, 0, sizeof (sl->q_buf));
buf[0] = STLINK_DEBUG_COMMAND;
buf[1] = STLINK_DEBUG_EXIT;
size = send_only(slu, buf, 16);
if (size == -1) {
printf("[!] send_only\n");
return;
}
}
void stlink_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
struct stlink_libusb * const slu = sl->backend_data;
unsigned char* const buf = sl->q_buf;
ssize_t size;
/* assume len < sizeof(sl->q_buf) */
memset(buf, 0, sizeof (sl->q_buf));
buf[0] = STLINK_DEBUG_COMMAND;
buf[1] = STLINK_DEBUG_READMEM_32BIT;
write_uint32(buf + 2, addr);
write_uint16(buf + 6, len);
#if 0
/* windows usb logs show only one byte is used for length ... */
buf[6] = (uint8_t) len;
#endif
size = send_recv(slu, buf, 0x10, buf, sizeof (sl->q_buf));
if (size == -1) {
printf("[!] send_recv\n");
return;
}
sl->q_len = (size_t) size;
stlink_print_data(sl);
}
stlink_backend_t _stlink_usb_backend = {
_stlink_usb_close,
_stlink_usb_exit_debug_mode,
_stlink_enter_swd_mode,
NULL,
_stlink_usb_exit_dfu_mode,
_stlink_usb_core_id,
_stlink_usb_reset,
_stlink_usb_run,
_stlink_usb_status,
_stlink_usb_version,
_stlink_usb_write_mem32,
_stlink_usb_write_mem8
};
stlink_t* stlink_open_usb(const char *dev_name, const int verbose) {
stlink_t* sl = NULL;
struct stlink_libusb* slu = NULL;
sl = malloc(sizeof (stlink_t));
slu = malloc(sizeof (struct stlink_libusb));
if (sl == NULL) goto on_error;
if (slu == NULL) goto on_error;
sl->verbose = verbose;
if (slu->libusb_ctx != NULL) {
fprintf(stderr, "reopening with an existing context? undefined behaviour!\n");
goto on_error;
} else {
if (libusb_init(&(slu->libusb_ctx))) {
fprintf(stderr, "failed to init libusb context, wrong version of libraries?\n");
goto on_error;
}
}
int error = -1;
libusb_device** devs = NULL;
libusb_device* dev;
ssize_t i;
ssize_t count;
int config;
count = libusb_get_device_list(slu->libusb_ctx, &devs);
if (count < 0) {
printf("libusb_get_device_list\n");
goto on_libusb_error;
}
for (i = 0; i < count; ++i) {
dev = devs[i];
if (is_stlink_device(dev)) break;
}
if (i == count) return NULL;
if (libusb_open(dev, &(slu->usb_handle))) {
printf("libusb_open()\n");
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");
goto on_libusb_error;
}
if (config != 1) {
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");
goto on_libusb_error;
}
}
if (libusb_claim_interface(slu->usb_handle, 0)) {
printf("libusb_claim_interface()\n");
goto on_libusb_error;
}
slu->req_trans = libusb_alloc_transfer(0);
if (slu->req_trans == NULL) {
printf("libusb_alloc_transfer\n");
goto on_libusb_error;
}
slu->rep_trans = libusb_alloc_transfer(0);
if (slu->rep_trans == NULL) {
printf("libusb_alloc_transfer\n");
goto on_libusb_error;
}
slu->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN;
slu->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT;
/* libusb_reset_device(slu->usb_handle); */
/* success */
error = 0;
on_libusb_error:
if (devs != NULL) {
libusb_free_device_list(devs, 1);
fprintf(stderr, "freed libusb device list\n");
}
if (error == -1) {
stlink_close(sl);
return NULL;
}
sl->backend = &_stlink_usb_backend;
sl->backend_data = slu;
/* success */
return sl;
on_error:
if (sl != NULL) free(sl);
if (slu != NULL) free(slu);
return 0;
}

40
src/stlink-usb.h 100644
Wyświetl plik

@ -0,0 +1,40 @@
/*
* File: stlink-usb.h
* Author: karl
*
* Created on October 1, 2011, 11:29 PM
*/
#ifndef STLINK_USB_H
#define STLINK_USB_H
#ifdef __cplusplus
extern "C" {
#endif
#include <libusb-1.0/libusb.h>
#if defined(CONFIG_USE_LIBUSB)
struct stlink_libusb {
libusb_context* libusb_ctx;
libusb_device_handle* usb_handle;
struct libusb_transfer* req_trans;
struct libusb_transfer* rep_trans;
unsigned int ep_req;
unsigned int ep_rep;
};
#else
#error "it's all bad!"
struct stlink_libusb {};
#endif
stlink_t* stlink_open_usb(const char *dev_name, const int verbose);
#ifdef __cplusplus
}
#endif
#endif /* STLINK_USB_H */

213
src/test_sg.c 100644
Wyświetl plik

@ -0,0 +1,213 @@
/*
* File: test_main.c
*
* main() ripped out of old stlink-hw.c
*/
#include <stdio.h>
#include <stdlib.h>
#include "stlink-common.h"
#if 0
int main(int argc, char *argv[]) {
// set scpi lib debug level: 0 for no debug info, 10 for lots
const int scsi_verbose = 2;
char *dev_name;
switch (argc) {
case 1:
fputs(
"\nUsage: stlink-access-test /dev/sg0, sg1, ...\n"
"\n*** Notice: The stlink firmware violates the USB standard.\n"
"*** If you plug-in the discovery's stlink, wait a several\n"
"*** minutes to let the kernel driver swallow the broken device.\n"
"*** Watch:\ntail -f /var/log/messages\n"
"*** This command sequence can shorten the waiting time and fix some issues.\n"
"*** Unplug the stlink and execute once as root:\n"
"modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:lrwsro\n\n",
stderr);
return EXIT_FAILURE;
case 2:
dev_name = argv[1];
break;
default:
return EXIT_FAILURE;
}
fputs("*** stlink access test ***\n", stderr);
DD(sl, "Using sg_lib %s : scsi_pt %s\n", sg_lib_version(),
scsi_pt_version());
struct stlink *sl = stlink_force_open(dev_name, scsi_verbose);
if (sl == NULL)
return EXIT_FAILURE;
// we are in mass mode, go to swd
stlink_enter_swd_mode(sl);
stlink_current_mode(sl);
stlink_core_id(sl);
//----------------------------------------------------------------------
stlink_status(sl);
//stlink_force_debug(sl);
stlink_reset(sl);
stlink_status(sl);
#if 0
// core system control block
stlink_read_mem32(sl, 0xe000ed00, 4);
DD(sl, "cpu id base register: SCB_CPUID = got 0x%08x expect 0x411fc231", read_uint32(sl->q_buf, 0));
// no MPU
stlink_read_mem32(sl, 0xe000ed90, 4);
DD(sl, "mpu type register: MPU_TYPER = got 0x%08x expect 0x0", read_uint32(sl->q_buf, 0));
stlink_read_mem32(sl, 0xe000edf0, 4);
DD(sl, "DHCSR = 0x%08x", read_uint32(sl->q_buf, 0));
stlink_read_mem32(sl, 0x4001100c, 4);
DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0));
#endif
#if 0
// happy new year 2011: let blink all the leds
// see "RM0041 Reference manual - STM32F100xx advanced ARM-based 32-bit MCUs"
#define GPIOC 0x40011000 // port C
#define GPIOC_CRH (GPIOC + 0x04) // port configuration register high
#define GPIOC_ODR (GPIOC + 0x0c) // port output data register
#define LED_BLUE (1<<8) // pin 8
#define LED_GREEN (1<<9) // pin 9
stlink_read_mem32(sl, GPIOC_CRH, 4);
uint32_t io_conf = read_uint32(sl->q_buf, 0);
DD(sl, "GPIOC_CRH = 0x%08x", io_conf);
// set: general purpose output push-pull, output mode, max speed 10 MHz.
write_uint32(sl->q_buf, 0x44444411);
stlink_write_mem32(sl, GPIOC_CRH, 4);
clear_buf(sl);
for (int i = 0; i < 100; i++) {
write_uint32(sl->q_buf, LED_BLUE | LED_GREEN);
stlink_write_mem32(sl, GPIOC_ODR, 4);
/* stlink_read_mem32(sl, 0x4001100c, 4); */
/* DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); */
delay(100);
clear_buf(sl);
stlink_write_mem32(sl, GPIOC_ODR, 4); // PC lo
delay(100);
}
write_uint32(sl->q_buf, io_conf); // set old state
#endif
#if 0
// TODO rtfm: stlink doesn't have flash write routines
// writing to the flash area confuses the fw for the next read access
//stlink_read_mem32(sl, 0, 1024*6);
// flash 0x08000000 128kB
fputs("++++++++++ read a flash at 0x0800 0000\n", stderr);
stlink_read_mem32(sl, 0x08000000, 1024 * 6); //max 6kB
clear_buf(sl);
stlink_read_mem32(sl, 0x08000c00, 5);
stlink_read_mem32(sl, 0x08000c00, 4);
mark_buf(sl);
stlink_write_mem32(sl, 0x08000c00, 4);
stlink_read_mem32(sl, 0x08000c00, 256);
stlink_read_mem32(sl, 0x08000c00, 256);
#endif
#if 0
// sram 0x20000000 8kB
fputs("\n++++++++++ read/write 8bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr);
clear_buf(sl);
stlink_write_mem8(sl, 0x20000000, 16);
mark_buf(sl);
stlink_write_mem8(sl, 0x20000000, 1);
stlink_write_mem8(sl, 0x20000001, 1);
stlink_write_mem8(sl, 0x2000000b, 3);
stlink_read_mem32(sl, 0x20000000, 16);
#endif
#if 0
// a not aligned mem32 access doesn't work indeed
fputs("\n++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr);
clear_buf(sl);
stlink_write_mem8(sl, 0x20000000, 32);
mark_buf(sl);
stlink_write_mem32(sl, 0x20000000, 1);
stlink_read_mem32(sl, 0x20000000, 16);
mark_buf(sl);
stlink_write_mem32(sl, 0x20000001, 1);
stlink_read_mem32(sl, 0x20000000, 16);
mark_buf(sl);
stlink_write_mem32(sl, 0x2000000b, 3);
stlink_read_mem32(sl, 0x20000000, 16);
mark_buf(sl);
stlink_write_mem32(sl, 0x20000000, 17);
stlink_read_mem32(sl, 0x20000000, 32);
#endif
#if 0
// sram 0x20000000 8kB
fputs("++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++\n", stderr);
mark_buf(sl);
stlink_write_mem8(sl, 0x20000000, 64);
stlink_read_mem32(sl, 0x20000000, 64);
mark_buf(sl);
stlink_write_mem32(sl, 0x20000000, 1024 * 8); //8kB
stlink_read_mem32(sl, 0x20000000, 1024 * 6);
stlink_read_mem32(sl, 0x20000000 + 1024 * 6, 1024 * 2);
#endif
#if 0
stlink_read_all_regs(sl);
stlink_step(sl);
fputs("++++++++++ write r0 = 0x12345678\n", stderr);
stlink_write_reg(sl, 0x12345678, 0);
stlink_read_reg(sl, 0);
stlink_read_all_regs(sl);
#endif
#if 0
stlink_run(sl);
stlink_status(sl);
stlink_force_debug(sl);
stlink_status(sl);
#endif
#if 1 /* read the system bootloader */
fputs("\n++++++++++ reading bootloader ++++++++++++++++\n\n", stderr);
stlink_fread(sl, "/tmp/barfoo", sl->sys_base, sl->sys_size);
#endif
#if 0 /* read the flash memory */
fputs("\n+++++++ read flash memory\n\n", stderr);
/* mark_buf(sl); */
stlink_read_mem32(sl, 0x08000000, 4);
#endif
#if 0 /* flash programming */
fputs("\n+++++++ program flash memory\n\n", stderr);
stlink_fwrite_flash(sl, "/tmp/foobar", 0x08000000);
#endif
#if 0 /* check file contents */
fputs("\n+++++++ check flash memory\n\n", stderr);
{
const int res = stlink_fcheck_flash(sl, "/tmp/foobar", 0x08000000);
printf("_____ stlink_fcheck_flash() == %d\n", res);
}
#endif
#if 0
fputs("\n+++++++ sram write and execute\n\n", stderr);
stlink_fwrite_sram(sl, "/tmp/foobar", sl->sram_base);
stlink_run_at(sl, sl->sram_base);
#endif
stlink_run(sl);
stlink_status(sl);
//----------------------------------------------------------------------
// back to mass mode, just in case ...
stlink_exit_debug_mode(sl);
stlink_current_mode(sl);
stlink_close(sl);
//fflush(stderr); fflush(stdout);
return EXIT_SUCCESS;
}
#endif

62
src/test_usb.c 100644
Wyświetl plik

@ -0,0 +1,62 @@
#include <stdio.h>
#include "stlink-common.h"
int main(int ac, char** av) {
stlink_t* sl;
sl = stlink_open_usb(NULL, 10);
if (sl != NULL) {
printf("-- version\n");
stlink_version(sl);
if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) {
printf("-- exit_dfu_mode\n");
stlink_exit_dfu_mode(sl);
}
printf("-- enter_swd_mode\n");
stlink_enter_swd_mode(sl);
printf("-- current_mode\n");
stlink_current_mode(sl);
/* printf("-- core_id\n"); */
/* stlink_core_id(sl); */
printf("-- read_sram\n");
static const uint32_t sram_base = 0x8000000;
uint32_t off;
for (off = 0; off < 16; off += 4)
stlink_read_mem32(sl, sram_base + off, 4);
printf("-- read_mem, cpuid\n");
stlink_read_mem32(sl, 0xe000e008, 4);
/* stlink_read_mem32(sl, 0xe000ed90, 4); */
/* stlink_read_mem32(sl, 0xe000edf0, 4); */
/* stlink_read_mem32(sl, 0x4001100c, 4); */
printf("-- status\n");
stlink_status(sl);
printf("-- reset\n");
stlink_reset(sl);
printf("-- status\n");
stlink_status(sl);
printf("-- step\n");
stlink_step(sl);
getchar();
printf("-- run\n");
stlink_run(sl);
printf("-- exit_debug_mode\n");
stlink_exit_debug_mode(sl);
stlink_close(sl);
}
return 0;
}