From 548cf57d5a5ea323bbfc3605b44c23fc48dec96b Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 18 Mar 2013 22:12:48 -0700 Subject: ao-tools: add ao-dump-up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dumps out a µP log. Useful for µPusb bring-up Signed-off-by: Keith Packard --- ao-tools/Makefile.am | 2 +- ao-tools/ao-dump-up/Makefile.am | 12 +++ ao-tools/ao-dump-up/ao-dump-up.1 | 45 +++++++++ ao-tools/ao-dump-up/ao-dump-up.c | 207 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 265 insertions(+), 1 deletion(-) create mode 100644 ao-tools/ao-dump-up/Makefile.am create mode 100644 ao-tools/ao-dump-up/ao-dump-up.1 create mode 100644 ao-tools/ao-dump-up/ao-dump-up.c (limited to 'ao-tools') diff --git a/ao-tools/Makefile.am b/ao-tools/Makefile.am index e4df2e63..4600f1d6 100644 --- a/ao-tools/Makefile.am +++ b/ao-tools/Makefile.am @@ -1,3 +1,3 @@ SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list \ ao-load ao-telem ao-stmload ao-send-telem ao-sky-flash \ - ao-dumpflash ao-edit-telem + ao-dumpflash ao-edit-telem ao-dump-up diff --git a/ao-tools/ao-dump-up/Makefile.am b/ao-tools/ao-dump-up/Makefile.am new file mode 100644 index 00000000..94bb94a9 --- /dev/null +++ b/ao-tools/ao-dump-up/Makefile.am @@ -0,0 +1,12 @@ +bin_PROGRAMS=ao-dump-up + +AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS) $(GNOME_CFLAGS) +AO_DUMP_LOG_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a + +ao_dump_up_DEPENDENCIES = $(AO_DUMP_LOG_LIBS) + +ao_dump_up_LDADD=$(AO_DUMP_LOG_LIBS) $(LIBUSB_LIBS) $(GNOME_LIBS) + +ao_dump_up_SOURCES = ao-dump-up.c + +man_MANS = ao-dump-up.1 diff --git a/ao-tools/ao-dump-up/ao-dump-up.1 b/ao-tools/ao-dump-up/ao-dump-up.1 new file mode 100644 index 00000000..cfa81b46 --- /dev/null +++ b/ao-tools/ao-dump-up/ao-dump-up.1 @@ -0,0 +1,45 @@ +.\" +.\" Copyright © 2009 Keith Packard +.\" +.\" 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 2 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, write to the Free Software Foundation, Inc., +.\" 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +.\" +.\" +.TH AO-DUMPLOG 1 "ao-dump-up" "" +.SH NAME +ao-dump-up \- Dump flight log from MicroPeak flight computer +.SH SYNOPSIS +.B "ao-dump-up" +[\-T \fItty-device\fP] +[\--tty \fItty-device\fP] +[\-D \fIaltos-device\fP] +[\--device \fIaltos-device\fP] +.SH OPTIONS +.TP +\-T tty-device | --tty tty-device +This selects which tty device ao-dump-up uses to communicate with +the target device. +.TP +\-D AltOS-device | --device AltOS-device +Search for a connected device. This forces the program to look +for a specific USB device name. +.SH DESCRIPTION +.I ao-dump-up +downloads a MicroPeak flight log from a connected MicroPeak USB adapter. +.SH USAGE +.I ao-dump-up +connects to the specified target device and dumps the stored flight +log. +.SH AUTHOR +Keith Packard diff --git a/ao-tools/ao-dump-up/ao-dump-up.c b/ao-tools/ao-dump-up/ao-dump-up.c new file mode 100644 index 00000000..6268dc8b --- /dev/null +++ b/ao-tools/ao-dump-up/ao-dump-up.c @@ -0,0 +1,207 @@ +/* + * Copyright © 2009 Keith Packard + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include +#include +#include +#include +#include +#include "cc-usb.h" +#include "cc.h" + +#define NUM_BLOCK 512 + +static const struct option options[] = { + { .name = "tty", .has_arg = 1, .val = 'T' }, + { .name = "device", .has_arg = 1, .val = 'D' }, + { 0, 0, 0, 0}, +}; + +static void usage(char *program) +{ + fprintf(stderr, "usage: %s [--tty ] [--device ]\n", program); + exit(1); +} + +static uint8_t +log_checksum(int d[8]) +{ + uint8_t sum = 0x5a; + int i; + + for (i = 0; i < 8; i++) + sum += (uint8_t) d[i]; + return -sum; +} + +static int get_nonwhite(struct cc_usb *cc, int timeout) +{ + int c; + + for (;;) { + c = cc_usb_getchar_timeout(cc, timeout); + putchar(c); + if (!isspace(c)) + return c; + } +} + +static uint8_t +get_hexc(struct cc_usb *cc) +{ + int c = get_nonwhite(cc, 1000); + + if ('0' <= c && c <= '9') + return c - '0'; + if ('a' <= c && c <= 'f') + return c - 'a' + 10; + if ('A' <= c && c <= 'F') + return c - 'A' + 10; + fprintf(stderr, "Non-hex char '%c'\n", c); + exit(1); +} + +static int file_crc; + +static const int POLY = 0x8408; + +static int +log_crc(int crc, int b) +{ + int i; + + for (i = 0; i < 8; i++) { + if (((crc & 0x0001) ^ (b & 0x0001)) != 0) + crc = (crc >> 1) ^ POLY; + else + crc = crc >> 1; + b >>= 1; + } + return crc & 0xffff; +} + +static uint8_t +get_hex(struct cc_usb *cc) +{ + int a = get_hexc(cc); + int b = get_hexc(cc); + int h = (a << 4) + b; + + file_crc = log_crc(file_crc, h); + return h; +} + +static int get_32(struct cc_usb *cc) +{ + int v = 0; + int i; + for (i = 0; i < 4; i++) { + v += get_hex(cc) << (i * 8); + } + return v; +} + +static int get_16(struct cc_usb *cc) +{ + int v = 0; + int i; + for (i = 0; i < 2; i++) { + v += get_hex(cc) << (i * 8); + } + return v; +} + +static int swap16(int i) +{ + return ((i << 8) & 0xff00) | ((i >> 8) & 0xff); +} + +static int find_header(struct cc_usb *cc) +{ + for (;;) { + if (get_nonwhite(cc, 0) == 'M' && get_nonwhite(cc, 1000) == 'P') + return 1; + } +} + +static const char *state_names[] = { + "startup", + "idle", + "pad", + "boost", + "fast", + "coast", + "drogue", + "main", + "landed", + "invalid" +}; + + +int +main (int argc, char **argv) +{ + struct cc_usb *cc; + char *tty = NULL; + char *device = NULL; + int c; + char line[8192]; + int nsamples; + int i; + int crc; + int current_crc; + + while ((c = getopt_long(argc, argv, "T:D:", options, NULL)) != -1) { + switch (c) { + case 'T': + tty = optarg; + break; + case 'D': + device = optarg; + break; + default: + usage(argv[0]); + break; + } + } + if (!tty) + tty = cc_usbdevs_find_by_arg(device, "FT230X Basic UART"); + if (!tty) + tty = getenv("ALTOS_TTY"); + if (!tty) + tty="/dev/ttyUSB0"; + cc = cc_usb_open(tty); + if (!cc) + exit(1); + find_header(cc); + file_crc = 0xffff; + get_32(cc); /* ground pressure */ + get_32(cc); /* min pressure */ + nsamples = get_16(cc); /* nsamples */ + for (i = 0; i < nsamples; i++) + get_16(cc); /* sample i */ + current_crc = swap16(~file_crc & 0xffff); + crc = get_16(cc); /* crc */ + putchar ('\n'); + if (crc == current_crc) + printf("CRC valid\n"); + else + printf("CRC invalid\n"); + cc_usb_close(cc); + exit (0); +} -- cgit v1.2.3 From 15bc83a0eaaa9a43d67fdc3e9f412d5b2c1f06dd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 20 Mar 2013 23:22:37 -0700 Subject: ao-tools: Make library support µPusb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set baud rate to 9600, look for FTDI-style names Signed-off-by: Keith Packard --- ao-tools/lib/cc-usb.c | 12 ++++++++++-- ao-tools/lib/cc-usb.h | 3 +++ ao-tools/lib/cc-usbdev.c | 25 +++++++++++++++++++++++-- 3 files changed, 36 insertions(+), 4 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/lib/cc-usb.c b/ao-tools/lib/cc-usb.c index 9f07e662..f8275243 100644 --- a/ao-tools/lib/cc-usb.c +++ b/ao-tools/lib/cc-usb.c @@ -254,10 +254,10 @@ cc_usb_printf(struct cc_usb *cc, char *format, ...) } int -cc_usb_getchar(struct cc_usb *cc) +cc_usb_getchar_timeout(struct cc_usb *cc, int timeout) { while (cc->in_pos == cc->in_count) { - if (_cc_usb_sync(cc, 5000) < 0) { + if (_cc_usb_sync(cc, timeout) < 0) { fprintf(stderr, "USB link timeout\n"); exit(1); } @@ -265,6 +265,12 @@ cc_usb_getchar(struct cc_usb *cc) return cc->in_buf[cc->in_pos++]; } +int +cc_usb_getchar(struct cc_usb *cc) +{ + return cc_usb_getchar_timeout(cc, 5000); +} + void cc_usb_getline(struct cc_usb *cc, char *line, int max) { @@ -420,6 +426,8 @@ cc_usb_open(char *tty) tcgetattr(cc->fd, &termios); save_termios = termios; cfmakeraw(&termios); + cfsetospeed(&termios, B9600); + cfsetispeed(&termios, B9600); tcsetattr(cc->fd, TCSAFLUSH, &termios); cc_usb_printf(cc, "\nE 0\nm 0\n"); do { diff --git a/ao-tools/lib/cc-usb.h b/ao-tools/lib/cc-usb.h index e90e1195..f1193456 100644 --- a/ao-tools/lib/cc-usb.h +++ b/ao-tools/lib/cc-usb.h @@ -53,6 +53,9 @@ cc_usb_sync(struct cc_usb *cc); void cc_queue_read(struct cc_usb *cc, uint8_t *buf, int len); +int +cc_usb_getchar_timeout(struct cc_usb *cc, int timeout); + int cc_usb_getchar(struct cc_usb *cc); diff --git a/ao-tools/lib/cc-usbdev.c b/ao-tools/lib/cc-usbdev.c index a19e231c..95bfa244 100644 --- a/ao-tools/lib/cc-usbdev.c +++ b/ao-tools/lib/cc-usbdev.c @@ -132,11 +132,23 @@ usb_tty(char *sys) /* Check for tty/ttyACMx style names */ tty_dir = cc_fullname(endpoint_full, "tty"); - free(endpoint_full); ntty = scandir(tty_dir, &namelist, dir_filter_tty, alphasort); free (tty_dir); + if (ntty > 0) { + tty = cc_fullname("/dev", namelist[0]->d_name); + free(endpoint_full); + free(namelist); + return tty; + } + + /* Check for ttyACMx style names + */ + ntty = scandir(endpoint_full, &namelist, + dir_filter_tty, + alphasort); + free(endpoint_full); if (ntty > 0) { tty = cc_fullname("/dev", namelist[0]->d_name); free(namelist); @@ -197,6 +209,15 @@ dir_filter_dev(const struct dirent *d) return 1; } +static int +is_am(int idVendor, int idProduct) { + if (idVendor == 0xfffe) + return 1; + if (idVendor == 0x0403 && idProduct == 0x6015) + return 1; + return 0; +} + struct cc_usbdevs * cc_usbdevs_scan(void) { @@ -220,7 +241,7 @@ cc_usbdevs_scan(void) dir = cc_fullname(USB_DEVICES, ents[e]->d_name); dev = usb_scan_device(dir); free(dir); - if (dev->idVendor == 0xfffe && dev->tty) { + if (is_am(dev->idVendor, dev->idProduct) && dev->tty) { if (devs->dev) devs->dev = realloc(devs->dev, (devs->ndev + 1) * sizeof (struct usbdev *)); -- cgit v1.2.3 From 649999863c7228ead0225968752d068dc0d30091 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 30 Mar 2013 01:33:49 -0700 Subject: altos: Add logging and telem to telegps This turns on telemetry, APRS, RDF and data logging for telegps. Data is logged as soon as GPS has a date to create the right filename, using files of the form YYYYMMDD.LOG which just barely fits in a FAT filename. Telemetry/RDF/APRS are all separately controllable. Signed-off-by: Keith Packard --- ao-tools/ao-telem/ao-telem.c | 9 ++++-- src/core/ao_gps_report_mega.c | 1 + src/core/ao_telemetry.c | 3 ++ src/drivers/ao_log_fat.c | 74 +++++++++++++++++++++++++++++++++++++++++++ src/telegps-v0.1/Makefile | 5 ++- src/telegps-v0.1/ao_telegps.c | 9 +++++- 6 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 src/drivers/ao_log_fat.c (limited to 'ao-tools') diff --git a/ao-tools/ao-telem/ao-telem.c b/ao-tools/ao-telem/ao-telem.c index e7fc8e26..d2dae5a7 100644 --- a/ao-tools/ao-telem/ao-telem.c +++ b/ao-tools/ao-telem/ao-telem.c @@ -24,6 +24,7 @@ #include "cc.h" static const struct option options[] = { + { .name = "crc", .has_arg = 0, .val = 'c' }, { 0, 0, 0, 0}, }; @@ -44,8 +45,12 @@ main (int argc, char **argv) char *s; FILE *file; int serial; - while ((c = getopt_long(argc, argv, "", options, NULL)) != -1) { + int ignore_crc = 0; + while ((c = getopt_long(argc, argv, "c", options, NULL)) != -1) { switch (c) { + case 'c': + ignore_crc = 1; + break; default: usage(argv[0]); break; @@ -74,7 +79,7 @@ main (int argc, char **argv) printf ("serial %5d rssi %d status %02x tick %5d type %3d ", telem.generic.serial, rssi, telem.generic.status, telem.generic.tick, telem.generic.type); - if ((telem.generic.status & (1 << 7)) == 0) { + if (!ignore_crc && (telem.generic.status & (1 << 7)) == 0) { printf ("CRC error\n"); continue; } diff --git a/src/core/ao_gps_report_mega.c b/src/core/ao_gps_report_mega.c index 47891cab..e3af4307 100644 --- a/src/core/ao_gps_report_mega.c +++ b/src/core/ao_gps_report_mega.c @@ -16,6 +16,7 @@ */ #include "ao.h" +#include "ao_log.h" void ao_gps_report_mega(void) diff --git a/src/core/ao_telemetry.c b/src/core/ao_telemetry.c index 8d440e15..3aa315c7 100644 --- a/src/core/ao_telemetry.c +++ b/src/core/ao_telemetry.c @@ -16,6 +16,7 @@ */ #include "ao.h" +#include "ao_log.h" #include "ao_product.h" static __pdata uint16_t ao_telemetry_interval; @@ -306,12 +307,14 @@ ao_telemetry(void) #ifdef AO_SEND_ALL_BARO ao_send_baro(); #endif +#if HAS_FLIGHT #ifdef AO_SEND_MEGA ao_send_mega_sensor(); ao_send_mega_data(); #else ao_send_sensor(); #endif +#endif #if HAS_COMPANION if (ao_companion_running) diff --git a/src/drivers/ao_log_fat.c b/src/drivers/ao_log_fat.c new file mode 100644 index 00000000..684148b7 --- /dev/null +++ b/src/drivers/ao_log_fat.c @@ -0,0 +1,74 @@ +/* + * Copyright © 2013 Keith Packard + * + * 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; version 2 of the License. + * + * 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, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "ao.h" +#include "ao_log.h" +#include "ao_fat.h" + +static uint8_t log_year, log_month, log_day; +static uint8_t log_running; +static uint8_t log_mutex; + +static void +ao_log_open(void) +{ + char name[12]; + + sprintf(name,"%04d%02d%02dLOG", 2000 + log_year, log_month, log_day); + if (ao_fat_open(name, AO_FAT_OPEN_WRITE) == AO_FAT_SUCCESS) + log_running = 1; +} + +static void +ao_log_close(void) +{ + log_running = 0; + ao_fat_close(); +} + +uint8_t +ao_log_full(void) +{ + return ao_fat_full(); +} + +uint8_t +ao_log_mega(struct ao_log_mega *log) +{ + uint8_t wrote = 0; + ao_mutex_get(&log_mutex); + if (log->type == AO_LOG_GPS_TIME) { + if (log_running && + (log_year != log->u.gps.year || + log_month != log->u.gps.month || + log_day != log->u.gps.day)) { + ao_log_close(); + } + if (!log_running) { + log_year = log->u.gps.year; + log_month = log->u.gps.month; + log_day = log->u.gps.day; + ao_log_open(); + } + } + if (log_running) { + wrote = ao_fat_write(log, sizeof (*log)) == AO_FAT_SUCCESS; + ao_fat_sync(); + } + ao_mutex_put(&log_mutex); + return wrote; +} diff --git a/src/telegps-v0.1/Makefile b/src/telegps-v0.1/Makefile index ae36c9fd..8e610db7 100644 --- a/src/telegps-v0.1/Makefile +++ b/src/telegps-v0.1/Makefile @@ -55,7 +55,10 @@ ALTOS_SRC = \ ao_eeprom_stm.c \ ao_sdcard.c \ ao_bufio.c \ - ao_fat.c + ao_fat.c \ + ao_log_fat.c \ + ao_gps_report_mega.c \ + ao_telemetry.c PRODUCT=TeleGPS-v0.1 PRODUCT_DEF=-DTELEGPS diff --git a/src/telegps-v0.1/ao_telegps.c b/src/telegps-v0.1/ao_telegps.c index 2f1f38f2..91796c21 100644 --- a/src/telegps-v0.1/ao_telegps.c +++ b/src/telegps-v0.1/ao_telegps.c @@ -19,6 +19,8 @@ #include #include +uint16_t ao_flight_number = 1; + int main(void) { @@ -47,9 +49,14 @@ main(void) ao_usb_init(); ao_radio_init(); + ao_fat_init(); + ao_gps_init(); + ao_gps_report_mega_init(); - ao_fat_init(); + ao_telemetry_init(); + ao_telemetry_set_interval(AO_SEC_TO_TICKS(1)); + ao_rdf_set(1); ao_config_init(); -- cgit v1.2.3 From db01557ce493c435db177fda78653697ba2afa51 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 23 Mar 2013 02:10:38 -0700 Subject: ao-tools/ao-stmload: Be smarter about ELF parsing. Retry open on failure. Figuring out what goes where is tricky; turns out we want to pull all of the sections that map inside any program area that is supposed to be loaded from the file. So, we walk the program headers, then walk all of the section headers looking for those that suck data from the same portion of the file. Compute where in ROM each relevant section goes and build a full ROM image in memory using that. This patch also adds code to close and re-open the device if the first open failed to do what we want. Much nicer to have the computer figure out when the open succeeded rather than having people re-run the app. Signed-off-by: Keith Packard --- ao-tools/ao-stmload/ao-stmload.c | 114 +++++++++++++++++++++++++++++++++------ 1 file changed, 98 insertions(+), 16 deletions(-) (limited to 'ao-tools') diff --git a/ao-tools/ao-stmload/ao-stmload.c b/ao-tools/ao-stmload/ao-stmload.c index a471dcc4..89b818da 100644 --- a/ao-tools/ao-stmload/ao-stmload.c +++ b/ao-tools/ao-stmload/ao-stmload.c @@ -69,6 +69,11 @@ find_symbols (Elf *e) int i, symbol_count, s; int required = 0; char *symbol_name; + char *section_name; + size_t shstrndx; + + if (elf_getshdrstrndx(e, &shstrndx) < 0) + return 0; /* * Find the symbols @@ -76,9 +81,29 @@ find_symbols (Elf *e) scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { + if (gelf_getshdr(scn, &shdr) != &shdr) return 0; +#if 0 + section_name = elf_strptr(e, shstrndx, shdr.sh_name); + + printf ("name %s\n", section_name); + + if (shdr.sh_type == SHT_PROGBITS) + { + printf ("\ttype %lx\n", shdr.sh_type); + printf ("\tflags %lx\n", shdr.sh_flags); + printf ("\taddr %lx\n", shdr.sh_addr); + printf ("\toffset %lx\n", shdr.sh_offset); + printf ("\tsize %lx\n", shdr.sh_size); + printf ("\tlink %lx\n", shdr.sh_link); + printf ("\tinfo %lx\n", shdr.sh_info); + printf ("\taddralign %lx\n", shdr.sh_addralign); + printf ("\tentsize %lx\n", shdr.sh_entsize); + } +#endif + if (shdr.sh_type == SHT_SYMTAB) { symbol_data = elf_getdata(scn, NULL); symbol_count = shdr.sh_size / shdr.sh_entsize; @@ -199,9 +224,15 @@ get_load(Elf *e) uint8_t *buf; char *got_name; size_t nphdr; - int p; + size_t p; GElf_Phdr phdr; + GElf_Addr p_paddr; + GElf_Off p_offset; + GElf_Addr sh_paddr; struct load *load = NULL; + char *section_name; + size_t nshdr; + size_t s; if (elf_getshdrstrndx(e, &shstrndx) < 0) return 0; @@ -209,6 +240,9 @@ get_load(Elf *e) if (elf_getphdrnum(e, &nphdr) < 0) return 0; + if (elf_getshdrnum(e, &nshdr) < 0) + return 0; + /* * As far as I can tell, all of the phdr sections should * be flashed to memory @@ -218,16 +252,54 @@ get_load(Elf *e) /* Find this phdr */ gelf_getphdr(e, p, &phdr); + if (phdr.p_type != PT_LOAD) + continue; + + p_offset = phdr.p_offset; /* Get the associated file section */ - scn = gelf_offscn(e, phdr.p_offset); - if (gelf_getshdr(scn, &shdr) != &shdr) - abort(); +#if 0 + printf ("offset %08x vaddr %08x paddr %08x filesz %08x memsz %08x\n", + (uint32_t) phdr.p_offset, + (uint32_t) phdr.p_vaddr, + (uint32_t) phdr.p_paddr, + (uint32_t) phdr.p_filesz, + (uint32_t) phdr.p_memsz); +#endif + + for (s = 0; s < nshdr; s++) { + scn = elf_getscn(e, s); + + if (!scn) { + printf ("getscn failed\n"); + abort(); + } + if (gelf_getshdr(scn, &shdr) != &shdr) { + printf ("gelf_getshdr failed\n"); + abort(); + } - data = elf_getdata(scn, NULL); + section_name = elf_strptr(e, shstrndx, shdr.sh_name); - /* Write the section data into the memory block */ - load = load_write(load, phdr.p_paddr, phdr.p_filesz, data->d_buf); + if (phdr.p_offset <= shdr.sh_offset && shdr.sh_offset < phdr.p_offset + phdr.p_filesz) { + + if (shdr.sh_size == 0) + continue; + + sh_paddr = phdr.p_paddr + shdr.sh_offset - phdr.p_offset; + + printf ("\tsize %08x rom %08x exec %08x %s\n", + (uint32_t) shdr.sh_size, + (uint32_t) sh_paddr, + (uint32_t) shdr.sh_addr, + section_name); + + data = elf_getdata(scn, NULL); + + /* Write the section data into the memory block */ + load = load_write(load, sh_paddr, shdr.sh_size, data->d_buf); + } + } } return load; } @@ -422,6 +494,7 @@ main (int argc, char **argv) stlink_t *sl; int was_flashed = 0; struct load *load; + int tries; while ((c = getopt_long(argc, argv, "D:c:s:", options, NULL)) != -1) { switch (c) { @@ -472,19 +545,28 @@ main (int argc, char **argv) /* Connect to the programming dongle */ - if (device) { - sl = stlink_v1_open(50); - } else { - sl = stlink_open_usb(50); + for (tries = 0; tries < 3; tries++) { + if (device) { + sl = stlink_v1_open(50); + } else { + sl = stlink_open_usb(50); + } + if (!sl) { + fprintf (stderr, "No STLink devices present\n"); + done (sl, 1); + } + + if (sl->chip_id != 0) + break; + stlink_reset(sl); + stlink_close(sl); } - if (!sl) { - fprintf (stderr, "No STLink devices present\n"); - done (sl, 1); + if (sl->chip_id == 0) { + fprintf (stderr, "Debugger connection failed\n"); + done(sl, 1); } - sl->verbose = 50; - /* Verify that the loaded image fits entirely within device flash */ if (load->addr < sl->flash_base || -- cgit v1.2.3