diff options
Diffstat (limited to 'ao-tools')
-rw-r--r-- | ao-tools/Makefile.am | 2 | ||||
-rw-r--r-- | ao-tools/ao-chaosread/.gitignore | 1 | ||||
-rw-r--r-- | ao-tools/ao-chaosread/Makefile.am | 9 | ||||
-rw-r--r-- | ao-tools/ao-chaosread/ao-chaosread.1 | 36 | ||||
-rw-r--r-- | ao-tools/ao-chaosread/ao-chaosread.c | 272 | ||||
-rw-r--r-- | ao-tools/ao-dump-up/ao-dump-up.c | 14 | ||||
-rw-r--r-- | ao-tools/ao-makebin/Makefile.am | 12 | ||||
-rw-r--r-- | ao-tools/ao-makebin/ao-makebin.1 | 47 | ||||
-rw-r--r-- | ao-tools/ao-makebin/ao-makebin.c | 172 | ||||
-rw-r--r-- | ao-tools/lib/Makefile.am | 2 | ||||
-rw-r--r-- | ao-tools/lib/ao-dfu.c | 202 | ||||
-rw-r--r-- | ao-tools/lib/ao-dfu.h | 35 | ||||
-rw-r--r-- | ao-tools/lib/ao-elf.c | 6 | ||||
-rw-r--r-- | ao-tools/lib/ao-hex.c | 33 | ||||
-rw-r--r-- | ao-tools/lib/ao-hex.h | 3 |
15 files changed, 824 insertions, 22 deletions
diff --git a/ao-tools/Makefile.am b/ao-tools/Makefile.am index 66d2560e..fb554857 100644 --- a/ao-tools/Makefile.am +++ b/ao-tools/Makefile.am @@ -3,7 +3,7 @@ SUBDIRS=lib ao-rawload ao-dbg ao-bitbang ao-eeprom ao-list \ ao-dumpflash ao-edit-telem ao-dump-up ao-elftohex \ ao-flash ao-usbload ao-test-igniter ao-test-baro \ ao-test-flash ao-cal-accel ao-test-gps ao-usbtrng \ - ao-cal-freq + ao-cal-freq ao-chaosread ao-makebin if LIBSTLINK SUBDIRS += ao-stmload endif diff --git a/ao-tools/ao-chaosread/.gitignore b/ao-tools/ao-chaosread/.gitignore new file mode 100644 index 00000000..b9443879 --- /dev/null +++ b/ao-tools/ao-chaosread/.gitignore @@ -0,0 +1 @@ +ao-chaosread diff --git a/ao-tools/ao-chaosread/Makefile.am b/ao-tools/ao-chaosread/Makefile.am new file mode 100644 index 00000000..581eb2d2 --- /dev/null +++ b/ao-tools/ao-chaosread/Makefile.am @@ -0,0 +1,9 @@ +bin_PROGRAMS=ao-chaosread + +AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS) + +ao_chaosread_LDADD=$(LIBUSB_LIBS) + +ao_chaosread_SOURCES = ao-chaosread.c + +man_MANS = ao-chaosread.1 diff --git a/ao-tools/ao-chaosread/ao-chaosread.1 b/ao-tools/ao-chaosread/ao-chaosread.1 new file mode 100644 index 00000000..d8ed6cb3 --- /dev/null +++ b/ao-tools/ao-chaosread/ao-chaosread.1 @@ -0,0 +1,36 @@ +.\" +.\" Copyright © 2016 Keith Packard <keithp@keithp.com> +.\" +.\" 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-LOAD 1 "ao-chaosread" "" +.SH NAME +ao-chaosread \- read raw noise source from chaoskey +.SH SYNOPSIS +.B "ao-chaosread" +.SH DESCRIPTION +.I ao-chaosread +reads ADC values from the noise source on the attached ChaosKey device. +.SH OPTIONS +.TP +\-s serial | --serial serial +This selects a ChaosKey by serial number instead of using the first +one found. +.SH USAGE +.I ao-chaosread +reads noise data. +.SH AUTHOR +Keith Packard diff --git a/ao-tools/ao-chaosread/ao-chaosread.c b/ao-tools/ao-chaosread/ao-chaosread.c new file mode 100644 index 00000000..806c2ef9 --- /dev/null +++ b/ao-tools/ao-chaosread/ao-chaosread.c @@ -0,0 +1,272 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * 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 <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <unistd.h> +#include <libusb.h> +#include <getopt.h> +#include <string.h> +#include <strings.h> + +#define CHAOS_SIZE 64 + +#define CHAOS_VENDOR 0x1d50 +#define CHAOS_PRODUCT 0x60c6 + +struct chaoskey { + libusb_context *ctx; + libusb_device_handle *handle; + int kernel_active; +}; + +libusb_device_handle * +chaoskey_match(libusb_device *dev, char *match_serial) +{ + struct libusb_device_descriptor desc; + int ret; + int match_len; + char *device_serial = NULL; + libusb_device_handle *handle = NULL; + + ret = libusb_get_device_descriptor(dev, &desc); + if (ret < 0) { + fprintf(stderr, "failed to get device descriptor: %s\n", libusb_strerror(ret)); + return 0; + } + + if (desc.idVendor != CHAOS_VENDOR) + return NULL; + if (desc.idProduct != CHAOS_PRODUCT) + return NULL; + + ret = libusb_open(dev, &handle); + + if (match_serial == NULL) + return handle; + + if (ret < 0) { + fprintf(stderr, "failed to open device: %s\n", libusb_strerror(ret)); + return NULL; + } + + match_len = strlen(match_serial); + device_serial = malloc(match_len + 2); + + if (!device_serial) { + fprintf(stderr, "malloc failed\n"); + goto out; + } + + ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, device_serial, match_len + 1); + + if (ret < 0) { + fprintf(stderr, "failed to get serial number: %s\n", libusb_strerror(ret)); + goto out; + } + + device_serial[ret] = '\0'; + + ret = strcmp(device_serial, match_serial); + free(device_serial); + if (ret) + goto out; + + return handle; + +out: + free(device_serial); + if (handle) + libusb_close(handle); + return 0; +} + +struct chaoskey * +chaoskey_open(char *serial) +{ + struct chaoskey *ck; + int ret; + ssize_t num; + libusb_device **list; + libusb_device *device = NULL; + int d; + + ck = calloc(sizeof (struct chaoskey), 1); + if (!ck) + goto out; + ret = libusb_init(&ck->ctx); + if (ret ) { + fprintf(stderr, "libusb_init failed: %s\n", libusb_strerror(ret)); + goto out; + } + + num = libusb_get_device_list(ck->ctx, &list); + if (num < 0) { + fprintf(stderr, "libusb_get_device_list failed: %s\n", libusb_strerror(num)); + goto out; + } + + for (d = 0; d < num; d++) { + libusb_device_handle *handle; + + handle = chaoskey_match(list[d], serial); + if (handle) { + ck->handle = handle; + break; + } + } + + libusb_free_device_list(list, 1); + + if (!ck->handle) { + if (serial) + fprintf (stderr, "No chaoskey matching %s\n", serial); + else + fprintf (stderr, "No chaoskey\n"); + goto out; + } + + ck->kernel_active = libusb_kernel_driver_active(ck->handle, 0); + if (ck->kernel_active) { + ret = libusb_detach_kernel_driver(ck->handle, 0); + if (ret) + goto out; + } + + ret = libusb_claim_interface(ck->handle, 0); + if (ret) + goto out; + + return ck; +out: + if (ck->kernel_active) + libusb_attach_kernel_driver(ck->handle, 0); + if (ck->ctx) + libusb_exit(ck->ctx); + free(ck); + return NULL; +} + +void +chaoskey_close(struct chaoskey *ck) +{ + libusb_release_interface(ck->handle, 0); + if (ck->kernel_active) + libusb_attach_kernel_driver(ck->handle, 0); + libusb_close(ck->handle); + libusb_exit(ck->ctx); + free(ck); +} + +void +chaoskey_transfer_callback(struct libusb_transfer *transfer) +{ + struct chaoskey *ck = transfer->user_data; +} + +#define ENDPOINT 0x86 + +int +chaoskey_read(struct chaoskey *ck, uint8_t *buffer, int len) +{ + int total = 0; + + while (len) { + int ret; + int transferred; + + ret = libusb_bulk_transfer(ck->handle, ENDPOINT, buffer, len, &transferred, 10000); + if (ret) { + if (total) + return total; + else { + errno = EIO; + return -1; + } + } + len -= transferred; + buffer += transferred; + } +} + +static const struct option options[] = { + { .name = "serial", .has_arg = 1, .val = 's' }, + { .name = "length", .has_arg = 1, .val = 'l' }, + { 0, 0, 0, 0}, +}; + +static void usage(char *program) +{ + fprintf(stderr, "usage: %s [--serial=<serial>] [--length=<length>[kMG]]\n", program); + exit(1); +} + +int +main (int argc, char **argv) +{ + struct chaoskey *ck; + char buf[1024]; + int got; + int c; + char *serial = NULL; + char *length_string; + char *length_end; + unsigned long length = sizeof(buf); + int this_time; + + while ((c = getopt_long(argc, argv, "s:l:", options, NULL)) != -1) { + switch (c) { + case 's': + serial = optarg; + break; + case 'l': + length_string = optarg; + length = strtoul(length_string, &length_end, 10); + if (!strcasecmp(length_end, "k")) + length *= 1024; + else if (!strcasecmp(length_end, "m")) + length *= 1024 * 1024; + else if (!strcasecmp(length_end, "g")) + length *= 1024 * 1024 * 1024; + else if (strlen(length_end)) + usage(argv[0]); + break; + default: + usage(argv[0]); + break; + } + } + + ck = chaoskey_open(serial); + if (!ck) + exit(1); + + while (length) { + this_time = sizeof(buf); + if (length < sizeof(buf)) + this_time = (int) length; + got = chaoskey_read(ck, buf, this_time); + if (got < 0) { + perror("read"); + exit(1); + } + write(1, buf, got); + length -= got; + } + exit(0); +} diff --git a/ao-tools/ao-dump-up/ao-dump-up.c b/ao-tools/ao-dump-up/ao-dump-up.c index b1f85af6..df05088c 100644 --- a/ao-tools/ao-dump-up/ao-dump-up.c +++ b/ao-tools/ao-dump-up/ao-dump-up.c @@ -140,20 +140,6 @@ static int find_header(struct cc_usb *cc) } } -static const char *state_names[] = { - "startup", - "idle", - "pad", - "boost", - "fast", - "coast", - "drogue", - "main", - "landed", - "invalid" -}; - - int main (int argc, char **argv) { diff --git a/ao-tools/ao-makebin/Makefile.am b/ao-tools/ao-makebin/Makefile.am new file mode 100644 index 00000000..758097a4 --- /dev/null +++ b/ao-tools/ao-makebin/Makefile.am @@ -0,0 +1,12 @@ +bin_PROGRAMS=ao-makebin + +AM_CFLAGS=-I$(top_srcdir)/ao-tools/lib $(LIBUSB_CFLAGS) +AO_ELFTOHEX_LIBS=$(top_builddir)/ao-tools/lib/libao-tools.a + +ao_makebin_DEPENDENCIES = $(AO_ELFTOHEX_LIBS) + +ao_makebin_LDADD=$(AO_ELFTOHEX_LIBS) -lelf + +ao_makebin_SOURCES=ao-makebin.c + +man_MANS = ao-makebin.1 diff --git a/ao-tools/ao-makebin/ao-makebin.1 b/ao-tools/ao-makebin/ao-makebin.1 new file mode 100644 index 00000000..e19ec2cc --- /dev/null +++ b/ao-tools/ao-makebin/ao-makebin.1 @@ -0,0 +1,47 @@ +.\" +.\" Copyright © 2013 Keith Packard <keithp@keithp.com> +.\" +.\" 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-LOAD 1 "ao-makebin" "" +.SH NAME +ao-makebin \- construct raw binary file or DFU image from collection of ELF files +.SH SYNOPSIS +.B "ao-makebin" +[\--base=\fIbase-address\fP] +[\--output=\fIoutput.bin\fP] +[\--dfu] +[\--verbose] +\fIinput.elf ...\fP +.SH DESCRIPTION +.I ao-makebin +reads the specified .elf files and writes out a raw binary flash image +.SH OPTIONS +.TP +\--base=\fIbase-address\fP +This specifies the target address for the first byte of the file (default is 0) +.TP +\--output=\fIoutput.bin\fP +This specifies the output file (default is stdout) +.TP +\--dfu +Creates a DFU file (as documented by ST's UM0391 user manual) instead +of a raw binary file. +.TP +\--verbose +Dumps some debug information. +.SH AUTHOR +Keith Packard diff --git a/ao-tools/ao-makebin/ao-makebin.c b/ao-tools/ao-makebin/ao-makebin.c new file mode 100644 index 00000000..31ce1889 --- /dev/null +++ b/ao-tools/ao-makebin/ao-makebin.c @@ -0,0 +1,172 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * 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 <getopt.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include "ao-hex.h" +#include "ao-elf.h" +#include "ao-dfu.h" + +static const struct option options[] = { + { .name = "verbose", .has_arg = 0, .val = 'v' }, + { .name = "output", .has_arg = 1, .val = 'o' }, + { .name = "base", .has_arg = 1, .val = 'b' }, + { .name = "align", .has_arg = 1, .val = 'a' }, + { .name = "dfu", .has_arg = 0, .val = 'd' }, + { 0, 0, 0, 0}, +}; + +static void usage(char *program) +{ + fprintf(stderr, "usage: %s [--verbose=<level>] [--output=<output.bin>] [--base=<base-address>] [--align=<align>] [--dfu] <input.elf> ...\n", program); + exit(1); +} + +static int +ends_with(char *whole, char *suffix) +{ + int whole_len = strlen(whole); + int suffix_len = strlen(suffix); + + if (suffix_len > whole_len) + return 0; + return strcmp(whole + whole_len - suffix_len, suffix) == 0; +} + +static struct ao_dfu_info dfu_info = { + .bcdDevice = 0x0000, + .idProduct = 0xdf11, + .idVendor = 0x0483, +}; + +int +main (int argc, char **argv) +{ + char *output = NULL; + struct ao_hex_image *image = NULL; + struct ao_sym *file_symbols; + int num_file_symbols; + FILE *file; + int c; + uint32_t base = 0xffffffff; + uint32_t align = 0; + uint32_t length; + int verbose = 0; + int dfu = 0; + + while ((c = getopt_long(argc, argv, "dvo:b:a:", options, NULL)) != -1) { + switch (c) { + case 'o': + output = optarg; + break; + case 'v': + verbose++; + break; + case 'b': + base = strtoul(optarg, NULL, 0); + break; + case 'a': + align = strtoul(optarg, NULL, 0); + break; + case 'd': + dfu = 1; + break; + default: + usage(argv[0]); + break; + } + } + + while (argv[optind]) { + char *input = argv[optind]; + struct ao_hex_image *tmp; + + if (ends_with (input, ".ihx")) + tmp = ao_hex_load(input, &file_symbols, &num_file_symbols); + else + tmp = ao_load_elf(input, &file_symbols, &num_file_symbols); + + if (!tmp) + usage(argv[0]); + + if (verbose) + fprintf(stderr, "%s: 0x%x %d\n", input, tmp->address, tmp->length); + + if (image) { + image = ao_hex_image_cat(image, tmp); + if (!image) + usage(argv[0]); + } else + image = tmp; + optind++; + } + + if (base != 0xffffffff && base > image->address) { + fprintf(stderr, "requested base 0x%x is after image address 0x%x\n", + base, image->address); + usage(argv[0]); + } + + if (verbose) + fprintf(stderr, "%s: base 0x%x length %d\n", output ? output : "<stdout>", image->address, image->length); + + if (!output) + file = stdout; + else { + file = fopen(output, "w"); + if (!file) { + perror(output); + exit(1); + } + } + + if (dfu) { + if (!ao_dfu_write(file, &dfu_info, 1, image)) { + fprintf(stderr, "%s: dfu_write failed: %s\n", output, strerror(errno)); + if (output) + unlink(output); + exit(1); + } + } else { + while (base < image->address) { + fputc(0xff, file); + base++; + } + + if (fwrite(image->data, 1, image->length, file) != image->length) { + fprintf(stderr, "%s: failed to write bin file\n", output ? output : "<stdout>"); + if (output) + unlink(output); + exit(1); + } + + if (align) { + length = image->length; + + while (length % align) { + fputc(0xff, file); + length++; + } + } + fflush(file); + } + + exit(0); +} diff --git a/ao-tools/lib/Makefile.am b/ao-tools/lib/Makefile.am index a03a976c..a33d682d 100644 --- a/ao-tools/lib/Makefile.am +++ b/ao-tools/lib/Makefile.am @@ -46,6 +46,8 @@ libao_tools_a_SOURCES = \ ao-editaltos.h \ ao-elf.c \ ao-elf.h \ + ao-dfu.c \ + ao-dfu.h \ ao-selfload.c \ ao-selfload.h \ ao-verbose.c \ diff --git a/ao-tools/lib/ao-dfu.c b/ao-tools/lib/ao-dfu.c new file mode 100644 index 00000000..b6778495 --- /dev/null +++ b/ao-tools/lib/ao-dfu.c @@ -0,0 +1,202 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * 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 <stdarg.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <stdint.h> +#include <errno.h> +#include "ao-hex.h" +#include "ao-dfu.h" + +static uint32_t dfu_crc; +static FILE *dfu_file; +static int dfu_failed; +static int dfu_error; + +static uint32_t update_crc(uint32_t crc, uint8_t byte) +{ + int j; + uint32_t mask; + + crc = crc ^ byte; + for (j = 0; j < 8; j++) { + mask = -(crc & 1); + crc = (crc >> 1) ^ (0xEDB88320 & mask); + } + return crc; +} + +static void dfu_init(FILE *file) +{ + dfu_crc = 0xffffffff; + dfu_file = file; + dfu_failed = 0; + dfu_error = 0; +} + +static int dfu_fini(void) +{ + if (fflush(dfu_file) == EOF) { + if (!dfu_failed) { + dfu_failed = 1; + dfu_error = errno; + } + } + if (dfu_failed) + errno = dfu_error; + return !dfu_failed; +} + +static void dfu_8(uint8_t byte) { + if (putc(byte, dfu_file) == EOF) { + if (!dfu_failed) { + dfu_failed = 1; + dfu_error = errno; + } + } + dfu_crc = update_crc(dfu_crc, byte); +} + +static void dfu_pad(int len) { + while (len--) + dfu_8(0); +} + +static void dfu_string(char *string) { + char c; + + while ((c = *string++)) + dfu_8((uint8_t) c); +} + +static void dfu_string_pad(char *string, int len) { + char c; + + while ((c = *string++)) { + dfu_8((uint8_t) c); + len--; + } + dfu_pad(len); +} + +static void dfu_block(uint8_t *bytes, int len) { + while (len--) + dfu_8(*bytes++); +} + +static void dfu_lsb16(uint16_t value) { + dfu_8(value); + dfu_8(value>>8); +} + +static void dfu_lsb32(uint32_t value) { + dfu_8(value); + dfu_8(value >> 8); + dfu_8(value >> 16); + dfu_8(value >> 24); +} + +static uint32_t dfu_image_size(struct ao_hex_image *image) { + return 8 + image->length; +} + +static uint32_t dfu_images_size(int num_image, struct ao_hex_image images[]) +{ + uint32_t size = 0; + int i; + + for (i = 0; i < num_image; i++) + size += dfu_image_size(&images[i]); + return size; +} + +static void dfu_image(struct ao_hex_image *image) +{ + dfu_lsb32(image->address); + dfu_lsb32(image->length); + dfu_block(image->data, image->length); +} + +static void dfu_target(char *name, int num_image, struct ao_hex_image images[]) +{ + uint32_t images_size = dfu_images_size(num_image, images); + int i; + + dfu_string("Target"); + dfu_8(0); + if (name) { + dfu_8(1); + dfu_pad(3); + dfu_string_pad(name, 255); + } else { + dfu_8(0); + dfu_pad(3); + dfu_pad(255); + } + dfu_lsb32(images_size); + dfu_lsb32(num_image); + for (i = 0; i < num_image; i++) + dfu_image(&images[i]); +} + +static uint32_t dfu_target_size(int num_image, struct ao_hex_image images[]) +{ + return 274 + dfu_images_size(num_image, images); +} + +static uint32_t +dfu_size(int num_image, struct ao_hex_image images[]) +{ + uint32_t size = 0; + size += 11; /* DFU Prefix */ + + size += dfu_target_size(num_image, images); + + return size; +} + +int +ao_dfu_write(FILE *file, struct ao_dfu_info *info, int num_image, struct ao_hex_image images[]) +{ + uint32_t total_size; + + total_size = dfu_size(num_image, images); + + dfu_init(file); + /* DFU Prefix */ + dfu_string(DFU_SIGNATURE); + dfu_8(0x01); + dfu_lsb32(total_size); + dfu_8(0x01); + + dfu_target("ST...", num_image, images); + + /* DFU Suffix */ + dfu_lsb16(info->bcdDevice); + dfu_lsb16(info->idProduct); + dfu_lsb16(info->idVendor); + dfu_lsb16(DFU_SPEC_VERSION); + dfu_string("UFD"); + dfu_8(16); + dfu_lsb32(dfu_crc); + return dfu_fini(); +} + diff --git a/ao-tools/lib/ao-dfu.h b/ao-tools/lib/ao-dfu.h new file mode 100644 index 00000000..c3dfc496 --- /dev/null +++ b/ao-tools/lib/ao-dfu.h @@ -0,0 +1,35 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * 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. + */ + +#ifndef _AO_DFU_H_ +#define _AO_DFU_H_ + +struct ao_dfu_info { + uint16_t bcdDevice; + uint16_t idProduct; + uint16_t idVendor; +}; + +#define DFU_SIGNATURE "DfuSe" +#define DFU_SPEC_VERSION 0x011a + +#define DFU_TARGET_SIGNATURE "Target" + +int +ao_dfu_write(FILE *file, struct ao_dfu_info *info, int num_image, struct ao_hex_image images[]); + +#endif /* _AO_DFU_H_ */ diff --git a/ao-tools/lib/ao-elf.c b/ao-tools/lib/ao-elf.c index 99b37210..680a80f0 100644 --- a/ao-tools/lib/ao-elf.c +++ b/ao-tools/lib/ao-elf.c @@ -206,7 +206,7 @@ get_load(Elf *e) #endif size_t nshdr; size_t s; - + if (elf_getshdrstrndx(e, &shstrndx) < 0) return 0; @@ -238,7 +238,7 @@ get_load(Elf *e) (uint32_t) phdr.p_filesz, (uint32_t) phdr.p_memsz); #endif - + for (s = 0; s < nshdr; s++) { scn = elf_getscn(e, s); @@ -256,7 +256,7 @@ get_load(Elf *e) #endif if (phdr.p_offset <= shdr.sh_offset && shdr.sh_offset < phdr.p_offset + phdr.p_filesz) { - + if (shdr.sh_size == 0) continue; diff --git a/ao-tools/lib/ao-hex.c b/ao-tools/lib/ao-hex.c index 5cfc63c1..2ceed7ab 100644 --- a/ao-tools/lib/ao-hex.c +++ b/ao-tools/lib/ao-hex.c @@ -294,7 +294,7 @@ load_symbols(struct ao_hex_file *hex, struct ao_sym *symbol; int num_symbols = 0; int size_symbols = 0; - + extended_addr = 0; for (i = 0; i < hex->nrecord; i++) { record = hex->records[i]; @@ -451,6 +451,31 @@ ao_hex_image_free(struct ao_hex_image *image) free(image); } +uint32_t min(uint32_t a, uint32_t b) { return a < b ? a : b; } +uint32_t max(uint32_t a, uint32_t b) { return a > b ? a : b; } + +struct ao_hex_image * +ao_hex_image_cat(struct ao_hex_image *a, struct ao_hex_image *b) +{ + struct ao_hex_image *n; + uint32_t base, bound; + uint32_t length; + + base = min(a->address, b->address); + bound = max(a->address + a->length, b->address + b->length); + length = bound - base; + + n = calloc (sizeof (struct ao_hex_image) + length, 1); + if (!n) + return NULL; + n->address = base; + n->length = length; + memset(n->data, 0xff, length); + memcpy(n->data + a->address - n->address, a->data, a->length); + memcpy(n->data + b->address - n->address, b->data, b->length); + return n; +} + int ao_hex_image_equal(struct ao_hex_image *a, struct ao_hex_image *b) { @@ -471,7 +496,7 @@ ao_hex_load(char *filename, struct ao_sym **symbols, int *num_symbolsp) file = fopen (filename, "r"); if (!file) return NULL; - + hex_file = ao_hex_file_read(file, filename); fclose(file); if (!hex_file) @@ -549,7 +574,7 @@ ao_hex_file_create(struct ao_hex_image *image, struct ao_sym *symbols, int num_s ao_hex_record_set_checksum(record); hex_file->records[nrecord++] = record; - + /* Add the symbols */ @@ -616,7 +641,7 @@ ao_hex_save(FILE *file, struct ao_hex_image *image, goto write_failed; } ret = true; - + if (fflush(file) != 0) ret = false; write_failed: diff --git a/ao-tools/lib/ao-hex.h b/ao-tools/lib/ao-hex.h index eb510ba2..a1ab490c 100644 --- a/ao-tools/lib/ao-hex.h +++ b/ao-tools/lib/ao-hex.h @@ -71,6 +71,9 @@ ao_hex_image_free(struct ao_hex_image *image); struct ao_hex_image * ao_hex_load(char *filename, struct ao_sym **symbols, int *num_symbols); +struct ao_hex_image * +ao_hex_image_cat(struct ao_hex_image *a, struct ao_hex_image *b); + int ao_hex_image_equal(struct ao_hex_image *a, struct ao_hex_image *b); |