From 8d6359867cb6bbed1edbd1de475caaa72c8427ab Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Mon, 22 May 2017 17:01:47 +0100 Subject: wip --- Makefile | 26 ++-- halfkay.h | 7 +- hktool.1 | 163 ------------------------- hktool.1.in | 175 ++++++++++++++++++++++++++ hktool.c | 6 +- params.c | 399 ++++++++++++++++++++---------------------------------------- params.h | 10 +- 7 files changed, 332 insertions(+), 454 deletions(-) delete mode 100644 hktool.1 create mode 100644 hktool.1.in diff --git a/Makefile b/Makefile index 8871eaa..d460268 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION != git describe --tags 2>/dev/null || echo "0.1" PROG := hktool -MANPAGE := hktool.1 +MANPAGE := $(PROG).1 WARNINGS := -Wall -Wcast-align -Wcast-qual -Wextra -Wpedantic -Wformat=2 \ -Winit-self -Wmissing-prototypes -Wpointer-arith -Wshadow \ @@ -10,33 +10,37 @@ WARNINGS := -Wall -Wcast-align -Wcast-qual -Wextra -Wpedantic -Wformat=2 \ PKG_CONFIG ?= pkg-config LIBS := libusb-1.0 -CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_POSIX_C_SOURCE=200112L +CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_POSIX_C_SOURCE=200112L -DDATADIR=\"$(datarootdir)/$(PROG)\" CFLAGS = -std=c11 -O2 -flto $(WARNINGS) -MMD -MP $(shell $(PKG_CONFIG) --cflags $(LIBS)) LDFLAGS = -Wl,--as-needed -O2 -flto LDLIBS = $(shell $(PKG_CONFIG) --libs $(LIBS)) OBJ := hktool.o halfkay.o params.o util.o eprintf.o -PREFIX ?= /usr/local +prefix ?= /usr/local +exec_prefix ?= $(prefix) -bindir = /bin -datarootdir = /share -mandir = /man +bindir = $(exec_prefix)/bin +datarootdir = $(prefix)/share +mandir = $(datarootdir)/man +man1dir = $(mandir)/man1 -all: $(PROG) +all: $(PROG) $(MANPAGE) $(PROG): $(OBJ) +%: %.in + $(CPP) $(CPPFLAGS) $< > $@ debug: all debug: CFLAGS += -ggdb -Og -Werror debug: LDFLAGS += -ggdb -Og install: $(PROG) $(MANPAGE) - install -Dm755 -s $(PROG) -t $(DESTDIR)$(PREFIX)$(bindir) - install -Dm644 ./data/* -t $(DESTDIR)$(PREFIX)$(datarootdir)/$(PROG) - install -Dm644 $(MANPAGE) -t $(DESTDIR)$(PREFIX)$(mandir)/man1 + install -Dm755 -s $(PROG) -t $(DESTDIR)$(bindir) + install -Dm644 ./data/* -t $(DESTDIR)$(datarootdir)/$(PROG) + install -Dm644 $(MANPAGE) -t $(DESTDIR)$(man1dir) clean: - $(RM) $(OBJ) $(OBJ:.o=.d) $(PROG) + $(RM) $(OBJ) $(OBJ:.o=.d) $(PROG) $(MANPAGE) -include $(OBJ:.o=.d) diff --git a/halfkay.h b/halfkay.h index b7b6360..2d459e3 100644 --- a/halfkay.h +++ b/halfkay.h @@ -21,12 +21,7 @@ #ifndef HALFKAY_H #define HALFKAY_H -struct flashparams { - size_t memsz; - size_t blksz; - size_t cmdsz; - size_t addrshft; -}; +#include "params.h" int flash(const struct flashparams *fp, const char *file); int reboot(const struct flashparams *fp); diff --git a/hktool.1 b/hktool.1 deleted file mode 100644 index 3eb8bce..0000000 --- a/hktool.1 +++ /dev/null @@ -1,163 +0,0 @@ -'\" t -.TH "HKTOOL" "1" "2016-05-22" "hktool 0.1" "hktool Manual" - -.SH "NAME" -hktool \- a simple HalfKay protocol flashing tool - -.SH "SYNOPSIS" -.BR hktool\ [ -hlvr ] -.RB [ -f -.IR file ] -.RB [ -- ] -.I mcu - -.SH "DESCRIPTION" -hktool is a HalfKay protocol flashing tool. hktool is currently only able to -flash to one connected device at a time, if multiple devices are connected, -only one will be flashed. hktool is designed to flash raw binary data and NOT -intel hex files. Converting from intel hex files to binary data can be easily -done with -.BR objcopy (1). -The main advantages of hktool over the teensy loader command line tool is that -devices are not hard coded, additionally, the command line interface is -noticeably simpler. - -.SH "OPTIONS" -.BI \-f\ file -.RS -Flash specified binary file to the device. Specifying '-' as the file name -causes hktool to read input from stdin. -.RE - -.B \-h -.RS -Show help. -.RE - -.B \-l -.RS -Show a list of supported devices. -.RE - -.B \-v -.RS -Show version and license information. -.RE - -.B \-r -.RS -Reboot device (if specified with -f, will happen after flashing). -.RE - -.SH "NOTES" -.SS Device parameter files -The list of devices that hktool can flash can be configured, either by creating -device parameter file and passing it to hktool as a relative path in the mcu -argument, or by adding more device parameter files to the hktool data -directories. - -hktool searches for data in the hktool subdirectory of any directories found in -the XDG_DATA_DIRS environment variable (which should be a colon delimited list -of directories), if this variable is not set or empty then hktool proceeds as -if XDG_DATA_DIRS was set to "/usr/local/share:/usr/local". Device parameter -files should bear the name of the device and should be located directly in the -hktool subdirectory of the aforementioned locations. If two or more files are -found to have the same name, the file which was found first will be used. -Directories are processed in the order that they appear in the XDG_DATA_DIRS -environment variable. - -The format of the device parameter files is very simple. These files should -consist of only one line detailing the flashing parameters and optionally the -canonical board name. The files are formatted as such: - -.RS 4 -.I memory_size block_size command_size address_shift -.RI [ board_name ] -.RE - -For example, to create a file for the Teensy 3.1 place a file with the name -"MK20DX256" in one of the aforementioned locations and include the contents: - -.RS 4 -0x40000 1024 64 0 Teensy 3.1 -.RE - -This would describe a Teensy 3.1 which hosts MK20DX256 MCU with a memory size -of 262144 bytes, memory block size of 1024 bytes, HalfKay transfer prefix size -of 64 bytes with no shift applied to the write address. (Also note: the board -name can be multiple words in length.) - -The table below shows the details for all the Teensy boards as of writing of -this man page. - -.TS -box; -lb lb rb rb rb rb -l l r r r r . -Chip Board Memory Block Prefix Shift -AT90USB162 Teensy 1.0 0x3e00 128 2 0 -AT90USB646 Teensy++ 1.0 0xfc00 256 2 8 -AT90USB1286 Teensy++ 2.0 0x1fc00 256 2 8 -ATMEGA32U4 Teensy 2.0 0x7e00 128 2 0 -MK20DX128 Teensy 3.0 0x20000 1024 64 0 -MK20DX256 Teensy 3.1 0x40000 1024 64 0 -MK64FX512 Teensy 3.5 0x100000 1024 64 0 -MK66FX1M0 Teensy 3.6 0x80000 1024 64 0 -MKL26Z64 Teensy LC 0xf800 512 64 0 -.TE - -.SS Unprivileged flashing -To be able to flash as an unprivileged user, udev must be configured correctly, -the rules recommended by PJRC can be found at: -\%http://www.pjrc.com/teensy/49-teensy.rules - -.SS Converting from intel hex to binary -Converting from an intel hex file to a binary file is very simple with the use -of the -.BR objcopy (1) -program: - -.RS 4 -objcopy -I ihex -O binary in.hex out.bin -.RE - -.SH "BUGS" -If multiple devices are connected at the same time, the device which will be -flashed is unspecified. - -Providing unusual but valid flashing parameters to hktool will cause it to exit -(usually from an allocation failure). This is unlikely to happen during correct -operation. - -If you find any other bugs, please report them to hktool.bugs@the-tk.com - -.SH "FILES" -.TP -.I /etc/hktoolrc -System device list configuration file. -.TP -.IR $XDG_CONFIG_HOME/hktoolrc " or " ~/.config/hktoolrc -User device list configuration file (XDG will be preferred). - -.SH "EXAMPLES" -hktool -f blink.bin MK20DX256 -.RS -Flash the file "blink.bin" to a connected Teensy 3.1 board which is currently -in HalfKay bootloader mode. -.RE - -hktool -r ATMEGA32U4 -.RS -Reboot a connected Teensy 2.0 board which is currently in HalfKay bootloader -mode. -.RE - -hktool -f prog.bin -r MKL26Z64 -.RS -Flash the file "prog.bin" to a connected Teensy LC board which is currently in -HalfKay bootloader mode and then reboot the device out of bootloader mode. -.RE - -.SH "SEE ALSO" -.BR objcopy (1), -.BR udev (7) diff --git a/hktool.1.in b/hktool.1.in new file mode 100644 index 0000000..4171db1 --- /dev/null +++ b/hktool.1.in @@ -0,0 +1,175 @@ +'\" t +.TH "HKTOOL" "1" "2017-05-22" "hktool 0.1" "hktool Manual" + +.SH "NAME" +hktool \- a simple HalfKay protocol flashing tool + +.SH "SYNOPSIS" +.BR hktool\ [ -hilvr ] +.RB [ -f +.IR file ] +.RB [ -- ] +.I mcu + +.SH "DESCRIPTION" +hktool is a HalfKay protocol flashing tool. hktool is currently only able to +flash to one connected device at a time, if multiple devices are connected, +only one will be flashed. hktool is designed to flash raw binary data and NOT +intel hex files. Converting from intel hex files to binary data can be easily +done with +.BR objcopy (1). +The main advantages of hktool over the teensy loader command line tool is that +the list of devices which can be flashed is not hard coded, additionally, the +command line interface is noticeably simpler. + +.SH "OPTIONS" +.BI \-f\ file +.RS +Flash specified binary file to the device. Specifying '-' as the file name +causes hktool to read input from stdin (provide a relative or absolute path if +you wish to flash a file named '-'). +.RE + +.B \-h +.RS +Show help. +.RE + +.B \-i +.RS +Show detailed device information. +.RE + +.B \-l +.RS +Show a list of supported devices. +.RE + +.B \-v +.RS +Show version and license information. +.RE + +.B \-r +.RS +Reboot device (if specified with -f, will happen after flashing). +.RE + +.SH "NOTES" +.SS Device parameter files +The list of devices that hktool can flash can be configured, either by creating +device parameter file and passing it to hktool as a relative path in the mcu +argument, or by adding more device parameter files to the hktool data +directories. + +hktool searches for parameter files in the directory specified in the +HKTOOL_DATADIR environment variable. If this variable is not set or empty, then +hktool proceeds as if HKTOOL_DATADIR was set to DATADIR. Device parameter files +should bear the name of the device and should be located directly inside the +search directory. + +"hktool searches for data in the hktool subdirectory of any directories found in +"the XDG_DATA_DIRS environment variable (which should be a colon delimited list +"of directories), if this variable is not set or empty then hktool proceeds as +"if XDG_DATA_DIRS was set to "/usr/local/share:/usr/local". Device parameter +"files should bear the name of the device and should be located directly in the +"hktool subdirectory of the aforementioned locations. If two or more files are +"found to have the same name, the file which was found first will be used. +"Directories are processed in the order that they appear in the XDG_DATA_DIRS +"environment variable. + +The format of the device parameter files is very simple. These files should +consist of only one line detailing the flashing parameters and optionally the +canonical board name. The files are formatted as such: + +.RS 4 +.I memory_size block_size command_size address_shift +.RI [ board_name ] +.RE + +For example, to create a file for the Teensy 3.1 place a file with the name +"MK20DX256" in one of the aforementioned locations and include the contents: + +.RS 4 +0x40000 1024 64 0 Teensy 3.1 +.RE + +This would describe a Teensy 3.1 which hosts MK20DX256 MCU with a memory size +of 262144 bytes, memory block size of 1024 bytes, HalfKay transfer prefix size +of 64 bytes with no shift applied to the write address. (Also note: the board +name can be multiple words in length.) + +The table below shows the details for all the Teensy boards as of writing of +this man page. + +.TS +box; +lb lb rb rb rb rb +l l r r r r . +Chip Board Memory Block Prefix Shift +AT90USB162 Teensy 1.0 0x3e00 128 2 0 +AT90USB646 Teensy++ 1.0 0xfc00 256 2 8 +AT90USB1286 Teensy++ 2.0 0x1fc00 256 2 8 +ATMEGA32U4 Teensy 2.0 0x7e00 128 2 0 +MK20DX128 Teensy 3.0 0x20000 1024 64 0 +MK20DX256 Teensy 3.1 0x40000 1024 64 0 +MK64FX512 Teensy 3.5 0x100000 1024 64 0 +MK66FX1M0 Teensy 3.6 0x80000 1024 64 0 +MKL26Z64 Teensy LC 0xf800 512 64 0 +.TE + +.SS Unprivileged flashing +To be able to flash as an unprivileged user, udev must be configured correctly, +the rules recommended by PJRC can be found at: +\%http://www.pjrc.com/teensy/49-teensy.rules + +.SS Converting from intel hex to binary +Converting from an intel hex file to a binary file is very simple with the use +of the +.BR objcopy (1) +program: + +.RS 4 +objcopy -I ihex -O binary in.hex out.bin +.RE + +.SH "BUGS" +If multiple devices are connected at the same time, the device which will be +flashed is unspecified. + +Providing unusual but valid flashing parameters to hktool will cause it to exit +(usually from an allocation failure). This is unlikely to happen during correct +operation. + +If you find any other bugs, please report them to hktool.bugs@the-tk.com + +.SH "FILES" +.TP +.I /etc/hktoolrc +System device list configuration file. +.TP +.IR $XDG_CONFIG_HOME/hktoolrc " or " ~/.config/hktoolrc +User device list configuration file (XDG will be preferred). + +.SH "EXAMPLES" +hktool -f blink.bin MK20DX256 +.RS +Flash the file "blink.bin" to a connected Teensy 3.1 board which is currently +in HalfKay bootloader mode. +.RE + +hktool -r ATMEGA32U4 +.RS +Reboot a connected Teensy 2.0 board which is currently in HalfKay bootloader +mode. +.RE + +hktool -f prog.bin -r MKL26Z64 +.RS +Flash the file "prog.bin" to a connected Teensy LC board which is currently in +HalfKay bootloader mode and then reboot the device out of bootloader mode. +.RE + +.SH "SEE ALSO" +.BR objcopy (1), +.BR udev (7) diff --git a/hktool.c b/hktool.c index dad7915..cee133e 100644 --- a/hktool.c +++ b/hktool.c @@ -81,7 +81,7 @@ int main(int argc, char **argv) return EXIT_SUCCESS; break; case 'l': - listparams(); + getparams(NULL, NULL); return EXIT_SUCCESS; break; case 'v': @@ -109,8 +109,8 @@ int main(int argc, char **argv) if (argc - optind > 1) eprintf("Invalid number of arguments\nUsage: %s %s", argv[0], usage); - if (getparams(&fp, argv[optind]) != 0) - return EXIT_FAILURE; + if (getparams(&fp, argv[optind]) == false) + eprintf("Could not find flash parameters for '%s'", argv[optind]); if (doflash) if (flash(&fp, flashfile) != 0) diff --git a/params.c b/params.c index 3fe324c..08272d6 100644 --- a/params.c +++ b/params.c @@ -18,18 +18,18 @@ */ #include -#include #include #include +#include +#include +#include #include #include #include #include -#include -#include +#include +#include -#include "halfkay.h" -/*#include "log.h"*/ #include "eprintf.h" #include "params.h" #include "util.h" @@ -37,305 +37,168 @@ /* TODO: make this dynamic */ #define SZMAX_PFILE 1024 -struct params { - char *chip; - char *board; - struct flashparams fp; -}; - -static int paramc = 0; -static struct params *paramv = NULL; - -/* addparams: add a param definition to the param list */ -static void addparams(struct params *p) -{ - static int avail = 1; - - for (int i = 0; i < paramc; i++) { - if (xstrcasecmp(paramv[i].chip, p->chip) != 0) - continue; - return; - } - - if (paramc >= avail - 1) { - avail *= 2; - if ((unsigned)avail >= INT_MAX / 2 / sizeof *paramv) - eprintf("Too many parameter files (%d)", paramc); - paramv = erealloc(paramv, avail * sizeof *paramv); - } - - paramv[paramc].chip = estrdup(p->chip); - paramv[paramc].board = p->board != NULL ? estrdup(p->board) : NULL; - paramv[paramc].fp = p->fp; - paramc++; -} - -static void freeparams(struct params *p) -{ - free(p->chip); - free(p->board); - free(p); -} - -/* atosz: convert string to size_t */ -static int atosz(size_t *size, char *str) -{ - unsigned long long val; - char *endptr; - - assert(size); - assert(str); - - /* for some silly reason strtoull actually allows negatives */ - if (str[0] == '-') - return -1; - - errno = 0; - val = strtoull(str, &endptr, 0); - if (errno || *endptr) - return -1; - - if (val > SIZE_MAX) - return -1; - - *size = val; +#ifndef DATADIR +#define DATADIR "hktool" +#endif - return 0; -} - -/* TODO: remove the need for freeparams by not allocating this */ /* readparams: read a file's param definition */ -static struct params *readparams(const char *file) +static void readparams(struct flashparams *fp, const char *file) { - const char *chip, *board; - struct flashparams fp; - struct params *par; + char cont[SZMAX_PFILE], *pos; size_t contsz; - char cont[SZMAX_PFILE], *tok; FILE *f; assert(file); - - chip = file; - for (size_t i = 0; i < strlen(file); i++) - if (file[i] == '/') - chip = &file[i + 1]; - - assert(chip[0]); + assert(fp); f = fopen(file, "r"); - if (f == NULL) { - weprintf("Could not open '%s':", file); - NULL; - } + if (f == NULL) + eprintf("Could not open '%s':", file); contsz = fread(cont, 1, SZMAX_PFILE, f); - if (contsz >= sizeof cont) { - weprintf("Parameter file '%s' is longer than %zu", file, - sizeof cont - 1); - contsz = sizeof cont - 1; - } - for (size_t i = 0; i < contsz; i++) { - if (cont[i] == '\0') { - weprintf("Parameter file '%s' contains null byte", file); - cont[i] = ' '; - } else if (isspace(cont[i]) || !isprint(cont[i])) { - cont[i] = ' '; + if (contsz >= sizeof cont) + eprintf("Parameter file '%s' is longer than %zu", file, sizeof cont - 1); + + pos = cont; + for (int i = 0; i < 4; i++) { + char *end; + unsigned long long val; + + errno = 0; + val = strtoull(pos, &end, 0); + if (pos == end) + eprintf("Parameter file '%s' is malformed (offset:%zd not a number)", file, pos - cont); + pos = end; + + if (errno == ERANGE || val > SIZE_MAX) + eprintf("Parameter file '%s' is malformed (offset:%zd number too large)", file, pos - cont); + + switch (i) { + case 0: fp->memsz = val; break; + case 1: fp->blksz = val; break; + case 2: fp->cmdsz = val; break; + case 3: fp->addrshft = val; break; } } - cont[contsz] = '\0'; - - tok = strtok(cont, " "); - if (tok == NULL) - goto fail; - if (atosz(&fp.memsz, tok) != 0) - goto fail; - - tok = strtok(NULL, " "); - if (tok == NULL) - goto fail; - if (atosz(&fp.blksz, tok) != 0) - goto fail; - - tok = strtok(NULL, " "); - if (tok == NULL) - goto fail; - if (atosz(&fp.cmdsz, tok) != 0) - goto fail; - - tok = strtok(NULL, " "); - if (tok == NULL) - goto fail; - if (atosz(&fp.addrshft, tok) != 0) - goto fail; - - board = strtok(NULL, ""); - - par = emalloc(sizeof *par); - par->chip = estrdup(chip); - par->board = board != NULL ? estrdup(board) : NULL; - par->fp = fp; - -fail: - if (par == NULL) - weprintf("Parameter file '%s' is malformed", file); - fclose(f); - return par; + fclose(f); } -/* getdirs: returns a NULL terminated list of data paths */ -static char **getdirs(void) +static void printcname(const char *file) { - static const char *globsuffix = "/hktool/*"; - char **dirs, *xddirs, *tok; - int len = 0, avail = 1; - - xddirs = getenv("XDG_DATA_DIRS"); - if (!xddirs || !*xddirs) - xddirs = "/usr/local/share:/usr/share"; - xddirs = estrdup(xddirs); + bool wasspace; + FILE *f; + int c, field; - dirs = emalloc(sizeof *dirs); + assert(file); - for (char *s = xddirs; tok = strtok(s, ":"), tok != NULL; s = NULL) { - size_t slen; + f = fopen(file, "r"); + if (f == NULL) { + printf(": Malformed file '%s'", file); + return; + } - if (tok[0] == '\\') + field = 0; + wasspace = false; + while (c = fgetc(f), c != EOF) { + if (isspace(c)) { + wasspace = true; continue; - - if (len >= avail - 1) { - avail *= 2; - if ((unsigned)avail >= INT_MAX / 2 / sizeof *dirs) - eprintf("Too many data dirs (%d)", len); - dirs = erealloc(dirs, avail * sizeof *dirs); } - - if (SIZE_MAX - (strlen(tok) + 1) < strlen(globsuffix)) - eprintf("Data dir too long (\"%.20s\")", tok); - slen = strlen(tok) + strlen(globsuffix) + 1; - dirs[len] = emalloc(slen); - snprintf(dirs[len], slen, "%s%s", tok, globsuffix); - len++; + if (wasspace) { + wasspace = false; + field++; + } + if (field >= 4) { + ungetc(c, f); + break; + } } - free(xddirs); - - dirs[len++] = NULL; - dirs = erealloc(dirs, len * sizeof *dirs); - - return dirs; -} - -/* freedirs: frees list returned by getdirs */ -static void freedirs(char **dirs) -{ - assert(dirs); + if (c == EOF) + return; - for (size_t i = 0; dirs[i]; i++) - free(dirs[i]); - free(dirs); + printf(": "); + while (c = fgetc(f), c != EOF) + if (c != '\n') + putchar(c); } -/* loadparams: locate and load all param files */ -static void loadparams(void) +/* getparams: Locate a parameter file and load it or show names of all files */ +bool getparams(struct flashparams *fp, const char *name) { - char **dirs; - glob_t globbuf; - - if (paramv != NULL) - return; - - dirs = getdirs(); - - for (int i = 0; dirs[i]; i++) { - int ret; - - ret = glob(dirs[i], i != 0 ? GLOB_APPEND : 0, NULL, &globbuf); - if (ret == GLOB_NOSPACE) - eprintf("glob ran out of memory"); - if (ret == GLOB_NOMATCH) - continue; - if (ret == GLOB_ABORTED) { - weprintf("A call to glob resulted in a read error"); - continue; + char pathbuf[PATH_MAX], *dirname, *fullpath; + struct dirent *de; + size_t pathsize; + bool found; + DIR *dir; + + assert((fp == NULL && name == NULL) || (fp != NULL && name != NULL)); + + fullpath = pathbuf; + pathsize = sizeof pathbuf; + + dirname = getenv("HKTOOL_DATADIR"); + if (dirname == NULL || strlen(dirname) == 0) + dirname = DATADIR; + + dir = opendir(dirname); + if (dir == NULL) + eprintf("Could not open directory '%s':", dirname); + + if (name == NULL) + printf("Searching '%s' for Device Parameter Files:\n", dirname); + + found = false; + while (errno = 0, de = readdir(dir), de != NULL) { + bool ismatch, doprint; + + doprint = name == NULL; + if (doprint) + ismatch = strcmp(de->d_name, name) == 0; + else + ismatch = false; + + if (doprint || ismatch) { + int size; + + size = snprintf(NULL, 0, "%s/%s", dirname, de->d_name); + assert(size > 0); + if ((size_t)size > pathsize) { + if (fullpath == pathbuf) + fullpath = NULL; + fullpath = erealloc(fullpath, size); + pathsize = size; + } + size = snprintf(fullpath, pathsize, "%s/%s", dirname, de->d_name); + assert(size > 0); + assert((size_t)size < pathsize); } - } - freedirs(dirs); - - for (size_t i = 0; i < globbuf.gl_pathc; i++) { - struct params *par; - par = readparams(globbuf.gl_pathv[i]); - if (par == NULL) + if (doprint) { + printf("%s", de->d_name); + printcname(fullpath); + putchar('\n'); continue; - addparams(par); - freeparams(par); - } - - globfree(&globbuf); -} - -static int b16len(size_t n) -{ - return snprintf(NULL, 0, "%zx", n); -} - -/* listparams: display a list of found parameter files */ -void listparams(void) -{ - int lengths[5] = { 0 }; - - loadparams(); + }; - for (int i = 0; i < paramc; i++) { - int clengths[5]; + if (!ismatch) + continue; - clengths[0] = strlen(paramv[i].chip); - clengths[1] = b16len(paramv[i].fp.memsz); - clengths[2] = b16len(paramv[i].fp.blksz); - clengths[3] = b16len(paramv[i].fp.cmdsz); - clengths[4] = b16len(paramv[i].fp.addrshft); - for (int j = 0; j < 5; j++) - if (clengths[j] > lengths[j]) - lengths[j] = clengths[j]; + readparams(fp, fullpath); + found = true; + errno = 0; + break; } + if (errno) + weprintf("Could not read directory '%s':", dirname); - for (int i = 0; i < paramc; i++) - printf("%-*s - (0x%.*zx 0x%.*zx 0x%.*zx 0x%.*zx) %s\n", - lengths[0], paramv[i].chip, - lengths[1], paramv[i].fp.memsz, lengths[2], paramv[i].fp.blksz, - lengths[3], paramv[i].fp.cmdsz, lengths[4], paramv[i].fp.addrshft, - paramv[i].board != NULL ? paramv[i].board : ""); -} - -/* getparams: return the flash params for the specified MCU */ -int getparams(struct flashparams *fp, const char *mcufile) -{ - assert(fp); - assert(mcufile); - - loadparams(); - - if (strchr(mcufile, '/') != NULL) { - struct params *par; - par = readparams(mcufile); - if (par == NULL) - return -1; - *fp = par->fp; - freeparams(par); - return 0; - } - - for (int i = 0; i < paramc; i++) { - if (xstrcasecmp(paramv[i].chip, mcufile) == 0) { - *fp = paramv[i].fp; - return 0; - } - } + if (fullpath != pathbuf) + free(fullpath); - weprintf("'%s' is not a valid MCU name", mcufile); + if (closedir(dir) == -1) + eprintf("Could not close directory '%s':", dirname); - return -1; + return found; } diff --git a/params.h b/params.h index 069d4fd..6417063 100644 --- a/params.h +++ b/params.h @@ -20,9 +20,13 @@ #ifndef PARAMS_H #define PARAMS_H -#include "halfkay.h" +struct flashparams { + size_t memsz; + size_t blksz; + size_t cmdsz; + size_t addrshft; +}; -void listparams(void); -int getparams(struct flashparams *fp, const char *mcufile); +bool getparams(struct flashparams *fp, const char *name); #endif /* PARAMS_H */ -- cgit v1.2.3-54-g00ecf