//Allways update the FLASH_PAGE before each use, by calling stlink_calculate_pagesize
#define FLASH_PAGE (sl->flash_pgsz)
//Allways update the FLASH_PAGE before each use, by calling stlink_calculate_pagesize
#define FLASH_PAGE (sl->flash_pgsz)
typedef struct _st_state_t {
// things from command line, bleh
int stlink_version;
typedef struct _st_state_t {
// things from command line, bleh
int stlink_version;
+static void cleanup(int signal __attribute__((unused))) {
+ if (connected_stlink) {
+ /* Switch back to mass storage mode before closing. */
+ stlink_run(connected_stlink);
+ stlink_exit_debug_mode(connected_stlink);
+ stlink_close(connected_stlink);
+ }
+
+ exit(1);
+}
+
+
int parse_options(int argc, char** argv, st_state_t *st) {
static struct option long_options[] = {
{"help", no_argument, NULL, 'h'},
{"verbose", optional_argument, NULL, 'v'},
int parse_options(int argc, char** argv, st_state_t *st) {
static struct option long_options[] = {
{"help", no_argument, NULL, 'h'},
{"verbose", optional_argument, NULL, 'v'},
{"stlink_version", required_argument, NULL, 's'},
{"stlinkv1", no_argument, NULL, '1'},
{"listen_port", required_argument, NULL, 'p'},
{"multi", optional_argument, NULL, 'm'},
{"stlink_version", required_argument, NULL, 's'},
{"stlinkv1", no_argument, NULL, '1'},
{"listen_port", required_argument, NULL, 'p'},
{"multi", optional_argument, NULL, 'm'},
{0, 0, 0, 0},
};
const char * help_str = "%s - usage:\n\n"
" -h, --help\t\tPrint this help\n"
{0, 0, 0, 0},
};
const char * help_str = "%s - usage:\n\n"
" -h, --help\t\tPrint this help\n"
- " -vXX, --verbose=XX\tspecify a specific verbosity level (0..99)\n"
- " -v, --verbose\tspecify generally verbose logging\n"
- " -d <device>, --device=/dev/stlink2_1\n"
- "\t\t\tWhere is your stlink device connected?\n"
+ " -vXX, --verbose=XX\tSpecify a specific verbosity level (0..99)\n"
+ " -v, --verbose\t\tSpecify generally verbose logging\n"
" -s X, --stlink_version=X\n"
"\t\t\tChoose what version of stlink to use, (defaults to 2)\n"
" -1, --stlinkv1\tForce stlink version 1\n"
" -s X, --stlink_version=X\n"
"\t\t\tChoose what version of stlink to use, (defaults to 2)\n"
" -1, --stlinkv1\tForce stlink version 1\n"
" -m, --multi\n"
"\t\t\tSet gdb server to extended mode.\n"
"\t\t\tst-util will continue listening for connections after disconnect.\n"
" -m, --multi\n"
"\t\t\tSet gdb server to extended mode.\n"
"\t\t\tst-util will continue listening for connections after disconnect.\n"
- while ((c = getopt_long(argc, argv, "hv::d:s:1p:m", long_options, &option_index)) != -1) {
+ while ((c = getopt_long(argc, argv, "hv::s:1p:mn", long_options, &option_index)) != -1) {
- break;
- case 'd':
- if (strlen(optarg) > sizeof (st->devicename)) {
- fprintf(stderr, "device name too long: %zd\n", strlen(optarg));
- } else {
- strcpy(st->devicename, optarg);
- }
state.stlink_version = 2;
state.logging_level = DEFAULT_LOGGING_LEVEL;
state.listen_port = DEFAULT_GDB_LISTEN_PORT;
state.stlink_version = 2;
state.logging_level = DEFAULT_LOGGING_LEVEL;
state.listen_port = DEFAULT_GDB_LISTEN_PORT;
parse_options(argc, argv, &state);
switch (state.stlink_version) {
case 2:
parse_options(argc, argv, &state);
switch (state.stlink_version) {
case 2:
printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id);
printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id);
struct code_hw_watchpoint data_watches[DATA_WATCH_NUM];
static void init_data_watchpoints(stlink_t *sl) {
struct code_hw_watchpoint data_watches[DATA_WATCH_NUM];
static void init_data_watchpoints(stlink_t *sl) {
for(i = 0; i < DATA_WATCH_NUM; i++) {
// is this an empty slot ?
if(data_watches[i].fun == WATCHDISABLED) {
for(i = 0; i < DATA_WATCH_NUM; i++) {
// is this an empty slot ?
if(data_watches[i].fun == WATCHDISABLED) {
printf("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len);
#endif
printf("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len);
#endif
printf("failure: add watchpoints addr %x wf %u len %u\n", addr, wf, len);
#endif
return -1;
printf("failure: add watchpoints addr %x wf %u len %u\n", addr, wf, len);
#endif
return -1;
for(i = 0 ; i < DATA_WATCH_NUM; i++) {
if((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) {
for(i = 0 ; i < DATA_WATCH_NUM; i++) {
if((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) {
static void init_code_breakpoints(stlink_t *sl) {
memset(sl->q_buf, 0, 4);
stlink_write_debug32(sl, CM3_REG_FP_CTRL, 0x03 /*KEY | ENABLE4*/);
static void init_code_breakpoints(stlink_t *sl) {
memset(sl->q_buf, 0, 4);
stlink_write_debug32(sl, CM3_REG_FP_CTRL, 0x03 /*KEY | ENABLE4*/);
- printf("KARL - should read back as 0x03, not 60 02 00 00\n");
- stlink_read_debug32(sl, CM3_REG_FP_CTRL);
+ unsigned int val = stlink_read_debug32(sl, CM3_REG_FP_CTRL);
+ if (((val & 3) != 1) ||
+ ((((val >> 8) & 0x70) | ((val >> 4) & 0xf)) != CODE_BREAK_NUM) ||
+ (((val >> 8) & 0xf) != CODE_LIT_NUM)){
+ fprintf(stderr, "[FP_CTRL] = 0x%08x expecting 0x%08x\n", val,
+ ((CODE_BREAK_NUM & 0x70) << 8) | (CODE_LIT_NUM << 8) | ((CODE_BREAK_NUM & 0xf) << 4) | 1);
+ }
+
printf("setting hw break %d at %08x (%d)\n",
id, brk->addr, brk->type);
printf("reg %08x \n",
printf("setting hw break %d at %08x (%d)\n",
id, brk->addr, brk->type);
printf("reg %08x \n",
struct sockaddr_in serv_addr;
memset(&serv_addr,0,sizeof(struct sockaddr_in));
serv_addr.sin_family = AF_INET;
struct sockaddr_in serv_addr;
memset(&serv_addr,0,sizeof(struct sockaddr_in));
serv_addr.sin_family = AF_INET;
- stlink_force_debug(sl);
- stlink_reset(sl);
- init_code_breakpoints(sl);
- init_data_watchpoints(sl);
-
- printf("Listening at *:%d...\n", port);
+ printf("Listening at *:%d...\n", st->listen_port);
int client = accept(sock, NULL, NULL);
//signal (SIGINT, SIG_DFL);
int client = accept(sock, NULL, NULL);
//signal (SIGINT, SIG_DFL);
char* queryName = calloc(queryNameLength + 1, 1);
strncpy(queryName, &packet[1], queryNameLength);
char* queryName = calloc(queryNameLength + 1, 1);
strncpy(queryName, &packet[1], queryNameLength);
unsigned addr = strtoul(__s_addr, NULL, 16),
length = strtoul(s_length, NULL, 16);
unsigned addr = strtoul(__s_addr, NULL, 16),
length = strtoul(s_length, NULL, 16);
printf("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n",
type, op, annex, addr, length);
#endif
printf("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n",
type, op, annex, addr, length);
#endif
printf("Rcmd: jtag_reset\n");
#endif
} else if (!strncmp(params,"7265736574",10)) { //reset
printf("Rcmd: jtag_reset\n");
#endif
} else if (!strncmp(params,"7265736574",10)) { //reset
unsigned addr = strtoul(__s_addr, NULL, 16),
length = strtoul(s_length, NULL, 16);
unsigned addr = strtoul(__s_addr, NULL, 16),
length = strtoul(s_length, NULL, 16);
* Also, set to persistent mode
* to allow GDB disconnect.
*/
* Also, set to persistent mode
* to allow GDB disconnect.
*/