license that can be found in the LICENSE file.
*/
+#include <getopt.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "gdb-remote.h"
+#define DEFAULT_LOGGING_LEVEL 50
+#define DEFAULT_GDB_LISTEN_PORT 4242
+
+#define STRINGIFY_inner(name) #name
+#define STRINGIFY(name) STRINGIFY_inner(name)
+
#define FLASH_BASE 0x08000000
//Allways update the FLASH_PAGE before each use, by calling stlink_calculate_pagesize
#define FLASH_PAGE (sl->flash_pgsz)
-volatile int do_exit = 0;
-void ctrl_c(int sig)
-{
- do_exit = 1;
-}
-
static const char hex[] = "0123456789abcdef";
static const char* current_memory_map = NULL;
-struct chip_params {
- uint32_t chip_id;
- char* description;
- uint32_t flash_size_reg;
- uint32_t max_flash_size, flash_pagesize;
- uint32_t sram_size;
- uint32_t bootrom_base, bootrom_size;
-} const devices[] = {
- { 0x410, "F1 Medium-density device", 0x1ffff7e0,
- 0x20000, 0x400, 0x5000, 0x1ffff000, 0x800 }, // table 2, pm0063
- { 0x411, "F2 device", 0, /* No flash size register found in the docs*/
- 0x100000, 0x20000, 0x20000, 0x1fff0000, 0x7800 }, // table 1, pm0059
- { 0x412, "F1 Low-density device", 0x1ffff7e0,
- 0x8000, 0x400, 0x2800, 0x1ffff000, 0x800 }, // table 1, pm0063
- /*Page size is variable */
- { 0x413, "F4 device", 0x1FFF7A10, //RM0090 error same as unique ID
- 0x100000, 0x4000, 0x30000, 0x1fff0000, 0x7800 }, // table 1, pm0081
- { 0x414, "F1 High-density device", 0x1ffff7e0,
- 0x80000, 0x800, 0x10000, 0x1ffff000, 0x800 }, // table 3 pm0063
- // This ignores the EEPROM! (and uses the page erase size,
- // not the sector write protection...)
- { 0x416, "L1 Med-density device", 0x1FF8004C, // table 1, pm0062
- 0x20000, 0x100, 0x4000, 0x1ff00000, 0x1000 },
- { 0x418, "F1 Connectivity line device", 0x1ffff7e0,
- 0x40000, 0x800, 0x10000, 0x1fffb000, 0x4800 },
- { 0x420, "F1 Medium-density value line device", 0x1ffff7e0,
- 0x20000, 0x400, 0x2000, 0x1ffff000, 0x800 },
- { 0x428, "F1 High-density value line device", 0x1ffff7e0,
- 0x80000, 0x800, 0x8000, 0x1ffff000, 0x800 },
- { 0x430, "F1 XL-density device", 0x1ffff7e0, // pm0068
- 0x100000, 0x800, 0x18000, 0x1fffe000, 0x1800 },
- { 0 }
-};
-
-int serve(stlink_t *sl, int port);
-char* make_memory_map(stlink_t *sl, const struct chip_params *params, uint32_t flash_size);
+typedef struct _st_state_t {
+ // things from command line, bleh
+ int stlink_version;
+ // "/dev/serial/by-id/usb-FTDI_TTL232R-3V3_FTE531X6-if00-port0" is only 58 chars
+ char devicename[100];
+ int logging_level;
+ int listen_port;
+} st_state_t;
-int main(int argc, char** argv) {
- stlink_t *sl = NULL;
- int port = 0;
- uint32_t flash_size;
-
- const char * HelpStr = "\nUsage:\n"
- "\tst-util [Arguments]\n"
- "\tArguments (no more than 2):\n"
- "\t\t<Port>: Port. Default: 4242.\n"
- "\t\t{usb|sgauto|/dev/sgX}: Transport, "
- "where X = {0, 1, 2, ...}. Default: USB.\n"
- "\tExamples:\n"
- "\t\tst-util 1234\n"
- "\t\tst-util sgauto\n"
- "\t\tst-util 1234 usb\n"
- "\t\tst-util /dev/sgX 1234\n"
- "\t\tst-util 1234 /dev/sgX\n";
-
-
- // Parsing the arguments of command line ...
-
- if (argc == 1 || argc > 3) {
- fprintf(stderr, HelpStr, NULL);
- return 1;
- }
-
- for(int a = 1; a < argc; a++) {
-
- // Port
- int p = atoi(argv[a]);
- if (p < 0 || p > 0xFFFF) {
- fprintf(stderr, "Invalid port\n");
- fprintf(stderr, HelpStr, NULL);
- return 1;
- }
- if (p > 0 && port == 0) {port = p; continue;}
-
- // if (p == 0) ...
-
- if (sl != NULL) {
- fprintf(stderr, "Invalid argumets\n");
- fprintf(stderr, HelpStr, NULL);
- return 1;
- }
-
- // usb
- if (!strcmp(argv[a], "usb")) {
- sl = stlink_open_usb(10);
- if(sl == NULL) return 1;
- continue;
+int serve(stlink_t *sl, int port);
+char* make_memory_map(stlink_t *sl);
+
+
+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'},
+ {"device", required_argument, NULL, 'd'},
+ {"stlink_version", required_argument, NULL, 's'},
+ {"stlinkv1", no_argument, NULL, '1'},
+ {"listen_port", required_argument, NULL, 'p'},
+ {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"
+ " -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"
+ " -p 4242, --listen_port=1234\n"
+ "\t\t\tSet the gdb server listen port. "
+ "(default port: " STRINGIFY(DEFAULT_GDB_LISTEN_PORT) ")\n"
+ ;
+
+
+ int option_index = 0;
+ int c;
+ int q;
+ while ((c = getopt_long(argc, argv, "hv::d:s:1p:", long_options, &option_index)) != -1) {
+ switch (c) {
+ case 0:
+ printf("XXXXX Shouldn't really normally come here, only if there's no corresponding option\n");
+ printf("option %s", long_options[option_index].name);
+ if (optarg) {
+ printf(" with arg %s", optarg);
}
-
- // /dev/sgX
- if (!strncmp(argv[a], "/dev/sgX", 7)) {
- if(!CONFIG_USE_LIBSG) {
- fprintf(stderr, "libsg not use\n");
- return 1;
- }
- sl = stlink_quirk_open(argv[a], 0);
- if(sl == NULL) return 1;
- continue;
+ printf("\n");
+ break;
+ case 'h':
+ printf(help_str, argv[0]);
+ exit(EXIT_SUCCESS);
+ break;
+ case 'v':
+ if (optarg) {
+ st->logging_level = atoi(optarg);
+ } else {
+ st->logging_level = DEFAULT_LOGGING_LEVEL;
}
-
- // sg_auto
- if (!strcmp(argv[a], "sgauto")) {
- if(!CONFIG_USE_LIBSG) {
- fprintf(stderr, "libsg not use\n");
- return 1;
- }
-
- // Search ST-LINK (from /dev/sg0 to /dev/sg99)
- for(int DevNum = 0; DevNum <= 99; DevNum++)
- {
- if(DevNum < 10) {
- char DevName[] = "/dev/sgX";
- DevName[7] = DevNum + '0';
- if ( !access(DevName, F_OK) )
- sl = stlink_quirk_open(DevName, 0);
- }
- else {
- char DevName[] = "/dev/sgXY";
- DevName[7] = DevNum/10 + '0';
- DevName[8] = DevNum%10 + '0';
- if ( !access(DevName, F_OK) )
- sl = stlink_quirk_open(DevName, 0);
- }
- if (sl != NULL) break;
- }
-
- if(sl == NULL) return 1;
- continue;
+ break;
+ case 'd':
+ if (strlen(optarg) > sizeof (st->devicename)) {
+ fprintf(stderr, "device name too long: %zd\n", strlen(optarg));
+ } else {
+ strcpy(st->devicename, optarg);
}
-
- // Invalid argumets
- fprintf(stderr, "Invalid argumets\n");
- fprintf(stderr, HelpStr, NULL);
- return 1;
+ break;
+ case '1':
+ st->stlink_version = 1;
+ break;
+ case 's':
+ sscanf(optarg, "%i", &q);
+ if (q < 0 || q > 2) {
+ fprintf(stderr, "stlink version %d unknown!\n", q);
+ exit(EXIT_FAILURE);
+ }
+ st->stlink_version = q;
+ break;
+ case 'p':
+ sscanf(optarg, "%i", &q);
+ if (q < 0) {
+ fprintf(stderr, "Can't use a negative port to listen on: %d\n", q);
+ exit(EXIT_FAILURE);
+ }
+ st->listen_port = q;
+ break;
}
-
- // Default transport: USB
- if (sl == NULL) sl = stlink_open_usb(10);
- // Default port: 4242
- if (port == 0) port = 4242;
-
- // End parsing
-
-
- if (sl == NULL) return 1;
-
- 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);
- }
-
- stlink_identify_device(sl);
- printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id);
-
- sl->verbose=0;
+ }
- const struct chip_params* params = NULL;
+ if (optind < argc) {
+ printf("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf("%s ", argv[optind++]);
+ printf("\n");
+ }
+ return 0;
+}
- for(int i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) {
- if(devices[i].chip_id == (sl->chip_id & 0xFFF)) {
- params = &devices[i];
- break;
- }
- }
- if(params == NULL) {
- fprintf(stderr, "Cannot recognize the connected device!\n");
- return 0;
- }
+int main(int argc, char** argv) {
- printf("Device connected: %s\n", params->description);
+ stlink_t *sl = NULL;
- if(sl->chip_id==STM32F4_CHIP_ID) {
- flash_size=0x100000; //todo: RM0090 error; size register same address as unique ID
- printf("Device parameters: SRAM: 0x%x bytes, Flash: up to 0x%x bytes with variable page size\n",
- params->sram_size, flash_size);
- }
- else {
- printf("Device parameters: SRAM: 0x%x bytes, Flash: up to 0x%x bytes in pages of 0x%x bytes\n",
- params->sram_size, params->max_flash_size, params->flash_pagesize);
- stlink_read_mem32(sl, params->flash_size_reg, 4);
- flash_size = sl->q_buf[0] | (sl->q_buf[1] << 8);
- //flash_size_reg is in 1k blocks.
- flash_size *= 0x400;
- }
+ st_state_t state;
+ memset(&state, 0, sizeof(state));
+ // set defaults...
+ 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:
+ sl = stlink_open_usb(state.logging_level);
+ if(sl == NULL) return 1;
+ break;
+ case 1:
+ sl = stlink_v1_open(state.logging_level);
+ if(sl == NULL) return 1;
+ break;
+ }
+
+ printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id);
- /* Init PAGE_SIZE for fixed page size devices.
- * stlink_calculate_pagesize will then return this value for them.
- * variable pagesize devices must allways update FLASH_PAGE before use! */
- FLASH_PAGE = params->flash_pagesize;
- sl->flash_size=flash_size;
+ sl->verbose=0;
- printf("Flash size is %d\n", flash_size);
- current_memory_map = make_memory_map(sl, params, flash_size);
+ current_memory_map = make_memory_map(sl);
- while(serve(sl, port) == 0);
+ while(serve(sl, state.listen_port) == 0);
/* Switch back to mass storage mode before closing. */
stlink_run(sl);
" <memory type=\"rom\" start=\"0x1ffff800\" length=\"0x8\"/>" // option byte area
"</memory-map>";
-char* make_memory_map(stlink_t *sl, const struct chip_params *params, uint32_t flash_size) {
+char* make_memory_map(stlink_t *sl) {
/* This will be freed in serve() */
char* map = malloc(4096);
map[0] = '\0';
if(sl->chip_id==STM32F4_CHIP_ID) {
strcpy(map, memory_map_template_F4);
- }
-
- else {
- snprintf(map, 4096, memory_map_template,
- flash_size,
- params->sram_size,
- flash_size, params->flash_pagesize,
- params->bootrom_base, params->bootrom_size);
+ } else {
+ snprintf(map, 4096, memory_map_template,
+ sl->flash_size,
+ sl->sram_size,
+ sl->flash_size, sl->flash_pgsz,
+ sl->sys_base, sl->sys_size);
}
return map;
}
printf("Listening at *:%d...\n", port);
- (void) signal (SIGINT, ctrl_c);
int client = accept(sock, NULL, NULL);
signal (SIGINT, SIG_DFL);
if(client < 0) {