diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d413cfe4..00b5231b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -53,6 +53,7 @@ jobs: libftdi1-dev libreadline-dev libserialport-dev + libgpiod-dev texinfo texlive texi2html @@ -96,6 +97,7 @@ jobs: libftdi1-dev libreadline-dev libserialport-dev + libgpiod-dev texinfo texlive texi2html @@ -163,6 +165,7 @@ jobs: libftdi1-dev:${{matrix.arch}} libreadline-dev:${{matrix.arch}} libserialport-dev:${{matrix.arch}} + libgpiod-dev:${{matrix.arch}} - name: Configure run: >- cmake @@ -214,11 +217,12 @@ jobs: libftdi readline libserialport + pkg-config - name: Configure run: >- cmake - -D CMAKE_C_FLAGS=-I/usr/local/include - -D CMAKE_EXE_LINKER_FLAGS=-L/usr/local/Cellar + -D CMAKE_C_FLAGS=-I/opt/homebrew/include + -D CMAKE_EXE_LINKER_FLAGS=-L/opt/homebrew/Cellar -D DEBUG_CMAKE=1 -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -B build @@ -241,6 +245,39 @@ jobs: build/src/avrdude build/src/avrdude.conf + macos-x86_64_autotools: + runs-on: macos-latest + steps: + - uses: actions/checkout@v3 + - name: Install prerequisites + run: >- + # brew update + + brew install + automake + autoconf + libtool + gettext + flex + bison + libelf + libusb + hidapi + libftdi + readline + libserialport + pkg-config + - name: Configure + run: >- + ./src/bootstrap + + mkdir _ambuild && cd _ambuild + + CFLAGS="-I/opt/homebrew/include" LDFLAGS="-L/opt/homebrew/lib" ../src/configure + + - name: Build + run: make -C _ambuild -j$(nproc) + msvc: runs-on: windows-latest strategy: diff --git a/CMakeLists.txt b/CMakeLists.txt index e8bcfbff..f0394759 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -126,7 +126,6 @@ if(USE_STATIC_LIBS) set(PREFERRED_LIBFTDI1 libftdi1.a ftdi1) set(PREFERRED_LIBREADLINE libreadline.a readline) set(PREFERRED_LIBSERIALPORT libserialport.a serialport) - set(PREFERRED_LIBGPIOD libgpiod.a gpiod) else() set(PREFERRED_LIBELF elf) set(PREFERRED_LIBUSB usb) @@ -136,7 +135,6 @@ else() set(PREFERRED_LIBFTDI1 ftdi1) set(PREFERRED_LIBREADLINE readline) set(PREFERRED_LIBSERIALPORT serialport) - set(PREFERRED_LIBGPIOD gpiod) endif() # ------------------------------------- @@ -237,12 +235,48 @@ if(HAVE_LIBSERIALPORT) endif() # ------------------------------------- -# Find libgpiod, if needed +# Find libgpiod using pkg-config, if needed if(HAVE_LINUXGPIO) - find_library(HAVE_LIBGPIOD NAMES ${PREFERRED_LIBGPIOD}) - if(HAVE_LIBGPIOD) - set(LIB_LIBGPIOD ${HAVE_LIBGPIOD}) - set(CMAKE_REQUIRED_LIBRARIES ${LIB_LIBGPIOD}) + # defaults/fallbacks + set(HAVE_LIBGPIOD 0) + set(HAVE_LIBGPIOD_V2 0) + set(HAVE_LIBGPIOD_V1_6 0) + + find_package(PkgConfig) + if(PKG_CONFIG_FOUND) + # check whether we have version >= 2.0 + message(STATUS "Checking for module 'libgpiod'...") + pkg_check_modules(LIBGPIODV2 QUIET libgpiod>=2.0) + if(LIBGPIODV2_FOUND) + message(STATUS "Found module 'libgpiod' (found version \"${LIBGPIODV2_VERSION}\")") + set(HAVE_LIBGPIOD 1) + set(HAVE_LIBGPIOD_V2 1) + set(CMAKE_REQUIRED_LIBRARIES ${LIBGPIODV2_LIBRARIES}) + set(LIB_LIBGPIOD ${LIBGPIODV2_LINK_LIBRARIES}) + else() + # check whether we have version >= 1.6 + pkg_check_modules(LIBGPIODV1_6 QUIET libgpiod>=1.6) + if(LIBGPIODV1_6_FOUND) + message(STATUS "Found module 'libgpiod' (found version \"${LIBGPIODV1_6_VERSION}\")") + set(HAVE_LIBGPIOD 1) + set(HAVE_LIBGPIOD_V1_6 1) + set(CMAKE_REQUIRED_LIBRARIES ${LIBGPIODV1_6_LIBRARIES}) + set(LIB_LIBGPIOD ${LIBGPIODV1_6_LINK_LIBRARIES}) + else() + # check whether we have at least an older version + pkg_check_modules(LIBGPIOD QUIET libgpiod) + if(LIBGPIOD_FOUND) + message(STATUS "Found module 'libgpiod' (found version \"${LIBGPIOD_VERSION}\")") + set(HAVE_LIBGPIOD 1) + set(CMAKE_REQUIRED_LIBRARIES ${LIBGPIOD_LIBRARIES}) + set(LIB_LIBGPIOD ${LIBGPIOD_LINK_LIBRARIES}) + else() + message(STATUS "Could not find module 'libgpiod', proceeding without.") + endif() + endif() + endif() + else() + message(WARNING "For using libgpiod, pkg-config would be required which is not available.") endif() endif() @@ -351,7 +385,9 @@ if (DEBUG_CMAKE) message(STATUS "HAVE_LIBUSB_1_0_LIBUSB_H: ${HAVE_LIBUSB_1_0_LIBUSB_H}") message(STATUS "HAVE_HIDAPI_HIDAPI_H: ${HAVE_HIDAPI_HIDAPI_H}") message(STATUS "LIBUSB_COMPAT_DIR: ${LIBUSB_COMPAT_DIR}") - message(STATUS "HAVE_LIBGPIOD: ${HAVE_LIBGPIOD}") + message(STATUS "LIBGPIODV2_FOUND: ${LIBGPIODV2_FOUND}") + message(STATUS "LIBGPIODV1_6_FOUND: ${LIBGPIODV1_6_FOUND}") + message(STATUS "LIBGPIOD_FOUND: ${LIBGPIOD_FOUND}") message(STATUS "----------------------") endif() @@ -421,8 +457,12 @@ endif() if(HAVE_LINUXGPIO) message(STATUS "ENABLED linuxgpio") - if (HAVE_LIBGPIOD) - message(STATUS "DO HAVE libgpiod") + if (LIBGPIODV2_FOUND) + message(STATUS "DO HAVE libgpiod (${LIBGPIODV2_VERSION})") + elseif(LIBGPIODV1_6_FOUND) + message(STATUS "DO HAVE libgpiod (${LIBGPIODV1_6_VERSION})") + elseif(LIBGPIOD_FOUND) + message(STATUS "DO HAVE libgpiod (${LIBGPIOD_VERSION})") else() message(STATUS "DON'T HAVE libgpiod") endif() diff --git a/NEWS b/NEWS index 5d092f75..75d71733 100644 --- a/NEWS +++ b/NEWS @@ -20,8 +20,13 @@ Changes since version 7.3: - Old avrdude_message() can go away #1719 - avr_{read,write}_mem fail to initialize progress reporting #1718 - avr*timestamp() oddities #1722 - - -F option not honored bug #1740 + - -F option not honored bug #1740 - "jtag2 is not a unique start of a programmer name" #1739 + - Regression: EEPROM issue with official STK500 V1 FW #1713 + - usbasp_write_byte in TPI mode not implemented #1755 + - Remove calls to exit() from libavrdude library #774 + - cmake enabling LINUXGPIO on ubuntu 20.04 fails #1782 + - macOS github action failed. #1793 * Pull requests: - Remove 32bit MSYS2 mingw32 and clang32 build #1687 @@ -48,6 +53,18 @@ Changes since version 7.3: - Consult -F option when signature cannot be read #1745 - Check all programmer ids for exact match #1746 - Update avrintel files #1747 + - Add buspirate hiz and pullups feature #1733 + - Add support for libgpiod v2+ API #1725 + - Remove deprecated ucr2 part #1749 + - Make programmers libavrdude ready #1750, 1752, 1756 ... 1786 + - Make default EEPROM readback 0xff for STK500 v1 #1753 + - Silence gcc warning when printf format is "" #1754 + - Remove calls to exit() from libavrdude library #1790 + - Include libgpiod-dev in build.yml for Linux builds #1788 + - linuxgpio: add support for libgpiod v1.4 #1792 + - Use magic memory tree interface throughout #1795 + - Silence MacOS compiler warning #1794 + - Add macOS autotools to github action #1798 * Internals: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ba59ec51..d4e89988 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -80,7 +80,7 @@ if(MSVC) list(APPEND EXTRA_WINDOWS_INCLUDES "msvc") else() set(LIB_MATH m) - add_compile_options(-Wall -Wextra -Wno-unused-parameter) + add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-format-zero-length) endif() # ===================================== diff --git a/src/Makefile.am b/src/Makefile.am index f477ac41..f90b82c8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -62,10 +62,10 @@ libavrdude_la_CPPFLAGS = $(libavrdude_a_CPPFLAGS) avrdude_CFLAGS = @ENABLE_WARNINGS@ -libavrdude_a_CFLAGS = @ENABLE_WARNINGS@ +libavrdude_a_CFLAGS = @ENABLE_WARNINGS@ $(LIBGPIOD_CFLAGS) libavrdude_la_CFLAGS = $(libavrdude_a_CFLAGS) -avrdude_LDADD = $(top_builddir)/$(noinst_LIBRARIES) @LIBUSB_1_0@ @LIBHIDAPI@ @LIBUSB@ @LIBFTDI1@ @LIBFTDI@ @LIBHID@ @LIBELF@ @LIBPTHREAD@ @LIBSERIALPORT@ -lm +avrdude_LDADD = $(top_builddir)/$(noinst_LIBRARIES) @LIBUSB_1_0@ @LIBHIDAPI@ @LIBUSB@ @LIBFTDI1@ @LIBFTDI@ @LIBHID@ @LIBELF@ @LIBPTHREAD@ @LIBSERIALPORT@ $(LIBGPIOD_LIBS) -lm bin_PROGRAMS = avrdude diff --git a/src/avr.c b/src/avr.c index d142e10d..7125a4a2 100644 --- a/src/avr.c +++ b/src/avr.c @@ -38,7 +38,7 @@ FP_UpdateProgress update_progress; #define DEBUG 0 -/* TPI: returns 1 if NVM controller busy, 0 if free */ +/* TPI: returns nonzero if NVM controller busy, 0 if free */ int avr_tpi_poll_nvmbsy(const PROGRAMMER *pgm) { unsigned char cmd; unsigned char res; @@ -471,7 +471,7 @@ int avr_read_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, con if (mem_is_signature(mem)) { if (pgm->read_sig_bytes) { int rc = pgm->read_sig_bytes(pgm, p, mem); - if (rc < 0) + if (rc < 0 && rc != LIBAVRDUDE_EXIT) led_set(pgm, LED_ERR); led_clr(pgm, LED_PGM); return rc; @@ -1083,7 +1083,7 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int return LIBAVRDUDE_GENERAL_FAILURE; } - uint8_t *spc = cfg_malloc(__func__, cm->page_size); + uint8_t *spc = mmt_malloc(cm->page_size); // Set cwsize as rounded-up wsize int cwsize = (wsize + pgsize-1)/pgsize*pgsize; @@ -1158,7 +1158,7 @@ int avr_write_mem(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, int } avr_free_mem(cm); - free(spc); + mmt_free(spc); if (!failure) { led_clr(pgm, LED_PGM); @@ -1236,13 +1236,13 @@ int avr_signature(const PROGRAMMER *pgm, const AVRPART *p) { if(verbose > 1) report_progress(0, 1, "Reading"); rc = avr_read(pgm, p, "signature", 0); - if (rc < LIBAVRDUDE_SUCCESS) { + if (rc < LIBAVRDUDE_SUCCESS && rc != LIBAVRDUDE_EXIT) { pmsg_error("unable to read signature data for part %s, rc=%d\n", p->desc, rc); return rc; } report_progress(1, 1, NULL); - return LIBAVRDUDE_SUCCESS; + return rc < LIBAVRDUDE_SUCCESS? LIBAVRDUDE_EXIT: LIBAVRDUDE_SUCCESS; } @@ -1539,7 +1539,7 @@ int avr_get_mem_type(const char *str) { return avr_mem_order[i].type; if(!avr_mem_order[i].str) { pmsg_warning("avr_mem_order[] does not know %s; add to array and recompile\n", str); - avr_mem_order[i].str = cfg_strdup(__func__, str); + avr_mem_order[i].str = mmt_strdup(str); return avr_mem_order[i].type; } } diff --git a/src/avr910.c b/src/avr910.c index 600cc249..1cc28f18 100644 --- a/src/avr910.c +++ b/src/avr910.c @@ -50,23 +50,40 @@ struct pdata unsigned int buffersize; unsigned char test_blockmode; unsigned char use_blockmode; + + int ctype; // Cache one byte for flash + unsigned char cvalue; + unsigned long caddr; }; #define PDATA(pgm) ((struct pdata *)(pgm->cookie)) -static void avr910_setup(PROGRAMMER * pgm) -{ - if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) { - pmsg_error("out of memory allocating private data\n"); - exit(1); - } - memset(pgm->cookie, 0, sizeof(struct pdata)); +// Print error and return when command failed +#define EI(x) do { \ + int Eret = (x); \ + if(Eret < 0) { \ + pmsg_error("%s failed\n", #x); \ + return -1; \ + } \ +} while(0) + +#define EV(x) do { \ + int Eret = (x); \ + if(Eret < 0) { \ + pmsg_error("%s failed\n", #x); \ + return; \ + } \ +} while(0) + + +static void avr910_setup(PROGRAMMER * pgm) { + pgm->cookie = mmt_malloc(sizeof(struct pdata)); PDATA(pgm)->test_blockmode = 1; } -static void avr910_teardown(PROGRAMMER * pgm) -{ - free(pgm->cookie); +static void avr910_teardown(PROGRAMMER * pgm) { + mmt_free(pgm->cookie); + pgm->cookie = NULL; } @@ -76,14 +93,7 @@ static int avr910_send(const PROGRAMMER *pgm, char *buf, size_t len) { static int avr910_recv(const PROGRAMMER *pgm, char *buf, size_t len) { - int rv; - - rv = serial_recv(&pgm->fd, (unsigned char *)buf, len); - if (rv < 0) { - pmsg_error("programmer is not responding\n"); - return 1; - } - return 0; + return serial_recv(&pgm->fd, (unsigned char *) buf, len); } @@ -95,11 +105,12 @@ static int avr910_drain(const PROGRAMMER *pgm, int display) { static int avr910_vfy_cmd_sent(const PROGRAMMER *pgm, char *errmsg) { char c; - avr910_recv(pgm, &c, 1); + EI(avr910_recv(pgm, &c, 1)); if (c != '\r') { - pmsg_error("programmer did not respond to command: %s\n", errmsg); - return 1; + pmsg_error("protocol error for command: %s\n", errmsg); + return -1; } + return 0; } @@ -108,7 +119,7 @@ static int avr910_vfy_cmd_sent(const PROGRAMMER *pgm, char *errmsg) { * issue the 'chip erase' command to the AVR device */ static int avr910_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { - avr910_send(pgm, "e", 1); + EI(avr910_send(pgm, "e", 1)); if (avr910_vfy_cmd_sent(pgm, "chip erase") < 0) return -1; @@ -122,22 +133,19 @@ static int avr910_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { static int avr910_enter_prog_mode(const PROGRAMMER *pgm) { - avr910_send(pgm, "P", 1); + EI(avr910_send(pgm, "P", 1)); return avr910_vfy_cmd_sent(pgm, "enter prog mode"); } static int avr910_leave_prog_mode(const PROGRAMMER *pgm) { - avr910_send(pgm, "L", 1); + EI(avr910_send(pgm, "L", 1)); return avr910_vfy_cmd_sent(pgm, "leave prog mode"); } -/* - * issue the 'program enable' command to the AVR device - */ static int avr910_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { - return -1; + return avr910_enter_prog_mode(pgm); } @@ -156,22 +164,22 @@ static int avr910_initialize(const PROGRAMMER *pgm, const AVRPART *p) { /* Get the programmer identifier. Programmer returns exactly 7 chars _without_ the null.*/ - avr910_send(pgm, "S", 1); + EI(avr910_send(pgm, "S", 1)); memset (id, 0, sizeof(id)); - avr910_recv(pgm, id, sizeof(id)-1); + EI(avr910_recv(pgm, id, sizeof(id)-1)); /* Get the HW and SW versions to see if the programmer is present. */ - avr910_send(pgm, "V", 1); - avr910_recv(pgm, sw, sizeof(sw)); + EI(avr910_send(pgm, "V", 1)); + EI(avr910_recv(pgm, sw, sizeof(sw))); - avr910_send(pgm, "v", 1); - avr910_recv(pgm, hw, sizeof(hw)); + EI(avr910_send(pgm, "v", 1)); + EI(avr910_recv(pgm, hw, sizeof(hw))); /* Get the programmer type (serial or parallel). Expect serial. */ - avr910_send(pgm, "p", 1); - avr910_recv(pgm, &type, 1); + EI(avr910_send(pgm, "p", 1)); + EI(avr910_recv(pgm, &type, 1)); msg_notice("Programmer id = %s; type = %c\n", id, type); msg_notice("Software version = %c.%c; ", sw[0], sw[1]); @@ -179,20 +187,20 @@ static int avr910_initialize(const PROGRAMMER *pgm, const AVRPART *p) { /* See if programmer supports autoincrement of address. */ - avr910_send(pgm, "a", 1); - avr910_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1); + EI(avr910_send(pgm, "a", 1)); + EI(avr910_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1)); if (PDATA(pgm)->has_auto_incr_addr == 'Y') msg_notice("programmer supports auto addr increment\n"); /* Check support for buffered memory access, ignore if not available */ if (PDATA(pgm)->test_blockmode == 1) { - avr910_send(pgm, "b", 1); - avr910_recv(pgm, &c, 1); + EI(avr910_send(pgm, "b", 1)); + EI(avr910_recv(pgm, &c, 1)); if (c == 'Y') { - avr910_recv(pgm, &c, 1); + EI(avr910_recv(pgm, &c, 1)); PDATA(pgm)->buffersize = (unsigned int)(unsigned char)c<<8; - avr910_recv(pgm, &c, 1); + EI(avr910_recv(pgm, &c, 1)); PDATA(pgm)->buffersize += (unsigned int)(unsigned char)c; msg_notice("programmer supports buffered memory access with " "buffersize = %u bytes\n", @@ -211,11 +219,11 @@ static int avr910_initialize(const PROGRAMMER *pgm, const AVRPART *p) { /* Get list of devices that the programmer supports. */ - avr910_send(pgm, "t", 1); + EI(avr910_send(pgm, "t", 1)); msg_notice2("\nProgrammer supports the following devices:\n"); devtype_1st = 0; - while (1) { - avr910_recv(pgm, &c, 1); + while(1) { + EI(avr910_recv(pgm, &c, 1)); if (devtype_1st == 0) devtype_1st = c; if (c == 0) @@ -251,28 +259,22 @@ static int avr910_initialize(const PROGRAMMER *pgm, const AVRPART *p) { buf[0] = 'T'; /* buf[1] has been set up above */ - avr910_send(pgm, buf, 2); - avr910_vfy_cmd_sent(pgm, "select device"); + EI(avr910_send(pgm, buf, 2)); + if(avr910_vfy_cmd_sent(pgm, "select device") < 0) + return -1; pmsg_notice("avr910_devcode selected: 0x%02x\n", (unsigned) buf[1]); - avr910_enter_prog_mode(pgm); - - return 0; + return pgm->program_enable(pgm, p); } static void avr910_disable(const PROGRAMMER *pgm) { - /* Do nothing. */ - - return; + avr910_leave_prog_mode(pgm); } static void avr910_enable(PROGRAMMER *pgm, const AVRPART *p) { - /* Do nothing. */ - - return; } @@ -293,8 +295,8 @@ static int avr910_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, buf[3] = cmd[2]; buf[4] = cmd[3]; - avr910_send (pgm, buf, 5); - avr910_recv (pgm, buf, 2); + EI(avr910_send(pgm, buf, 5)); + EI(avr910_recv(pgm, buf, 2)); res[0] = 0x00; /* Dummy value */ res[1] = cmd[0]; @@ -337,7 +339,7 @@ static int avr910_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { msg_error(" -xdevcode= Override device code\n"); msg_error(" -xno_blockmode Disable default checking for block transfer capability\n"); msg_error(" -xhelp Show this help menu and exit\n"); - exit(0); + return LIBAVRDUDE_EXIT; } pmsg_error("invalid extended parameter '%s'\n", extended_param); @@ -350,32 +352,22 @@ static int avr910_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { static int avr910_open(PROGRAMMER *pgm, const char *port) { union pinfo pinfo; - /* - * If baudrate was not specified use 19.200 Baud - */ - if(pgm->baudrate == 0) { + + if(pgm->baudrate == 0) pgm->baudrate = 19200; - } pgm->port = port; pinfo.serialinfo.baud = pgm->baudrate; pinfo.serialinfo.cflags = SERIAL_8N1; - if (serial_open(port, pinfo, &pgm->fd)==-1) { + if(serial_open(port, pinfo, &pgm->fd) < 0) return -1; - } - /* - * drain any extraneous input - */ - avr910_drain (pgm, 0); + (void) avr910_drain (pgm, 0); return 0; } -static void avr910_close(PROGRAMMER * pgm) -{ - avr910_leave_prog_mode(pgm); - +static void avr910_close(PROGRAMMER *pgm) { serial_close(&pgm->fd); pgm->fd.ifd = -1; } @@ -393,7 +385,7 @@ static void avr910_set_addr(const PROGRAMMER *pgm, unsigned long addr) { cmd[1] = (addr >> 8) & 0xff; cmd[2] = addr & 0xff; - avr910_send(pgm, cmd, sizeof(cmd)); + EV(avr910_send(pgm, cmd, sizeof(cmd))); avr910_vfy_cmd_sent(pgm, "set addr"); } @@ -405,18 +397,16 @@ static int avr910_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRM if (mem_is_flash(m)) { if (addr & 0x01) { - cmd[0] = 'C'; /* Write Program Mem high byte */ - } - else { + cmd[0] = 'C'; // Write program mem high byte + } else { cmd[0] = 'c'; } addr >>= 1; - } - else if (mem_is_eeprom(m)) { + PDATA(pgm)->ctype = 0; // Invalidate read cache + } else if (mem_is_eeprom(m)) { cmd[0] = 'D'; - } - else { + } else { return avr_write_byte_default(pgm, p, m, addr, value); } @@ -424,10 +414,8 @@ static int avr910_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRM avr910_set_addr(pgm, addr); - avr910_send(pgm, cmd, sizeof(cmd)); - avr910_vfy_cmd_sent(pgm, "write byte"); - - return 0; + EI(avr910_send(pgm, cmd, sizeof(cmd))); + return avr910_vfy_cmd_sent(pgm, "write byte"); } @@ -436,19 +424,20 @@ static int avr910_read_byte_flash(const PROGRAMMER *pgm, const AVRPART *p, const { char buf[2]; + if(PDATA(pgm)->ctype == 'F' && PDATA(pgm)->caddr == addr) { + *value = PDATA(pgm)->cvalue; + return 0; + } + avr910_set_addr(pgm, addr >> 1); - avr910_send(pgm, "R", 1); + EI(avr910_send(pgm, "R", 1)); + EI(avr910_recv(pgm, buf, sizeof(buf))); - /* Read back the program mem word (MSB first) */ - avr910_recv(pgm, buf, sizeof(buf)); - - if ((addr & 0x01) == 0) { - *value = buf[1]; - } - else { - *value = buf[0]; - } + *value = buf[(addr & 1) ^ 1]; // MSB in buffer first + PDATA(pgm)->ctype = 'F'; + PDATA(pgm)->cvalue = buf[addr & 1]; + PDATA(pgm)->caddr = addr ^ 1; return 0; } @@ -458,8 +447,8 @@ static int avr910_read_byte_eeprom(const PROGRAMMER *pgm, const AVRPART *p, cons unsigned long addr, unsigned char * value) { avr910_set_addr(pgm, addr); - avr910_send(pgm, "d", 1); - avr910_recv(pgm, (char *)value, 1); + EI(avr910_send(pgm, "d", 1)); + EI(avr910_recv(pgm, (char *) value, 1)); return 0; } @@ -491,6 +480,8 @@ static int avr910_paged_write_flash(const PROGRAMMER *pgm, const AVRPART *p, con int page_bytes = page_size; int page_wr_cmd_pending = 0; + PDATA(pgm)->ctype = 0; // Invalidate read cache + page_addr = addr; avr910_set_addr(pgm, addr>>1); @@ -498,8 +489,9 @@ static int avr910_paged_write_flash(const PROGRAMMER *pgm, const AVRPART *p, con page_wr_cmd_pending = 1; buf[0] = cmd[addr & 0x01]; buf[1] = m->buf[addr]; - avr910_send(pgm, buf, sizeof(buf)); - avr910_vfy_cmd_sent(pgm, "write byte"); + EI(avr910_send(pgm, buf, sizeof(buf))); + if(avr910_vfy_cmd_sent(pgm, "write byte") < 0) + return -1; addr++; page_bytes--; @@ -508,8 +500,9 @@ static int avr910_paged_write_flash(const PROGRAMMER *pgm, const AVRPART *p, con /* Send the "Issue Page Write" if we have sent a whole page. */ avr910_set_addr(pgm, page_addr>>1); - avr910_send(pgm, "m", 1); - avr910_vfy_cmd_sent(pgm, "flush page"); + EI(avr910_send(pgm, "m", 1)); + if(avr910_vfy_cmd_sent(pgm, "flush page") < 0) + return -1; page_wr_cmd_pending = 0; usleep(m->max_write_delay); @@ -530,12 +523,13 @@ static int avr910_paged_write_flash(const PROGRAMMER *pgm, const AVRPART *p, con if (page_wr_cmd_pending) { avr910_set_addr(pgm, page_addr>>1); - avr910_send(pgm, "m", 1); - avr910_vfy_cmd_sent(pgm, "flush final page"); + EI(avr910_send(pgm, "m", 1)); + if(avr910_vfy_cmd_sent(pgm, "flush final page") < 0) + return -1; usleep(m->max_write_delay); } - return addr; + return n_bytes; } @@ -553,18 +547,18 @@ static int avr910_paged_write_eeprom(const PROGRAMMER *pgm, const AVRPART *p, while (addr < max_addr) { cmd[1] = m->buf[addr]; - avr910_send(pgm, cmd, sizeof(cmd)); - avr910_vfy_cmd_sent(pgm, "write byte"); + EI(avr910_send(pgm, cmd, sizeof(cmd))); + if(avr910_vfy_cmd_sent(pgm, "write byte") < 0) + return -1; usleep(m->max_write_delay); addr++; - if (PDATA(pgm)->has_auto_incr_addr != 'Y') { + if (PDATA(pgm)->has_auto_incr_addr != 'Y') avr910_set_addr(pgm, addr); - } } - return addr; + return n_bytes; } @@ -572,59 +566,56 @@ static int avr910_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVR unsigned int page_size, unsigned int addr, unsigned int n_bytes) { - int rval = 0; + int isee = mem_is_eeprom(m); + if (PDATA(pgm)->use_blockmode == 0) { - if (mem_is_flash(m)) { - rval = avr910_paged_write_flash(pgm, p, m, page_size, addr, n_bytes); - } else if (mem_is_eeprom(m)) { - rval = avr910_paged_write_eeprom(pgm, p, m, page_size, addr, n_bytes); - } else { - rval = -2; - } + if(mem_is_flash(m)) + return avr910_paged_write_flash(pgm, p, m, page_size, addr, n_bytes); + if(isee) + return avr910_paged_write_eeprom(pgm, p, m, page_size, addr, n_bytes); + return -2; } if (PDATA(pgm)->use_blockmode == 1) { unsigned int max_addr = addr + n_bytes; char *cmd; unsigned int blocksize = PDATA(pgm)->buffersize; - int wr_size; - if (!mem_is_flash(m) && !mem_is_eeprom(m)) + if(!mem_is_flash(m) && !isee) return -2; - if (m->desc[0] == 'e') { - blocksize = 1; /* Write to eeprom single bytes only */ - wr_size = 1; - } else { - wr_size = 2; - } + if(isee) + blocksize = 1; // Write single bytes only to EEPROM + else + PDATA(pgm)->ctype = 0; // Invalidate read cache - avr910_set_addr(pgm, addr / wr_size); + avr910_set_addr(pgm, isee? addr: addr>>1); + + cmd = mmt_malloc(4 + blocksize); - cmd = malloc(4 + blocksize); - if (!cmd) return -1; - cmd[0] = 'B'; - cmd[3] = toupper((int)(m->desc[0])); + cmd[3] = isee? 'E': 'F'; while (addr < max_addr) { - if ((max_addr - addr) < blocksize) { + if ((max_addr - addr) < blocksize) blocksize = max_addr - addr; - }; + memcpy(&cmd[4], &m->buf[addr], blocksize); cmd[1] = (blocksize >> 8) & 0xff; cmd[2] = blocksize & 0xff; - avr910_send(pgm, cmd, 4 + blocksize); - avr910_vfy_cmd_sent(pgm, "write block"); + if(avr910_send(pgm, cmd, 4 + blocksize) < 0 || + avr910_vfy_cmd_sent(pgm, "write block") < 0) { + mmt_free(cmd); + return -1; + } addr += blocksize; - } /* while */ - free(cmd); - - rval = addr; + } + mmt_free(cmd); } - return rval; + + return n_bytes; } @@ -633,31 +624,27 @@ static int avr910_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRM unsigned int addr, unsigned int n_bytes) { char cmd[4]; - int rd_size; unsigned int max_addr; char buf[2]; - int rval=0; + int isee = mem_is_eeprom(m); max_addr = addr + n_bytes; - if (mem_is_flash(m)) { + if(mem_is_flash(m)) cmd[0] = 'R'; - rd_size = 2; /* read two bytes per addr */ - } else if (mem_is_eeprom(m)) { + else if(isee) cmd[0] = 'd'; - rd_size = 1; - } else { + else return -2; - } + + avr910_set_addr(pgm, isee? addr: addr>>1); if (PDATA(pgm)->use_blockmode) { /* use buffered mode */ int blocksize = PDATA(pgm)->buffersize; cmd[0] = 'g'; - cmd[3] = toupper((int)(m->desc[0])); - - avr910_set_addr(pgm, addr / rd_size); + cmd[3] = isee? 'E': 'F'; while (addr < max_addr) { if (max_addr - addr < (unsigned int) blocksize) @@ -666,41 +653,30 @@ static int avr910_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRM cmd[1] = (blocksize >> 8) & 0xff; cmd[2] = blocksize & 0xff; - avr910_send(pgm, cmd, 4); - avr910_recv(pgm, (char *)&m->buf[addr], blocksize); + EI(avr910_send(pgm, cmd, 4)); + EI(avr910_recv(pgm, (char *) &m->buf[addr], blocksize)); addr += blocksize; } - - rval = addr; } else { - - avr910_set_addr(pgm, addr / rd_size); - while (addr < max_addr) { - avr910_send(pgm, cmd, 1); - if (rd_size == 2) { - /* The 'R' command returns two bytes, MSB first, we need to put the data - into the memory buffer LSB first. */ - avr910_recv(pgm, buf, 2); - m->buf[addr] = buf[1]; /* LSB */ - m->buf[addr + 1] = buf[0]; /* MSB */ - } - else { - avr910_recv(pgm, (char *)&m->buf[addr], 1); - } + EI(avr910_send(pgm, cmd, 1)); + if(!isee) { + // The 'R' command returns two bytes, MSB first, ie, reverse data + EI(avr910_recv(pgm, buf, 2)); + m->buf[addr] = buf[1]; // LSB + m->buf[addr+1] = buf[0]; // MSB + } else + EI(avr910_recv(pgm, (char *) &m->buf[addr], 1)); - addr += rd_size; + addr += isee? 1: 2; - if (PDATA(pgm)->has_auto_incr_addr != 'Y') { - avr910_set_addr(pgm, addr / rd_size); - } + if (PDATA(pgm)->has_auto_incr_addr != 'Y') + avr910_set_addr(pgm, isee? addr: addr>>1); } - - rval = addr; } - return rval; + return n_bytes; } /* Signature byte reads are always 3 bytes. */ @@ -713,8 +689,8 @@ static int avr910_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, const return -1; } - avr910_send(pgm, "s", 1); - avr910_recv(pgm, (char *)m->buf, 3); + EI(avr910_send(pgm, "s", 1)); + EI(avr910_recv(pgm, (char *) m->buf, 3)); /* Returned signature has wrong order. */ tmp = m->buf[2]; m->buf[2] = m->buf[0]; diff --git a/src/avrcache.c b/src/avrcache.c index bcf6d5fb..f509fff1 100644 --- a/src/avrcache.c +++ b/src/avrcache.c @@ -158,7 +158,7 @@ int avr_read_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM led_clr(pgm, LED_ERR); led_set(pgm, LED_PGM); - unsigned char *pagecopy = cfg_malloc(__func__, pgsize); + unsigned char *pagecopy = mmt_malloc(pgsize); memcpy(pagecopy, mem->buf + base, pgsize); if((rc = pgm->paged_load(pgm, p, mem, pgsize, base, pgsize)) >= 0) memcpy(buf, mem->buf + base, pgsize); @@ -175,7 +175,7 @@ int avr_read_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM if(rc == LIBAVRDUDE_SUCCESS) memcpy(buf, pagecopy, pgsize); } - free(pagecopy); + mmt_free(pagecopy); if(rc < 0) led_set(pgm, LED_ERR); @@ -200,12 +200,12 @@ int avr_write_page_default(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM if(pgsize == 1) return fallback_write_byte(pgm, p, mem, addr, *data); - unsigned char *pagecopy = cfg_malloc(__func__, pgsize); + unsigned char *pagecopy = mmt_malloc(pgsize); memcpy(pagecopy, mem->buf + base, pgsize); memcpy(mem->buf + base, data, pgsize); rc = pgm->paged_write(pgm, p, mem, pgsize, base, pgsize); memcpy(mem->buf + base, pagecopy, pgsize); - free(pagecopy); + mmt_free(pagecopy); return rc; } @@ -271,9 +271,9 @@ static int initCache(AVR_Cache *cp, const PROGRAMMER *pgm, const AVRPART *p) { cp->size = basemem->size; cp->page_size = basemem->page_size; cp->offset = basemem->offset; - cp->cont = cfg_malloc("initCache()", cp->size); - cp->copy = cfg_malloc("initCache()", cp->size); - cp->iscached = cfg_malloc("initCache()", cp->size/cp->page_size); + cp->cont = mmt_malloc(cp->size); + cp->copy = mmt_malloc( cp->size); + cp->iscached = mmt_malloc(cp->size/cp->page_size); if((pgm->prog_modes & PM_SPM) && mem_is_in_flash(basemem)) { // Could be vector bootloader // Caching the vector page hands over to the progammer that then can patch the reset vector @@ -802,11 +802,11 @@ int avr_reset_cache(const PROGRAMMER *pgm, const AVRPART *p_unused) { for(size_t i = 0; i < sizeof mems/sizeof*mems; i++) { AVR_Cache *cp = mems[i]; if(cp->cont) - free(cp->cont); + mmt_free(cp->cont); if(cp->copy) - free(cp->copy); + mmt_free(cp->copy); if(cp->iscached) - free(cp->iscached); + mmt_free(cp->iscached); memset(cp, 0, sizeof*cp); } diff --git a/src/avrdude.conf.in b/src/avrdude.conf.in index 78372b05..10513680 100644 --- a/src/avrdude.conf.in +++ b/src/avrdude.conf.in @@ -19575,15 +19575,6 @@ part # uc3a0512 ; ; -#------------------------------------------------------------ -# deprecated, use 'uc3a0512' -#------------------------------------------------------------ - -part parent "uc3a0512" # ucr2 - desc = "deprecated, use 'uc3a0512'"; - id = "ucr2"; -; - #------------------------------------------------------------ # ATtiny1634 #------------------------------------------------------------ diff --git a/src/avrdude.h b/src/avrdude.h index 25b0517e..f8952d00 100644 --- a/src/avrdude.h +++ b/src/avrdude.h @@ -40,7 +40,17 @@ extern int quell_progress; // Quell progress report -q, reduce effective verbo extern const char *partdesc; // Part -p string extern const char *pgmid; // Programmer -c string -int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, int msgmode, int msglvl, const char *format, ...); +// Magic memory tree: these functions succeed or exit() +#define mmt_strdup(s) cfg_strdup(__func__, s) +#define mmt_malloc(n) cfg_malloc(__func__, n) +#define mmt_realloc(p, n) cfg_realloc(__func__, p, n) +#define mmt_free(p) free(p) + +int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, int msgmode, int msglvl, const char *format, ...) +#if defined(__GNUC__) // Ask gcc to check whether format and parameters match + __attribute__ ((format (printf, 7, 8))) +#endif +; // Shortcuts #define msg_ext_error(...) avrdude_message2(stderr, __LINE__, __FILE__, __func__, 0, MSG_EXT_ERROR, __VA_ARGS__) diff --git a/src/avrftdi.c b/src/avrftdi.c index ba41635f..29d6fb6a 100644 --- a/src/avrftdi.c +++ b/src/avrftdi.c @@ -52,7 +52,8 @@ #ifdef DO_NOT_BUILD_AVRFTDI static int avrftdi_noftdi_open(PROGRAMMER *pgm, const char *name) { - pmsg_error("no libftdi or libusb support; install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again\n"); + pmsg_error("no libftdi or libusb support\n"); + imsg_error("install libftdi1/libusb-1.0 or libftdi/libusb and run configure/make again\n"); return -1; } @@ -89,94 +90,35 @@ static int write_flush(avrftdi_t *); * returns a human-readable name for a pin number. The name should match with * the pin names used in FTDI datasheets. */ -static char* -ftdi_pin_name(avrftdi_t* pdata, struct pindef_t pin) -{ - static char str[128]; +static char *ftdi_pin_name(avrftdi_t *pdata, struct pindef_t pin) { + char *str = pdata->name_str; + size_t strsiz = sizeof pdata->name_str; - char interface = '@'; - - /* INTERFACE_ANY is zero, so @ is used - * INTERFACE_A is one, so '@' + 1 = 'A' - * and so forth ... - * be aware, there is an 'interface' member in ftdi_context, - * however, we really want the 'index' member here. + /* + * INTERFACE_ANY is zero: print @ + * INTERFACE_A is one, use '@' + 1 = 'A' and so forth ... + * Be aware, there is an interface member in ftdi_context, + * however, we really want the index member here. */ - interface += pdata->ftdic->index; + char interface = '@' + pdata->ftdic->index; - int pinno; - int n = 0; + size_t n = 0; int mask = pin.mask[0]; - const char * fmt; - str[0] = 0; - for(pinno = 0; mask; mask >>= 1, pinno++) { + for(int pinno = 0; mask && n < strsiz-1; mask >>= 1, pinno++) { if(!(mask & 1)) continue; - int chars = 0; - - char port; - /* This is FTDI's naming scheme. - * probably 'D' is for data and 'C' for control - */ - if(pinno < 8) - port = 'D'; - else - port = 'C'; - - if(str[0] == 0) - fmt = "%c%cBUS%d%n"; - else - fmt = ", %c%cBUS%d%n"; - - snprintf(&str[n], sizeof(str) - n, fmt, interface, port, pinno, &chars); - n += chars; + // FTDI port: probably 'D' for data and 'C' for control + n += snprintf(&str[n], strsiz - n, "%s%c%cBUS%d", n? ", ": "", + interface, pinno < 8? 'D': 'C', pinno); } return str; } -/* - * output function, to save if(vebose>level)-constructs. Also prefixes output - * with "avrftdi function-name(line-number):" to identify were messages came - * from. - * This function is the backend of the log_*-macros, but it can be used - * directly. - */ -void avrftdi_log(int level, const char * func, int line, - const char * fmt, ...) { - static int skip_prefix = 0; - const char *p = fmt; - va_list ap; - - if(verbose >= level) - { - if(!skip_prefix) - { - switch(level) { - case ERR: msg_error("E "); break; - case WARN: msg_error("W "); break; - case INFO: msg_error("I "); break; - case DEBUG: msg_error("D "); break; - case TRACE: msg_error("T "); break; - default: msg_error(" "); break; - } - msg_error("%s(%d): ", func, line); - } - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - } - - skip_prefix = 1; - while(*p++) - if(*p == '\n' && !(*(p+1))) - skip_prefix = 0; -} - /* * helper function to print a binary buffer *buf of size len. Begin and end of * the dump are enclosed in the string contained in *desc. Offset denotes the @@ -187,16 +129,16 @@ static void buf_dump(const unsigned char *buf, int len, char *desc, int offset, int width) { int i; - msg_info("%s begin:\n", desc); + msg_trace2("%s begin:\n", desc); for (i = 0; i < offset; i++) - msg_info("%02x ", buf[i]); - msg_info("\n"); + msg_trace2("%02x ", buf[i]); + msg_trace2("\n"); for (i++; i <= len; i++) { - msg_info("%02x ", buf[i-1]); + msg_trace2("%02x ", buf[i-1]); if((i-offset) != 0 && (i-offset)%width == 0) - msg_info("\n"); + msg_trace2("\n"); } - msg_info("%s end\n", desc); + msg_trace2("%s end\n", desc); } /* @@ -234,19 +176,22 @@ static int set_frequency(avrftdi_t* ftdi, uint32_t freq) } if (divisor < 0) { - log_warn("Frequency too high (%u > %u MHz)\n", freq, clock / 2000000); - log_warn("Resetting Frequency to %uMHz\n", clock / 2000000); + char *f = str_frq(freq, 6), *h = str_frq(clock/2.0, 6); + pmsg_warning("frequency %s too high, resetting to %s\n", f, h); + mmt_free(f); mmt_free(h); divisor = 0; } if (divisor > 65535) { - log_warn("Frequency too low (%u < %.3f Hz)\n", freq, (float) clock / 2 / 65535); - log_warn("Resetting Frequency to %.3fHz\n", (float) clock / 2 / 65535); + char *f = str_frq(freq, 6), *l = str_frq(clock/2.0 / 65536, 6); + pmsg_warning("frequency %s too low, resetting to %s\n", f, l); + mmt_free(f); mmt_free(l); divisor = 65535; } - log_info("Using frequency: %d\n", clock / 2 / (divisor + 1)); - log_info("Clock divisor: 0x%04x\n", divisor); + char *f = str_frq(clock/2.0 / (divisor + 1), 6); + imsg_notice(" - frequency %s (clock divisor %d = 0x%04x)\n", f, divisor, divisor); + mmt_free(f); *ptr++ = TCK_DIVISOR; *ptr++ = (uint8_t)(divisor & 0xff); @@ -277,7 +222,7 @@ static int set_pin(const PROGRAMMER *pgm, int pinfunc, int value) { return 0; } - log_debug("Setting pin %s (%s) as %s: %s (%s active)\n", + pmsg_debug("setting pin %s (%s) as %s: %s (%s active)\n", pinmask_to_str(pin.mask), ftdi_pin_name(pdata, pin), avr_pin_name(pinfunc), (value) ? "high" : "low", (pin.inverse[0]) ? "low" : "high"); @@ -311,7 +256,7 @@ static void avrftdi_enable(PROGRAMMER *pgm, const AVRPART *p) { // Switch to TPI initialisation in avrftdi_tpi.c if(p->prog_modes & PM_TPI) - avrftdi_tpi_initpgm(pgm); + avrftdi_tpi_initpgm(pgm); } static void avrftdi_disable(const PROGRAMMER *pgm) { @@ -510,7 +455,7 @@ static int write_flush(avrftdi_t* pdata) { unsigned char buf[6]; - log_debug("Setting pin direction (0x%04x) and value (0x%04x)\n", + pmsg_debug("setting pin direction (0x%04x) and value (0x%04x)\n", pdata->pin_direction, pdata->pin_value); buf[0] = SET_BITS_LOW; @@ -522,7 +467,7 @@ static int write_flush(avrftdi_t* pdata) E(ftdi_write_data(pdata->ftdic, buf, 6) != 6, pdata->ftdic); - log_trace("Set pins command: %02x %02x %02x %02x %02x %02x\n", + msg_trace("set pins command: %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); /* we need to flush here, because set_pin is used as reset. @@ -549,7 +494,7 @@ static int write_flush(avrftdi_t* pdata) } while(num < 1); if(num > 1) - log_warn("Read %d extra bytes\n", num-1); + pmsg_warning("read %d extra bytes\n", num-1); return 0; @@ -566,16 +511,16 @@ static int avrftdi_check_pins_bb(const PROGRAMMER *pgm, bool output) { /* value for 8/12/16 bit wide interface */ int valid_mask = ((1 << pdata->pin_limit) - 1); - log_debug("Using valid mask bitbanging: 0x%08x\n", valid_mask); - static struct pindef_t valid_pins; - valid_pins.mask[0] = valid_mask; - valid_pins.inverse[0] = valid_mask ; + pmsg_debug("using valid mask bitbanging: 0x%08x\n", valid_mask); + struct pindef_t *valid_pins_p = &pdata->valid_pins; + valid_pins_p->mask[0] = valid_mask; + valid_pins_p->inverse[0] = valid_mask ; /* build pin checklist */ for(pin = 0; pin < N_PINS; ++pin) { pin_checklist[pin].pinname = pin; pin_checklist[pin].mandatory = 0; - pin_checklist[pin].valid_pins = &valid_pins; + pin_checklist[pin].valid_pins = valid_pins_p; } /* assumes all checklists above have same number of entries */ @@ -590,14 +535,7 @@ static int avrftdi_check_pins_mpsse(const PROGRAMMER *pgm, bool output) { avrftdi_t* pdata = to_pdata(pgm); - /* SCK/SDO/SDI are fixed and not invertible? */ - /* TODO: inverted SCK/SDI/SDO */ - static const struct pindef_t valid_pins[4] = { - {{0x01}, {0x00}}, - {{0x02}, {0x00}}, - {{0x04}, {0x00}}, - {{0x08}, {0x00}}, - }; + struct pindef_t *valid_pins = pdata->mpsse_pins; /* value for 8/12/16 bit wide interface for other pins */ int valid_mask = ((1 << pdata->pin_limit) - 1); @@ -608,16 +546,16 @@ static int avrftdi_check_pins_mpsse(const PROGRAMMER *pgm, bool output) { valid_mask &= ~(1 << FTDI_TMS_CS); } - log_debug("Using valid mask mpsse: 0x%08x\n", valid_mask); - static struct pindef_t valid_pins_others; - valid_pins_others.mask[0] = valid_mask; - valid_pins_others.inverse[0] = valid_mask ; + pmsg_debug("using valid mask mpsse: 0x%08x\n", valid_mask); + struct pindef_t *valid_pins_others_p = &pdata->other_pins; + valid_pins_others_p->mask[0] = valid_mask; + valid_pins_others_p->inverse[0] = valid_mask ; /* build pin checklist */ for(pin = 0; pin < N_PINS; ++pin) { pin_checklist[pin].pinname = pin; pin_checklist[pin].mandatory = 0; - pin_checklist[pin].valid_pins = &valid_pins_others; + pin_checklist[pin].valid_pins = valid_pins_others_p; } /* now set mpsse specific pins */ @@ -631,7 +569,7 @@ static int avrftdi_check_pins_mpsse(const PROGRAMMER *pgm, bool output) { pin_checklist[PIN_JTAG_TMS].mandatory = 1; pin_checklist[PIN_JTAG_TMS].valid_pins = &valid_pins[FTDI_TMS_CS]; } else { - pin_checklist[PIN_AVR_SCK].mandatory = 1; + pin_checklist[PIN_AVR_SCK].mandatory = 1; pin_checklist[PIN_AVR_SCK].valid_pins = &valid_pins[FTDI_TCK_SCK]; pin_checklist[PIN_AVR_SDO].mandatory = 1; pin_checklist[PIN_AVR_SDO].valid_pins = &valid_pins[FTDI_TDI_SDO]; @@ -653,16 +591,17 @@ static int avrftdi_pin_setup(const PROGRAMMER *pgm) { avrftdi_t* pdata = to_pdata(pgm); + bool pin_check_mpsse = (0 == avrftdi_check_pins_mpsse(pgm, verbose>3)); bool pin_check_bitbanging = (0 == avrftdi_check_pins_bb(pgm, verbose>3)); if (!pin_check_mpsse && !pin_check_bitbanging) { - log_err("No valid pin configuration found.\n"); + pmsg_error("no valid pin configuration found\n"); avrftdi_check_pins_bb(pgm, true); - log_err("Pin configuration for FTDI MPSSE must be:\n"); + imsg_error("pin configuration for FTDI MPSSE must be:\n"); if (pgm->flag == PGM_FL_IS_JTAG) { - log_err("%s: 0, %s: 1, %s: 2, %s :3 (is: %s, %s, %s, %s)\n", + imsg_error("%s: 0, %s: 1, %s: 2, %s :3 (is: %s, %s, %s, %s)\n", avr_pin_name(PIN_JTAG_TCK), avr_pin_name(PIN_JTAG_TDI), avr_pin_name(PIN_JTAG_TDO), avr_pin_name(PIN_JTAG_TMS), pins_to_str(&pgm->pin[PIN_JTAG_TCK]), @@ -670,7 +609,7 @@ static int avrftdi_pin_setup(const PROGRAMMER *pgm) { pins_to_str(&pgm->pin[PIN_JTAG_TDO]), pins_to_str(&pgm->pin[PIN_JTAG_TMS])); } else { - log_err("%s: 0, %s: 1, %s: 2 (is: %s, %s, %s)\n", + imsg_error("%s: 0, %s: 1, %s: 2 (is: %s, %s, %s)\n", avr_pin_name(PIN_AVR_SCK), avr_pin_name(PIN_AVR_SDO), avr_pin_name(PIN_AVR_SDI), @@ -678,14 +617,14 @@ static int avrftdi_pin_setup(const PROGRAMMER *pgm) { pins_to_str(&pgm->pin[PIN_AVR_SDO]), pins_to_str(&pgm->pin[PIN_AVR_SDI])); } - log_err("If other pin configuration is used, fallback to slower bitbanging mode is used.\n"); + imsg_error("if other pin configuration is used, fallback to slower bitbanging mode is used\n"); return -1; } pdata->use_bitbanging = !pin_check_mpsse; if (pdata->use_bitbanging) - log_info("Because of pin configuration fallback to bitbanging mode.\n"); + imsg_info("because of pin configuration fallback to bitbanging mode\n"); /* * TODO: No need to fail for a wrongly configured led or something. @@ -719,15 +658,14 @@ static int avrftdi_pin_setup(const PROGRAMMER *pgm) { } - log_info("Pin direction mask: %04x\n", pdata->pin_direction); - log_info("Pin value mask: %04x\n", pdata->pin_value); + imsg_notice(" - pin direction mask %04x\n", pdata->pin_direction); + imsg_notice(" - pin value mask %04x\n", pdata->pin_value); return 0; } static int avrftdi_open(PROGRAMMER *pgm, const char *port) { - int vid, pid, interface, index, err; - const char *serial, *desc; + int vid, pid, interface, err; avrftdi_t* pdata = to_pdata(pgm); @@ -751,23 +689,12 @@ static int avrftdi_open(PROGRAMMER *pgm, const char *port) { } else pid = USB_DEVICE_FT2232; - if (0 == pgm->usbsn[0]) /* we don't care about SN. Use first avail. */ - serial = NULL; - else - serial = pgm->usbsn; - - /* not used yet, but i put them here, just in case someone does needs or - * wants to implement this. - */ - desc = NULL; - index = 0; - if (pgm->usbdev[0] == 'a' || pgm->usbdev[0] == 'A') interface = INTERFACE_A; else if (pgm->usbdev[0] == 'b' || pgm->usbdev[0] == 'B') interface = INTERFACE_B; else { - log_warn("Invalid interface '%s'. Setting to Interface A\n", pgm->usbdev); + pmsg_warning("invalid interface '%s'. Setting to Interface A\n", pgm->usbdev); interface = INTERFACE_A; } @@ -777,16 +704,17 @@ static int avrftdi_open(PROGRAMMER *pgm, const char *port) { E(ftdi_set_interface(pdata->ftdic, interface) < 0, pdata->ftdic); - err = ftdi_usb_open_desc_index(pdata->ftdic, vid, pid, desc, serial, index); + const char *serial = *pgm->usbsn? pgm->usbsn: NULL; // no SN means use first available + // Todo: use desc and index argument, currently set to NULL and 0 + err = ftdi_usb_open_desc_index(pdata->ftdic, vid, pid, NULL, serial, 0); if(err) { - log_err("Error %d occurred: %s\n", err, ftdi_get_error_string(pdata->ftdic)); - //stupid hack, because avrdude calls pgm->close() even when pgm->open() fails - //and usb_dev is initialized to the last usb device from probing + pmsg_error("error %d occurred: %s\n", err, ftdi_get_error_string(pdata->ftdic)); + // usb_dev is initialized to the last usb device from probing pdata->ftdic->usb_dev = NULL; return err; } else { - log_info("Using device VID:PID %04x:%04x and SN '%s' on interface %c.\n", - vid, pid, serial, INTERFACE_A == interface? 'A': 'B'); + pmsg_info("using device VID:PID %04x:%04x and SN %s on interface %c\n", + vid, pid, serial? serial: "(none)", INTERFACE_A == interface? 'A': 'B'); } ftdi_set_latency_timer(pdata->ftdic, 1); @@ -817,8 +745,8 @@ static int avrftdi_open(PROGRAMMER *pgm, const char *port) { case TYPE_AM: case TYPE_BM: case TYPE_R: - log_err("Found unsupported device type AM, BM or R. avrftdi "); - log_err("cannot work with your chip. Try the 'synbb' programmer.\n"); + pmsg_error("found unsupported device type AM, BM or R\n"); + imsg_error("avrftdi cannot work with your chip; try the 'synbb' programmer type\n"); return -1; case TYPE_2232C: pdata->pin_limit = 12; @@ -849,18 +777,15 @@ static int avrftdi_open(PROGRAMMER *pgm, const char *port) { pdata->tx_buffer_size = 2048; break; default: - log_warn("Found unknown device %x. I will do my ", pdata->ftdic->type); - log_warn("best to work with it, but no guarantees ...\n"); + pmsg_warning("unknown device type 0x%02x\n", pdata->ftdic->type); + imsg_warning("continuing but no guarantees...\n"); pdata->pin_limit = 8; pdata->rx_buffer_size = pdata->ftdic->max_packet_size; pdata->tx_buffer_size = pdata->ftdic->max_packet_size; break; } - if(avrftdi_pin_setup(pgm)) - return -1; - - return 0; + return avrftdi_pin_setup(pgm)? -1: 0; } static void avrftdi_close(PROGRAMMER * pgm) @@ -871,8 +796,8 @@ static void avrftdi_close(PROGRAMMER * pgm) set_pin(pgm, PIN_AVR_RESET, ON); /* Stop driving the pins - except for the LEDs */ - log_info("LED Mask=0x%04x value =0x%04x &=0x%04x\n", - pdata->led_mask, pdata->pin_value, pdata->led_mask & pdata->pin_value); + pmsg_debug("LED Mask 0x%04x, pin value 0x%04x, anded 0x%04x\n", + pdata->led_mask, pdata->pin_value, pdata->led_mask & pdata->pin_value); pdata->pin_direction = pdata->led_mask; pdata->pin_value &= pdata->led_mask; @@ -916,7 +841,7 @@ static int avrftdi_initialize(const PROGRAMMER *pgm, const AVRPART *p) { static void avrftdi_display(const PROGRAMMER *pgm, const char *p) { - msg_info("%sPin assignment : 0..7 = DBUS0..7, 8..15 = CBUS0..7\n", p); + msg_info("%spin assignment : 0..7 = DBUS0..7, 8..15 = CBUS0..7\n", p); if (pgm->flag & PGM_FL_IS_JTAG) { pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS & ~SHOW_AVR_PINS); } else { @@ -933,11 +858,12 @@ static int avrftdi_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned static int avrftdi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { int i; unsigned char buf[4]; + int polli = p->pollindex - 1, pollok = polli >= 0 && polli < (int) sizeof buf; memset(buf, 0, sizeof(buf)); if (p->op[AVR_OP_PGM_ENABLE] == NULL) { - log_err("AVR_OP_PGM_ENABLE command not defined for %s\n", p->desc); + pmsg_error("AVR_OP_PGM_ENABLE command not defined for %s\n", p->desc); return -1; } @@ -945,8 +871,8 @@ static int avrftdi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { for(i = 0; i < 4; i++) { pgm->cmd(pgm, buf, buf); - if (buf[p->pollindex-1] != p->pollvalue) { - log_warn("Program enable command not successful. Retrying.\n"); + if (pollok && buf[polli] != p->pollvalue) { + pmsg_warning("program enable command not successful%s\n", i < 3? "; retrying": ""); set_pin(pgm, PIN_AVR_RESET, ON); usleep(20); set_pin(pgm, PIN_AVR_RESET, OFF); @@ -955,7 +881,7 @@ static int avrftdi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { return 0; } - log_err("Device is not responding to program enable. Check connection.\n"); + pmsg_error("device is not responding to program enable. Check connection.\n"); return -1; } @@ -966,7 +892,7 @@ static int avrftdi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char res[4]; if (p->op[AVR_OP_CHIP_ERASE] == NULL) { - log_err("AVR_OP_CHIP_ERASE command not defined for %s\n", p->desc); + pmsg_error("AVR_OP_CHIP_ERASE command not defined for %s\n", p->desc); return -1; } @@ -982,8 +908,7 @@ static int avrftdi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { /* Load extended address byte command */ -static int -avrftdi_lext(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int address) { +static int avrftdi_lext(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int address) { /* nothing to do if load extended address command unavailable */ if(m->op[AVR_OP_LOAD_EXT_ADDR] == NULL) return 0; @@ -1000,7 +925,7 @@ avrftdi_lext(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned avr_set_bits(m->op[AVR_OP_LOAD_EXT_ADDR], buf); avr_set_addr(m->op[AVR_OP_LOAD_EXT_ADDR], buf, address); - if(verbose > TRACE) + if(verbose >= MSG_TRACE2) buf_dump(buf, sizeof(buf), "load extended address command", 0, 16 * 3); @@ -1074,17 +999,17 @@ static int avrftdi_flash_write(const PROGRAMMER *pgm, const AVRPART *p, const AV /* pre-check opcodes */ if (m->op[AVR_OP_LOADPAGE_LO] == NULL) { - log_err("AVR_OP_LOADPAGE_LO command not defined for %s\n", p->desc); + pmsg_error("AVR_OP_LOADPAGE_LO command not defined for %s\n", p->desc); return -1; } if (m->op[AVR_OP_LOADPAGE_HI] == NULL) { - log_err("AVR_OP_LOADPAGE_HI command not defined for %s\n", p->desc); + pmsg_error("AVR_OP_LOADPAGE_HI command not defined for %s\n", p->desc); return -1; } if(page_size != (unsigned int) m->page_size) { - log_warn("Parameter page_size is %d, ", page_size); - log_warn("but m->page_size is %d. Using the latter.\n", m->page_size); + pmsg_warning("parameter page_size is %d ", page_size); + msg_warning("but m->page_size is %d; using the latter\n", m->page_size); } page_size = m->page_size; @@ -1097,7 +1022,7 @@ static int avrftdi_flash_write(const PROGRAMMER *pgm, const AVRPART *p, const AV /* addr is in bytes, but we program in words. */ for(word = addr/2; word < (len + addr)/2; word++) { - log_debug("-< bytes = %d of %d\n", word * 2, len + addr); + pmsg_debug("-< bytes = %d of %d\n", word * 2, len + addr); /*setting word*/ avr_set_bits(m->op[AVR_OP_LOADPAGE_LO], bufptr); @@ -1113,7 +1038,7 @@ static int avrftdi_flash_write(const PROGRAMMER *pgm, const AVRPART *p, const AV /* issue write page command, if available */ if (m->op[AVR_OP_WRITEPAGE] == NULL) { - log_err("AVR_OP_WRITEPAGE command not defined for %s\n", p->desc); + pmsg_error("AVR_OP_WRITEPAGE command not defined for %s\n", p->desc); return -1; } else { avr_set_bits(m->op[AVR_OP_WRITEPAGE], bufptr); @@ -1133,29 +1058,29 @@ static int avrftdi_flash_write(const PROGRAMMER *pgm, const AVRPART *p, const AV if(poll_index+1 > addr) { buf_size = bufptr - buf; - if(verbose > TRACE) + if(verbose >= MSG_TRACE2) buf_dump(buf, buf_size, "command buffer", 0, 16*2); - log_info("Transmitting buffer of size: %d\n", buf_size); + pmsg_info("transmitting buffer of size: %d\n", buf_size); if (0 > avrftdi_transmit(pgm, MPSSE_DO_WRITE, buf, buf, buf_size)) return -1; bufptr = buf; - log_info("Using m->buf[%d] = 0x%02x as polling value ", poll_index, + pmsg_info("using m->buf[%d] = 0x%02x as polling value ", poll_index, m->buf[poll_index]); /* poll page write ready */ do { - log_info("."); + msg_info("."); pgm->read_byte(pgm, p, m, poll_index, &poll_byte); } while (m->buf[poll_index] != poll_byte); - log_info("\n"); + msg_info("\n"); } else { - log_warn("Skipping empty page (containing only 0xff bytes)\n"); + pmsg_warning("skipping empty page (containing only 0xff bytes)\n"); /* TODO sync write */ /* sleep */ usleep((m->max_write_delay)); @@ -1182,11 +1107,11 @@ static int avrftdi_flash_read(const PROGRAMMER *pgm, const AVRPART *p, const AVR /* pre-check opcodes */ if (m->op[AVR_OP_READ_LO] == NULL) { - log_err("AVR_OP_READ_LO command not defined for %s\n", p->desc); + pmsg_error("AVR_OP_READ_LO command not defined for %s\n", p->desc); return -1; } if (m->op[AVR_OP_READ_HI] == NULL) { - log_err("AVR_OP_READ_HI command not defined for %s\n", p->desc); + pmsg_error("AVR_OP_READ_HI command not defined for %s\n", p->desc); return -1; } @@ -1211,14 +1136,14 @@ static int avrftdi_flash_read(const PROGRAMMER *pgm, const AVRPART *p, const AVR * if there was an error, we did not see, memory validation will * subsequently fail. */ - if(verbose > TRACE) { + if(verbose >= MSG_TRACE2) { buf_dump(o_buf, sizeof(o_buf), "o_buf", 0, 32); } if (0 > avrftdi_transmit(pgm, MPSSE_DO_READ | MPSSE_DO_WRITE, o_buf, i_buf, len * 4)) return -1; - if(verbose > TRACE) { + if(verbose >= MSG_TRACE2) { buf_dump(i_buf, sizeof(i_buf), "i_buf", 0, 32); } @@ -1237,7 +1162,7 @@ static int avrftdi_flash_read(const PROGRAMMER *pgm, const AVRPART *p, const AVR avr_get_output(readop, &i_buf[byte*4], &m->buf[addr+byte]); } - if(verbose > TRACE) + if(verbose >= MSG_TRACE2) buf_dump(&m->buf[addr], page_size, "page:", 0, 32); return len; @@ -1265,23 +1190,27 @@ static int avrftdi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVR return -2; } -static void -avrftdi_setup(PROGRAMMER * pgm) -{ +static void avrftdi_setup(PROGRAMMER * pgm) { avrftdi_t* pdata; - - if(!(pgm->cookie = calloc(1, sizeof(avrftdi_t)))) { - log_err("Error allocating memory.\n"); - exit(1); - } + pgm->cookie = mmt_malloc(sizeof(avrftdi_t)); pdata = to_pdata(pgm); + /* SCK/SDO/SDI are fixed and not invertible? */ + /* TODO: inverted SCK/SDI/SDO */ + const struct pindef_t valid_mpsse_pins[4] = { + {{0x01}, {0x00}}, + {{0x02}, {0x00}}, + {{0x04}, {0x00}}, + {{0x08}, {0x00}}, + }; + for(int i=0; i<4; i++) + pdata->mpsse_pins[i] = valid_mpsse_pins[i]; + pdata->ftdic = ftdi_new(); - if(!pdata->ftdic) - { - log_err("Error allocating memory.\n"); - exit(1); + if(!pdata->ftdic) { + pmsg_ext_error("ftdi_new() failed to allocate memory\n"); + exit(1); // pgm->setup() should return an int, but it doesn't } E_VOID(ftdi_init(pdata->ftdic), pdata->ftdic); @@ -1291,15 +1220,13 @@ avrftdi_setup(PROGRAMMER * pgm) pdata->lext_byte = 0xff; } -static void -avrftdi_teardown(PROGRAMMER * pgm) -{ - avrftdi_t* pdata = to_pdata(pgm); - - if(pdata) { +static void avrftdi_teardown(PROGRAMMER * pgm) { + if(pgm->cookie) { + avrftdi_t *pdata = to_pdata(pgm); ftdi_deinit(pdata->ftdic); ftdi_free(pdata->ftdic); - free(pdata); + mmt_free(pdata); + pgm->cookie = NULL; } } @@ -1457,18 +1384,6 @@ static int avrftdi_jtag_dr_inout(const PROGRAMMER *pgm, unsigned int dr, static void avrftdi_jtag_enable(PROGRAMMER *pgm, const AVRPART *p) { - if(!ovsigck) { - if(str_eq(p->id, "m128a") || str_eq(p->id, "m128") || - str_eq(p->id, "m64a") || str_eq(p->id, "m64") || - str_eq(p->id, "m32a") || str_eq(p->id, "m32") || - str_eq(p->id, "m16a") || str_eq(p->id, "m16") || - str_eq(p->id, "m162")) { - pmsg_error("programmer type %s is known not to work for %s\n", pgm->type, p->desc); - imsg_error("exiting; use -F to carry on regardless\n"); - exit(1); - } - } - pgm->powerup(pgm); set_pin(pgm, PIN_AVR_RESET, OFF); @@ -1481,6 +1396,18 @@ static void avrftdi_jtag_enable(PROGRAMMER *pgm, const AVRPART *p) static int avrftdi_jtag_initialize(const PROGRAMMER *pgm, const AVRPART *p) { + if(!ovsigck) { + if(str_eq(p->id, "m128a") || str_eq(p->id, "m128") || + str_eq(p->id, "m64a") || str_eq(p->id, "m64") || + str_eq(p->id, "m32a") || str_eq(p->id, "m32") || + str_eq(p->id, "m16a") || str_eq(p->id, "m16") || + str_eq(p->id, "m162")) { + pmsg_error("programmer type %s is known not to work for %s\n", pgm->type, p->desc); + imsg_error("exiting; use -F to carry on regardless\n"); + return LIBAVRDUDE_EXIT; + } + } + set_pin(pgm, PPI_AVR_BUFF, ON); avrftdi_jtag_reset(pgm); @@ -1763,9 +1690,9 @@ static int avrftdi_jtag_paged_read(const PROGRAMMER *pgm, const AVRPART *p, unsigned int maxaddr = addr + n_bytes; unsigned char *buf, *ptr; unsigned int bytes; - - buf = alloca(n_bytes * 8 + 1); - ptr = buf; + + buf = alloca(n_bytes * 8 + 1); + ptr = buf; if (mem_is_flash(m)) { avrftdi_jtag_ir_out(pgm, JTAG_IR_PROG_COMMANDS); diff --git a/src/avrftdi_private.h b/src/avrftdi_private.h index 4ee45c1d..2d453099 100644 --- a/src/avrftdi_private.h +++ b/src/avrftdi_private.h @@ -26,39 +26,21 @@ #ifndef DO_NOT_BUILD_AVRFTDI -enum { ERR, WARN, INFO, DEBUG, TRACE }; - -#define __log(lvl, fmt, ...) \ - do { \ - avrftdi_log(lvl, __func__, __LINE__, fmt, ##__VA_ARGS__); \ +#define E(x, ftdi) \ + do { \ + if((x)) { \ + pmsg_error("%s: %s (%d)\n", #x, strerror(errno), errno); \ + imsg_error("%s\n", ftdi_get_error_string(ftdi)); \ + return -1; \ + } \ } while(0) - -#define log_err(fmt, ...) __log(ERR, fmt, ##__VA_ARGS__) -#define log_warn(fmt, ...) __log(WARN, fmt, ##__VA_ARGS__) -#define log_info(fmt, ...) __log(INFO, fmt, ##__VA_ARGS__) -#define log_debug(fmt, ...) __log(DEBUG, fmt, ##__VA_ARGS__) -#define log_trace(fmt, ...) __log(TRACE, fmt, ##__VA_ARGS__) - -#define E(x, ftdi) \ - do { \ - if ((x)) \ - { \ - msg_error("%s:%d %s() %s: %s (%d)\n\t%s\n", \ - __FILE__, __LINE__, __FUNCTION__, \ - #x, strerror(errno), errno, ftdi_get_error_string(ftdi)); \ - return -1; \ - } \ - } while(0) - -#define E_VOID(x, ftdi) \ - do { \ - if ((x)) \ - { \ - msg_error("%s:%d %s() %s: %s (%d)\n\t%s\n", \ - __FILE__, __LINE__, __FUNCTION__, \ - #x, strerror(errno), errno, ftdi_get_error_string(ftdi)); \ - } \ +#define E_VOID(x, ftdi) \ + do { \ + if((x)) { \ + pmsg_error("%s: %s (%d)\n", #x, strerror(errno), errno); \ + imsg_error("%s\n", ftdi_get_error_string(ftdi)); \ + } \ } while(0) enum { @@ -111,9 +93,12 @@ typedef struct avrftdi_s { bool use_bitbanging; /* bits 16-23 of extended 24-bit word flash address for parts with flash > 128k */ uint8_t lext_byte; -} avrftdi_t; -void avrftdi_log(int level, const char * func, int line, const char * fmt, ...); + char name_str[128]; // Used in ftdi_pin_name() + struct pindef_t valid_pins; // Used in avrftdi_check_pins_bb() + struct pindef_t mpsse_pins[4]; // Used in avrftdi_check_pins_mpsse() + struct pindef_t other_pins; // Used in avrftdi_check_pins_mpsse() +} avrftdi_t; #endif /* DO_NOT_BUILD_AVRFDTI */ diff --git a/src/avrftdi_tpi.c b/src/avrftdi_tpi.c index e36ce244..be09e112 100644 --- a/src/avrftdi_tpi.c +++ b/src/avrftdi_tpi.c @@ -19,9 +19,7 @@ static void avrftdi_tpi_disable(const PROGRAMMER *); static int avrftdi_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p); #ifdef notyet -static void -avrftdi_debug_frame(uint16_t frame) -{ +static void avrftdi_debug_frame(uint16_t frame) { static char bit_name[] = "IDLES01234567PSS"; //static char bit_name[] = "SSP76543210SELDI"; char line0[34], line1[34], line2[34]; @@ -56,9 +54,9 @@ avrftdi_debug_frame(uint16_t frame) line1[32] = 0; line2[32] = 0; - log_debug("%s\n", line0); - log_debug("%s\n", line1); - //log_debug("%s\n", line2); + msg_debug("%s\n", line0); + msg_debug("%s\n", line1); + // msg_debug("%s\n", line2); } #endif /* notyet */ @@ -69,7 +67,7 @@ avrftdi_tpi_initialize(const PROGRAMMER *pgm, const AVRPART *p) { avrftdi_t* pdata = to_pdata(pgm); unsigned char buf[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 0x01, 0x00, 0xff, 0xff }; - log_info("Setting /Reset pin low\n"); + pmsg_info("Setting /Reset pin low\n"); pgm->setpin(pgm, PIN_AVR_RESET, OFF); pgm->setpin(pgm, PIN_AVR_SCK, OFF); pgm->setpin(pgm, PIN_AVR_SDO, ON); @@ -84,7 +82,7 @@ avrftdi_tpi_initialize(const PROGRAMMER *pgm, const AVRPART *p) { /*wait at least 20ms bevor issuing spi commands to avr */ usleep(20 * 1000); - log_info("Sending 16 init clock cycles ...\n"); + pmsg_info("Sending 16 init clock cycles ...\n"); ret = ftdi_write_data(pdata->ftdic, buf, sizeof(buf)); return ret; @@ -92,7 +90,7 @@ avrftdi_tpi_initialize(const PROGRAMMER *pgm, const AVRPART *p) { void avrftdi_tpi_initpgm(PROGRAMMER *pgm) { - log_info("Using TPI interface\n"); + pmsg_info("Using TPI interface\n"); pgm->program_enable = avrftdi_tpi_program_enable; pgm->cmd_tpi = avrftdi_cmd_tpi; @@ -106,8 +104,7 @@ void avrftdi_tpi_initpgm(PROGRAMMER *pgm) { #define TPI_PARITY_MASK 0x2000 -static inline int count1s(unsigned int x) -{ +static inline int count1s(unsigned int x) { #if defined(__GNUC__) return __builtin_popcount(x); #else @@ -123,9 +120,7 @@ static inline int count1s(unsigned int x) #endif } -static uint16_t -tpi_byte2frame(uint8_t byte) -{ +static uint16_t tpi_byte2frame(uint8_t byte) { uint16_t frame = 0xc00f; int parity = count1s(byte) & 1; @@ -137,9 +132,7 @@ tpi_byte2frame(uint8_t byte) return frame; } -static int -tpi_frame2byte(uint16_t frame, uint8_t * byte) -{ +static int tpi_frame2byte(uint16_t frame, uint8_t * byte) { /* drop idle and start bit(s) */ *byte = (frame >> 5) & 0xff; @@ -150,8 +143,7 @@ tpi_frame2byte(uint16_t frame, uint8_t * byte) } #ifdef notyet -static int -avrftdi_tpi_break(const PROGRAMMER *pgm) { +static int avrftdi_tpi_break(const PROGRAMMER *pgm) { unsigned char buffer[] = { MPSSE_DO_WRITE | MPSSE_WRITE_NEG | MPSSE_LSB, 1, 0, 0, 0 }; E(ftdi_write_data(to_pdata(pgm)->ftdic, buffer, sizeof(buffer)) != sizeof(buffer), to_pdata(pgm)->ftdic); @@ -159,8 +151,7 @@ avrftdi_tpi_break(const PROGRAMMER *pgm) { } #endif /* notyet */ -static int -avrftdi_tpi_write_byte(const PROGRAMMER *pgm, unsigned char byte) { +static int avrftdi_tpi_write_byte(const PROGRAMMER *pgm, unsigned char byte) { uint16_t frame; struct ftdi_context* ftdic = to_pdata(pgm)->ftdic; @@ -172,7 +163,7 @@ avrftdi_tpi_write_byte(const PROGRAMMER *pgm, unsigned char byte) { buffer[3] = frame & 0xff; buffer[4] = frame >> 8; - log_trace("Byte %02x, frame: %04x, MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", + msg_trace("Byte %02x, frame: %04x, MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", byte, frame, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4]); //avrftdi_debug_frame(frame); @@ -185,8 +176,7 @@ avrftdi_tpi_write_byte(const PROGRAMMER *pgm, unsigned char byte) { #define TPI_FRAME_SIZE 12 #define TPI_IDLE_BITS 2 -static int -avrftdi_tpi_read_byte(const PROGRAMMER *pgm, unsigned char *byte) { +static int avrftdi_tpi_read_byte(const PROGRAMMER *pgm, unsigned char *byte) { uint16_t frame; /* use 2 guard bits, 2 default idle bits + 12 frame bits = 16 bits total */ @@ -200,7 +190,7 @@ avrftdi_tpi_read_byte(const PROGRAMMER *pgm, unsigned char *byte) { buffer[2] = ((bytes-1) >> 8) & 0xff; buffer[3] = SEND_IMMEDIATE; - log_trace("MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x (Read frame)\n", + msg_trace("MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x (Read frame)\n", buffer[0], buffer[1], buffer[2], buffer[3]); ftdi_write_data(to_pdata(pgm)->ftdic, buffer, 4); @@ -215,22 +205,21 @@ avrftdi_tpi_read_byte(const PROGRAMMER *pgm, unsigned char *byte) { } while(i < bytes); - log_trace("MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x (Read frame)\n", + msg_trace("MPSSE: 0x%02x 0x%02x 0x%02x 0x%02x (Read frame)\n", buffer[0], buffer[1], buffer[2], buffer[3]); frame = buffer[0] | (buffer[1] << 8); err = tpi_frame2byte(frame, byte); - log_trace("Frame: 0x%04x, byte: 0x%02x\n", frame, *byte); + pmsg_trace("Frame: 0x%04x, byte: 0x%02x\n", frame, *byte); //avrftdi_debug_frame(frame); return err; } -static int -avrftdi_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { +static int avrftdi_tpi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { return avr_tpi_program_enable(pgm, p, TPIPCR_GT_2b); } @@ -257,12 +246,11 @@ avrftdi_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd, int cmd_len, return 0; } -static void -avrftdi_tpi_disable(const PROGRAMMER *pgm) { +static void avrftdi_tpi_disable(const PROGRAMMER *pgm) { unsigned char cmd[] = {TPI_OP_SSTCS(TPIPCR), 0}; pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0); - log_info("Leaving Programming mode.\n"); + pmsg_info("Leaving Programming mode.\n"); } #endif /* DO_NOT_BUILD_AVRFTDI */ diff --git a/src/avrpart.c b/src/avrpart.c index baaebd9d..86235fce 100644 --- a/src/avrpart.c +++ b/src/avrpart.c @@ -33,22 +33,21 @@ ***/ OPCODE *avr_new_opcode(void) { - return (OPCODE *) cfg_malloc("avr_new_opcode()", sizeof(OPCODE)); + return (OPCODE *) mmt_malloc(sizeof(OPCODE)); } static OPCODE *avr_dup_opcode(const OPCODE *op) { if(op == NULL) // Caller wants NULL if op == NULL return NULL; - OPCODE *m = (OPCODE *) cfg_malloc("avr_dup_opcode()", sizeof(*m)); + OPCODE *m = (OPCODE *) mmt_malloc(sizeof(*m)); memcpy(m, op, sizeof(*m)); return m; } void avr_free_opcode(OPCODE *op) { - if(op) - free(op); + mmt_free(op); } @@ -296,7 +295,7 @@ int avr_get_output_index(const OPCODE *op) { ***/ AVRMEM *avr_new_mem(void) { - AVRMEM *m = (AVRMEM *) cfg_malloc("avr_new_mem()", sizeof(*m)); + AVRMEM *m = (AVRMEM *) mmt_malloc(sizeof(*m)); m->desc = cache_string(""); m->page_size = 1; // Ensure not 0 m->initval = -1; // Unknown value represented as -1 @@ -306,7 +305,7 @@ AVRMEM *avr_new_mem(void) { } AVRMEM_ALIAS *avr_new_memalias(void) { - AVRMEM_ALIAS *m = (AVRMEM_ALIAS *) cfg_malloc("avr_new_memalias()", sizeof*m); + AVRMEM_ALIAS *m = (AVRMEM_ALIAS *) mmt_malloc(sizeof *m); m->desc = cache_string(""); return m; } @@ -322,8 +321,8 @@ int avr_initmem(const AVRPART *p) { for (LNODEID ln=lfirst(p->mem); ln; ln=lnext(ln)) { AVRMEM *m = ldata(ln); - m->buf = (unsigned char *) cfg_malloc("avr_initmem()", m->size); - m->tags = (unsigned char *) cfg_malloc("avr_initmem()", m->size); + m->buf = mmt_malloc(m->size); + m->tags = mmt_malloc(m->size); } return 0; @@ -337,12 +336,12 @@ AVRMEM *avr_dup_mem(const AVRMEM *m) { *n = *m; if(m->buf) { - n->buf = (unsigned char *) cfg_malloc("avr_dup_mem()", n->size); + n->buf = mmt_malloc(n->size); memcpy(n->buf, m->buf, n->size); } if(m->tags) { - n->tags = (unsigned char *) cfg_malloc("avr_dup_mem()", n->size); + n->tags = (unsigned char *) mmt_malloc(n->size); memcpy(n->tags, m->tags, n->size); } @@ -367,11 +366,11 @@ void avr_free_mem(AVRMEM * m) { return; if(m->buf) { - free(m->buf); + mmt_free(m->buf); m->buf = NULL; } if(m->tags) { - free(m->tags); + mmt_free(m->tags); m->tags = NULL; } for(size_t i=0; iop)/sizeof(m->op[0]); i++) { @@ -380,12 +379,11 @@ void avr_free_mem(AVRMEM * m) { m->op[i] = NULL; } } - free(m); + mmt_free(m); } void avr_free_memalias(AVRMEM_ALIAS *m) { - if(m) - free(m); + mmt_free(m); } AVRMEM_ALIAS *avr_locate_memalias(const AVRPART *p, const char *desc) { @@ -602,7 +600,7 @@ const Register_file_t *avr_locate_register(const Register_file_t *rgf, int nr, c const Register_file_t **avr_locate_registerlist(const Register_file_t *rgf, int nr, const char *reg, int (*match)(const char *, const char*)) { - const Register_file_t **ret = cfg_malloc(__func__, sizeof rgf*(nr>0? nr+1: 1)), **r = ret; + const Register_file_t **ret = mmt_malloc(sizeof rgf*(nr>0? nr+1: 1)), **r = ret; int eqmatch = match == str_eq; if(rgf && reg && match) @@ -617,7 +615,7 @@ const Register_file_t **avr_locate_registerlist(const Register_file_t *rgf, int return ret; } if(!eqmatch && str_eq(p, reg)) { // reg same as segment: switch to str_eq() match - free(ret); + mmt_free(ret); return avr_locate_registerlist(rgf, nr, reg, str_eq); } if(!reg_matched++) // Record a matching register only once @@ -668,7 +666,7 @@ const Configitem_t *avr_locate_config(const Configitem_t *cfg, int nc, const cha const Configitem_t **avr_locate_configlist(const Configitem_t *cfg, int nc, const char *name, int (*match)(const char *, const char*)) { - const Configitem_t **ret = cfg_malloc(__func__, sizeof cfg*(nc>0? nc+1: 1)), **r = ret; + const Configitem_t **ret = mmt_malloc(sizeof cfg*(nc>0? nc+1: 1)), **r = ret; if(cfg && name && match) { for(int i = 0; i < nc; i++) @@ -774,7 +772,7 @@ static char *print_num(const char *fmt, int n) { static int num_len(const char *fmt, int n) { char *p = print_num(fmt, n); int ret = strlen(p); - free(p); + mmt_free(p); return ret; } @@ -848,7 +846,7 @@ void avr_mem_display(FILE *f, const AVRPART *p, const char *prefix) { m_char_max[1], m->size, m_char_max[2], m->page_size, m_char_max[3], m_offset); - free(m_offset); + mmt_free(m_offset); } else { fprintf(f, "%s%-*s %*d %*d\n", prefix, @@ -856,7 +854,7 @@ void avr_mem_display(FILE *f, const AVRPART *p, const char *prefix) { m_char_max[1], m->size, m_char_max[2], m->page_size); } - free(m_desc_str); + mmt_free(m_desc_str); } } @@ -922,7 +920,7 @@ int avr_variants_display(FILE *f, const AVRPART *p, const char *prefix) { */ AVRPART *avr_new_part(void) { - AVRPART *p = (AVRPART *) cfg_malloc("avr_new_part()", sizeof(AVRPART)); + AVRPART *p = (AVRPART *) mmt_malloc(sizeof(AVRPART)); const char *nulp = cache_string(""); memset(p, 0, sizeof(*p)); @@ -986,13 +984,12 @@ AVRPART *avr_dup_part(const AVRPART *d) { return p; } -void avr_free_part(AVRPART * d) -{ - ldestroy_cb(d->mem, (void(*)(void *))avr_free_mem); +void avr_free_part(AVRPART * d) { + ldestroy_cb(d->mem, (void(*)(void *)) avr_free_mem); d->mem = NULL; - ldestroy_cb(d->mem_alias, (void(*)(void *))avr_free_memalias); + ldestroy_cb(d->mem_alias, (void(*)(void *)) avr_free_memalias); d->mem_alias = NULL; - ldestroy_cb(d->variants, free); + ldestroy_cb(d->variants, mmt_f_free); d->variants = NULL; /* do not free d->parent_id and d->config_file */ @@ -1002,7 +999,7 @@ void avr_free_part(AVRPART * d) d->op[i] = NULL; } } - free(d); + mmt_free(d); } AVRPART *locate_part(const LISTID parts, const char *partdesc) { @@ -1159,7 +1156,7 @@ char *cmdbitstr(CMDBIT cb) { else space[1] = 0; - return cfg_strdup("cmdbitstr()", space); + return mmt_strdup(space); } @@ -1201,7 +1198,7 @@ char *opcode2str(const OPCODE *op, int opnum, int detailed) { int compact = 1, printbit; if(!op) - return cfg_strdup("opcode2str()", "NULL"); + return mmt_strdup("NULL"); // Can the opcode be printed in a compact way? Only if i, o and a bits are systematic. for(int i=31; i >= 0; i--) @@ -1245,7 +1242,7 @@ char *opcode2str(const OPCODE *op, int opnum, int detailed) { *sp++ = '"'; *sp = 0; - return cfg_strdup("opcode2str()", space); + return mmt_strdup(space); } diff --git a/src/buspirate.c b/src/buspirate.c index cf8287e6..8a741570 100644 --- a/src/buspirate.c +++ b/src/buspirate.c @@ -63,6 +63,8 @@ #define BP_FLAG_XPARM_CPUFREQ (1<<5) #define BP_FLAG_XPARM_RAWFREQ (1<<6) #define BP_FLAG_NOPAGEDREAD (1<<7) +#define BP_FLAG_PULLUPS (1<<8) +#define BP_FLAG_HIZ (1<<9) struct pdata { @@ -77,15 +79,23 @@ struct pdata unsigned char pin_val; /* Last written pin values for bitbang mode */ int unread_bytes; /* How many bytes we expected, but ignored */ int flag; + char buf_local[100]; /* Local buffer for buspirate_readline_noexit() */ }; #define PDATA(pgm) ((struct pdata *)(pgm->cookie)) /* ====== Feature checks ====== */ -static inline int -buspirate_uses_ascii(const PROGRAMMER *pgm) { +static inline int buspirate_uses_ascii(const PROGRAMMER *pgm) { return (PDATA(pgm)->flag & BP_FLAG_XPARM_FORCE_ASCII); } +static inline int buspirate_uses_pullups(const PROGRAMMER *pgm) { + return (PDATA(pgm)->flag & BP_FLAG_PULLUPS); +} + +static inline int buspirate_uses_hiz(const PROGRAMMER *pgm) { + return (PDATA(pgm)->flag & BP_FLAG_HIZ); +} + /* ====== Serial talker functions - binmode ====== */ static void dump_mem(const unsigned char *buf, size_t len) @@ -174,12 +184,9 @@ static char *buspirate_readline_noexit(const PROGRAMMER *pgm, char *buf, size_t int c; long orig_serial_recv_timeout = serial_recv_timeout; - /* Static local buffer - this may come handy at times */ - static char buf_local[100]; - if (buf == NULL) { - buf = buf_local; - len = sizeof(buf_local); + buf = PDATA(pgm)->buf_local; + len = sizeof(PDATA(pgm)->buf_local); } buf_p = buf; memset(buf, 0, len); @@ -214,6 +221,7 @@ static char *buspirate_readline(const PROGRAMMER *pgm, char *buf, size_t len) { } return ret; } + static int buspirate_send(const PROGRAMMER *pgm, const char *str) { int rc; const char * readline; @@ -279,8 +287,7 @@ static void buspirate_dummy_6(const PROGRAMMER *pgm, const char *p) { } /* ====== Config / parameters handling functions ====== */ -static int -buspirate_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { +static int buspirate_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { LNODEID ln; const char *extended_param; char reset[10]; @@ -297,6 +304,16 @@ buspirate_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { continue; } + if (str_eq(extended_param, "pullups")) { + PDATA(pgm)->flag |= BP_FLAG_PULLUPS; + continue; + } + + if (str_eq(extended_param, "hiz")) { + PDATA(pgm)->flag |= BP_FLAG_HIZ; + continue; + } + if (sscanf(extended_param, "spifreq=%u", &spifreq) == 1) { if (spifreq & (~0x07)) { pmsg_error("spifreq must be between 0 and 7\n"); @@ -386,8 +403,10 @@ buspirate_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { msg_error(" -xnopagedread Disable page read functionality\n"); msg_error(" -xcpufreq=<125..4000> Set the AUX pin to output a frequency to n [kHz]\n"); msg_error(" -xserial_recv_timeout= Set serial receive timeout to [ms]\n"); + msg_error(" -xpullups Enable internal pull-ups\n"); + msg_error(" -xhiz SPI HiZ mode (open collector)\n"); msg_error(" -xhelp Show this help menu and exit\n"); - exit(0); + return LIBAVRDUDE_EXIT;; } pmsg_error("do not understand extended param '%s'\n", extended_param); @@ -397,8 +416,7 @@ buspirate_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { return 0; } -static int -buspirate_verifyconfig(const PROGRAMMER *pgm) { +static int buspirate_verifyconfig(const PROGRAMMER *pgm) { /* Default reset pin is CS */ if (PDATA(pgm)->reset == 0x00) PDATA(pgm)->reset |= BP_RESET_CS; @@ -515,6 +533,10 @@ static int buspirate_start_mode_bin(PROGRAMMER *pgm) * of the pulse (0) * => 0b10001010 = 0x8a */ submode.config = 0x8A; + if (buspirate_uses_hiz(pgm)) { + submode.config &= ~(1<<3); + pmsg_info("spi hi-z mode (open-collector)\n"); + } } unsigned char buf[20] = { '\0' }; @@ -575,7 +597,7 @@ static int buspirate_start_mode_bin(PROGRAMMER *pgm) pgm->paged_write = NULL; } else { /* Check for write-then-read without !CS/CS and disable paged_write if absent: */ - static const unsigned char buf2[] = {5,0,0,0,0}; + const unsigned char buf2[] = {5, 0, 0, 0, 0}; buspirate_send_bin(pgm, buf2, sizeof(buf2)); buspirate_recv_bin(pgm, buf, 1); if (buf[0] != 0x01) { @@ -599,6 +621,11 @@ static int buspirate_start_mode_bin(PROGRAMMER *pgm) /* 0b0100wxyz - Configure peripherals w=power, x=pull-ups/aux2, y=AUX, z=CS * we want power (0x48) and all reset pins high. */ PDATA(pgm)->current_peripherals_config = 0x48 | PDATA(pgm)->reset; + if (buspirate_uses_pullups(pgm)) { + PDATA(pgm)->current_peripherals_config |= 1<<2; + submode.config &= ~(1<<3); + pmsg_info("enabling pull-ups (open-collector)\n"); + } if (buspirate_expect_bin_byte(pgm, PDATA(pgm)->current_peripherals_config, 0x01) < 0) return -1; usleep(50000); // sleep for 50ms after power up @@ -621,7 +648,7 @@ static int buspirate_start_mode_bin(PROGRAMMER *pgm) return -1; if (rv) { unsigned int ver = 0; - static const unsigned char buf2[] = {1}; + const unsigned char buf2[] = {1}; buspirate_send_bin(pgm, buf2, sizeof(buf2)); buspirate_recv_bin(pgm, buf, 3); ver = buf[1] << 8 | buf[2]; @@ -693,8 +720,8 @@ static int buspirate_start_spi_mode_ascii(const PROGRAMMER *pgm) { } static void buspirate_enable(PROGRAMMER *pgm, const AVRPART *p) { - static const char *reset_str = "#\n"; - static const char *accept_str = "y\n"; + const char * const reset_str = "#\n"; + const char * const accept_str = "y\n"; char *rcvd; int rc, print_banner = 0; @@ -721,7 +748,7 @@ static void buspirate_enable(PROGRAMMER *pgm, const AVRPART *p) { msg_info("attempting to initiate BusPirate ASCII mode ...\n"); - /* Call buspirate_send_bin() instead of buspirate_send() + /* Call buspirate_send_bin() instead of buspirate_send() * because we don't know if BP is in text or bin mode */ rc = buspirate_send_bin(pgm, (const unsigned char*)reset_str, strlen(reset_str)); if (rc) { @@ -937,6 +964,7 @@ static int buspirate_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const A return n_bytes; } + /* Paged write function which utilizes the Bus Pirate's "Write then Read" binary SPI instruction */ static int buspirate_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int page_size, unsigned int base_addr, unsigned int n_data_bytes) { @@ -1087,20 +1115,16 @@ static int buspirate_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { } /* Interface - management */ -static void buspirate_setup(PROGRAMMER *pgm) -{ - /* Allocate private data */ - if ((pgm->cookie = calloc(1, sizeof(struct pdata))) == 0) { - pmsg_error("out of memory allocating private data\n"); - exit(1); - } +static void buspirate_setup(PROGRAMMER *pgm) { + pgm->cookie = mmt_malloc(sizeof(struct pdata)); PDATA(pgm)->serial_recv_timeout = 100; } -static void buspirate_teardown(PROGRAMMER *pgm) -{ - free(pgm->cookie); +static void buspirate_teardown(PROGRAMMER *pgm) { + mmt_free(pgm->cookie); + pgm->cookie = NULL; } + const char buspirate_desc[] = "Using the Bus Pirate's SPI interface for programming"; void buspirate_initpgm(PROGRAMMER *pgm) { @@ -1180,7 +1204,7 @@ static void buspirate_bb_enable(PROGRAMMER *pgm, const AVRPART *p) { return; } -/* +/* Direction: 010xxxxx Input (1) or output (0): @@ -1248,7 +1272,7 @@ static int buspirate_bb_setpin_internal(const PROGRAMMER *pgm, int pin, int valu if (value) PDATA(pgm)->pin_val |= (1 << (pin - 1)); - else + else PDATA(pgm)->pin_val &= ~(1 << (pin - 1)); buf[0] = PDATA(pgm)->pin_val | 0x80; diff --git a/src/butterfly.c b/src/butterfly.c index 64ffb11b..9d453748 100644 --- a/src/butterfly.c +++ b/src/butterfly.c @@ -56,22 +56,39 @@ struct pdata { char has_auto_incr_addr; unsigned int buffersize; + + int ctype; // Cache one byte for flash + unsigned char cvalue; + unsigned long caddr; }; #define PDATA(pgm) ((struct pdata *)(pgm->cookie)) -static void butterfly_setup(PROGRAMMER * pgm) -{ - if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) { - pmsg_error("out of memory allocating private data\n"); - exit(1); - } - memset(pgm->cookie, 0, sizeof(struct pdata)); +// Print error and return when command failed +#define EI(x) do { \ + int Eret = (x); \ + if(Eret < 0) { \ + pmsg_error("%s failed\n", #x); \ + return -1; \ + } \ +} while(0) + +#define EV(x) do { \ + int Eret = (x); \ + if(Eret < 0) { \ + pmsg_error("%s failed\n", #x); \ + return; \ + } \ +} while(0) + + +static void butterfly_setup(PROGRAMMER *pgm) { + pgm->cookie = mmt_malloc(sizeof(struct pdata)); } -static void butterfly_teardown(PROGRAMMER * pgm) -{ - free(pgm->cookie); +static void butterfly_teardown(PROGRAMMER *pgm) { + mmt_free(pgm->cookie); + pgm->cookie = NULL; } static int butterfly_send(const PROGRAMMER *pgm, char *buf, size_t len) { @@ -80,14 +97,7 @@ static int butterfly_send(const PROGRAMMER *pgm, char *buf, size_t len) { static int butterfly_recv(const PROGRAMMER *pgm, char *buf, size_t len) { - int rv; - - rv = serial_recv(&pgm->fd, (unsigned char *)buf, len); - if (rv < 0) { - pmsg_error("programmer is not responding\n"); - return -1; - } - return 0; + return serial_recv(&pgm->fd, (unsigned char *) buf, len); } @@ -99,11 +109,12 @@ static int butterfly_drain(const PROGRAMMER *pgm, int display) { static int butterfly_vfy_cmd_sent(const PROGRAMMER *pgm, char *errmsg) { char c; - butterfly_recv(pgm, &c, 1); + EI(butterfly_recv(pgm, &c, 1)); if (c != '\r') { - pmsg_error("programmer did not respond to command: %s\n", errmsg); + pmsg_error("protocol error for command: %s\n", errmsg); return -1; } + return 0; } @@ -127,7 +138,7 @@ static int butterfly_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { if(serial_recv_timeout < new_timeout) serial_recv_timeout = new_timeout; - butterfly_send(pgm, "e", 1); + EI(butterfly_send(pgm, "e", 1)); if(butterfly_vfy_cmd_sent(pgm, "chip erase") < 0) ret = -1; @@ -136,23 +147,20 @@ static int butterfly_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { } -static void butterfly_enter_prog_mode(const PROGRAMMER *pgm) { - butterfly_send(pgm, "P", 1); - butterfly_vfy_cmd_sent(pgm, "enter prog mode"); +static int butterfly_enter_prog_mode(const PROGRAMMER *pgm) { + EI(butterfly_send(pgm, "P", 1)); + return butterfly_vfy_cmd_sent(pgm, "enter prog mode"); } static void butterfly_leave_prog_mode(const PROGRAMMER *pgm) { - butterfly_send(pgm, "L", 1); + EV(butterfly_send(pgm, "L", 1)); butterfly_vfy_cmd_sent(pgm, "leave prog mode"); } -/* - * issue the 'program enable' command to the AVR device - */ static int butterfly_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { - return -1; + return butterfly_enter_prog_mode(pgm); } @@ -199,22 +207,22 @@ static int butterfly_initialize(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char mk_timeout = 0; msg_notice("."); - butterfly_send(pgm, mk_reset_cmd, sizeof(mk_reset_cmd)); + EI(butterfly_send(pgm, mk_reset_cmd, sizeof(mk_reset_cmd))); usleep(20000); do { c = 27; - butterfly_send(pgm, &c, 1); + EI(butterfly_send(pgm, &c, 1)); usleep(20000); c = 0xaa; usleep(80000); - butterfly_send(pgm, &c, 1); + EI(butterfly_send(pgm, &c, 1)); if (mk_timeout % 10 == 0) msg_notice("."); } while (mk_timeout++ < 10); - butterfly_recv(pgm, &c, 1); + EI(butterfly_recv(pgm, &c, 1)); if ( c != 'M' && c != '?') { msg_error("\n"); @@ -230,10 +238,10 @@ static int butterfly_initialize(const PROGRAMMER *pgm, const AVRPART *p) { { do { msg_notice("."); - butterfly_send(pgm, "\033", 1); - butterfly_drain(pgm, 0); - butterfly_send(pgm, "S", 1); - butterfly_recv(pgm, &c, 1); + EI(butterfly_send(pgm, "\033", 1)); + (void) butterfly_drain(pgm, 0); + EI(butterfly_send(pgm, "S", 1)); + EI(butterfly_recv(pgm, &c, 1)); if (c != '?') { msg_notice("\n"); /* @@ -242,28 +250,28 @@ static int butterfly_initialize(const PROGRAMMER *pgm, const AVRPART *p) { * the null. */ id[0] = c; - butterfly_recv(pgm, &id[1], sizeof(id)-2); + EI(butterfly_recv(pgm, &id[1], sizeof(id)-2)); id[sizeof(id)-1] = '\0'; } } while (c == '?'); } /* Get the HW and SW versions to see if the programmer is present. */ - butterfly_drain(pgm, 0); + (void) butterfly_drain(pgm, 0); - butterfly_send(pgm, "V", 1); - butterfly_recv(pgm, sw, sizeof(sw)); + EI(butterfly_send(pgm, "V", 1)); + EI(butterfly_recv(pgm, sw, sizeof(sw))); - butterfly_send(pgm, "v", 1); - butterfly_recv(pgm, hw, 1); /* first, read only _one_ byte */ + EI(butterfly_send(pgm, "v", 1)); + EI(butterfly_recv(pgm, hw, 1)); // First, read only _one_ byte if (hw[0]!='?') { - butterfly_recv(pgm, &hw[1], 1);/* now, read second byte */ + EI(butterfly_recv(pgm, &hw[1], 1)); // Now, read second byte }; /* Get the programmer type (serial or parallel). Expect serial. */ - butterfly_send(pgm, "p", 1); - butterfly_recv(pgm, &type, 1); + EI(butterfly_send(pgm, "p", 1)); + EI(butterfly_recv(pgm, &type, 1)); msg_notice("Programmer id = %s; type = %c\n", id, type); msg_notice("Software version = %c.%c; ", sw[0], sw[1]); @@ -275,34 +283,34 @@ static int butterfly_initialize(const PROGRAMMER *pgm, const AVRPART *p) { /* See if programmer supports autoincrement of address. */ - butterfly_send(pgm, "a", 1); - butterfly_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1); + EI(butterfly_send(pgm, "a", 1)); + EI(butterfly_recv(pgm, &PDATA(pgm)->has_auto_incr_addr, 1)); if (PDATA(pgm)->has_auto_incr_addr == 'Y') msg_notice("programmer supports auto addr increment\n"); /* Check support for buffered memory access, abort if not available */ - butterfly_send(pgm, "b", 1); - butterfly_recv(pgm, &c, 1); + EI(butterfly_send(pgm, "b", 1)); + EI(butterfly_recv(pgm, &c, 1)); if (c != 'Y') { pmsg_notice("buffered memory access not supported; maybe it isn't\n"\ "a butterfly/AVR109 but a AVR910 device?\n"); return -1; }; - butterfly_recv(pgm, &c, 1); + EI(butterfly_recv(pgm, &c, 1)); PDATA(pgm)->buffersize = (unsigned int)(unsigned char)c<<8; - butterfly_recv(pgm, &c, 1); + EI(butterfly_recv(pgm, &c, 1)); PDATA(pgm)->buffersize += (unsigned int)(unsigned char)c; msg_notice("programmer supports buffered memory access with buffersize=%i bytes\n", PDATA(pgm)->buffersize); /* Get list of devices that the programmer supports. */ - butterfly_send(pgm, "t", 1); + EI(butterfly_send(pgm, "t", 1)); msg_notice2("\nProgrammer supports the following devices:\n"); devtype_1st = 0; while (1) { - butterfly_recv(pgm, &c, 1); + EI(butterfly_recv(pgm, &c, 1)); if (devtype_1st == 0) devtype_1st = c; @@ -323,14 +331,15 @@ static int butterfly_initialize(const PROGRAMMER *pgm, const AVRPART *p) { buf[0] = 'T'; buf[1] = devtype_1st; - butterfly_send(pgm, buf, 2); + EI(butterfly_send(pgm, buf, 2)); if (butterfly_vfy_cmd_sent(pgm, "select device") < 0) return -1; pmsg_notice("devcode selected: 0x%02x\n", (unsigned) buf[1]); - butterfly_enter_prog_mode(pgm); - butterfly_drain(pgm, 0); + if(pgm->program_enable(pgm, p) < 0) + return -1; + (void) butterfly_drain(pgm, 0); return 0; } @@ -367,7 +376,7 @@ static int butterfly_open(PROGRAMMER *pgm, const char *port) { /* * drain any extraneous input */ - butterfly_drain (pgm, 0); + (void) butterfly_drain(pgm, 0); return 0; } @@ -376,7 +385,7 @@ static int butterfly_open(PROGRAMMER *pgm, const char *port) { static void butterfly_close(PROGRAMMER * pgm) { /* "exit programmer" */ - butterfly_send(pgm, "E", 1); + EV(butterfly_send(pgm, "E", 1)); butterfly_vfy_cmd_sent(pgm, "exit bootloader"); serial_close(&pgm->fd); @@ -397,7 +406,7 @@ static void butterfly_set_addr(const PROGRAMMER *pgm, unsigned long addr) { cmd[1] = (addr >> 8) & 0xff; cmd[2] = addr & 0xff; - butterfly_send(pgm, cmd, sizeof(cmd)); + EV(butterfly_send(pgm, cmd, sizeof(cmd))); butterfly_vfy_cmd_sent(pgm, "set addr"); } else { char cmd[4]; @@ -407,7 +416,7 @@ static void butterfly_set_addr(const PROGRAMMER *pgm, unsigned long addr) { cmd[2] = (addr >> 8) & 0xff; cmd[3] = addr & 0xff; - butterfly_send(pgm, cmd, sizeof(cmd)); + EV(butterfly_send(pgm, cmd, sizeof(cmd))); butterfly_vfy_cmd_sent(pgm, "set extaddr"); } } @@ -421,7 +430,7 @@ static void butterfly_set_extaddr(const PROGRAMMER *pgm, unsigned long addr) { cmd[2] = (addr >> 8) & 0xff; cmd[3] = addr & 0xff; - butterfly_send(pgm, cmd, sizeof(cmd)); + EV(butterfly_send(pgm, cmd, sizeof(cmd))); butterfly_vfy_cmd_sent(pgm, "set extaddr"); } @@ -432,30 +441,30 @@ static int butterfly_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const A { char cmd[6]; int size; - int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL; - if (mem_is_flash(m) || mem_is_eeprom(m)) - { + if(mem_is_flash(m)) { + int ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL; + + PDATA(pgm)->ctype = 0; // Invalidate read cache cmd[0] = 'B'; cmd[1] = 0; - if ((cmd[3] = toupper((int)(m->desc[0]))) == 'E') { /* write to eeprom */ - cmd[2] = 1; - cmd[4] = value; - size = 5; - } else { /* write to flash */ - /* @@@ not yet implemented */ - cmd[2] = 2; - size = 6; - return -1; - } - if (use_ext_addr) { - butterfly_set_extaddr(pgm, addr); - } else { - butterfly_set_addr(pgm, addr); - } + cmd[2] = 2; + cmd[3] = 'F'; + size = 6; + (ext_addr? butterfly_set_extaddr: butterfly_set_addr)(pgm, addr >> 1); + + return -1; // @@@ not yet implemented (and what about usersig?) } - else if (mem_is_lock(m)) - { + + if(mem_is_eeprom(m)) { + cmd[0] = 'B'; + cmd[1] = 0; + cmd[2] = 1; + cmd[3] = 'E'; + cmd[4] = value; + size = 5; + butterfly_set_addr(pgm, addr); + } else if(mem_is_lock(m)) { cmd[0] = 'l'; cmd[1] = value; size = 2; @@ -470,7 +479,7 @@ static int butterfly_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const A else return -1; - butterfly_send(pgm, cmd, size); + EI(butterfly_send(pgm, cmd, size)); if (butterfly_vfy_cmd_sent(pgm, "write byte") < 0) return -1; @@ -481,44 +490,31 @@ static int butterfly_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const A static int butterfly_read_byte_flash(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr, unsigned char * value) { - static int cached = 0; - static unsigned char cvalue; - static unsigned long caddr; - int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL; + int ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL; + char mtype = mem_is_flash(m)? 'F': mem_is_sigrow(m)? 'P': mem_is_userrow(m)? 'U': '?'; - if (cached && ((caddr + 1) == addr)) { - *value = cvalue; - cached = 0; + if(mtype == '?') { + pmsg_error("cannot read memory %s\n", m->desc); + return -1; } - else { - char buf[2]; - if (use_ext_addr) { - butterfly_set_extaddr(pgm, addr >> 1); - } else { - butterfly_set_addr(pgm, addr >> 1); - } - // Defaults to flash read ('F') - char msg[4] = {'g', 0x00, 0x02, 'F'}; - if (mem_is_sigrow(m)) - msg[3] = 'P'; - else if (mem_is_userrow(m)) - msg[3] = 'U'; - butterfly_send(pgm, msg, 4); - /* Read back the program mem word (MSB first) */ - butterfly_recv(pgm, buf, sizeof(buf)); - - if ((addr & 0x01) == 0) { - *value = buf[0]; - cached = 1; - cvalue = buf[1]; - caddr = addr; - } - else { - *value = buf[1]; - } + if(PDATA(pgm)->ctype == mtype && PDATA(pgm)->caddr == addr) { + *value = PDATA(pgm)->cvalue; + return 0; } + char buf[2]; // Read word and cache the other byte + char msg[4] = {'g', 0x00, 0x02, mtype}; + + (ext_addr? butterfly_set_extaddr: butterfly_set_addr)(pgm, addr >> 1); + EI(butterfly_send(pgm, msg, 4)); + EI(butterfly_recv(pgm, buf, sizeof(buf))); + + PDATA(pgm)->ctype = mtype; + *value = buf[addr & 1]; + PDATA(pgm)->cvalue = buf[1 - (addr & 1)]; + PDATA(pgm)->caddr = addr ^ 1; + return 0; } @@ -527,8 +523,8 @@ static int butterfly_read_byte_eeprom(const PROGRAMMER *pgm, const AVRPART *p, c unsigned long addr, unsigned char * value) { butterfly_set_addr(pgm, addr); - butterfly_send(pgm, "g\000\001E", 4); - butterfly_recv(pgm, (char *)value, 1); + EI(butterfly_send(pgm, "g\000\001E", 4)); + EI(butterfly_recv(pgm, (char *) value, 1)); return 0; } @@ -560,8 +556,8 @@ static int butterfly_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AV else return -1; - butterfly_send(pgm, &cmd, 1); - butterfly_recv(pgm, (char *)value, 1); + EI(butterfly_send(pgm, &cmd, 1)); + EI(butterfly_recv(pgm, (char *) value, 1)); return *value == '?'? -1: 0; } @@ -575,50 +571,51 @@ static int butterfly_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const unsigned int max_addr = addr + n_bytes; char *cmd; unsigned int blocksize = PDATA(pgm)->buffersize; - int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL; - unsigned int wr_size = 2; + int ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL; + int isee = mem_is_eeprom(m); - if (!mem_is_flash(m) && !mem_is_eeprom(m) && !mem_is_userrow(m)) + if (!mem_is_flash(m) && !isee && !mem_is_userrow(m)) return -2; - if (m->desc[0] == 'e') - wr_size = blocksize = 1; /* Write to eeprom single bytes only */ + if(isee) // Write single bytes to EEPROM + blocksize = 1; + else + PDATA(pgm)->ctype = 0; // Invalidate flash byte read cache - if (use_ext_addr) { - butterfly_set_extaddr(pgm, addr / wr_size); - } else { - butterfly_set_addr(pgm, addr / wr_size); - } + (ext_addr? butterfly_set_extaddr: butterfly_set_addr)(pgm, isee? addr: addr>>1); #if 0 usleep(1000000); - butterfly_send(pgm, "y", 1); + EI(butterfly_send(pgm, "y", 1)); if (butterfly_vfy_cmd_sent(pgm, "clear LED") < 0) return -1; #endif - cmd = malloc(4+blocksize); - if (!cmd) return -1; + cmd = mmt_malloc(4+blocksize); + cmd[0] = 'B'; - cmd[3] = toupper((int)(m->desc[0])); + cmd[3] = isee? 'E': mem_is_flash(m)? 'F': 'U'; while (addr < max_addr) { - if ((max_addr - addr) < blocksize) { + if ((max_addr - addr) < blocksize) blocksize = max_addr - addr; - }; + memcpy(&cmd[4], &m->buf[addr], blocksize); cmd[1] = (blocksize >> 8) & 0xff; cmd[2] = blocksize & 0xff; - butterfly_send(pgm, cmd, 4+blocksize); - if (butterfly_vfy_cmd_sent(pgm, "write block") < 0) + if(butterfly_send(pgm, cmd, 4+blocksize) < 0 || + butterfly_vfy_cmd_sent(pgm, "write block") < 0) { + + mmt_free(cmd); return -1; + } addr += blocksize; - } /* while */ - free(cmd); + } + mmt_free(cmd); - return addr; + return n_bytes; } @@ -628,43 +625,38 @@ static int butterfly_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const A unsigned int addr, unsigned int n_bytes) { unsigned int max_addr = addr + n_bytes; - int rd_size = 2; int blocksize = PDATA(pgm)->buffersize; - int use_ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL; + int ext_addr = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL; + int isee = mem_is_eeprom(m); - /* check parameter syntax: only "flash", "eeprom" or "usersig"/"userrow" is allowed */ - if (!mem_is_flash(m) && !mem_is_eeprom(m) && !mem_is_userrow(m)) + // Only flash, EEPROM or usersig/userrow is allowed + if (!mem_is_flash(m) && !isee && !mem_is_userrow(m)) return -2; - if (m->desc[0] == 'e') - rd_size = blocksize = 1; /* Read from eeprom single bytes only */ + if(isee) // Read single bytes from EEPROM + blocksize = 1; - { /* use buffered mode */ - char cmd[4]; + char cmd[4]; - cmd[0] = 'g'; - cmd[3] = toupper((int)(m->desc[0])); + cmd[0] = 'g'; + cmd[3] = isee? 'E': mem_is_flash(m)? 'F': 'U'; - if (use_ext_addr) { - butterfly_set_extaddr(pgm, addr / rd_size); - } else { - butterfly_set_addr(pgm, addr / rd_size); - } - while (addr < max_addr) { - if ((max_addr - addr) < (unsigned int) blocksize) { - blocksize = max_addr - addr; - }; - cmd[1] = (blocksize >> 8) & 0xff; - cmd[2] = blocksize & 0xff; + (ext_addr? butterfly_set_extaddr: butterfly_set_addr)(pgm, isee? addr: addr>>1); - butterfly_send(pgm, cmd, 4); - butterfly_recv(pgm, (char *)&m->buf[addr], blocksize); + while (addr < max_addr) { + if ((max_addr - addr) < (unsigned int) blocksize) + blocksize = max_addr - addr; - addr += blocksize; - } /* while */ + cmd[1] = (blocksize >> 8) & 0xff; + cmd[2] = blocksize & 0xff; + + EI(butterfly_send(pgm, cmd, 4)); + EI(butterfly_recv(pgm, (char *) &m->buf[addr], blocksize)); + + addr += blocksize; } - return addr * rd_size; + return n_bytes; } @@ -677,8 +669,8 @@ static int butterfly_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *p, con return -1; } - butterfly_send(pgm, "s", 1); - butterfly_recv(pgm, (char *)m->buf, 3); + EI(butterfly_send(pgm, "s", 1)); + EI(butterfly_recv(pgm, (char *) m->buf, 3)); /* Returned signature has wrong order. */ tmp = m->buf[2]; m->buf[2] = m->buf[0]; diff --git a/src/ch341a.c b/src/ch341a.c index 42f4d9f5..60bf9395 100644 --- a/src/ch341a.c +++ b/src/ch341a.c @@ -49,8 +49,6 @@ #include #ifdef USE_LIBUSB_1_0 -static libusb_context *ctx = NULL; - static int libusb_to_errno(int result) { switch (result) { case LIBUSB_SUCCESS: @@ -96,6 +94,9 @@ static int libusb_to_errno(int result) { struct pdata { libusb_device_handle *usbhandle; int sckfreq_hz; + + libusb_context *ctx; + int USB_init; // Used in ch341a_open() }; #define PDATA(pgm) ((struct pdata *)(pgm->cookie)) @@ -204,13 +205,12 @@ static int ch341a_open(PROGRAMMER *pgm, const char *port) { int pid, vid, j, r; int errorCode = USB_ERROR_NOTFOUND; libusb_device_handle *handle = NULL; - static int didUsbInit = 0; pmsg_trace("ch341a_open(\"%s\")\n", port); - if(!didUsbInit) { - didUsbInit = 1; - libusb_init(&ctx); + if(!PDATA(pgm)->USB_init) { + PDATA(pgm)->USB_init = 1; + libusb_init(&PDATA(pgm)->ctx); } if(usbpid) { @@ -223,7 +223,7 @@ static int ch341a_open(PROGRAMMER *pgm, const char *port) { vid = pgm->usbvid? pgm->usbvid: CH341A_VID; libusb_device **dev_list; - int dev_list_len = libusb_get_device_list(ctx, &dev_list); + int dev_list_len = libusb_get_device_list(PDATA(pgm)->ctx, &dev_list); for(j = 0; j < dev_list_len; ++j) { libusb_device *dev = dev_list[j]; @@ -252,7 +252,7 @@ static int ch341a_open(PROGRAMMER *pgm, const char *port) { if((r = libusb_claim_interface(PDATA(pgm)->usbhandle, 0))) { pmsg_error("libusb_claim_interface failed, return value %d (%s)\n", r, libusb_error_name(r)); libusb_close(PDATA(pgm)->usbhandle); - libusb_exit(ctx); + libusb_exit(PDATA(pgm)->ctx); return -1; } return 0; @@ -272,7 +272,7 @@ static void ch341a_close(PROGRAMMER *pgm) { libusb_release_interface(PDATA(pgm)->usbhandle, 0); libusb_close(PDATA(pgm)->usbhandle); } - libusb_exit(ctx); + libusb_exit(PDATA(pgm)->ctx); } @@ -429,11 +429,12 @@ static int ch341a_spi_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { // Interface management static void ch341a_setup(PROGRAMMER *pgm) { - pgm->cookie = cfg_malloc(__func__, sizeof(struct pdata)); + pgm->cookie = mmt_malloc(sizeof(struct pdata)); } static void ch341a_teardown(PROGRAMMER *pgm) { - free(pgm->cookie); + mmt_free(pgm->cookie); + pgm->cookie = NULL; } // Dummy functions @@ -487,4 +488,4 @@ void ch341a_initpgm(PROGRAMMER * pgm) { } #endif // !defined(HAVE_LIBUSB_1_0) -const char ch341a_desc[] = "Driver for \"ch341a\"-type programmers"; +const char ch341a_desc[] = "Programmer chip CH341A (AVR must have minimum F_CPU of 6.8 MHz)"; diff --git a/src/cmake_config.h.in b/src/cmake_config.h.in index b8e9c250..f11ca00c 100644 --- a/src/cmake_config.h.in +++ b/src/cmake_config.h.in @@ -30,6 +30,12 @@ /* Let linuxgpio know if libgpiod is available. */ #cmakedefine HAVE_LIBGPIOD +/* Let linuxgpio know whether libgpiod is available in version >= v1.6 but < v2.0. */ +#cmakedefine01 HAVE_LIBGPIOD_V1_6 + +/* Let linuxgpio know whether v2.0 or higher of libgpiod is available. */ +#cmakedefine01 HAVE_LIBGPIOD_V2 + /* Linux SPI support enabled */ #cmakedefine HAVE_LINUXSPI 1 diff --git a/src/config.c b/src/config.c index 8c376606..b9b9adb5 100644 --- a/src/config.c +++ b/src/config.c @@ -162,10 +162,10 @@ Component_t avr_comp[] = { void cleanup_config(void) { - ldestroy_cb(part_list, (void(*)(void*))avr_free_part); - ldestroy_cb(programmers, (void(*)(void*))pgm_free); - ldestroy_cb(string_list, (void(*)(void*))free_token); - ldestroy_cb(number_list, (void(*)(void*))free_token); + ldestroy_cb(part_list, (void(*)(void*)) avr_free_part); + ldestroy_cb(programmers, (void(*)(void*)) pgm_free); + ldestroy_cb(string_list, (void(*)(void*)) free_token); + ldestroy_cb(number_list, (void(*)(void*)) free_token); } int init_config(void) @@ -188,7 +188,8 @@ int init_config(void) void *cfg_malloc(const char *funcname, size_t n) { void *ret = malloc(n); if(!ret) { - pmsg_error("out of memory in %s (needed %lu bytes)\n", funcname, (unsigned long) n); + pmsg_error("out of memory in %s() for malloc(); needed %lu bytes\n", + funcname, (unsigned long) n); exit(1); } memset(ret, 0, n); @@ -197,12 +198,11 @@ void *cfg_malloc(const char *funcname, size_t n) { void *cfg_realloc(const char *funcname, void *p, size_t n) { void *ret; - if(!(ret = p? realloc(p, n): calloc(1, n))) { - pmsg_error("out of memory in %s (needed %lu bytes)\n", funcname, (unsigned long) n); + pmsg_error("out of memory in %s() for %salloc(); needed %lu bytes\n", + funcname, p? "re": "c", (unsigned long) n); exit(1); } - return ret; } @@ -210,13 +210,18 @@ void *cfg_realloc(const char *funcname, void *p, size_t n) { char *cfg_strdup(const char *funcname, const char *s) { char *ret = strdup(s); if(!ret) { - pmsg_error("out of memory in %s\n", funcname); + pmsg_error("out of memory in %s() for strdup()\n", funcname); exit(1); } return ret; } +void mmt_f_free(void *ptr) { + mmt_free(ptr); +} + + int yywrap() { return 1; @@ -258,7 +263,7 @@ int yywarning(char * errmsg, ...) TOKEN * new_token(int primary) { - TOKEN * tkn = (TOKEN *) cfg_malloc("new_token()", sizeof(TOKEN)); + TOKEN * tkn = (TOKEN *) mmt_malloc(sizeof(TOKEN)); tkn->primary = primary; return tkn; } @@ -270,12 +275,12 @@ void free_token(TOKEN * tkn) switch (tkn->value.type) { case V_STR: if (tkn->value.string) - free(tkn->value.string); + mmt_free(tkn->value.string); tkn->value.string = NULL; break; } - free(tkn); + mmt_free(tkn); } } @@ -377,7 +382,7 @@ TOKEN *new_constant(const char *con) { TOKEN *new_string(const char *text) { struct token_t *tkn = new_token(TKN_STRING); tkn->value.type = V_STR; - tkn->value.string = cfg_strdup("new_string()", text); + tkn->value.string = mmt_strdup(text); #if DEBUG msg_info("STRING(%s)\n", tkn->value.string); @@ -446,7 +451,7 @@ int read_config(const char * file) f = fopen(cfg_infile, "r"); if (f == NULL) { pmsg_ext_error("cannot open config file %s: %s\n", cfg_infile, strerror(errno)); - free(cfg_infile); + mmt_free(cfg_infile); cfg_infile = NULL; return -1; } @@ -464,7 +469,7 @@ int read_config(const char * file) fclose(f); if(cfg_infile) { - free(cfg_infile); + mmt_free(cfg_infile); cfg_infile = NULL; } @@ -495,18 +500,18 @@ const char *cache_string(const char *p) { h = strhash(p) % (sizeof hstrings/sizeof*hstrings); if(!(hs=hstrings[h])) - hs = hstrings[h] = (char **) cfg_realloc("cache_string()", NULL, (16+1)*sizeof**hstrings); + hs = hstrings[h] = (char **) mmt_realloc(NULL, (16+1)*sizeof**hstrings); for(k=0; hs[k]; k++) if(*p == *hs[k] && str_eq(p, hs[k])) return hs[k]; if(k && k%16 == 0) - hstrings[h] = (char **) cfg_realloc("cache_string()", hstrings[h], (k+16+1)*sizeof**hstrings); + hstrings[h] = (char **) mmt_realloc(hstrings[h], (k+16+1)*sizeof**hstrings); - hstrings[h][k+1]=NULL; + hstrings[h][k+1] = NULL; - return hstrings[h][k] = cfg_strdup("cache_string()", p); + return hstrings[h][k] = mmt_strdup(p); } @@ -532,9 +537,9 @@ COMMENT *locate_comment(const LISTID comments, const char *where, int rhs) { static void addcomment(int rhs) { if(lkw) { - COMMENT *node = cfg_malloc("addcomment()", sizeof(*node)); + COMMENT *node = mmt_malloc(sizeof(*node)); node->rhs = rhs; - node->kw = cfg_strdup("addcomment()", lkw); + node->kw = mmt_strdup(lkw); node->comms = cfg_comms; cfg_comms = NULL; if(!cfg_strctcomms) @@ -557,7 +562,7 @@ LISTID cfg_get_prologue(void) { void capture_comment_str(const char *com, int lineno) { if(!cfg_comms) cfg_comms = lcreat(NULL, 0); - ladd(cfg_comms, cfg_strdup("capture_comment_str()", com)); + ladd(cfg_comms, mmt_strdup(com)); // Last keyword lineno is the same as this comment's if(lkw && lkw_lineno == lineno) @@ -578,8 +583,8 @@ void capture_lvalue_kw(const char *kw, int lineno) { kw = "*"; // Show comment before programmer/part/memory if(lkw) - free(lkw); - lkw = cfg_strdup("capture_lvalue_kw()", kw); + mmt_free(lkw); + lkw = mmt_strdup(kw); lkw_lineno = lineno; if(cfg_comms) // Accrued list of # one-line comments addcomment(0); // Register comment to appear before lkw assignment @@ -784,7 +789,7 @@ char *cfg_unescape(char *d, const char *s) { return (char *) cfg_unescapeu((unsigned char *) d, (const unsigned char *) s); } -// Return an escaped string that looks like a C-style input string incl quotes, memory is malloc'd +// Return an mmt_malloc'd escaped string that looks like a C-style input string incl quotes char *cfg_escape(const char *s) { char buf[50*1024], *d = buf; @@ -828,7 +833,7 @@ char *cfg_escape(const char *s) { *d++ = '"'; *d = 0; - return cfg_strdup("cfg_escape()", buf); + return mmt_strdup(buf); } diff --git a/src/config_gram.y b/src/config_gram.y index 212df9bc..1cac8e58 100644 --- a/src/config_gram.y +++ b/src/config_gram.y @@ -436,7 +436,7 @@ prog_parm : { while (lsize(string_list)) { TOKEN *t = lrmv_n(string_list, 1); - ladd(current_prog->id, cfg_strdup("config_gram.y", t->value.string)); + ladd(current_prog->id, mmt_strdup(t->value.string)); free_token(t); } } @@ -491,11 +491,11 @@ usb_pid_list: { /* overwrite pids, so clear the existing entries */ if(current_prog->usbpid) - ldestroy_cb(current_prog->usbpid, free); + ldestroy_cb(current_prog->usbpid, mmt_f_free); current_prog->usbpid = lcreat(NULL, 0); } { - int *ip = cfg_malloc("usb_pid_list", sizeof(int)); + int *ip = mmt_malloc(sizeof(int)); *ip = $1->value.number; ladd(current_prog->usbpid, ip); free_token($1); @@ -503,7 +503,7 @@ usb_pid_list: } | usb_pid_list TKN_COMMA numexpr { { - int *ip = cfg_malloc("usb_pid_list", sizeof(int)); + int *ip = mmt_malloc(sizeof(int)); *ip = $3->value.number; ladd(current_prog->usbpid, ip); free_token($3); @@ -520,11 +520,11 @@ hvupdi_support_list: { /* overwrite list entries, so clear the existing entries */ if(current_prog->hvupdi_support) - ldestroy_cb(current_prog->hvupdi_support, free); + ldestroy_cb(current_prog->hvupdi_support, mmt_f_free); current_prog->hvupdi_support = lcreat(NULL, 0); } { - int *ip = cfg_malloc("hvupdi_support_list", sizeof(int)); + int *ip = mmt_malloc(sizeof(int)); *ip = $1->value.number; ladd(current_prog->hvupdi_support, ip); free_token($1); @@ -532,7 +532,7 @@ hvupdi_support_list: } | hvupdi_support_list TKN_COMMA numexpr { { - int *ip = cfg_malloc("hvupdi_support_list", sizeof(int)); + int *ip = mmt_malloc(sizeof(int)); *ip = $3->value.number; ladd(current_prog->hvupdi_support, ip); free_token($3); @@ -631,7 +631,7 @@ part_parm : K_VARIANTS TKN_EQUAL K_NULL { { - ldestroy_cb(current_part->variants, free); + ldestroy_cb(current_part->variants, mmt_f_free); current_part->variants = lcreat(NULL, 0); } } | @@ -648,7 +648,7 @@ part_parm : } } if(!found) - ladd(current_part->variants, cfg_strdup("config_gram.y", t->value.string)); + ladd(current_part->variants, mmt_strdup(t->value.string)); free_token(t); } } diff --git a/src/configure.ac b/src/configure.ac index 4b680927..969fc085 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -99,6 +99,13 @@ AC_PROG_LEX([noyywrap]) AM_PROG_AR LT_INIT() +# If macro PKG_PROG_PKG_CONFIG is not available, Autoconf generates a misleading error message, +# so check for existence first, and otherwise provide helpful advice. +m4_ifndef([PKG_PROG_PKG_CONFIG], [m4_fatal(m4_normalize([ + Macro PKG_PROG_PKG_CONFIG is not available. + It is usually defined in file pkg.m4 provided by package pkg-config.]))]) +PKG_PROG_PKG_CONFIG([0.23]) + AH_TEMPLATE([HAVE_YYLEX_DESTROY], [Define if lex/flex has yylex_destroy]) # flex should have this @@ -411,7 +418,7 @@ AC_ARG_ENABLE( AC_ARG_ENABLE( [linuxgpio], AS_HELP_STRING([--enable-linuxgpio], - [Enable the Linux sysfs GPIO interface programmer type]), + [Enable the Linux GPIO interface programmer type]), [case "${enableval}" in yes) enabled_linuxgpio=yes ;; no) enabled_linuxgpio=no ;; @@ -517,6 +524,32 @@ fi if test "x$enabled_linuxgpio" = xyes; then AC_DEFINE([HAVE_LINUXGPIO], [1], [Linux sysfs GPIO support enabled]) confsubst="$confsubst -e /^@HAVE_LINUXGPIO_/d" + + PKG_CHECK_MODULES([LIBGPIOD], [libgpiod >= 2.0], [ + have_libgpiod=yes + have_libgpiodv2=yes + AC_DEFINE([HAVE_LIBGPIOD], [1], [Linux libgpiod available]) + AC_DEFINE([HAVE_LIBGPIOD_V1_6], [0], [Linux libgpiod >= v1.6 but < 2.0 available]) + AC_DEFINE([HAVE_LIBGPIOD_V2], [1], [Linux libgpiod >= 2.0 available]) + ], [ + PKG_CHECK_MODULES([LIBGPIOD], [libgpiod >= 1.6], [ + have_libgpiod=yes + have_libgpiodv1_6=yes + AC_DEFINE([HAVE_LIBGPIOD], [1], [Linux libgpiod available]) + AC_DEFINE([HAVE_LIBGPIOD_V1_6], [1], [Linux libgpiod >= v1.6 but < 2.0 available]) + AC_DEFINE([HAVE_LIBGPIOD_V2], [0], [Linux libgpiod >= 2.0 available]) + ], [ + PKG_CHECK_MODULES([LIBGPIOD], [libgpiod], [ + have_libgpiod=yes + AC_DEFINE([HAVE_LIBGPIOD], [1], [Linux libgpiod available]) + AC_DEFINE([HAVE_LIBGPIOD_V1_6], [0], [Linux libgpiod >= v1.6 but < 2.0 available]) + AC_DEFINE([HAVE_LIBGPIOD_V2], [0], [Linux libgpiod >= 2.0 available]) + ], [ + have_libgpiod=no + ]) + ]) + ]) + else confsubst="$confsubst -e /^@HAVE_LINUXGPIO_BEGIN@/,/^@HAVE_LINUXGPIO_END@/d" fi @@ -533,7 +566,7 @@ fi # If we are compiling with gcc, enable all warnings and make warnings errors. ENABLE_WARNINGS="" if test "x$GCC" = xyes; then - ENABLE_WARNINGS="-Wall -Wextra -Wno-unused-parameter" + ENABLE_WARNINGS="-Wall -Wextra -Wno-unused-parameter -Wno-format-zero-length" # does this compiler support -Wno-pointer-sign ? AC_MSG_CHECKING([if gcc accepts -Wno-pointer-sign ]) @@ -724,6 +757,15 @@ fi if test "x$enabled_linuxgpio" = xyes; then echo "ENABLED linuxgpio" + if test "x$have_libgpiodv2" = xyes; then + echo "DO HAVE libgpiod (>= 2.0)" + elif test "x$have_libgpiodv1_6" = xyes; then + echo "DO HAVE libgpiod (>= 1.6 < 2.0)" + elif test "x$have_libgpiod" = xyes; then + echo "DO HAVE libgpiod (< 1.6)" + else + echo "DON'T HAVE libgpiod" + fi else echo "DISABLED linuxgpio" fi diff --git a/src/developer_opts.c b/src/developer_opts.c index a0f7a11f..3d28bc61 100644 --- a/src/developer_opts.c +++ b/src/developer_opts.c @@ -93,10 +93,6 @@ static int opcodecmp(const OPCODE *op1, const OPCODE *op2, int opnum) { opstr1 = opcode2str(op1, opnum, 1); opstr2 = opcode2str(op2, opnum, 1); - if(!opstr1 || !opstr2) { - dev_info("%s: out of memory\n", progname); - exit(1); - } // Don't care x and 0 are functionally equivalent for(p=opstr1; *p; p++) @@ -107,8 +103,8 @@ static int opcodecmp(const OPCODE *op1, const OPCODE *op2, int opnum) { *p = '0'; cmp = strcmp(opstr1, opstr2); - free(opstr1); - free(opstr2); + mmt_free(opstr1); + mmt_free(opstr2); return cmp; } @@ -210,7 +206,7 @@ static void checkaddr(int memsize, int pagesize, int opnum, const OPCODE *op, co dev_info(".cmderr\t%s\t%s-%s\tbit %d outside addressable space should be x or 0 but is %s\n", p->desc, m->desc, opstr, i+8, cbs? cbs: "NULL"); if(cbs) - free(cbs); + mmt_free(cbs); } } else { if(op->bit[i+8].type != AVR_CMDBIT_ADDRESS) @@ -237,10 +233,10 @@ static char *dev_sprintf(const char *fmt, ...) { va_end(ap); if(size < 0) - return cfg_strdup("dev_sprintf()", ""); + return mmt_strdup(""); size++; // For terminating '\0' - p = cfg_malloc("dev_sprintf()", size); + p = mmt_malloc(size); va_start(ap, fmt); size = vsnprintf(p, size, fmt, ap); @@ -337,8 +333,7 @@ static int dev_part_strct_entry(bool tsv, // Print as spreadsheet? dev_cout(comms, n, 1, 1); // Print comments on rhs } - if(cont) - free(cont); + mmt_free(cont); return 1; } @@ -606,7 +601,7 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool firstid = 0; char *str = cfg_escape(ldata(ln)); dev_info("%*s%s", tsv? 0: 8, "", str); - free(str); + mmt_free(str); } if(tsv) dev_info("\n"); @@ -625,9 +620,9 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool } _if_partout_str(strcmp, cfg_escape(p->family_id), family_id); - _if_partout_str(intcmp, cfg_strdup("dev_part_strct()", prog_modes_str(p->prog_modes)), prog_modes); + _if_partout_str(intcmp, mmt_strdup(prog_modes_str(p->prog_modes)), prog_modes); if(p->mcuid == 21) { - _if_partout_str(intcmp, cfg_strdup(__func__, "XVII + IV"), mcuid); + _if_partout_str(intcmp, mmt_strdup("XVII + IV"), mcuid); } else { _if_partout(intcmp, "%d", mcuid); } @@ -645,13 +640,12 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool _if_partout(intcmp, "0x%04x", usbpid); if(!base || base->reset_disposition != p->reset_disposition) - _partout_str(cfg_strdup("dev_part_strct()", - p->reset_disposition == RESET_DEDICATED? "dedicated": p->reset_disposition == RESET_IO? "io": "unknown"), + _partout_str(mmt_strdup(p->reset_disposition == RESET_DEDICATED? + "dedicated": p->reset_disposition == RESET_IO? "io": "unknown"), reset); - _if_partout_str(intcmp, cfg_strdup("dev_part_strct()", - p->retry_pulse == PIN_AVR_RESET? "reset": p->retry_pulse == PIN_AVR_SCK? "sck": "unknown"), - retry_pulse); + _if_partout_str(intcmp, mmt_strdup(p->retry_pulse == PIN_AVR_RESET? + "reset": p->retry_pulse == PIN_AVR_SCK? "sck": "unknown"), retry_pulse); if(!base || base->flags != p->flags) { if(tsv) { @@ -664,9 +658,8 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool if(!base || (base->flags & (AVRPART_PARALLELOK | AVRPART_PSEUDOPARALLEL)) != (p->flags & (AVRPART_PARALLELOK | AVRPART_PSEUDOPARALLEL))) { int par = p->flags & (AVRPART_PARALLELOK | AVRPART_PSEUDOPARALLEL); - _partout_str(cfg_strdup("dev_part_strct()", - par == 0? "no": par == AVRPART_PSEUDOPARALLEL? "unknown": AVRPART_PARALLELOK? "yes": "pseudo"), - parallel); + _partout_str(mmt_strdup(par == 0? "no": + par == AVRPART_PSEUDOPARALLEL? "unknown": AVRPART_PARALLELOK? "yes": "pseudo"), parallel); } } } @@ -788,7 +781,7 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool if(meminj[i].mcu && str_casematch(meminj[i].mcu, p->desc)) if(str_match(meminj[i].mem, m->desc)) { dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, - meminj[i].var, cfg_strdup("meminj", meminj[i].value), NULL); + meminj[i].var, mmt_strdup(meminj[i].value), NULL); meminj[i].mcu = NULL; } @@ -824,14 +817,14 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool if(ptinj[i].mcu) if(str_casematch(ptinj[i].mcu, p->desc)) dev_part_strct_entry(tsv, ".pt", p->desc, NULL, - ptinj[i].var, cfg_strdup("ptinj", ptinj[i].value), NULL); + ptinj[i].var, mmt_strdup(ptinj[i].value), NULL); for(size_t i=0; idesc)) { if(!tsv) dev_info(" memory \"%s\"\n", meminj[i].mem); dev_part_strct_entry(tsv, ".ptmm", p->desc, meminj[i].mem, - meminj[i].var, cfg_strdup("meminj", meminj[i].value), NULL); + meminj[i].var, mmt_strdup(meminj[i].value), NULL); meminj[i].mcu = NULL; if(!tsv) dev_info(" ;\n"); @@ -850,21 +843,21 @@ void dev_output_pgm_part(int dev_opt_c, const char *programmer, int dev_opt_p, c char *p; dev_print_comment(cfg_get_prologue()); - dev_info("avrdude_conf_version = %s;\n\n", p = cfg_escape(avrdude_conf_version)); free(p); - dev_info("default_programmer = %s;\n", p = cfg_escape(default_programmer)); free(p); - dev_info("default_parallel = %s;\n", p = cfg_escape(default_parallel)); free(p); - dev_info("default_serial = %s;\n", p = cfg_escape(default_serial)); free(p); - dev_info("default_spi = %s;\n", p = cfg_escape(default_spi)); free(p); + dev_info("avrdude_conf_version = %s;\n\n", p = cfg_escape(avrdude_conf_version)); mmt_free(p); + dev_info("default_programmer = %s;\n", p = cfg_escape(default_programmer)); mmt_free(p); + dev_info("default_parallel = %s;\n", p = cfg_escape(default_parallel)); mmt_free(p); + dev_info("default_serial = %s;\n", p = cfg_escape(default_serial)); mmt_free(p); + dev_info("default_spi = %s;\n", p = cfg_escape(default_spi)); mmt_free(p); dev_info("default_baudrate = %d;\n", default_baudrate); dev_info("default_bitclock = %7.5f;\n", default_bitclock); - dev_info("default_linuxgpio = %s;\n", p = cfg_escape(default_linuxgpio)); free(p); + dev_info("default_linuxgpio = %s;\n", p = cfg_escape(default_linuxgpio)); mmt_free(p); dev_info("allow_subshells = %s;\n", allow_subshells? "yes": "no"); dev_info("\n#\n# PROGRAMMER DEFINITIONS\n#\n\n"); } if(dev_opt_c) - dev_output_pgm_defs(cfg_strdup("main()", programmer)); + dev_output_pgm_defs(mmt_strdup(programmer)); if(dev_opt_p == 2 && dev_opt_c) dev_info("\n"); @@ -872,7 +865,7 @@ void dev_output_pgm_part(int dev_opt_c, const char *programmer, int dev_opt_p, c dev_info("#\n# PART DEFINITIONS\n#\n"); if(dev_opt_p) - dev_output_part_defs(cfg_strdup("main()", partdesc)); + dev_output_part_defs(mmt_strdup(partdesc)); } @@ -1250,7 +1243,7 @@ static char *dev_usbpid_liststr(const PROGRAMMER *pgm) { sprintf(spc + strlen(spc), "0x%04x", *(unsigned int *) ldata(ln)); } - return cfg_strdup(__func__, *spc? spc: "NULL"); + return mmt_strdup(*spc? spc: "NULL"); } static char *dev_hvupdi_support_liststr(const PROGRAMMER *pgm) { @@ -1267,7 +1260,7 @@ static char *dev_hvupdi_support_liststr(const PROGRAMMER *pgm) { sprintf(spc + strlen(spc), "%d", *(unsigned int *) ldata(ln)); } - return cfg_strdup(__func__, *spc? spc: "NULL"); + return mmt_strdup(*spc? spc: "NULL"); } @@ -1313,7 +1306,7 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas firstid = 0; char *str = cfg_escape(ldata(ln)); dev_info("%s", str); - free(str); + mmt_free(str); } if(tsv) dev_info("\n"); @@ -1325,9 +1318,9 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas _if_pgmout_str(strcmp, cfg_escape(pgm->desc), desc); if(!base || base->initpgm != pgm->initpgm) _pgmout_fmt("type", "\"%s\"", locate_programmer_type_id(pgm->initpgm)); - _if_pgmout_str(intcmp, cfg_strdup("dev_pgm_strct()", prog_modes_str(pgm->prog_modes)), prog_modes); - _if_pgmout_str(boolcmp, cfg_strdup("dev_pgm_strct()", pgm->is_serialadapter? "yes": "no"), is_serialadapter); - _if_pgmout_str(intcmp, cfg_strdup("dev_pgm_strct()", extra_features_str(pgm->extra_features)), extra_features); + _if_pgmout_str(intcmp, mmt_strdup(prog_modes_str(pgm->prog_modes)), prog_modes); + _if_pgmout_str(boolcmp, mmt_strdup(pgm->is_serialadapter? "yes": "no"), is_serialadapter); + _if_pgmout_str(intcmp, mmt_strdup(extra_features_str(pgm->extra_features)), extra_features); if(!base || base->conntype != pgm->conntype) _pgmout_fmt("connection_type", "%s", connstr(pgm->conntype)); _if_pgmout(intcmp, "%d", baudrate); @@ -1340,12 +1333,12 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas if(base) { char *basestr = dev_usbpid_liststr(base); show = !str_eq(basestr, pgmstr); - free(basestr); + mmt_free(basestr); } if(show) dev_part_strct_entry(tsv, ".prog", id, NULL, "usbpid", pgmstr, pgm->comments); else // dev_part_strct_entry() frees pgmstr - free(pgmstr); + mmt_free(pgmstr); _if_pgmout_str(strcmp, cfg_escape(pgm->usbdev), usbdev); _if_pgmout_str(strcmp, cfg_escape(pgm->usbsn), usbsn); @@ -1358,9 +1351,8 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas if(!base || !str_eq(bstr, str)) _pgmout_fmt(avr_pin_lcname(i), "%s", str); - free(str); - if(bstr) - free(bstr); + mmt_free(str); + mmt_free(bstr); } pgmstr = dev_hvupdi_support_liststr(pgm); @@ -1369,12 +1361,12 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas if(base) { char *basestr = dev_hvupdi_support_liststr(base); show = !str_eq(basestr, pgmstr); - free(basestr); + mmt_free(basestr); } if(show) dev_part_strct_entry(tsv, ".prog", id, NULL, "hvupdi_support", pgmstr, pgm->comments); else // dev_part_strct_entry() frees pgmstr - free(pgmstr); + mmt_free(pgmstr); if(injct) for(size_t i=0; iid); ln; ln=lnext(ln)) if(str_casematch(pgminj[i].pgmid, ldata(ln))) dev_part_strct_entry(tsv, ".prog", ldata(ln), NULL, - pgminj[i].var, cfg_strdup("pgminj", pgminj[i].value), NULL); + pgminj[i].var, mmt_strdup(pgminj[i].value), NULL); if(!tsv) { dev_cout(pgm->comments, ";", 0, 0); diff --git a/src/developer_opts_private.h b/src/developer_opts_private.h index 72acb77f..5e66e38d 100644 --- a/src/developer_opts_private.h +++ b/src/developer_opts_private.h @@ -67,7 +67,7 @@ static int dev_message(int msglvl, const char *fmt, ...); dev_part_strct_entry(tsv, ".prog", id, NULL, #component, dev_sprintf("%s", pgm->component? "true": "false"), pgm->comments); \ } while(0) -// Result must be a malloc'd string +// Result must be an mmt_malloc'd string #define _if_pgmout_str(cmp, result, component) do { \ if(!base || cmp(base->component, pgm->component)) \ dev_part_strct_entry(tsv, ".prog", id, NULL, #component, result, pgm->comments); \ @@ -92,17 +92,17 @@ static int dev_message(int msglvl, const char *fmt, ...); dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, dev_sprintf(fmt, p->component), p->comments); \ } while(0) -// Result must be a malloc'd string +// Result must be an mmt_malloc'd string #define _partout_str(result, component) \ dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result, p->comments) -// Result must be a malloc'd string +// Result must be an mmt_malloc'd string #define _if_partout_str(cmp, result, component) do { \ if(!base || cmp(base->component, p->component)) \ dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result, p->comments); \ } while(0) -// Result must be a malloc'd string +// Result must be an mmt_malloc'd string #define _if_n_partout_str(cmp, n, result, component) do { \ if(!base || cmp(base->component, p->component, n)) \ dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, result, p->comments); \ @@ -117,18 +117,18 @@ static int dev_message(int msglvl, const char *fmt, ...); dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, dev_sprintf(fmt, m->component), m->comments); \ } while(0) -// Result must be a malloc'd string +// Result must be an mmt_malloc'd string #define _memout_str(result, component) \ dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, result, m->comments) -// Result must be a malloc'd string +// Result must be an mmt_malloc'd string #define _if_n_memout_str(cmp, n, result, component) do { \ if(!bm || cmp(bm->component, m->component, n)) \ dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, result, m->comments); \ } while(0) #define _memout_yn(component) \ - dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, cfg_strdup("_memout_yn()", m->component? "yes": "no"), m->comments) + dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, mmt_strdup(m->component? "yes": "no"), m->comments) #define _if_memout_bool(component) do { \ if(!bm || !!bm->component != !!m->component) \ @@ -137,18 +137,18 @@ static int dev_message(int msglvl, const char *fmt, ...); #define _if_memout_yn(component) do { \ if(!bm || bm->component != m->component) \ - dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, cfg_strdup("_if_memout_yn()", m->component? "yes": "no"), m->comments); \ + dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, mmt_strdup(m->component? "yes": "no"), m->comments); \ } while(0) #define _flagout(mask, name) \ - _partout_str(cfg_strdup("_flagout()", p->flags & (mask)? "yes": "no"), name) + _partout_str(mmt_strdup(p->flags & (mask)? "yes": "no"), name) #define _if_flagout(mask, name) do { \ if(!base || (base->flags & (mask)) != (p->flags & (mask))) \ - _partout_str(cfg_strdup("_if_flagout()", p->flags & (mask)? "yes": "no"), name); \ + _partout_str(mmt_strdup(p->flags & (mask)? "yes": "no"), name); \ } while(0) -// Result must be a malloc'd string +// Result must be an mmt_malloc'd string #define _cmderr(result, component) \ dev_part_strct_entry(tsv, ".cmderr", p->desc, m->desc, #component, result, NULL) diff --git a/src/dfu.c b/src/dfu.c index b7866fd5..bfc6bdf2 100644 --- a/src/dfu.c +++ b/src/dfu.c @@ -115,11 +115,7 @@ struct dfu_dev *dfu_open(const char *port_spec) { } if(':' == port_spec[3]) { - bus_name = strdup(port_spec + 3 + 1); - if (bus_name == NULL) { - pmsg_error("out of memory in strdup\n"); - return NULL; - } + bus_name = mmt_strdup(port_spec + 3 + 1); dev_name = strchr(bus_name, ':'); if(NULL != dev_name) @@ -130,14 +126,7 @@ struct dfu_dev *dfu_open(const char *port_spec) { * strings for use in dfu_initialize(). */ - dfu = calloc(1, sizeof(struct dfu_dev)); - - if (dfu == NULL) - { - pmsg_error("out of memory\n"); - free(bus_name); - return NULL; - } + dfu = mmt_malloc(sizeof(struct dfu_dev)); dfu->bus_name = bus_name; dfu->dev_name = dev_name; @@ -251,13 +240,13 @@ void dfu_close(struct dfu_dev *dfu) if (dfu->dev_handle != NULL) usb_close(dfu->dev_handle); if (dfu->bus_name != NULL) - free(dfu->bus_name); + mmt_free(dfu->bus_name); if (dfu->manf_str != NULL) - free(dfu->manf_str); + mmt_free(dfu->manf_str); if (dfu->prod_str != NULL) - free(dfu->prod_str); + mmt_free(dfu->prod_str); if (dfu->serno_str != NULL) - free(dfu->serno_str); + mmt_free(dfu->serno_str); } int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status) @@ -281,8 +270,8 @@ int dfu_getstatus(struct dfu_dev *dfu, struct dfu_status *status) } if (result > (int) sizeof(struct dfu_status)) { - pmsg_error("oversize read (should not happen); exiting\n"); - exit(1); + pmsg_error("oversize read (should not happen)\n"); + return -1; } pmsg_trace("dfu_getstatus(): bStatus 0x%02x, bwPollTimeout %d, bState 0x%02x, iString %d\n", @@ -382,8 +371,8 @@ int dfu_upload(struct dfu_dev *dfu, void *ptr, int size) } if (result > size) { - pmsg_error("oversize read (should not happen); exiting\n"); - exit(1); + pmsg_error("oversize read (should not happen)\n"); + return -1; } return 0; @@ -432,15 +421,10 @@ char * get_usb_string(usb_dev_handle * dev_handle, int index) { return NULL; } - str = malloc(result+1); - - if (str == NULL) { - pmsg_error("out of memory allocating a string\n"); - return 0; - } - + str = mmt_malloc(result+1); memcpy(str, buffer, result); str[result] = '\0'; + return str; } diff --git a/src/doc/avrdude.texi b/src/doc/avrdude.texi index b77186a5..68486c9c 100644 --- a/src/doc/avrdude.texi +++ b/src/doc/avrdude.texi @@ -1454,6 +1454,18 @@ of the default binary SPI mode: The only advantage of the ``raw-wire'' mode is that different SPI frequencies are available. Paged writing is not implemented in this mode. +@item @samp{pullups} +Enable the Bus Pirate's built-in pull-up resistors. These resistors are +useful when working with different voltage levels. VPU pin of the Bus Pirate +must be connected to an external voltage. +For example: connect VPU pin to the +5V pin or an external power supply. + +@item @samp{hiz} +Enable the Bus Pirate's HiZ mode on SPI, allowing it to work as an +open-collector and interface with external pull-up circuits. +If the external target circuit does not have pull-ups, the Bus Pirate +will not be able to send data. + @item @samp{ascii} Attempt to use ASCII mode even when the firmware supports BinMode (binary mode). diff --git a/src/dryrun.c b/src/dryrun.c index bb4f821c..04da53d0 100644 --- a/src/dryrun.c +++ b/src/dryrun.c @@ -535,13 +535,13 @@ static int dryrun_readonly(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM static void dryrun_setup(PROGRAMMER *pgm) { pmsg_debug("%s()\n", __func__); // Allocate dry - pgm->cookie = cfg_malloc(__func__, sizeof(dryrun_t)); + pgm->cookie = mmt_malloc(sizeof(dryrun_t)); } static void dryrun_teardown(PROGRAMMER *pgm) { pmsg_debug("%s()\n", __func__); - free(pgm->cookie); + mmt_free(pgm->cookie); pgm->cookie = NULL; } diff --git a/src/fileio.c b/src/fileio.c index f7018ee2..694af668 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -352,7 +352,7 @@ static int ihex2b(const char *infile, FILE *inf, const AVRMEM *mem, nextaddr = 0; digits = mem->size > 0x10000? 5: 4; - for(char *buffer; (buffer = str_fgets(inf, &errstr)); free(buffer)) { + for(char *buffer; (buffer = str_fgets(inf, &errstr)); mmt_free(buffer)) { lineno++; int len = strlen(buffer); if(len > 0 && buffer[len-1] == '\n') @@ -362,14 +362,14 @@ static int ihex2b(const char *infile, FILE *inf, const AVRMEM *mem, rc = ihex_readrec(&ihex, buffer); if(rc < 0) { pmsg_error("invalid record at line %d of %s\n", lineno, infile); - free(buffer); + mmt_free(buffer); return -1; } if(rc != ihex.cksum) { if(ffmt == FMT_IHEX) { pmsg_error("checksum mismatch at line %d of %s\n", lineno, infile); imsg_error("checksum=0x%02x, computed checksum=0x%02x\n", ihex.cksum, rc); - free(buffer); + mmt_free(buffer); return -1; } // Just warn with more permissive format FMT_IHXC @@ -382,7 +382,7 @@ static int ihex2b(const char *infile, FILE *inf, const AVRMEM *mem, if (fileoffset != 0 && ihex.loadofs + baseaddr < fileoffset) { pmsg_error("address 0x%04x out of range (below fileoffset 0x%x) at line %d of %s\n", ihex.loadofs + baseaddr, fileoffset, lineno, infile); - free(buffer); + mmt_free(buffer); return -1; } nextaddr = ihex.loadofs + baseaddr - fileoffset; @@ -391,7 +391,7 @@ static int ihex2b(const char *infile, FILE *inf, const AVRMEM *mem, pmsg_error("Intel Hex record [0x%0*x, 0x%0*x] out of range [0x%0*x, 0x%0*x]\n", digits, nextaddr, digits, nextaddr+ihex.reclen-1, digits, beg, digits, end); imsg_error("at line %d of %s\n", lineno, infile); - free(buffer); + mmt_free(buffer); return -1; } for(int i=0; isize > 0x10000? 5: 4; - for(char *buffer; (buffer = str_fgets(inf, &errstr)); free(buffer)) { + for(char *buffer; (buffer = str_fgets(inf, &errstr)); mmt_free(buffer)) { lineno++; int len = strlen(buffer); if(len > 0 && buffer[len-1] == '\n') @@ -633,13 +633,13 @@ static int srec2b(const char *infile, FILE * inf, rc = srec_readrec(&srec, buffer); if(rc < 0) { pmsg_error("invalid record at line %d of %s\n", lineno, infile); - free(buffer); + mmt_free(buffer); return -1; } if(rc != srec.cksum) { pmsg_error("checksum mismatch at line %d of %s\n", lineno, infile); imsg_error("checksum=0x%02x, computed checksum=0x%02x\n", srec.cksum, rc); - free(buffer); + mmt_free(buffer); return -1; } @@ -665,14 +665,14 @@ static int srec2b(const char *infile, FILE * inf, case '4': // S4: symbol record (LSI extension) pmsg_error("not supported record at line %d of %s\n", lineno, infile); - free(buffer); + mmt_free(buffer); return -1; case '5': // S5: count of S1, S2 and S3 records previously tx'd if (srec.loadofs != reccount){ pmsg_error("count of transmitted data records mismatch at line %d of %s\n", lineno, infile); imsg_error("transmitted data records= %d, expected value= %d\n", reccount, srec.loadofs); - free(buffer); + mmt_free(buffer); return -1; } break; @@ -680,13 +680,13 @@ static int srec2b(const char *infile, FILE * inf, case '7': // S7: end record for 32 bit addresses case '8': // S8: end record for 24 bit addresses case '9': // S9: end record for 16 bit addresses - free(buffer); + mmt_free(buffer); return maxaddr; default: pmsg_error("do not know how to deal with rectype S%d at line %d of %s\n", srec.rectyp, lineno, infile); - free(buffer); + mmt_free(buffer); return -1; } @@ -695,7 +695,7 @@ static int srec2b(const char *infile, FILE * inf, if (nextaddr < fileoffset) { pmsg_error("address 0x%0*x below memory offset at line %d of %s\n", hexdigs, nextaddr, lineno, infile); - free(buffer); + mmt_free(buffer); return -1; } nextaddr -= fileoffset; @@ -704,7 +704,7 @@ static int srec2b(const char *infile, FILE * inf, pmsg_error("Motorola S-Record [0x%0*x, 0x%0*x] out of range [0x%0*x, 0x%0*x]\n", digits, nextaddr, digits, nextaddr+srec.reclen-1, digits, beg, digits, end); imsg_error("at line %d of %s\n", lineno, infile); - free(buffer); + mmt_free(buffer); return -1; } for(int i=0; iaddr, end = segp->addr + segp->len; - p = line = cfg_strdup(__func__, fname); + p = line = mmt_strdup(fname); switch (fio->op) { case FIO_READ: @@ -1055,7 +1055,7 @@ static int fileio_imm(struct fioparms *fio, const char *fname, FILE *f_unused, int set = str_membuf(tok, STR_ANY, mem->buf+n, end-n, &errstr); if(errstr || set < 0) { pmsg_error("invalid data %s in immediate mode: %s\n", tok, errstr); - free(line); + mmt_free(line); return -1; } memset(mem->tags+n, TAG_ALLOCATED, set); @@ -1065,16 +1065,16 @@ static int fileio_imm(struct fioparms *fio, const char *fname, FILE *f_unused, case FIO_WRITE: pmsg_error("invalid file format 'immediate' for output\n"); - free(line); + mmt_free(line); return -1; default: pmsg_error("invalid operation=%d\n", fio->op); - free(line); + mmt_free(line); return -1; } - free(line); + mmt_free(line); return n; } @@ -1232,14 +1232,14 @@ static int num2b(const char *filename, FILE *f, const AVRMEM *mem, const Segment int set = str_membuf(tok, STR_ANY, mem->buf+n, end-n, &errstr); if(errstr || set < 0) { pmsg_error("invalid data %s in immediate mode: %s\n", tok, errstr); - free(line); + mmt_free(line); return -1; } memset(mem->tags+n, TAG_ALLOCATED, set); n += set; } } - free(line); + mmt_free(line); } if(geterr) { pmsg_error("fgets() errror: %s\n", geterr); @@ -1386,7 +1386,7 @@ int fileio_fmt_autodetect_fp(FILE *f) { unsigned char *buf; for(int first = 1; ret == FMT_ERROR && (buf = (unsigned char *) str_fgets(f, &err)); first = 0) { ret = couldbe(first, buf); - free(buf); + mmt_free(buf); } if(err) pmsg_error("fgets() error: %s\n", err); @@ -1612,10 +1612,10 @@ static int fileio_segments_normalise(int oprwv, const char *filename, FILEFMT fo int fileio_segments(int oprwv, const char *filename, FILEFMT format, const AVRPART *p, const AVRMEM *mem, int n, const Segment_t *list) { - Segment_t *seglist = cfg_malloc(__func__, n*sizeof*seglist); + Segment_t *seglist = mmt_malloc(n*sizeof*seglist); memcpy(seglist, list, n*sizeof*seglist); int ret = fileio_segments_normalise(oprwv, filename, format, p, mem, n, seglist); - free(seglist); + mmt_free(seglist); return ret; } diff --git a/src/flip1.c b/src/flip1.c index bae50fe4..1ad390c3 100644 --- a/src/flip1.c +++ b/src/flip1.c @@ -153,8 +153,8 @@ static int flip1_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AV static int flip1_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, unsigned int page_size, unsigned int addr, unsigned int n_bytes); static int flip1_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem); -static void flip1_setup(PROGRAMMER * pgm); -static void flip1_teardown(PROGRAMMER * pgm); +static void flip1_setup(PROGRAMMER *pgm); +static void flip1_teardown(PROGRAMMER *pgm); /* INTERNAL PROGRAMMER FUNCTION PROTOTYPES */ #ifdef HAVE_LIBUSB @@ -200,12 +200,12 @@ void flip1_initpgm(PROGRAMMER *pgm) { #ifdef HAVE_LIBUSB /* EXPORTED PROGRAMMER FUNCTION DEFINITIONS */ -int flip1_open(PROGRAMMER *pgm, const char *port_spec) { +static int flip1_open(PROGRAMMER *pgm, const char *port_spec) { FLIP1(pgm)->dfu = dfu_open(port_spec); return (FLIP1(pgm)->dfu != NULL) ? 0 : -1; } -int flip1_initialize(const PROGRAMMER *pgm, const AVRPART *part) { +static int flip1_initialize(const PROGRAMMER *pgm, const AVRPART *part) { unsigned short vid, pid; int result; struct dfu_dev *dfu = FLIP1(pgm)->dfu; @@ -305,26 +305,23 @@ flip1_initialize_fail: return 0; } -void flip1_close(PROGRAMMER *pgm) { +static void flip1_close(PROGRAMMER *pgm) { if (FLIP1(pgm)->dfu != NULL) { dfu_close(FLIP1(pgm)->dfu); FLIP1(pgm)->dfu = NULL; } } -void flip1_enable(PROGRAMMER *pgm, const AVRPART *p) { - /* Nothing to do. */ +static void flip1_enable(PROGRAMMER *pgm, const AVRPART *p) { } -void flip1_disable(const PROGRAMMER *pgm) { - /* Nothing to do. */ +static void flip1_disable(const PROGRAMMER *pgm) { } -void flip1_display(const PROGRAMMER *pgm, const char *prefix) { - /* Nothing to do. */ +static void flip1_display(const PROGRAMMER *pgm, const char *prefix) { } -int flip1_program_enable(const PROGRAMMER *pgm, const AVRPART *part) { +static int flip1_program_enable(const PROGRAMMER *pgm, const AVRPART *part) { /* I couldn't find anything that uses this function, although it is marked * as "mandatory" in pgm.c. In case anyone does use it, we'll report an * error if we failed to initialize. @@ -333,7 +330,7 @@ int flip1_program_enable(const PROGRAMMER *pgm, const AVRPART *part) { return (FLIP1(pgm)->dfu != NULL) ? 0 : -1; } -int flip1_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) { +static int flip1_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) { struct dfu_status status; int cmd_result = 0; int aux_result; @@ -363,7 +360,7 @@ int flip1_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) { return 0; } -int flip1_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, +static int flip1_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, unsigned long addr, unsigned char *value) { enum flip1_mem_unit mem_unit; @@ -396,7 +393,7 @@ int flip1_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *me return flip1_read_memory(pgm, mem_unit, addr, value, 1); } -int flip1_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, +static int flip1_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, unsigned long addr, unsigned char value) { enum flip1_mem_unit mem_unit; @@ -423,7 +420,7 @@ int flip1_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *m return flip1_write_memory(FLIP1(pgm)->dfu, mem_unit, addr, &value, 1); } -int flip1_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, +static int flip1_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, unsigned int page_size, unsigned int addr, unsigned int n_bytes) { enum flip1_mem_unit mem_unit; @@ -445,7 +442,7 @@ int flip1_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *m return flip1_read_memory(pgm, mem_unit, addr, mem->buf + addr, n_bytes); } -int flip1_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, +static int flip1_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, unsigned int page_size, unsigned int addr, unsigned int n_bytes) { enum flip1_mem_unit mem_unit; @@ -464,7 +461,7 @@ int flip1_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM * if (n_bytes > INT_MAX) { /* This should never happen, unless the int type is only 16 bits. */ pmsg_error("attempting to read more than %d bytes\n", INT_MAX); - exit(1); + return -1; } result = flip1_write_memory(FLIP1(pgm)->dfu, mem_unit, addr, @@ -473,7 +470,7 @@ int flip1_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM * return result == 0? (int) n_bytes: -1; } -int flip1_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem) { +static int flip1_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem) { pmsg_notice2("flip1_read_sig_bytes(): "); if (FLIP1(pgm)->dfu == NULL) @@ -545,32 +542,24 @@ int flip1_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRME return 0; } -void flip1_setup(PROGRAMMER * pgm) -{ - pgm->cookie = calloc(1, sizeof(struct flip1)); - - if (pgm->cookie == NULL) { - pmsg_error("out of memory allocating private data structure\n"); - exit(1); - } +static void flip1_setup(PROGRAMMER *pgm) { + pgm->cookie = mmt_malloc(sizeof(struct flip1)); } -void flip1_teardown(PROGRAMMER * pgm) -{ - free(pgm->cookie); +static void flip1_teardown(PROGRAMMER *pgm) { + mmt_free(pgm->cookie); pgm->cookie = NULL; } /* INTERNAL FUNCTION DEFINITIONS */ -void flip1_show_info(struct flip1 *flip1) -{ +static void flip1_show_info(struct flip1 *flip1) { dfu_show_info(flip1->dfu); msg_info(" USB max packet size : %hu\n", (unsigned short) flip1->dfu->dev_desc.bMaxPacketSize0); } -int flip1_read_memory(const PROGRAMMER *pgm, +static int flip1_read_memory(const PROGRAMMER *pgm, enum flip1_mem_unit mem_unit, uint32_t addr, void *ptr, int size) { struct dfu_dev *dfu = FLIP1(pgm)->dfu; @@ -652,7 +641,7 @@ int flip1_read_memory(const PROGRAMMER *pgm, return 0; } -int flip1_write_memory(struct dfu_dev *dfu, +static int flip1_write_memory(struct dfu_dev *dfu, enum flip1_mem_unit mem_unit, uint32_t addr, const void *ptr, int size) { unsigned short page_addr; @@ -690,12 +679,7 @@ int flip1_write_memory(struct dfu_dev *dfu, write_size = size; } - if ((buf = malloc(sizeof(struct flip1_cmd_header) + - write_size + - sizeof(struct flip1_prog_footer))) == 0) { - pmsg_error("out of memory\n"); - return -1; - } + buf = mmt_malloc(sizeof(struct flip1_cmd_header) + write_size + sizeof(struct flip1_prog_footer)); /* * As this function is called once per page, no need to handle 64 @@ -707,7 +691,7 @@ int flip1_write_memory(struct dfu_dev *dfu, if (mem_unit == FLIP1_MEM_UNIT_FLASH) { page_addr = addr >> 16; if (flip1_set_mem_page(dfu, page_addr) < 0) { - free(buf); + mmt_free(buf); return -1; } } @@ -735,7 +719,7 @@ int flip1_write_memory(struct dfu_dev *dfu, aux_result = dfu_getstatus(dfu, &status); dfu->timeout = default_timeout; - free(buf); + mmt_free(buf); if (aux_result < 0 || cmd_result < 0) return -1; @@ -752,9 +736,7 @@ int flip1_write_memory(struct dfu_dev *dfu, return 0; } -int flip1_set_mem_page(struct dfu_dev *dfu, - unsigned short page_addr) -{ +static int flip1_set_mem_page(struct dfu_dev *dfu, unsigned short page_addr) { struct dfu_status status; int cmd_result = 0; int aux_result; @@ -781,8 +763,7 @@ int flip1_set_mem_page(struct dfu_dev *dfu, return 0; } -const char * flip1_status_str(const struct dfu_status *status) -{ +static const char *flip1_status_str(const struct dfu_status *status) { static const char *msg[] = { "No error condition is present", "File is not targeted for use by this device", @@ -807,8 +788,7 @@ const char * flip1_status_str(const struct dfu_status *status) return "Unknown status code"; } -const char * flip1_mem_unit_str(enum flip1_mem_unit mem_unit) -{ +static const char *flip1_mem_unit_str(enum flip1_mem_unit mem_unit) { switch (mem_unit) { case FLIP1_MEM_UNIT_FLASH: return "Flash"; case FLIP1_MEM_UNIT_EEPROM: return "EEPROM"; @@ -816,7 +796,7 @@ const char * flip1_mem_unit_str(enum flip1_mem_unit mem_unit) } } -enum flip1_mem_unit flip1_mem_unit(const char *name) { +static enum flip1_mem_unit flip1_mem_unit(const char *name) { if (str_eq(name, "flash")) return FLIP1_MEM_UNIT_FLASH; if (str_eq(name, "eeprom")) @@ -824,72 +804,67 @@ enum flip1_mem_unit flip1_mem_unit(const char *name) { return FLIP1_MEM_UNIT_UNKNOWN; } #else /* HAVE_LIBUSB */ + // Dummy functions -int flip1_open(PROGRAMMER *pgm, const char *port_spec) { +static int flip1_open(PROGRAMMER *pgm, const char *port_spec) { pmsg_error("no USB support compiled for avrdude\n"); return -1; } -int flip1_initialize(const PROGRAMMER *pgm, const AVRPART *part) { +static int flip1_initialize(const PROGRAMMER *pgm, const AVRPART *part) { return -1; } -void flip1_close(PROGRAMMER* pgm) -{ +static void flip1_close(PROGRAMMER *pgm) { } -void flip1_enable(PROGRAMMER *pgm, const AVRPART *p) { +static void flip1_enable(PROGRAMMER *pgm, const AVRPART *p) { } -void flip1_disable(const PROGRAMMER *pgm) { +static void flip1_disable(const PROGRAMMER *pgm) { } -void flip1_display(const PROGRAMMER *pgm, const char *prefix) { +static void flip1_display(const PROGRAMMER *pgm, const char *prefix) { } -int flip1_program_enable(const PROGRAMMER *pgm, const AVRPART *part) { +static int flip1_program_enable(const PROGRAMMER *pgm, const AVRPART *part) { return -1; } -int flip1_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) { +static int flip1_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) { return -1; } -int flip1_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, - unsigned long addr, unsigned char *value) -{ +static int flip1_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, + unsigned long addr, unsigned char *value) { return -1; } -int flip1_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, +static int flip1_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, unsigned long addr, unsigned char value) { return -1; } -int flip1_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, +static int flip1_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, unsigned int page_size, unsigned int addr, unsigned int n_bytes) { return -1; } -int flip1_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, - unsigned int page_size, unsigned int addr, unsigned int n_bytes) -{ +static int flip1_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { return -1; } -int flip1_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem) { +static int flip1_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem) { return -1; } -void flip1_setup(PROGRAMMER * pgm) -{ +static void flip1_setup(PROGRAMMER * pgm) { } -void flip1_teardown(PROGRAMMER * pgm) -{ +static void flip1_teardown(PROGRAMMER *pgm) { } - #endif /* HAVE_LIBUSB */ diff --git a/src/flip2.c b/src/flip2.c index 267cc3de..8aaf6b2c 100644 --- a/src/flip2.c +++ b/src/flip2.c @@ -144,8 +144,8 @@ static int flip2_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const A unsigned int page_size, unsigned int addr, unsigned int n_bytes); static int flip2_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem); static int flip2_parseexitspecs(PROGRAMMER* pgm, const char *s); -static void flip2_setup(PROGRAMMER * pgm); -static void flip2_teardown(PROGRAMMER * pgm); +static void flip2_setup(PROGRAMMER *pgm); +static void flip2_teardown(PROGRAMMER *pgm); /* INTERNAL PROGRAMMER FUNCTION PROTOTYPES */ @@ -192,12 +192,12 @@ void flip2_initpgm(PROGRAMMER *pgm) { /* EXPORTED PROGRAMMER FUNCTION DEFINITIONS */ -int flip2_open(PROGRAMMER *pgm, const char *port_spec) { +static int flip2_open(PROGRAMMER *pgm, const char *port_spec) { FLIP2(pgm)->dfu = dfu_open(port_spec); return (FLIP2(pgm)->dfu != NULL) ? 0 : -1; } -int flip2_initialize(const PROGRAMMER *pgm, const AVRPART *part) { +static int flip2_initialize(const PROGRAMMER *pgm, const AVRPART *part) { unsigned short vid, pid; int result; struct dfu_dev *dfu = FLIP2(pgm)->dfu; @@ -308,8 +308,7 @@ flip2_initialize_fail: return 0; } -void flip2_close(PROGRAMMER* pgm) -{ +static void flip2_close(PROGRAMMER *pgm) { if (FLIP2(pgm)->dfu != NULL) { if (pgm->exit_reset == EXIT_RESET_ENABLED) flip2_start_app(pgm); @@ -319,28 +318,20 @@ void flip2_close(PROGRAMMER* pgm) } } -void flip2_enable(PROGRAMMER *pgm, const AVRPART *p) { - /* Nothing to do. */ +static void flip2_enable(PROGRAMMER *pgm, const AVRPART *p) { } -void flip2_disable(const PROGRAMMER *pgm) { - /* Nothing to do. */ +static void flip2_disable(const PROGRAMMER *pgm) { } -void flip2_display(const PROGRAMMER *pgm, const char *prefix) { - /* Nothing to do. */ +static void flip2_display(const PROGRAMMER *pgm, const char *prefix) { } -int flip2_program_enable(const PROGRAMMER *pgm, const AVRPART *part) { - /* I couldn't find anything that uses this function, although it is marked - * as "mandatory" in pgm.c. In case anyone does use it, we'll report an - * error if we failed to initialize. - */ - - return (FLIP2(pgm)->dfu != NULL) ? 0 : -1; +static int flip2_program_enable(const PROGRAMMER *pgm, const AVRPART *part) { + return 0; } -int flip2_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) { +static int flip2_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) { struct dfu_status status; int cmd_result = 0; int aux_result; @@ -373,7 +364,7 @@ int flip2_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) { return cmd_result; } -int flip2_start_app(const PROGRAMMER *pgm) { +static int flip2_start_app(const PROGRAMMER *pgm) { pmsg_info("starting application\n"); struct flip2_cmd cmd = { @@ -389,9 +380,8 @@ int flip2_start_app(const PROGRAMMER *pgm) { return cmd_result; } -int flip2_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, - unsigned long addr, unsigned char *value) -{ +static int flip2_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, + unsigned long addr, unsigned char *value) { enum flip2_mem_unit mem_unit; if (FLIP2(pgm)->dfu == NULL) @@ -410,9 +400,8 @@ int flip2_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *me return flip2_read_memory(FLIP2(pgm)->dfu, mem_unit, addr, value, 1); } -int flip2_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, - unsigned long addr, unsigned char value) -{ +static int flip2_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, + unsigned long addr, unsigned char value) { enum flip2_mem_unit mem_unit; if(mem_is_readonly(mem)) { @@ -440,9 +429,9 @@ int flip2_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *m return flip2_write_memory(FLIP2(pgm)->dfu, mem_unit, addr, &value, 1); } -int flip2_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, - unsigned int page_size, unsigned int addr, unsigned int n_bytes) -{ +static int flip2_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + enum flip2_mem_unit mem_unit; int result; @@ -462,7 +451,7 @@ int flip2_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *m if (n_bytes > INT_MAX) { /* This should never happen, unless the int type is only 16 bits. */ pmsg_error("attempting to read more than %d bytes\n", INT_MAX); - exit(1); + return -1; } result = flip2_read_memory(FLIP2(pgm)->dfu, mem_unit, addr, @@ -471,9 +460,9 @@ int flip2_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *m return result == 0? (int) n_bytes: -1; } -int flip2_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, - unsigned int page_size, unsigned int addr, unsigned int n_bytes) -{ +static int flip2_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem, + unsigned int page_size, unsigned int addr, unsigned int n_bytes) { + enum flip2_mem_unit mem_unit; int result; @@ -493,7 +482,7 @@ int flip2_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM * if (n_bytes > INT_MAX) { /* This should never happen, unless the int type is only 16 bits. */ pmsg_error("attempting to read more than %d bytes\n", INT_MAX); - exit(1); + return -1; } result = flip2_write_memory(FLIP2(pgm)->dfu, mem_unit, addr, @@ -503,8 +492,8 @@ int flip2_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM * } // Parse the -E option flag -int flip2_parseexitspecs(PROGRAMMER *pgm, const char *sp) { - char *cp, *s, *str = cfg_strdup("flip2_parseextitspecs()", sp); +static int flip2_parseexitspecs(PROGRAMMER *pgm, const char *sp) { + char *cp, *s, *str = mmt_strdup(sp); s = str; while ((cp = strtok(s, ","))) { @@ -517,15 +506,15 @@ int flip2_parseexitspecs(PROGRAMMER *pgm, const char *sp) { pgm->exit_reset = EXIT_RESET_DISABLED; continue; } - free(str); + mmt_free(str); return -1; } - free(str); + mmt_free(str); return 0; } -int flip2_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem) { +static int flip2_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem) { if (FLIP2(pgm)->dfu == NULL) return -1; @@ -538,27 +527,19 @@ int flip2_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRME return 0; } -void flip2_setup(PROGRAMMER * pgm) -{ - pgm->cookie = calloc(1, sizeof(struct flip2)); - - if (pgm->cookie == NULL) { - pmsg_error("out of memory allocating private data structure\n"); - exit(1); - } +static void flip2_setup(PROGRAMMER *pgm) { + pgm->cookie = mmt_malloc(sizeof(struct flip2)); } -void flip2_teardown(PROGRAMMER * pgm) -{ - free(pgm->cookie); +static void flip2_teardown(PROGRAMMER *pgm) { + mmt_free(pgm->cookie); pgm->cookie = NULL; } /* INTERNAL FUNCTION DEFINITIONS */ -void flip2_show_info(struct flip2 *flip2) -{ +static void flip2_show_info(struct flip2 *flip2) { dfu_show_info(flip2->dfu); msg_info(" Part signature : 0x%02X%02X%02X\n", @@ -582,9 +563,9 @@ void flip2_show_info(struct flip2 *flip2) (unsigned short) flip2->dfu->dev_desc.bMaxPacketSize0); } -int flip2_read_memory(struct dfu_dev *dfu, - enum flip2_mem_unit mem_unit, uint32_t addr, void *ptr, int size) -{ +static int flip2_read_memory(struct dfu_dev *dfu, + enum flip2_mem_unit mem_unit, uint32_t addr, void *ptr, int size) { + unsigned short prev_page_addr; unsigned short page_addr; const char * mem_name; @@ -639,9 +620,9 @@ int flip2_read_memory(struct dfu_dev *dfu, return 0; } -int flip2_write_memory(struct dfu_dev *dfu, - enum flip2_mem_unit mem_unit, uint32_t addr, const void *ptr, int size) -{ +static int flip2_write_memory(struct dfu_dev *dfu, + enum flip2_mem_unit mem_unit, uint32_t addr, const void *ptr, int size) { + unsigned short prev_page_addr; unsigned short page_addr; const char * mem_name; @@ -696,8 +677,7 @@ int flip2_write_memory(struct dfu_dev *dfu, return 0; } -int flip2_set_mem_unit(struct dfu_dev *dfu, enum flip2_mem_unit mem_unit) -{ +static int flip2_set_mem_unit(struct dfu_dev *dfu, enum flip2_mem_unit mem_unit) { struct dfu_status status; int cmd_result = 0; int aux_result; @@ -729,9 +709,9 @@ int flip2_set_mem_unit(struct dfu_dev *dfu, enum flip2_mem_unit mem_unit) return cmd_result; } -int flip2_set_mem_page(struct dfu_dev *dfu, - unsigned short page_addr) -{ +static int flip2_set_mem_page(struct dfu_dev *dfu, + unsigned short page_addr) { + struct dfu_status status; int cmd_result = 0; int aux_result; @@ -764,9 +744,9 @@ int flip2_set_mem_page(struct dfu_dev *dfu, return cmd_result; } -int flip2_read_max1k(struct dfu_dev *dfu, - unsigned short offset, void *ptr, unsigned short size) -{ +static int flip2_read_max1k(struct dfu_dev *dfu, + unsigned short offset, void *ptr, unsigned short size) { + struct dfu_status status; int cmd_result = 0; int aux_result; @@ -807,9 +787,9 @@ flip2_read_max1k_status: return cmd_result; } -int flip2_write_max1k(struct dfu_dev *dfu, - unsigned short offset, const void *ptr, unsigned short size) -{ +static int flip2_write_max1k(struct dfu_dev *dfu, + unsigned short offset, const void *ptr, unsigned short size) { + char buffer[64+64+0x400]; unsigned short data_offset; struct dfu_status status; @@ -865,8 +845,7 @@ int flip2_write_max1k(struct dfu_dev *dfu, return cmd_result; } -const char * flip2_status_str(const struct dfu_status *status) -{ +static const char *flip2_status_str(const struct dfu_status *status) { unsigned short selector; selector = (unsigned short) status->bStatus << 8; @@ -884,8 +863,7 @@ const char * flip2_status_str(const struct dfu_status *status) } } -const char * flip2_mem_unit_str(enum flip2_mem_unit mem_unit) -{ +static const char * flip2_mem_unit_str(enum flip2_mem_unit mem_unit) { switch (mem_unit) { case FLIP2_MEM_UNIT_FLASH: return "Flash"; case FLIP2_MEM_UNIT_EEPROM: return "EEPROM"; @@ -908,7 +886,7 @@ const char * flip2_mem_unit_str(enum flip2_mem_unit mem_unit) } } -enum flip2_mem_unit flip2_mem_unit(const char *name) { +static enum flip2_mem_unit flip2_mem_unit(const char *name) { if (str_eq(name, "application")) return FLIP2_MEM_UNIT_FLASH; if (str_eq(name, "eeprom")) diff --git a/src/ft245r.c b/src/ft245r.c index 1b76f189..410ef594 100644 --- a/src/ft245r.c +++ b/src/ft245r.c @@ -1,6 +1,5 @@ - /* - * avrdude - A Downloader/Uploader for AVR device programmers + * AVRDUDE - A Downloader/Uploader for AVR device programmers * Copyright (C) 2003-2004 Theodore A. Roth * some code: * Copyright (C) 2011-2012 Roger E. Wolff @@ -125,56 +124,67 @@ void ft245r_initpgm(PROGRAMMER *pgm) { */ #define FT245R_BITBANG_VARIABLE_PULSE_WIDTH_WORKAROUND 0 -static struct ftdi_context *handle; -#if FT245R_BITBANG_VARIABLE_PULSE_WIDTH_WORKAROUND -static unsigned int baud_multiplier; -#else -# define baud_multiplier 1 // this let's C compiler optimize -#endif -static unsigned char ft245r_ddr; -static unsigned char ft245r_out; +// Private data for this programmer #define FT245R_BUFSIZE 0x2000 // receive buffer size #define FT245R_MIN_FIFO_SIZE 128 // min of FTDI RX/TX FIFO size -static struct { +struct pdata { + struct ftdi_context *handle; +#if FT245R_BITBANG_VARIABLE_PULSE_WIDTH_WORKAROUND + int baud_mult; +# define baud_multiplier my.baud_mult +#else +# define baud_multiplier 1 // Optimised by C compiler +#endif + unsigned char ft245r_ddr; + unsigned char ft245r_out; + struct { int len; // # of bytes in transmit buffer - uint8_t buf[FT245R_MIN_FIFO_SIZE]; // transmit buffer -} tx; - -static struct { + uint8_t buf[FT245R_MIN_FIFO_SIZE]; // Transmit buffer + } tx; + struct { int discard; // # of bytes to discard during read int pending; // # of bytes that have been written since last read int len; // # of bytes in receive buffer - int wr; // write pointer - int rd; // read pointer - uint8_t buf[FT245R_BUFSIZE]; // receive ring buffer -} rx; + int wr; // Write pointer + int rd; // Read pointer + uint8_t buf[FT245R_BUFSIZE]; // Receive ring buffer + } rx; + struct ft245r_request { + int addr; + int bytes; + int n; + struct ft245r_request *next; + } *req_head, *req_tail, *req_pool; +}; -static int ft245r_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, - unsigned char *res); +// Use private programmer data as if they were a global structure my +#define my (*(struct pdata *)(pgm->cookie)) + +static int ft245r_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res); static int ft245r_tpi_tx(const PROGRAMMER *pgm, uint8_t byte); static int ft245r_tpi_rx(const PROGRAMMER *pgm, uint8_t *bytep); // Discard all data from the receive buffer. static void ft245r_rx_buf_purge(const PROGRAMMER *pgm) { - rx.len = 0; - rx.rd = rx.wr = 0; + my.rx.len = 0; + my.rx.rd = my.rx.wr = 0; } static void ft245r_rx_buf_put(const PROGRAMMER *pgm, uint8_t byte) { - rx.len++; - rx.buf[rx.wr++] = byte; - if (rx.wr >= (int) sizeof(rx.buf)) - rx.wr = 0; + my.rx.len++; + my.rx.buf[my.rx.wr++] = byte; + if (my.rx.wr >= (int) sizeof(my.rx.buf)) + my.rx.wr = 0; } static uint8_t ft245r_rx_buf_get(const PROGRAMMER *pgm) { - rx.len--; - uint8_t byte = rx.buf[rx.rd++]; - if (rx.rd >= (int) sizeof(rx.buf)) - rx.rd = 0; + my.rx.len--; + uint8_t byte = my.rx.buf[my.rx.rd++]; + if (my.rx.rd >= (int) sizeof(my.rx.buf)) + my.rx.rd = 0; return byte; } @@ -183,12 +193,12 @@ static int ft245r_fill(const PROGRAMMER *pgm) { uint8_t raw[FT245R_MIN_FIFO_SIZE]; int i, nread; - nread = ftdi_read_data(handle, raw, rx.pending); + nread = ftdi_read_data(my.handle, raw, my.rx.pending); if (nread < 0) return -1; - rx.pending -= nread; + my.rx.pending -= nread; #if FT245R_DEBUG - msg_info("%s: read %d bytes (pending=%d)\n", __func__, nread, rx.pending); + msg_info("%s: read %d bytes (pending=%d)\n", __func__, nread, my.rx.pending); #endif for (i = 0; i < nread; ++i) ft245r_rx_buf_put(pgm, raw[i]); @@ -196,13 +206,10 @@ static int ft245r_fill(const PROGRAMMER *pgm) { } static int ft245r_rx_buf_fill_and_get(const PROGRAMMER *pgm) { - while (rx.len == 0) - { + while(my.rx.len == 0) { int result = ft245r_fill(pgm); - if (result < 0) - { + if(result < 0) return result; - } } return ft245r_rx_buf_get(pgm); @@ -210,18 +217,18 @@ static int ft245r_rx_buf_fill_and_get(const PROGRAMMER *pgm) { /* Flush pending TX data to the FTDI send FIFO. */ static int ft245r_flush(const PROGRAMMER *pgm) { - int rv, len = tx.len, avail; - uint8_t *src = tx.buf; + int rv, len = my.tx.len, avail; + uint8_t *src = my.tx.buf; if (!len) return 0; while (len > 0) { - avail = FT245R_MIN_FIFO_SIZE - rx.pending; + avail = FT245R_MIN_FIFO_SIZE - my.rx.pending; if (avail <= 0) { avail = ft245r_fill(pgm); if (avail < 0) { - pmsg_error("fill returned %d: %s\n", avail, ftdi_get_error_string(handle)); + pmsg_error("fill returned %d: %s\n", avail, ftdi_get_error_string(my.handle)); return -1; } } @@ -231,16 +238,16 @@ static int ft245r_flush(const PROGRAMMER *pgm) { #if FT245R_DEBUG msg_info("%s: writing %d bytes\n", __func__, avail); #endif - rv = ftdi_write_data(handle, src, avail); + rv = ftdi_write_data(my.handle, src, avail); if (rv != avail) { - msg_error("write returned %d (expected %d): %s\n", rv, avail, ftdi_get_error_string(handle)); + msg_error("write returned %d (expected %d): %s\n", rv, avail, ftdi_get_error_string(my.handle)); return -1; } src += avail; len -= avail; - rx.pending += avail; + my.rx.pending += avail; } - tx.len = 0; + my.tx.len = 0; return 0; } @@ -249,9 +256,9 @@ static int ft245r_send2(const PROGRAMMER *pgm, unsigned char *buf, size_t len, for (size_t i = 0; i < len; ++i) { for (int j = 0; j < baud_multiplier; ++j) { if (discard_rx_data) - ++rx.discard; - tx.buf[tx.len++] = buf[i]; - if (tx.len >= FT245R_MIN_FIFO_SIZE) + ++my.rx.discard; + my.tx.buf[my.tx.len++] = buf[i]; + if (my.tx.len >= FT245R_MIN_FIFO_SIZE) ft245r_flush(pgm); } } @@ -272,16 +279,16 @@ static int ft245r_recv(const PROGRAMMER *pgm, unsigned char *buf, size_t len) { ft245r_fill(pgm); #if FT245R_DEBUG - msg_info("%s: discarding %d, consuming %lu bytes\n", __func__, rx.discard, (unsigned long) len); + msg_info("%s: discarding %d, consuming %lu bytes\n", __func__, my.rx.discard, (unsigned long) len); #endif - while (rx.discard > 0) { + while (my.rx.discard > 0) { int result = ft245r_rx_buf_fill_and_get(pgm); if (result < 0) { return result; } - --rx.discard; + --my.rx.discard; } for (size_t i = 0; i < len; ++i) @@ -310,9 +317,9 @@ static int ft245r_drain(const PROGRAMMER *pgm, int display) { int r; // flush the buffer in the chip by changing the mode ... - r = ftdi_set_bitmode(handle, 0, BITMODE_RESET); // reset + r = ftdi_set_bitmode(my.handle, 0, BITMODE_RESET); // reset if (r) return -1; - r = ftdi_set_bitmode(handle, ft245r_ddr, BITMODE_SYNCBB); // set Synchronuse BitBang + r = ftdi_set_bitmode(my.handle, my.ft245r_ddr, BITMODE_SYNCBB); // set Synchronuse BitBang if (r) return -1; // drain our buffer. @@ -329,7 +336,7 @@ static void ft245r_usleep(const PROGRAMMER *pgm, useconds_t usec) { static int ft245r_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { - unsigned char cmd[4] = {0,0,0,0}; + unsigned char cmd[4] = {0, 0, 0, 0}; unsigned char res[4]; if (p->prog_modes & PM_TPI) @@ -361,10 +368,7 @@ static int ft245r_set_bitclock(const PROGRAMMER *pgm) { } #if FT245R_BITBANG_VARIABLE_PULSE_WIDTH_WORKAROUND - if (rate > 0 && rate < ftdi_rate) - baud_multiplier = round((ftdi_rate + rate - 1) / rate); - else - baud_multiplier = 1; + my.baud_mult = rate > 0 && rate < ftdi_rate? round((ftdi_rate + rate - 1) / rate): 1; #else ftdi_rate = rate; #endif @@ -372,9 +376,9 @@ static int ft245r_set_bitclock(const PROGRAMMER *pgm) { msg_notice2("%s: bitclk %d -> FTDI rate %d, baud multiplier %d\n", __func__, rate, ftdi_rate, baud_multiplier); - r = ftdi_set_baudrate(handle, ftdi_rate); + r = ftdi_set_baudrate(my.handle, ftdi_rate); if (r) { - msg_error("set baudrate %d failed with error '%s'\n", rate, ftdi_get_error_string (handle)); + msg_error("set baudrate %d failed with error '%s'\n", rate, ftdi_get_error_string (my.handle)); return -1; } return 0; @@ -385,7 +389,7 @@ static int get_pin(const PROGRAMMER *pgm, int pinname) { ft245r_flush(pgm); - if (ftdi_read_pins(handle, &byte) != 0) + if (ftdi_read_pins(my.handle, &byte) != 0) return -1; if (FT245R_DEBUG) msg_info("%s: in 0x%02x\n", __func__, byte); @@ -400,8 +404,8 @@ static int set_pin(const PROGRAMMER *pgm, int pinname, int val) { return 0; } - ft245r_out = SET_BITS_0(ft245r_out,pgm,pinname,val); - buf[0] = ft245r_out; + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, pinname, val); + buf[0] = my.ft245r_out; ft245r_send_and_discard(pgm, buf, 1); return 0; @@ -484,7 +488,7 @@ static void ft245r_enable(PROGRAMMER *pgm, const AVRPART *p) { * issue the 'program enable' command to the AVR device */ static int ft245r_program_enable(const PROGRAMMER *pgm, const AVRPART *p) { - unsigned char cmd[4] = {0,0,0,0}; + unsigned char cmd[4] = {0, 0, 0, 0}; unsigned char res[4]; int i; @@ -602,15 +606,14 @@ static int ft245r_initialize(const PROGRAMMER *pgm, const AVRPART *p) { return ft245r_program_enable(pgm, p); } -static inline void add_bit(const PROGRAMMER *pgm, unsigned char *buf, int *buf_pos, - uint8_t bit) { - ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SDO, bit); - ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0); - buf[*buf_pos] = ft245r_out; +static inline void add_bit(const PROGRAMMER *pgm, unsigned char *buf, int *buf_pos, uint8_t bit) { + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SDO, bit); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SCK, 0); + buf[*buf_pos] = my.ft245r_out; (*buf_pos)++; - ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,1); - buf[*buf_pos] = ft245r_out; + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SCK, 1); + buf[*buf_pos] = my.ft245r_out; (*buf_pos)++; } @@ -635,7 +638,7 @@ static inline unsigned char extract_data(const PROGRAMMER *pgm, unsigned char *b buf += offset * (8 * FT245R_CYCLES); for (j=0; j<8; j++) { - if (GET_BITS_0(buf[buf_pos],pgm,PIN_AVR_SDI)) { + if (GET_BITS_0(buf[buf_pos], pgm, PIN_AVR_SDI)) { r |= bit; } buf_pos += FT245R_CYCLES; @@ -654,7 +657,7 @@ static inline unsigned char extract_data_out(const PROGRAMMER *pgm, unsigned cha buf += offset * (8 * FT245R_CYCLES); for (j=0; j<8; j++) { - if (GET_BITS_0(buf[buf_pos],pgm,PIN_AVR_SDO)) { + if (GET_BITS_0(buf[buf_pos], pgm, PIN_AVR_SDO)) { r |= bit; } buf_pos += FT245R_CYCLES; @@ -669,9 +672,8 @@ static inline unsigned char extract_data_out(const PROGRAMMER *pgm, unsigned cha * transmit an AVR device command and return the results; 'cmd' and * 'res' must point to at least a 4 byte data buffer */ -static int ft245r_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, - unsigned char *res) { - int i,buf_pos; +static int ft245r_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, unsigned char *res) { + int i, buf_pos; unsigned char buf[128]; buf_pos = 0; @@ -691,8 +693,7 @@ static int ft245r_cmd(const PROGRAMMER *pgm, const unsigned char *cmd, return 0; } -static inline uint8_t extract_tpi_data(const PROGRAMMER *pgm, unsigned char *buf, - int *buf_pos) { +static inline uint8_t extract_tpi_data(const PROGRAMMER *pgm, unsigned char *buf, int *buf_pos) { uint8_t bit = 0x1, byte = 0; int j; @@ -705,8 +706,7 @@ static inline uint8_t extract_tpi_data(const PROGRAMMER *pgm, unsigned char *buf return byte; } -static inline int set_tpi_data(const PROGRAMMER *pgm, unsigned char *buf, - uint8_t byte) { +static inline int set_tpi_data(const PROGRAMMER *pgm, unsigned char *buf, uint8_t byte) { uint8_t bit = 0x1, parity = 0; int j, buf_pos = 0; @@ -804,13 +804,13 @@ static int ft245r_cmd_tpi(const PROGRAMMER *pgm, const unsigned char *cmd, } /* lower 8 pins are accepted, they might be also inverted */ -static const struct pindef_t valid_pins = {{0xff},{0xff}} ; +static const struct pindef_t valid_pins = {{0xff}, {0xff}} ; static const struct pin_checklist_t pin_checklist[] = { - { PIN_AVR_SCK, 1, &valid_pins}, + { PIN_AVR_SCK, 1, &valid_pins}, { PIN_AVR_SDO, 1, &valid_pins}, { PIN_AVR_SDI, 1, &valid_pins}, - { PIN_AVR_RESET,1, &valid_pins}, + { PIN_AVR_RESET, 1, &valid_pins}, { PPI_AVR_BUFF, 0, &valid_pins}, }; @@ -819,7 +819,7 @@ static int ft245r_open(PROGRAMMER *pgm, const char *port) { int devnum = -1; char device[9] = ""; - rv = pins_check(pgm,pin_checklist,sizeof(pin_checklist)/sizeof(pin_checklist[0]), true); + rv = pins_check(pgm, pin_checklist, sizeof(pin_checklist)/sizeof(pin_checklist[0]), true); if(rv) { pgm->display(pgm, progbuf); @@ -844,7 +844,7 @@ static int ft245r_open(PROGRAMMER *pgm, const char *port) { else if (strncmp("ft", device, 2) || strlen(device) <= 8) { // classic device number char *startptr = device + 2; char *endptr = NULL; - devnum = strtol(startptr,&endptr,10); + devnum = strtol(startptr, &endptr, 10); if ((startptr==endptr) || (*endptr != '\0')) { devnum = -1; } @@ -858,8 +858,8 @@ static int ft245r_open(PROGRAMMER *pgm, const char *port) { return -1; } - handle = malloc (sizeof (struct ftdi_context)); - ftdi_init(handle); + my.handle = mmt_malloc(sizeof (struct ftdi_context)); + ftdi_init(my.handle); LNODEID usbpid = lfirst(pgm->usbpid); int pid; if (usbpid) { @@ -869,18 +869,18 @@ static int ft245r_open(PROGRAMMER *pgm, const char *port) { } else { pid = USB_DEVICE_FT245; } - rv = ftdi_usb_open_desc_index(handle, + rv = ftdi_usb_open_desc_index(my.handle, pgm->usbvid?pgm->usbvid:USB_VENDOR_FTDI, pid, pgm->usbproduct[0]?pgm->usbproduct:NULL, pgm->usbsn[0]?pgm->usbsn:NULL, devnum); if (rv) { - pmsg_error("cannot open ftdi device: %s\n", ftdi_get_error_string(handle)); + pmsg_error("cannot open ftdi device: %s\n", ftdi_get_error_string(my.handle)); goto cleanup_no_usb; } - ft245r_ddr = + my.ft245r_ddr = pgm->pin[PIN_AVR_SCK].mask[0] | pgm->pin[PIN_AVR_SDO].mask[0] | pgm->pin[PIN_AVR_RESET].mask[0] @@ -892,27 +892,27 @@ static int ft245r_open(PROGRAMMER *pgm, const char *port) { | pgm->pin[PIN_LED_VFY].mask[0]; /* set initial values for outputs, no reset everything else is off */ - ft245r_out = 0; - ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_RESET,1); - ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SCK,0); - ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_AVR_SDO,0); - ft245r_out = SET_BITS_0(ft245r_out,pgm,PPI_AVR_BUFF,0); - ft245r_out = SET_BITS_0(ft245r_out,pgm,PPI_AVR_VCC,0); - ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_ERR,0); - ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_RDY,0); - ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_PGM,0); - ft245r_out = SET_BITS_0(ft245r_out,pgm,PIN_LED_VFY,0); + my.ft245r_out = 0; + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_RESET, 1); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SCK, 0); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SDO, 0); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PPI_AVR_BUFF, 0); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PPI_AVR_VCC, 0); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_LED_ERR, 0); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_LED_RDY, 0); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_LED_PGM, 0); + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_LED_VFY, 0); - rv = ftdi_set_latency_timer(handle, 1); + rv = ftdi_set_latency_timer(my.handle, 1); if (rv) { - pmsg_error("unable to set latency timer to 1 (%s)\n", ftdi_get_error_string(handle)); + pmsg_error("unable to set latency timer to 1 (%s)\n", ftdi_get_error_string(my.handle)); goto cleanup; } - rv = ftdi_set_bitmode(handle, ft245r_ddr, BITMODE_SYNCBB); // set Synchronous BitBang + rv = ftdi_set_bitmode(my.handle, my.ft245r_ddr, BITMODE_SYNCBB); // set Synchronous BitBang if (rv) { - pmsg_error("synchronous BitBangMode is not supported (%s)\n", ftdi_get_error_string(handle)); + pmsg_error("synchronous BitBangMode is not supported (%s)\n", ftdi_get_error_string(my.handle)); goto cleanup; } @@ -926,34 +926,34 @@ static int ft245r_open(PROGRAMMER *pgm, const char *port) { */ ft245r_drain (pgm, 0); - ft245r_send_and_discard(pgm, &ft245r_out, 1); + ft245r_send_and_discard(pgm, &my.ft245r_out, 1); return 0; cleanup: - ftdi_usb_close(handle); + ftdi_usb_close(my.handle); cleanup_no_usb: - ftdi_deinit (handle); - free(handle); - handle = NULL; + ftdi_deinit (my.handle); + mmt_free(my.handle); + my.handle = NULL; return -1; } static void ft245r_close(PROGRAMMER * pgm) { - if (handle) { + if (my.handle) { // I think the switch to BB mode and back flushes the buffer. - ftdi_set_bitmode(handle, 0, BITMODE_SYNCBB); // set Synchronous BitBang, all in puts - ftdi_set_bitmode(handle, 0, BITMODE_RESET); // disable Synchronous BitBang - ftdi_usb_close(handle); - ftdi_deinit (handle); - free(handle); - handle = NULL; + ftdi_set_bitmode(my.handle, 0, BITMODE_SYNCBB); // set Synchronous BitBang, all in puts + ftdi_set_bitmode(my.handle, 0, BITMODE_RESET); // disable Synchronous BitBang + ftdi_usb_close(my.handle); + ftdi_deinit (my.handle); + mmt_free(my.handle); + my.handle = NULL; } } static void ft245r_display(const PROGRAMMER *pgm, const char *p) { - msg_info("%sPin assignment : 0..7 = DBUS0..7\n", p); // , 8..11 = GPIO0..3\n",p); + msg_info("%sPin assignment : 0..7 = DBUS0..7\n", p); // , 8..11 = GPIO0..3\n", p); pgm_display_generic_mask(pgm, p, SHOW_ALL_PINS); } @@ -968,35 +968,23 @@ static int ft245r_paged_write_gen(const PROGRAMMER *pgm, const AVRPART *p, const return n_bytes; } - -static struct ft245r_request { - int addr; - int bytes; - int n; - struct ft245r_request *next; -} *req_head,*req_tail,*req_pool; - -static void put_request(int addr, int bytes, int n) { +static void put_request(const PROGRAMMER *pgm, int addr, int bytes, int n) { struct ft245r_request *p; - if (req_pool) { - p = req_pool; - req_pool = p->next; - } else { - p = malloc(sizeof(struct ft245r_request)); - if (!p) { - msg_error("cannot alloc memory\n"); - exit(1); - } + if (my.req_pool) { // Allocate struct ft245r_request from pool + p = my.req_pool; + my.req_pool = p->next; + } else { // ... or from memory + p = mmt_malloc(sizeof(struct ft245r_request)); } memset(p, 0, sizeof(struct ft245r_request)); p->addr = addr; p->bytes = bytes; p->n = n; - if (req_tail) { - req_tail->next = p; - req_tail = p; + if (my.req_tail) { + my.req_tail->next = p; + my.req_tail = p; } else { - req_head = req_tail = p; + my.req_head = my.req_tail = p; } } @@ -1005,17 +993,20 @@ static int do_request(const PROGRAMMER *pgm, const AVRMEM *m) { int addr, bytes, j, n; unsigned char buf[FT245R_FRAGMENT_SIZE+1+128]; - if (!req_head) return 0; - p = req_head; - req_head = p->next; - if (!req_head) req_tail = req_head; + if (!my.req_head) + return 0; + p = my.req_head; + my.req_head = p->next; + if (!my.req_head) + my.req_tail = my.req_head; addr = p->addr; bytes = p->bytes; n = p->n; + // Insert p into request pool memset(p, 0, sizeof(struct ft245r_request)); - p->next = req_pool; - req_pool = p; + p->next = my.req_pool; + my.req_pool = p; ft245r_recv(pgm, buf, bytes); for (j=0; j= (int) n_bytes || j >= FT245R_FRAGMENT_SIZE/FT245R_CMD_SIZE) { if(i >= (int) n_bytes) { - ft245r_out = SET_BITS_0(ft245r_out, pgm, PIN_AVR_SCK, 0); // SCK down - buf[buf_pos++] = ft245r_out; + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SCK, 0); // SCK down + buf[buf_pos++] = my.ft245r_out; } else { // stretch sequence to allow correct readout, see extract_data() buf[buf_pos] = buf[buf_pos - 1]; buf_pos++; } ft245r_send(pgm, buf, buf_pos); - put_request(addr_save, buf_pos, 0); + put_request(pgm, addr_save, buf_pos, 0); if(++req_count > REQ_OUTSTANDINGS) do_request(pgm, m); @@ -1165,15 +1156,15 @@ static int ft245r_paged_load_flash(const PROGRAMMER *pgm, const AVRPART *p, cons // finished or buffer exhausted? queue up requests if(i >= (int) n_bytes || j >= FT245R_FRAGMENT_SIZE/FT245R_CMD_SIZE) { if(i >= (int) n_bytes) { - ft245r_out = SET_BITS_0(ft245r_out, pgm, PIN_AVR_SCK, 0); // SCK down - buf[buf_pos++] = ft245r_out; + my.ft245r_out = SET_BITS_0(my.ft245r_out, pgm, PIN_AVR_SCK, 0); // SCK down + buf[buf_pos++] = my.ft245r_out; } else { // stretch sequence to allow correct readout, see extract_data() buf[buf_pos] = buf[buf_pos - 1]; buf_pos++; } ft245r_send(pgm, buf, buf_pos); - put_request(addr_save, buf_pos, j); + put_request(pgm, addr_save, buf_pos, j); if(++req_count > REQ_OUTSTANDINGS) do_request(pgm, m); @@ -1205,6 +1196,28 @@ static int ft245r_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRM return -2; } +void ft245r_setup(PROGRAMMER *pgm) { + pgm->cookie = mmt_malloc(sizeof(struct pdata)); +} + +void ft245r_teardown(PROGRAMMER *pgm) { + if(!pgm->cookie) + return; + + while(my.req_pool) { // Free request pool + struct ft245r_request *p = my.req_pool; + my.req_pool = p->next; + mmt_free(p); + } + while(my.req_head) { // Free pending queue + struct ft245r_request *p = my.req_head; + my.req_head = p->next; + mmt_free(p); + } + mmt_free(pgm->cookie); + pgm->cookie = NULL; +} + void ft245r_initpgm(PROGRAMMER *pgm) { strcpy(pgm->type, "ftdi_syncbb"); @@ -1236,10 +1249,10 @@ void ft245r_initpgm(PROGRAMMER *pgm) { pgm->vfy_led = ft245_vfy_led; pgm->powerup = ft245r_powerup; pgm->powerdown = ft245r_powerdown; - - handle = NULL; + pgm->setup = ft245r_setup; + pgm->teardown = ft245r_teardown; } #endif -const char ft245r_desc[] = "FT245R/FT232R Synchronous BitBangMode Programmer"; +const char ft245r_desc[] = "FT245R/FT232R synchronous bit-bang programmer of type ftdi_syncbb"; diff --git a/src/jtag3.c b/src/jtag3.c index 168562e6..c18f518e 100644 --- a/src/jtag3.c +++ b/src/jtag3.c @@ -97,6 +97,8 @@ struct pdata /* Function to set the appropriate clock parameter */ int (*set_sck)(const PROGRAMMER *, unsigned char *); + + unsigned char signature_cache[2]; // Used in jtag3_read_byte() }; #define PDATA(pgm) ((struct pdata *)(pgm->cookie)) @@ -134,24 +136,17 @@ static unsigned char jtag3_mtype(const PROGRAMMER *pgm, const AVRPART *p, unsign static unsigned int jtag3_memaddr(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned long addr); -void jtag3_setup(PROGRAMMER * pgm) -{ - if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) { - pmsg_error("out of memory allocating private data\n"); - exit(1); - } - memset(pgm->cookie, 0, sizeof(struct pdata)); +void jtag3_setup(PROGRAMMER *pgm) { + pgm->cookie = mmt_malloc(sizeof(struct pdata)); } -void jtag3_teardown(PROGRAMMER * pgm) -{ - free(pgm->cookie); +void jtag3_teardown(PROGRAMMER *pgm) { + mmt_free(pgm->cookie); + pgm->cookie = NULL; } -static unsigned long -b4_to_u32(unsigned char *b) -{ +static unsigned long b4_to_u32(unsigned char *b) { unsigned long l; l = b[0]; l += (unsigned)b[1] << 8; @@ -161,18 +156,14 @@ b4_to_u32(unsigned char *b) return l; } -static void -u32_to_b4(unsigned char *b, unsigned long l) -{ +static void u32_to_b4(unsigned char *b, unsigned long l) { b[0] = l & 0xff; b[1] = (l >> 8) & 0xff; b[2] = (l >> 16) & 0xff; b[3] = (l >> 24) & 0xff; } -static unsigned short -b2_to_u16(unsigned char *b) -{ +static unsigned short b2_to_u16(unsigned char *b) { unsigned short l; l = b[0]; l += (unsigned)b[1] << 8; @@ -180,31 +171,24 @@ b2_to_u16(unsigned char *b) return l; } -static void -u16_to_b2(unsigned char *b, unsigned short l) -{ +static void u16_to_b2(unsigned char *b, unsigned short l) { b[0] = l & 0xff; b[1] = (l >> 8) & 0xff; } -static void -u32_to_b4_big_endian(unsigned char *b, unsigned long l) -{ +static void u32_to_b4_big_endian(unsigned char *b, unsigned long l) { b[0] = (l >> 24) & 0xff; b[1] = (l >> 16) & 0xff; b[2] = (l >> 8) & 0xff; b[3] = l & 0xff; } -static void -u16_to_b2_big_endian(unsigned char *b, unsigned short l) -{ +static void u16_to_b2_big_endian(unsigned char *b, unsigned short l) { b[0] = (l >> 8) & 0xff; b[1] = l & 0xff; } -static void jtag3_print_data(unsigned char *b, size_t s) -{ +static void jtag3_print_data(unsigned char *b, size_t s) { size_t i; if (s < 2) @@ -344,8 +328,7 @@ static void jtag3_prmsg(const PROGRAMMER *pgm, unsigned char *data, size_t len) } } -static int jtag3_errcode(int reason) -{ +static int jtag3_errcode(int reason) { if (reason == RSP3_FAIL_OCD_LOCKED || reason == RSP3_FAIL_CRC_FAILURE) return LIBAVRDUDE_SOFTFAIL; @@ -449,11 +432,7 @@ int jtag3_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) { msg_debug("\n"); pmsg_debug("jtag3_send(): sending %lu bytes\n", (unsigned long) len); - if ((buf = malloc(len + 4)) == NULL) { - pmsg_error("out of memory"); - return -1; - } - + buf = mmt_malloc(len + 4); buf[0] = TOKEN; buf[1] = 0; /* dummy */ u16_to_b2(buf + 2, PDATA(pgm)->command_sequence); @@ -461,11 +440,11 @@ int jtag3_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) { if (serial_send(&pgm->fd, buf, len + 4) != 0) { pmsg_error("unable to send command to serial port\n"); - free(buf); + mmt_free(buf); return -1; } - free(buf); + mmt_free(buf); return 0; } @@ -657,7 +636,7 @@ static int jtag3_drain(const PROGRAMMER *pgm, int display) { * whether it matches the expected sequence number, including event * notification frames (seqno == 0xffff). * - * Caller must eventually free the buffer. + * Caller must eventually mmt_free() the buffer. */ static int jtag3_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) { int rv; @@ -668,19 +647,12 @@ static int jtag3_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) { pmsg_trace("jtag3_recv_frame():\n"); - if ((buf = malloc(pgm->fd.usb.max_xfer)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - if (verbose >= 4) - memset(buf, 0, pgm->fd.usb.max_xfer); - + buf = mmt_malloc(pgm->fd.usb.max_xfer); rv = serial_recv(&pgm->fd, buf, pgm->fd.usb.max_xfer); if (rv < 0) { - /* timeout in receive */ pmsg_notice2("jtag3_recv_frame(): timeout receiving packet\n"); - free(buf); + mmt_free(buf); return -1; } @@ -691,20 +663,13 @@ static int jtag3_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) { static int jtag3_edbg_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) { int rv, len = 0; - unsigned char *buf = NULL; + unsigned char *buf; unsigned char *request; pmsg_trace("jtag3_edbg_recv():\n"); - if ((buf = malloc(USBDEV_MAX_XFER_3)) == NULL) { - pmsg_notice("jtag3_edbg_recv(): out of memory\n"); - return -1; - } - if ((request = malloc(pgm->fd.usb.max_xfer)) == NULL) { - pmsg_notice("jtag3_edbg_recv(): out of memory\n"); - free(buf); - return -1; - } + buf = mmt_malloc(USBDEV_MAX_XFER_3); + request = mmt_malloc(pgm->fd.usb.max_xfer); *msg = buf; @@ -716,8 +681,8 @@ static int jtag3_edbg_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) { if (serial_send(&pgm->fd, request, pgm->fd.usb.max_xfer) != 0) { pmsg_notice("jtag3_edbg_recv(): unable to send CMSIS-DAP vendor command\n"); - free(request); - free(*msg); + mmt_free(request); + mmt_free(*msg); return -1; } @@ -726,15 +691,15 @@ static int jtag3_edbg_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) { if (rv < 0) { /* timeout in receive */ pmsg_notice2("jtag3_edbg_recv(): timeout receiving packet\n"); - free(*msg); - free(request); + mmt_free(*msg); + mmt_free(request); return -1; } if (buf[0] != EDBG_VENDOR_AVR_RSP) { pmsg_notice("jtag3_edbg_recv(): unexpected response 0x%02x\n", buf[0]); - free(*msg); - free(request); + mmt_free(*msg); + mmt_free(request); return -1; } @@ -743,8 +708,8 @@ static int jtag3_edbg_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) { // "FragmentInfo 0x00 indicates that no response data is // available, and the rest of the packet is ignored." pmsg_notice("jtag3_edbg_recv(): no response available\n"); - free(*msg); - free(request); + mmt_free(*msg); + mmt_free(request); return -1; } @@ -758,8 +723,8 @@ static int jtag3_edbg_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) { pmsg_notice("jtag3_edbg_recv(): " "Inconsistent # of fragments; had %d, now %d\n", nfrags, (buf[1] & 0x0F)); - free(*msg); - free(request); + mmt_free(*msg); + mmt_free(request); return -1; } } @@ -767,8 +732,8 @@ static int jtag3_edbg_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) { pmsg_notice("jtag3_edbg_recv(): " "inconsistent fragment number; expect %d, got %d\n", thisfrag, ((buf[1] >> 4) & 0x0F)); - free(*msg); - free(request); + mmt_free(*msg); + mmt_free(request); return -1; } @@ -787,7 +752,7 @@ static int jtag3_edbg_recv_frame(const PROGRAMMER *pgm, unsigned char **msg) { buf += thislen; } while (thisfrag <= nfrags); - free(request); + mmt_free(request); return len; } @@ -803,7 +768,7 @@ int jtag3_recv(const PROGRAMMER *pgm, unsigned char **msg) { if (verbose >= 3) jtag3_prevent(pgm, *msg, rv & USB_RECV_LENGTH_MASK); - free(*msg); + mmt_free(*msg); continue; } @@ -817,12 +782,12 @@ int jtag3_recv(const PROGRAMMER *pgm, unsigned char **msg) { /* * We move the payload to the beginning of the buffer, to make * the job easier for the caller. We have to return the - * original pointer though, as the caller must free() it. + * original pointer though, as the caller must mmt_free() it. */ rv -= 3; if (rv < 0) { pmsg_error("unexpected return value %d from jtag3_recv_frame()\n", rv); - free(*msg); + mmt_free(*msg); return -1; } memmove(*msg, *msg + 3, rv); @@ -832,7 +797,7 @@ int jtag3_recv(const PROGRAMMER *pgm, unsigned char **msg) { pmsg_notice2("jtag3_recv(): " "got wrong sequence number, %u != %u\n", r_seqno, PDATA(pgm)->command_sequence); - free(*msg); + mmt_free(*msg); } } @@ -849,7 +814,7 @@ int jtag3_command(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen msg_notice2("\n"); pmsg_notice2("%s command: timeout/error communicating with programmer (status %d)\n", descr, status); if (status == 0) - free(*resp); + mmt_free(*resp); return LIBAVRDUDE_GENERAL_FAILURE; } else if (verbose >= 3) { msg_debug("\n"); @@ -867,7 +832,7 @@ int jtag3_command(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen pmsg_notice("bad response to %s command: 0x%02x\n", descr, c); } status = (*resp)[3]; - free(*resp); + mmt_free(*resp); resp = 0; return jtag3_errcode(status); } @@ -899,7 +864,7 @@ int jtag3_getsync(const PROGRAMMER *pgm, int mode) { if (jtag3_command(pgm, buf, 3, &resp, "sign-on") < 0) return -1; - free(resp); + mmt_free(resp); return 0; } @@ -919,7 +884,7 @@ static int jtag3_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { if (jtag3_command(pgm, buf, 8, &resp, "chip erase") < 0) return -1; - free(resp); + mmt_free(resp); return 0; } @@ -939,13 +904,14 @@ static int jtag3_unlock_erase_key(const PROGRAMMER *pgm, const AVRPART *p) { if (jtag3_command(pgm, buf, 3, &resp, "enter progmode") < 0) return -1; + mmt_free(resp); + PDATA(pgm)->prog_enabled = 1; buf[0] = 0; /* Disable */ if (jtag3_setparm(pgm, SCOPE_AVR, SET_GET_CTXT_OPTIONS, PARM3_OPT_CHIP_ERASE_TO_ENTER, buf, 1) < 0) return -1; - free(resp); return 0; } @@ -974,7 +940,7 @@ static int jtag3_program_enable(const PROGRAMMER *pgm) { buf[2] = 0; if ((status = jtag3_command(pgm, buf, 3, &resp, "enter progmode")) >= 0) { - free(resp); + mmt_free(resp); PDATA(pgm)->prog_enabled = 1; return LIBAVRDUDE_SUCCESS; @@ -996,7 +962,7 @@ static int jtag3_program_disable(const PROGRAMMER *pgm) { if (jtag3_command(pgm, buf, 3, &resp, "leave progmode") < 0) return -1; - free(resp); + mmt_free(resp); PDATA(pgm)->prog_enabled = 0; @@ -1433,7 +1399,7 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) { resp[3], resp[4], resp[5], resp[6]); } - free(resp); + mmt_free(resp); if (pgm->read_sib) { if (pgm->read_sib(pgm, p, PDATA(pgm)->sib_string) < 0) { @@ -1460,27 +1426,19 @@ static int jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) { } } - free(PDATA(pgm)->flash_pagecache); - free(PDATA(pgm)->eeprom_pagecache); - if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) { - pmsg_error("out of memory\n"); - free(PDATA(pgm)->flash_pagecache); - return -1; - } - PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; + mmt_free(PDATA(pgm)->flash_pagecache); + mmt_free(PDATA(pgm)->eeprom_pagecache); + PDATA(pgm)->flash_pagecache = mmt_malloc(PDATA(pgm)->flash_pagesize); + PDATA(pgm)->eeprom_pagecache = mmt_malloc(PDATA(pgm)->eeprom_pagesize); + PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long) -1L; return 0; } static void jtag3_disable(const PROGRAMMER *pgm) { - - free(PDATA(pgm)->flash_pagecache); + mmt_free(PDATA(pgm)->flash_pagecache); PDATA(pgm)->flash_pagecache = NULL; - free(PDATA(pgm)->eeprom_pagecache); + mmt_free(PDATA(pgm)->eeprom_pagecache); PDATA(pgm)->eeprom_pagecache = NULL; /* @@ -1665,7 +1623,7 @@ static int jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { if(str_starts(pgmid, "pickit4") || str_starts(pgmid, "snap")) msg_error(" -xmode=avr|pic Set programmer to AVR or PIC mode, then exit\n"); msg_error (" -xhelp Show this help menu and exit\n"); - exit(0); + return LIBAVRDUDE_EXIT;; } pmsg_error("invalid extended parameter %s\n", extended_param); @@ -1768,7 +1726,7 @@ int jtag3_open_common(PROGRAMMER *pgm, const char *port, int mode_switch) { imsg_error("avrdude -c%s -p%s -P%s -xmode=avr\n", pgmid, partdesc, port); } serial_close(&pgm->fd); - exit(0); + return LIBAVRDUDE_EXIT;; } } } @@ -1817,7 +1775,7 @@ int jtag3_open_common(PROGRAMMER *pgm, const char *port, int mode_switch) { } imsg_error("PIC mode switch successful\n"); serial_close(&pgm->fd); - exit(0); + return LIBAVRDUDE_EXIT;; } return 0; @@ -1832,17 +1790,15 @@ static int jtag3_open(PROGRAMMER *pgm, const char *port) { if (rc < 0) return rc; - if (jtag3_getsync(pgm, PARM3_CONN_JTAG) < 0) - return -1; - - return 0; + return jtag3_getsync(pgm, PARM3_CONN_JTAG) < 0? -1: 0; } static int jtag3_open_dw(PROGRAMMER *pgm, const char *port) { pmsg_notice2("jtag3_open_dw()\n"); - if (jtag3_open_common(pgm, port, PDATA(pgm)->pk4_snap_mode) < 0) - return -1; + int rc = jtag3_open_common(pgm, port, PDATA(pgm)->pk4_snap_mode); + if (rc < 0) + return rc; if (jtag3_getsync(pgm, PARM3_CONN_DW) < 0) return -1; @@ -1852,14 +1808,11 @@ static int jtag3_open_dw(PROGRAMMER *pgm, const char *port) { static int jtag3_open_pdi(PROGRAMMER *pgm, const char *port) { pmsg_notice2("jtag3_open_pdi()\n"); + int rc = jtag3_open_common(pgm, port, PDATA(pgm)->pk4_snap_mode); + if (rc < 0) + return rc; - if (jtag3_open_common(pgm, port, PDATA(pgm)->pk4_snap_mode) < 0) - return -1; - - if (jtag3_getsync(pgm, PARM3_CONN_PDI) < 0) - return -1; - - return 0; + return jtag3_getsync(pgm, PARM3_CONN_PDI) < 0? -1: 0; } static int jtag3_open_updi(PROGRAMMER *pgm, const char *port) { @@ -1871,13 +1824,11 @@ static int jtag3_open_updi(PROGRAMMER *pgm, const char *port) { msg_notice2(" %d", *(int *) ldata(ln)); msg_notice2("\n"); - if (jtag3_open_common(pgm, port, PDATA(pgm)->pk4_snap_mode) < 0) - return -1; + int rc = jtag3_open_common(pgm, port, PDATA(pgm)->pk4_snap_mode); + if (rc < 0) + return rc; - if (jtag3_getsync(pgm, PARM3_CONN_UPDI) < 0) - return -1; - - return 0; + return jtag3_getsync(pgm, PARM3_CONN_UPDI) < 0? -1: 0; } void jtag3_close(PROGRAMMER * pgm) { @@ -1890,13 +1841,13 @@ void jtag3_close(PROGRAMMER * pgm) { buf[2] = buf[3] = 0; if (jtag3_command(pgm, buf, 3, &resp, "AVR sign-off") >= 0) - free(resp); + mmt_free(resp); buf[0] = SCOPE_GENERAL; buf[1] = CMD3_SIGN_OFF; if (jtag3_command(pgm, buf, 4, &resp, "sign-off") >= 0) - free(resp); + mmt_free(resp); /* XplainedMini boards do not need this, and early revisions had a * firmware bug where they complained about it. */ @@ -1950,7 +1901,7 @@ static int jtag3_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AVRME if (jtag3_command(pgm, cmd, 8, &resp, "page erase") < 0) return -1; - free(resp); + mmt_free(resp); return 0; } @@ -1977,11 +1928,7 @@ static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRM if (page_size == 0) page_size = 256; - if ((cmd = malloc(page_size + 13)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - + cmd = mmt_malloc(page_size + 13); cmd[0] = SCOPE_AVR; cmd[1] = CMD3_WRITE_MEMORY; cmd[2] = 0; @@ -2000,11 +1947,11 @@ static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRM for (; addr < maxaddr; addr++) { status = jtag3_write_byte(pgm, p, m, addr, m->buf[addr]); if (status < 0) { - free(cmd); + mmt_free(cmd); return -1; } } - free(cmd); + mmt_free(cmd); return n_bytes; } cmd[3] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_EEPROM_XMEGA: MTYPE_EEPROM_PAGE; @@ -2046,15 +1993,15 @@ static int jtag3_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRM if ((status = jtag3_command(pgm, cmd, page_size + 13, &resp, "write memory")) < 0) { - free(cmd); + mmt_free(cmd); serial_recv_timeout = otimeout; return -1; } - free(resp); + mmt_free(resp); } - free(cmd); + mmt_free(cmd); serial_recv_timeout = otimeout; return n_bytes; @@ -2130,18 +2077,18 @@ static int jtag3_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AVRME if (resp[1] != RSP3_DATA || status < (int) block_size + 4) { pmsg_error("wrong/short reply to read memory command\n"); serial_recv_timeout = otimeout; - free(resp); + mmt_free(resp); return -1; } if(status < 4) { pmsg_error("unexpected response from read memory jtag3_command()\n"); - free(resp); + mmt_free(resp); return -1; } memcpy(m->buf + addr, resp + 3, status - 4); - free(resp); + mmt_free(resp); } serial_recv_timeout = otimeout; @@ -2250,8 +2197,6 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *value = PDATA(pgm)->sib_string[addr]; return 0; } else if (mem_is_signature(mem)) { - static unsigned char signature_cache[2]; - cmd[3] = MTYPE_SIGN_JTAG; /* @@ -2267,13 +2212,13 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM if ((status = jtag3_command(pgm, cmd, 12, &resp, "read memory")) < 0) return status; - signature_cache[0] = resp[4]; - signature_cache[1] = resp[5]; + PDATA(pgm)->signature_cache[0] = resp[4]; + PDATA(pgm)->signature_cache[1] = resp[5]; *value = resp[3]; - free(resp); + mmt_free(resp); return 0; } else if (addr <= 2) { - *value = signature_cache[addr - 1]; + *value = PDATA(pgm)->signature_cache[addr - 1]; return 0; } else { /* should not happen */ @@ -2323,7 +2268,7 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM if (resp[1] != RSP3_DATA || status < (int) (pagesize? pagesize: 1) + 4) { pmsg_error("wrong/short reply to read memory command\n"); - free(resp); + mmt_free(resp); return -1; } @@ -2334,7 +2279,7 @@ static int jtag3_read_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM } else *value = resp[3]; - free(resp); + mmt_free(resp); return 0; } @@ -2438,7 +2383,7 @@ static int jtag3_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRME if ((status = jtag3_command(pgm, cmd, 14, &resp, "write memory")) < 0) return status; - free(resp); + mmt_free(resp); return 0; } @@ -2540,18 +2485,18 @@ int jtag3_getparm(const PROGRAMMER *pgm, unsigned char scope, c = resp[1]; if (c != RSP3_DATA || status < 3) { pmsg_notice("jtag3_getparm(): bad response to %s\n", descr); - free(resp); + mmt_free(resp); return -1; } status -= 3; if (status < 0) { pmsg_error("unexpected return value %d from jtag3_command()\n", status); - free(resp); + mmt_free(resp); return -1; } memcpy(value, resp + 3, (length < status? length: status)); - free(resp); + mmt_free(resp); return 0; } @@ -2571,11 +2516,7 @@ int jtag3_setparm(const PROGRAMMER *pgm, unsigned char scope, sprintf(descr, "set parameter (scope 0x%02x, section %d, parm %d)", scope, section, parm); - if ((buf = malloc(6 + length)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - + buf = mmt_malloc(6 + length); buf[0] = scope; buf[1] = CMD3_SET_PARAMETER; buf[2] = 0; @@ -2586,9 +2527,9 @@ int jtag3_setparm(const PROGRAMMER *pgm, unsigned char scope, status = jtag3_command(pgm, buf, length + 6, &resp, descr); - free(buf); + mmt_free(buf); if (status >= 0) - free(resp); + mmt_free(resp); return status; } @@ -2611,7 +2552,7 @@ int jtag3_read_sib(const PROGRAMMER *pgm, const AVRPART *p, char *sib) { memcpy(sib, resp+3, AVR_SIBLEN); sib[AVR_SIBLEN-1] = 0; // Zero terminate string pmsg_debug("jtag3_read_sib(): received SIB: %s\n", sib); - free(resp); + mmt_free(resp); return 0; } @@ -2698,19 +2639,19 @@ void jtag3_display(const PROGRAMMER *pgm, const char *p) { cmd[3] = CMD3_INFO_SERIAL; if ((status = jtag3_command(pgm, cmd, 4, &resp, "get info (serial number)")) < 0) { - free(resp); + mmt_free(resp); return; } c = resp[1]; if (c != RSP3_INFO) { pmsg_error("response is not RSP3_INFO\n"); - free(resp); + mmt_free(resp); return; } if (status < 3) { msg_error("unexpected response from CMD3_GET_INFO command\n"); - free(resp); + mmt_free(resp); return; } memmove(resp, resp + 3, status - 3); @@ -2721,7 +2662,7 @@ void jtag3_display(const PROGRAMMER *pgm, const char *p) { msg_info("%sICE FW version : %d.%02d (rel. %d)\n", p, parms[1], parms[2], (parms[3] | (parms[4] << 8))); msg_info("%sSerial number : %s\n", p, sn); - free(resp); + mmt_free(resp); } @@ -2893,15 +2834,11 @@ static int jtag3_send_tpi(const PROGRAMMER *pgm, unsigned char *data, size_t len unsigned char *cmdbuf; int rv; - if ((cmdbuf = malloc(len + 1)) == NULL) { - pmsg_error("jtag3_send_tpi(): out of memory for command packet\n"); - exit(1); - } - + cmdbuf = mmt_malloc(len + 1); cmdbuf[0] = SCOPE_AVR_TPI; if (len > INT_MAX) { pmsg_error("invalid jtag3_send_tpi() packet length %lu\n", (unsigned long) len); - free(cmdbuf); + mmt_free(cmdbuf); return -1; } memcpy(cmdbuf + 1, data, len); @@ -2912,7 +2849,7 @@ static int jtag3_send_tpi(const PROGRAMMER *pgm, unsigned char *data, size_t len msg_trace("\n"); rv = jtag3_send(pgm, cmdbuf, len + 1); - free(cmdbuf); + mmt_free(cmdbuf); return rv; } @@ -2955,7 +2892,7 @@ int jtag3_command_tpi(const PROGRAMMER *pgm, unsigned char *cmd, unsigned int cm if (c != XPRG_ERR_OK) { pmsg_error("[TPI] command %s FAILED! Status: 0x%02x\n", descr, c); status = (*resp)[3]; - free(*resp); + mmt_free(*resp); resp = 0; return LIBAVRDUDE_GENERAL_FAILURE; } @@ -3000,7 +2937,7 @@ static int jtag3_initialize_tpi(const PROGRAMMER *pgm, const AVRPART *p) { if ((status = jtag3_command_tpi(pgm, cmd, 1, &resp, "Enter Progmode")) < 0) return -1; - free(resp); + mmt_free(resp); cmd[0] = XPRG_CMD_SET_PARAM; cmd[1] = XPRG_PARAM_NVMCMD_ADDR; @@ -3008,7 +2945,7 @@ static int jtag3_initialize_tpi(const PROGRAMMER *pgm, const AVRPART *p) { if ((status = jtag3_command_tpi(pgm, cmd, 3, &resp, "Set NVMCMD")) < 0) return -1; - free(resp); + mmt_free(resp); cmd[0] = XPRG_CMD_SET_PARAM; cmd[1] = XPRG_PARAM_NVMCSR_ADDR; @@ -3016,7 +2953,7 @@ static int jtag3_initialize_tpi(const PROGRAMMER *pgm, const AVRPART *p) { if ((status = jtag3_command_tpi(pgm, cmd, 3, &resp, "Set NVMCSR")) < 0) return -1; - free(resp); + mmt_free(resp); return 0; } @@ -3034,7 +2971,7 @@ static void jtag3_disable_tpi(const PROGRAMMER *pgm) { if ((status = jtag3_command_tpi(pgm, cmd, 1, &resp, "Leave Progmode")) < 0) return; - free(resp); + mmt_free(resp); } static int jtag3_read_byte_tpi(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *mem, @@ -3058,7 +2995,7 @@ static int jtag3_read_byte_tpi(const PROGRAMMER *pgm, const AVRPART *p, const AV if ((status = jtag3_command_tpi(pgm, cmd, len, &resp, "Read Byte")) < 0) return -1; *value = resp[2]; - free(resp); + mmt_free(resp); return 0; } @@ -3084,7 +3021,7 @@ static int jtag3_erase_tpi(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM if ((status = jtag3_command_tpi(pgm, cmd, len, &resp, "Erase")) < 0) return -1; - free(resp); + mmt_free(resp); return 0; } @@ -3141,7 +3078,7 @@ static int jtag3_write_byte_tpi(const PROGRAMMER *pgm, const AVRPART *p, const A if ((status = jtag3_command_tpi(pgm, cmd, len, &resp, "Write Byte")) < 0) return -1; - free(resp); + mmt_free(resp); return 0; } @@ -3167,16 +3104,14 @@ static int jtag3_chip_erase_tpi(const PROGRAMMER *pgm, const AVRPART *p) { if ((status = jtag3_command_tpi(pgm, cmd, len, &resp, "Chip Erase")) < 0) return -1; - free(resp); + mmt_free(resp); return 0; } static int jtag3_open_tpi(PROGRAMMER *pgm, const char *port) { pmsg_notice2("jtag3_open_tpi()\n"); - if (jtag3_open_common(pgm, port, PDATA(pgm)->pk4_snap_mode) < 0) - return -1; - return 0; + return jtag3_open_common(pgm, port, PDATA(pgm)->pk4_snap_mode); } void jtag3_close_tpi(PROGRAMMER *pgm) { @@ -3224,18 +3159,18 @@ static int jtag3_paged_load_tpi(const PROGRAMMER *pgm, const AVRPART *p, if (resp[1] != XPRG_ERR_OK || status < (int) block_size + 2) { pmsg_error("wrong/short reply to read memory command\n"); serial_recv_timeout = otimeout; - free(resp); + mmt_free(resp); return -1; } if (status < 2) { pmsg_error("unexpected return value %d from jtag3_paged_load_tpi()\n", status); - free(resp); + mmt_free(resp); return -1; } memcpy(m->buf + addr, resp + 2, status - 2); - free(resp); + mmt_free(resp); } serial_recv_timeout = otimeout; @@ -3261,11 +3196,7 @@ static int jtag3_paged_write_tpi(const PROGRAMMER *pgm, const AVRPART *p, if (page_size == 0) page_size = m->page_size; - if ((cmd = malloc(page_size + 9)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - + cmd = mmt_malloc(page_size + 9); cmd[0] = XPRG_CMD_WRITE_MEM; cmd[1] = tpi_get_mtype(m); cmd[2] = 0; // Page Mode; Not used - ignored @@ -3292,15 +3223,15 @@ static int jtag3_paged_write_tpi(const PROGRAMMER *pgm, const AVRPART *p, if ((status = jtag3_command_tpi(pgm, cmd, page_size + 9, &resp, "Write Memory")) < 0) { - free(cmd); + mmt_free(cmd); serial_recv_timeout = otimeout; return -1; } - free(resp); + mmt_free(resp); } - free(cmd); + mmt_free(cmd); serial_recv_timeout = otimeout; return n_bytes; diff --git a/src/jtagmkI.c b/src/jtagmkI.c index b02c9626..9f546cf8 100644 --- a/src/jtagmkI.c +++ b/src/jtagmkI.c @@ -97,32 +97,23 @@ static void jtagmkI_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp) static int jtagmkI_resync(const PROGRAMMER *pgm, int maxtries, int signon); -static void jtagmkI_setup(PROGRAMMER * pgm) -{ - if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) { - pmsg_error("out of memory allocating private data\n"); - exit(1); - } - memset(pgm->cookie, 0, sizeof(struct pdata)); +static void jtagmkI_setup(PROGRAMMER *pgm) { + pgm->cookie = mmt_malloc(sizeof(struct pdata)); } -static void jtagmkI_teardown(PROGRAMMER * pgm) -{ - free(pgm->cookie); +static void jtagmkI_teardown(PROGRAMMER *pgm) { + mmt_free(pgm->cookie); + pgm->cookie = NULL; } -static void -u32_to_b3(unsigned char *b, unsigned long l) -{ +static void u32_to_b3(unsigned char *b, unsigned long l) { b[2] = l & 0xff; b[1] = (l >> 8) & 0xff; b[0] = (l >> 16) & 0xff; } -static void -u16_to_b2(unsigned char *b, unsigned short l) -{ +static void u16_to_b2(unsigned char *b, unsigned short l) { b[0] = l & 0xff; b[1] = (l >> 8) & 0xff; } @@ -186,23 +177,18 @@ static int jtagmkI_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) msg_debug("\n"); pmsg_debug("jtagmkI_send(): sending %u bytes\n", (unsigned int) len); - if ((buf = malloc(len + 2)) == NULL) - { - pmsg_error("out of memory"); - exit(1); - } - + buf = mmt_malloc(len + 2); memcpy(buf, data, len); buf[len] = ' '; /* "CRC" */ buf[len + 1] = ' '; /* EOP */ if (serial_send(&pgm->fd, buf, len + 2) != 0) { pmsg_error("unable to send command to serial port\n"); - free(buf); + mmt_free(buf); return -1; } - free(buf); + mmt_free(buf); return 0; } @@ -402,7 +388,6 @@ static int jtagmkI_reset(const PROGRAMMER *pgm) { } static int jtagmkI_program_enable_dummy(const PROGRAMMER *pgm, const AVRPART *p) { - return 0; } @@ -458,8 +443,7 @@ static int jtagmkI_program_disable(const PROGRAMMER *pgm) { return 0; } -static unsigned char jtagmkI_get_baud(long baud) -{ +static unsigned char jtagmkI_get_baud(long baud) { for (size_t i = 0; i < sizeof baudtab / sizeof baudtab[0]; i++) if (baud == baudtab[i].baud) return baudtab[i].val; @@ -523,18 +507,11 @@ static int jtagmkI_initialize(const PROGRAMMER *pgm, const AVRPART *p) { jtagmkI_setparm(pgm, PARM_FLASH_PAGESIZE_HIGH, PDATA(pgm)->flash_pagesize >> 8); jtagmkI_setparm(pgm, PARM_EEPROM_PAGESIZE, PDATA(pgm)->eeprom_pagesize & 0xff); - free(PDATA(pgm)->flash_pagecache); - free(PDATA(pgm)->eeprom_pagecache); - if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) { - pmsg_error("out of memory\n"); - free(PDATA(pgm)->flash_pagecache); - return -1; - } - PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; + mmt_free(PDATA(pgm)->flash_pagecache); + mmt_free(PDATA(pgm)->eeprom_pagecache); + PDATA(pgm)->flash_pagecache = mmt_malloc(PDATA(pgm)->flash_pagesize); + PDATA(pgm)->eeprom_pagecache = mmt_malloc(PDATA(pgm)->eeprom_pagesize); + PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long) -1L; if (jtagmkI_reset(pgm) < 0) return -1; @@ -548,10 +525,9 @@ static int jtagmkI_initialize(const PROGRAMMER *pgm, const AVRPART *p) { static void jtagmkI_disable(const PROGRAMMER *pgm) { - - free(PDATA(pgm)->flash_pagecache); + mmt_free(PDATA(pgm)->flash_pagecache); PDATA(pgm)->flash_pagecache = NULL; - free(PDATA(pgm)->eeprom_pagecache); + mmt_free(PDATA(pgm)->eeprom_pagecache); PDATA(pgm)->eeprom_pagecache = NULL; (void)jtagmkI_program_disable(pgm); @@ -562,8 +538,7 @@ static void jtagmkI_enable(PROGRAMMER *pgm, const AVRPART *p) { } -static int jtagmkI_open(PROGRAMMER *pgm, const char *port) -{ +static int jtagmkI_open(PROGRAMMER *pgm, const char *port) { size_t i; pmsg_notice2("jtagmkI_open()\n"); @@ -601,8 +576,7 @@ static int jtagmkI_open(PROGRAMMER *pgm, const char *port) } -static void jtagmkI_close(PROGRAMMER * pgm) -{ +static void jtagmkI_close(PROGRAMMER *pgm) { unsigned char b; pmsg_notice2("jtagmkI_close()\n"); @@ -638,7 +612,7 @@ static int jtagmkI_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AV { int block_size, send_size, tries; unsigned int maxaddr = addr + n_bytes; - unsigned char cmd[6], *datacmd; + unsigned char cmd[6], *datacmd = NULL; unsigned char resp[2]; int is_flash = 0; long otimeout = serial_recv_timeout; @@ -657,11 +631,7 @@ static int jtagmkI_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AV return -1; } - if ((datacmd = malloc(page_size + 1)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - + datacmd = mmt_malloc(page_size + 1); cmd[0] = CMD_WRITE_MEM; if (mem_is_flash(m)) { cmd[1] = MTYPE_FLASH_PAGE; @@ -682,6 +652,7 @@ static int jtagmkI_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AV if (tries != 0 && jtagmkI_resync(pgm, 2000, 0) < 0) { pmsg_error("sync loss, retries exhausted\n"); + mmt_free(datacmd); return -1; } @@ -707,14 +678,17 @@ static int jtagmkI_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AV /* First part, send the write command. */ jtagmkI_send(pgm, cmd, 6); - if (jtagmkI_recv(pgm, resp, 1) < 0) + if (jtagmkI_recv(pgm, resp, 1) < 0) { + mmt_free(datacmd); return -1; + } if (resp[0] != RESP_OK) { msg_notice2("\n"); pmsg_warning("timeout/error communicating with programmer (resp %c)\n", resp[0]); if (tries++ < MAXTRIES) goto again; serial_recv_timeout = otimeout; + mmt_free(datacmd); return -1; } else { msg_notice2("OK\n"); @@ -732,21 +706,24 @@ static int jtagmkI_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AV /* Second, send the data command. */ jtagmkI_send(pgm, datacmd, send_size + 1); - if (jtagmkI_recv(pgm, resp, 2) < 0) + if (jtagmkI_recv(pgm, resp, 2) < 0) { + mmt_free(datacmd); return -1; + } if (resp[1] != RESP_OK) { msg_notice2("\n"); pmsg_warning("timeout/error communicating with programmer (resp %c)\n", resp[0]); if (tries++ < MAXTRIES) goto again; serial_recv_timeout = otimeout; + mmt_free(datacmd); return -1; } else { msg_notice2("OK\n"); } } - free(datacmd); + mmt_free(datacmd); serial_recv_timeout = otimeout; #undef MAXTRIES diff --git a/src/jtagmkII.c b/src/jtagmkII.c index 0266ce9f..12c4b53b 100644 --- a/src/jtagmkII.c +++ b/src/jtagmkII.c @@ -94,12 +94,14 @@ struct pdata #define FLAGS32_WRITE 2 // At least one write operation specified // Couple of flag bits for AVR32 programming int flags32; + + char msg[64]; // Used in jtagmkII_get_rc() }; #define PDATA(pgm) ((struct pdata *)(pgm->cookie)) #define RC(x) { x, #x }, -static struct { +static const struct { unsigned int code; const char *descr; } jtagresults[] = { @@ -174,18 +176,16 @@ static int jtagmkII_paged_load32(const PROGRAMMER *pgm, const AVRPART *p, const unsigned int addr, unsigned int n_bytes); void jtagmkII_setup(PROGRAMMER *pgm) { - pgm->cookie = cfg_malloc("jtagmkII_setup()", sizeof(struct pdata)); + pgm->cookie = mmt_malloc(sizeof(struct pdata)); PDATA(pgm)->rts_mode = RTS_MODE_DEFAULT; } void jtagmkII_teardown(PROGRAMMER *pgm) { - free(pgm->cookie); + mmt_free(pgm->cookie); + pgm->cookie = NULL; } - -static unsigned long -b4_to_u32(unsigned char *b) -{ +static unsigned long b4_to_u32(unsigned char *b) { unsigned long l; l = b[0]; l += (unsigned)b[1] << 8; @@ -194,9 +194,8 @@ b4_to_u32(unsigned char *b) return l; } -static unsigned long -b4_to_u32r(unsigned char *b) -{ + +static unsigned long b4_to_u32r(unsigned char *b) { unsigned long l; l = b[3]; l += (unsigned)b[2] << 8; @@ -206,26 +205,21 @@ b4_to_u32r(unsigned char *b) return l; } -static void -u32_to_b4(unsigned char *b, unsigned long l) -{ +static void u32_to_b4(unsigned char *b, unsigned long l) { b[0] = l & 0xff; b[1] = (l >> 8) & 0xff; b[2] = (l >> 16) & 0xff; b[3] = (l >> 24) & 0xff; } -static void -u32_to_b4r(unsigned char *b, unsigned long l) -{ + +static void u32_to_b4r(unsigned char *b, unsigned long l) { b[3] = l & 0xff; b[2] = (l >> 8) & 0xff; b[1] = (l >> 16) & 0xff; b[0] = (l >> 24) & 0xff; } -static unsigned short -b2_to_u16(unsigned char *b) -{ +static unsigned short b2_to_u16(unsigned char *b) { unsigned short l; l = b[0]; l += (unsigned)b[1] << 8; @@ -233,29 +227,22 @@ b2_to_u16(unsigned char *b) return l; } -static void -u16_to_b2(unsigned char *b, unsigned short l) -{ +static void u16_to_b2(unsigned char *b, unsigned short l) { b[0] = l & 0xff; b[1] = (l >> 8) & 0xff; } -static const char * -jtagmkII_get_rc(unsigned int rc) -{ - static char msg[64]; - +static const char *jtagmkII_get_rc(const PROGRAMMER *pgm, unsigned int rc) { for (size_t i = 0; i < sizeof jtagresults/sizeof*jtagresults; i++) if (jtagresults[i].code == rc) return jtagresults[i].descr; - sprintf(msg, "Unknown JTAG ICE mkII result code 0x%02x", rc); - return msg; + sprintf(PDATA(pgm)->msg, "Unknown JTAG ICE mkII result code 0x%02x", rc); + return PDATA(pgm)->msg; } -static void jtagmkII_print_memory(unsigned char *b, size_t s) -{ +static void jtagmkII_print_memory(unsigned char *b, size_t s) { size_t i; if (s < 2) @@ -418,12 +405,7 @@ int jtagmkII_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) { msg_debug("\n"); pmsg_debug("jtagmkII_send(): sending %lu bytes\n", (unsigned long) len); - if ((buf = malloc(len + 10)) == NULL) - { - pmsg_error("out of memory"); - return -1; - } - + buf = mmt_malloc(len + 10); buf[0] = MESSAGE_START; u16_to_b2(buf + 1, PDATA(pgm)->command_sequence); u32_to_b4(buf + 3, len); @@ -434,11 +416,11 @@ int jtagmkII_send(const PROGRAMMER *pgm, unsigned char *data, size_t len) { if (serial_send(&pgm->fd, buf, len + 10) != 0) { pmsg_error("unable to send command to serial port\n"); - free(buf); + mmt_free(buf); return -1; } - free(buf); + mmt_free(buf); return 0; } @@ -455,7 +437,7 @@ static int jtagmkII_drain(const PROGRAMMER *pgm, int display) { * whether it matches the expected sequence number, including event * notification frames (seqno == 0xffff). * - * Caller must eventually free the buffer. + * Caller must eventually mmt_free() the buffer. */ static int jtagmkII_recv_frame(const PROGRAMMER *pgm, unsigned char **msg, unsigned short * seqno) { @@ -492,13 +474,14 @@ static int jtagmkII_recv_frame(const PROGRAMMER *pgm, unsigned char **msg, for(l = 0; l < msglen; l++) rv += serial_recv(&pgm->fd, &c, 1); } else { - rv += serial_recv(&pgm->fd, buf + 8, msglen); + if(buf) + rv += serial_recv(&pgm->fd, buf + 8, msglen); } if (rv != 0) { timedout: /* timeout in receive */ pmsg_notice2("jtagmkII_recv(): timeout receiving packet\n"); - free(buf); + mmt_free(buf); return -1; } } else { @@ -539,10 +522,8 @@ static int jtagmkII_recv_frame(const PROGRAMMER *pgm, unsigned char **msg, msglen, MAX_MESSAGE); state = sSTART; headeridx = 0; - } else if ((buf = malloc(msglen + 10)) == NULL) { - pmsg_error("out of memory\n"); - ignorpkt++; } else { + buf = mmt_malloc(msglen + 10); memcpy(buf, header, 8); } } else { @@ -557,15 +538,16 @@ static int jtagmkII_recv_frame(const PROGRAMMER *pgm, unsigned char **msg, break; case sCSUM1: case sCSUM2: - buf[l++] = c; - if (state == sCSUM2) { + if(buf) + buf[l++] = c; + if (state == sCSUM2 && buf) { if (crcverify(buf, msglen + 10)) { if (verbose >= 9) pmsg_trace2("jtagmkII_recv(): CRC OK"); state = sDONE; } else { pmsg_error("wrong checksum\n"); - free(buf); + mmt_free(buf); return -4; } } else @@ -573,14 +555,14 @@ static int jtagmkII_recv_frame(const PROGRAMMER *pgm, unsigned char **msg, break; default: pmsg_error("unknown state\n"); - free(buf); + mmt_free(buf); return -5; } tnow = avr_timestamp(); if (tnow - tstart > timeoutval) { pmsg_error("timeout\n"); - free(buf); + mmt_free(buf); return -1; } @@ -608,7 +590,7 @@ int jtagmkII_recv(const PROGRAMMER *pgm, unsigned char **msg) { /* * We move the payload to the beginning of the buffer, to make * the job easier for the caller. We have to return the - * original pointer though, as the caller must free() it. + * original pointer though, as the caller must mmt_free() it. */ memmove(*msg, *msg + 8, rv); @@ -623,7 +605,7 @@ int jtagmkII_recv(const PROGRAMMER *pgm, unsigned char **msg) { pmsg_notice2("jtagmkII_recv(): got wrong sequence number, %u != %u\n", r_seqno, PDATA(pgm)->command_sequence); } - free(*msg); + mmt_free(*msg); } } @@ -695,17 +677,17 @@ int jtagmkII_getsync(const PROGRAMMER *pgm, int mode) { imsg_notice2("Device ID: %s\n", resp + 16); } - free(resp); + mmt_free(resp); break; } - free(resp); + mmt_free(resp); } } if (tries >= MAXTRIES) { if (status <= 0) pmsg_error("timeout/error communicating with programmer (status %d)\n", status); else - pmsg_error("bad response to sign-on command: %s\n", jtagmkII_get_rc(c)); + pmsg_error("bad response to sign-on command: %s\n", jtagmkII_get_rc(pgm, c)); return -1; } @@ -803,9 +785,9 @@ retry: } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; - free(resp); + mmt_free(resp); if (c != RSP_OK) { - pmsg_error("bad response to set parameter command: %s\n", jtagmkII_get_rc(c)); + pmsg_error("bad response to set parameter command: %s\n", jtagmkII_get_rc(pgm, c)); return -1; } @@ -844,9 +826,9 @@ static int jtagmkII_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; - free(resp); + mmt_free(resp); if (c != RSP_OK) { - pmsg_error("bad response to chip erase command: %s\n", jtagmkII_get_rc(c)); + pmsg_error("bad response to chip erase command: %s\n", jtagmkII_get_rc(pgm, c)); return -1; } @@ -861,7 +843,6 @@ static int jtagmkII_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { * There is no chip erase functionality in debugWire mode. */ static int jtagmkII_chip_erase_dw(const PROGRAMMER *pgm_unused, const AVRPART *p_unused) { - pmsg_info("chip erase not supported in debugWire mode\n"); return 0; @@ -930,9 +911,9 @@ static void jtagmkII_set_devdescr(const PROGRAMMER *pgm, const AVRPART *p) { } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; - free(resp); + mmt_free(resp); if (c != RSP_OK) { - pmsg_error("bad response to set device descriptor command: %s\n", jtagmkII_get_rc(c)); + pmsg_error("bad response to set device descriptor command: %s\n", jtagmkII_get_rc(pgm, c)); } } @@ -1000,9 +981,9 @@ static void jtagmkII_set_xmega_params(const PROGRAMMER *pgm, const AVRPART *p) { } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; - free(resp); + mmt_free(resp); if (c != RSP_OK) { - pmsg_error("bad response to set device descriptor command: %s\n", jtagmkII_get_rc(c)); + pmsg_error("bad response to set device descriptor command: %s\n", jtagmkII_get_rc(pgm, c)); } } @@ -1041,9 +1022,9 @@ static int jtagmkII_reset(const PROGRAMMER *pgm, unsigned char flags) { } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; - free(resp); + mmt_free(resp); if (c != RSP_OK) { - pmsg_error("bad response to reset command: %s\n", jtagmkII_get_rc(c)); + pmsg_error("bad response to reset command: %s\n", jtagmkII_get_rc(pgm, c)); return -1; } @@ -1080,9 +1061,9 @@ static int jtagmkII_program_enable(const PROGRAMMER *pgm) { } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; - free(resp); + mmt_free(resp); if (c != RSP_OK) { - pmsg_warning("bad response to enter progmode command: %s\n", jtagmkII_get_rc(c)); + pmsg_warning("bad response to enter progmode command: %s\n", jtagmkII_get_rc(pgm, c)); if (c == RSP_ILLEGAL_JTAG_ID) { if (use_ext_reset == 0) { unsigned char parm[] = { 1}; @@ -1126,9 +1107,9 @@ static int jtagmkII_program_disable(const PROGRAMMER *pgm) { } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; - free(resp); + mmt_free(resp); if (c != RSP_OK) { - pmsg_error("bad response to leave progmode command: %s\n", jtagmkII_get_rc(c)); + pmsg_error("bad response to leave progmode command: %s\n", jtagmkII_get_rc(pgm, c)); return -1; } @@ -1139,44 +1120,44 @@ static int jtagmkII_program_disable(const PROGRAMMER *pgm) { return 0; } -static unsigned char jtagmkII_get_baud(long baud) -{ - static struct { +#define BR(x) { x ## L, PAR_BAUD_ ## x } +static unsigned char jtagmkII_get_baud(long baud) { + struct { long baud; unsigned char val; - } baudtab[] = { - { 2400L, PAR_BAUD_2400 }, - { 4800L, PAR_BAUD_4800 }, - { 9600L, PAR_BAUD_9600 }, - { 19200L, PAR_BAUD_19200 }, - { 38400L, PAR_BAUD_38400 }, - { 57600L, PAR_BAUD_57600 }, - { 115200L, PAR_BAUD_115200 }, - { 14400L, PAR_BAUD_14400 }, - /* Extension to jtagmkII protocol: extra baud rates, standard series. */ - { 153600L, PAR_BAUD_153600 }, - { 230400L, PAR_BAUD_230400 }, - { 460800L, PAR_BAUD_460800 }, - { 921600L, PAR_BAUD_921600 }, - /* Extension to jtagmkII protocol: extra baud rates, binary series. */ - { 128000L, PAR_BAUD_128000 }, - { 256000L, PAR_BAUD_256000 }, - { 512000L, PAR_BAUD_512000 }, - { 1024000L, PAR_BAUD_1024000 }, - /* Extension to jtagmkII protocol: extra baud rates, decimal series. */ - { 150000L, PAR_BAUD_150000 }, - { 200000L, PAR_BAUD_200000 }, - { 250000L, PAR_BAUD_250000 }, - { 300000L, PAR_BAUD_300000 }, - { 400000L, PAR_BAUD_400000 }, - { 500000L, PAR_BAUD_500000 }, - { 600000L, PAR_BAUD_600000 }, - { 666666L, PAR_BAUD_666666 }, - { 1000000L, PAR_BAUD_1000000 }, - { 1500000L, PAR_BAUD_1500000 }, - { 2000000L, PAR_BAUD_2000000 }, - { 3000000L, PAR_BAUD_3000000 }, -}; + } const baudtab[] = { + BR(2400), + BR(4800), + BR(9600), + BR(19200), + BR(38400), + BR(57600), + BR(115200), + BR(14400), + // Extension to jtagmkII protocol: extra baud rates, standard series + BR(153600), + BR(230400), + BR(460800), + BR(921600), + // Extension to jtagmkII protocol: extra baud rates, binary series + BR(128000), + BR(256000), + BR(512000), + BR(1024000), + // Extension to jtagmkII protocol: extra baud rates, decimal series + BR(150000), + BR(200000), + BR(250000), + BR(300000), + BR(400000), + BR(500000), + BR(600000), + BR(666666), + BR(1000000), + BR(1500000), + BR(2000000), + BR(3000000), + }; for (size_t i = 0; i < sizeof baudtab/sizeof*baudtab; i++) if (baud == baudtab[i].baud) @@ -1288,18 +1269,11 @@ static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) { } } - free(PDATA(pgm)->flash_pagecache); - free(PDATA(pgm)->eeprom_pagecache); - if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) { - pmsg_error("out of memory\n"); - free(PDATA(pgm)->flash_pagecache); - return -1; - } - PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; + mmt_free(PDATA(pgm)->flash_pagecache); + mmt_free(PDATA(pgm)->eeprom_pagecache); + PDATA(pgm)->flash_pagecache = mmt_malloc(PDATA(pgm)->flash_pagesize); + PDATA(pgm)->eeprom_pagecache = mmt_malloc(PDATA(pgm)->eeprom_pagesize); + PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long) -1L; if (PDATA(pgm)->fwver >= 0x700 && (p->prog_modes & (PM_PDI | PM_UPDI))) { /* @@ -1334,10 +1308,9 @@ static int jtagmkII_initialize(const PROGRAMMER *pgm, const AVRPART *p) { } static void jtagmkII_disable(const PROGRAMMER *pgm) { - - free(PDATA(pgm)->flash_pagecache); + mmt_free(PDATA(pgm)->flash_pagecache); PDATA(pgm)->flash_pagecache = NULL; - free(PDATA(pgm)->eeprom_pagecache); + mmt_free(PDATA(pgm)->eeprom_pagecache); PDATA(pgm)->eeprom_pagecache = NULL; /* @@ -1410,7 +1383,7 @@ static int jtagmkII_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) if (pgm->flag & PGM_FL_IS_PDI) msg_error(" -xrtsdtr=low,high Force RTS/DTR lines low or high state during programming\n"); msg_error( " -xhelp Show this help menu and exit\n"); - exit(0); + return LIBAVRDUDE_EXIT;; } pmsg_error("invalid extended parameter '%s'\n", extended_param); @@ -1767,9 +1740,9 @@ void jtagmkII_close(PROGRAMMER * pgm) } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; - free(resp); + mmt_free(resp); if (c != RSP_OK) { - pmsg_error("bad response to GO command: %s\n", jtagmkII_get_rc(c)); + pmsg_error("bad response to GO command: %s\n", jtagmkII_get_rc(pgm, c)); } } } @@ -1790,9 +1763,9 @@ void jtagmkII_close(PROGRAMMER * pgm) } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; - free(resp); + mmt_free(resp); if (c != RSP_OK) { - pmsg_error("bad response to sign-off command: %s\n", jtagmkII_get_rc(c)); + pmsg_error("bad response to sign-off command: %s\n", jtagmkII_get_rc(pgm, c)); } if (PDATA(pgm)->rts_mode != RTS_MODE_DEFAULT) { @@ -1885,12 +1858,12 @@ static int jtagmkII_page_erase(const PROGRAMMER *pgm, const AVRPART *p, const AV } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); if (resp[0] != RSP_OK) { - pmsg_error("bad response to xmega erase command: %s\n", jtagmkII_get_rc(resp[0])); - free(resp); + pmsg_error("bad response to xmega erase command: %s\n", jtagmkII_get_rc(pgm, resp[0])); + mmt_free(resp); serial_recv_timeout = otimeout; return -1; } - free(resp); + mmt_free(resp); serial_recv_timeout = otimeout; @@ -1916,11 +1889,7 @@ static int jtagmkII_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const A if (page_size == 0) page_size = 256; else if (page_size > 256) page_size = 256; - if ((cmd = malloc(page_size + 10)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - + cmd = mmt_malloc(page_size + 10); cmd[0] = CMND_WRITE_MEMORY; if (mem_is_flash(m)) { PDATA(pgm)->flash_pageaddr = (unsigned long)-1L; @@ -1936,11 +1905,11 @@ static int jtagmkII_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const A for (; addr < maxaddr; addr++) { status = jtagmkII_write_byte(pgm, p, m, addr, m->buf[addr]); if (status < 0) { - free(cmd); + mmt_free(cmd); return -1; } } - free(cmd); + mmt_free(cmd); return n_bytes; } cmd[1] = p->prog_modes & (PM_PDI | PM_UPDI)? MTYPE_EEPROM_XMEGA: MTYPE_EEPROM_PAGE; @@ -1995,7 +1964,7 @@ static int jtagmkII_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const A goto retry; } pmsg_error("timeout/error communicating with programmer (status %d)\n", status); - free(cmd); + mmt_free(cmd); serial_recv_timeout = otimeout; return -1; } @@ -2005,16 +1974,16 @@ static int jtagmkII_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const A } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); if (resp[0] != RSP_OK) { - pmsg_error("bad response to write memory command: %s\n", jtagmkII_get_rc(resp[0])); - free(resp); - free(cmd); + pmsg_error("bad response to write memory command: %s\n", jtagmkII_get_rc(pgm, resp[0])); + mmt_free(resp); + mmt_free(cmd); serial_recv_timeout = otimeout; return -1; } - free(resp); + mmt_free(resp); } - free(cmd); + mmt_free(cmd); serial_recv_timeout = otimeout; PDATA(pgm)->recently_written = 1; @@ -2098,13 +2067,13 @@ static int jtagmkII_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const AV } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); if (resp[0] != RSP_MEMORY) { - pmsg_error("bad response to read memory command: %s\n", jtagmkII_get_rc(resp[0])); - free(resp); + pmsg_error("bad response to read memory command: %s\n", jtagmkII_get_rc(pgm, resp[0])); + mmt_free(resp); serial_recv_timeout = otimeout; return -1; } memcpy(m->buf + addr, resp + 1, status-1); - free(resp); + mmt_free(resp); } serial_recv_timeout = otimeout; @@ -2285,7 +2254,7 @@ retry: } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); if (resp[0] != RSP_MEMORY) { - pmsg_error("bad response to read memory command: %s\n", jtagmkII_get_rc(resp[0])); + pmsg_error("bad response to read memory command: %s\n", jtagmkII_get_rc(pgm, resp[0])); goto fail; } @@ -2296,12 +2265,12 @@ retry: } else *value = resp[1]; - free(resp); + mmt_free(resp); PDATA(pgm)->recently_written = 0; return 0; fail: - free(resp); + mmt_free(resp); return -1; } @@ -2403,16 +2372,16 @@ retry: } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); if (resp[0] != RSP_OK) { - pmsg_error("bad response to write memory command: %s\n", jtagmkII_get_rc(resp[0])); + pmsg_error("bad response to write memory command: %s\n", jtagmkII_get_rc(pgm, resp[0])); goto fail; } - free(resp); + mmt_free(resp); PDATA(pgm)->recently_written = 1; return 0; fail: - free(resp); + mmt_free(resp); return -1; } @@ -2493,13 +2462,13 @@ int jtagmkII_getparm(const PROGRAMMER *pgm, unsigned char parm, msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; if (c != RSP_PARAMETER) { - pmsg_error("bad response to get parameter command: %s\n", jtagmkII_get_rc(c)); - free(resp); + pmsg_error("bad response to get parameter command: %s\n", jtagmkII_get_rc(pgm, c)); + mmt_free(resp); return -1; } memcpy(value, resp + 1, 4); - free(resp); + mmt_free(resp); return 0; } @@ -2557,9 +2526,9 @@ static int jtagmkII_setparm(const PROGRAMMER *pgm, unsigned char parm, } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; - free(resp); + mmt_free(resp); if (c != RSP_OK) { - pmsg_error("bad response to set parameter %s: %s\n", parstr, jtagmkII_get_rc(c)); + pmsg_error("bad response to set parameter %s: %s\n", parstr, jtagmkII_get_rc(pgm, c)); return -1; } @@ -2998,18 +2967,11 @@ static int jtagmkII_initialize32(const PROGRAMMER *pgm, const AVRPART *p) { return -1; } - free(PDATA(pgm)->flash_pagecache); - free(PDATA(pgm)->eeprom_pagecache); - if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) { - pmsg_error("out of memory\n"); - free(PDATA(pgm)->flash_pagecache); - return -1; - } - PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; + mmt_free(PDATA(pgm)->flash_pagecache); + mmt_free(PDATA(pgm)->eeprom_pagecache); + PDATA(pgm)->flash_pagecache = mmt_malloc(PDATA(pgm)->flash_pagesize); + PDATA(pgm)->eeprom_pagecache = mmt_malloc(PDATA(pgm)->eeprom_pagesize); + PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long) -1L; for(j=0; j<2; ++j) { buf[0] = CMND_GET_IR; @@ -3022,7 +2984,7 @@ static int jtagmkII_initialize32(const PROGRAMMER *pgm, const AVRPART *p) { pmsg_error("timeout/error communicating with programmer (status %d)\n", status); return -1; } - free(resp); + mmt_free(resp); memset(buf, 0, sizeof(buf)); buf[0] = CMND_GET_xxx; @@ -3050,7 +3012,7 @@ static int jtagmkII_initialize32(const PROGRAMMER *pgm, const AVRPART *p) { return -1; } } - free(resp); + mmt_free(resp); } return 0; @@ -3085,7 +3047,7 @@ static int jtagmkII_chip_erase32(const PROGRAMMER *pgm, const AVRPART *p_unused) {lineno = __LINE__; goto eRR;} } x = resp[1]; - free(resp); + mmt_free(resp); if(x == *retP) ++retP; if(*retP == 0x00) break; } @@ -3104,7 +3066,7 @@ static int jtagmkII_chip_erase32(const PROGRAMMER *pgm, const AVRPART *p_unused) jtagmkII_send(pgm, buf, 3); status = jtagmkII_recv(pgm, &resp); if(status < 0 || resp[0] != RSP_OK) {lineno = __LINE__; goto eRR;} - free(resp); + mmt_free(resp); return 0; @@ -3158,7 +3120,7 @@ static unsigned long jtagmkII_read_SABaddr(const PROGRAMMER *pgm, unsigned long } val = b4_to_u32r(&resp[1]); - free(resp); + mmt_free(resp); msg_notice2("\n"); pmsg_notice("jtagmkII_read_SABaddr(): OCD Register %lx -> %4.4lx\n", addr, val); @@ -3252,7 +3214,7 @@ static int jtagmkII_open32(PROGRAMMER *pgm, const char *port) { status = jtagmkII_recv(pgm, &resp); if(status < 0 || resp[0] != RSP_OK) return -1; - free(resp); + mmt_free(resp); buf[1] = 0x03; buf[2] = 0x02; @@ -3260,7 +3222,7 @@ static int jtagmkII_open32(PROGRAMMER *pgm, const char *port) { status = jtagmkII_recv(pgm, &resp); if(status < 0 || resp[0] != RSP_OK) return -1; - free(resp); + mmt_free(resp); buf[1] = 0x03; buf[2] = 0x04; @@ -3268,13 +3230,12 @@ static int jtagmkII_open32(PROGRAMMER *pgm, const char *port) { status = jtagmkII_recv(pgm, &resp); if(status < 0 || resp[0] != RSP_OK) return -1; - free(resp); + mmt_free(resp); return 0; } -static void jtagmkII_close32(PROGRAMMER * pgm) -{ +static void jtagmkII_close32(PROGRAMMER * pgm) { int status, lineno; unsigned char *resp, buf[3], c; unsigned long val=0; @@ -3288,7 +3249,7 @@ static void jtagmkII_close32(PROGRAMMER * pgm) jtagmkII_send(pgm, buf, 3); status = jtagmkII_recv(pgm, &resp); if(status < 0 || resp[0] != RSP_OK) {lineno = __LINE__; goto eRR;} - free(resp); + mmt_free(resp); buf[0] = CMND_SIGN_OFF; pmsg_notice2("jtagmkII_close(): sending sign-off command: "); @@ -3306,9 +3267,9 @@ static void jtagmkII_close32(PROGRAMMER * pgm) } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); c = resp[0]; - free(resp); + mmt_free(resp); if (c != RSP_OK) { - pmsg_error("bad response to sign-off command: %s\n", jtagmkII_get_rc(c)); + pmsg_error("bad response to sign-off command: %s\n", jtagmkII_get_rc(pgm, c)); } ret: @@ -3374,12 +3335,12 @@ static int jtagmkII_paged_load32(const PROGRAMMER *pgm, const AVRPART *p_unused, } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); if (resp[0] != 0x87) { - pmsg_error("bad response to write memory command: %s\n", jtagmkII_get_rc(resp[0])); - free(resp); + pmsg_error("bad response to write memory command: %s\n", jtagmkII_get_rc(pgm, resp[0])); + mmt_free(resp); return -1; } memcpy(m->buf + addr, resp + 1, block_size); - free(resp); + mmt_free(resp); } @@ -3421,11 +3382,7 @@ static int jtagmkII_paged_write32(const PROGRAMMER *pgm, const AVRPART *p_unused // page_size, n_bytes, pages, m->offset, pgm->page_size); // Before any errors can happen - if ((cmd = malloc(pgm->page_size + 10)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - + cmd = mmt_malloc(pgm->page_size + 10); // Init SMC and set clocks if(!(PDATA(pgm)->flags32 & FLAGS32_INIT_SMC)) { status = jtagmkII_smc_init32(pgm); @@ -3475,12 +3432,12 @@ static int jtagmkII_paged_write32(const PROGRAMMER *pgm, const AVRPART *p_unused } else msg_notice2("0x%02x (%d bytes msg)\n", resp[0], status); if (resp[0] != RSP_OK) { - pmsg_error("bad response to write memory command: %s\n", jtagmkII_get_rc(resp[0])); - free(resp); - free(cmd); + pmsg_error("bad response to write memory command: %s\n", jtagmkII_get_rc(pgm, resp[0])); + mmt_free(resp); + mmt_free(cmd); return -1; } - free(resp); + mmt_free(resp); addr += block_size; @@ -3494,12 +3451,12 @@ static int jtagmkII_paged_write32(const PROGRAMMER *pgm, const AVRPART *p_unused status = jtagmkII_reset32(pgm, AVR32_SET4RUNNING); // AVR32_SET4RUNNING | AVR32_RELEASE_JTAG if(status < 0) {lineno = __LINE__; goto eRR;} - free(cmd); + mmt_free(cmd); return addr; eRR: serial_recv_timeout = otimeout; - free(cmd); + mmt_free(cmd); pmsg_error("paged write failed at line %d (status=%x val=%lx)\n", lineno, status, val); return -1; } @@ -3635,9 +3592,9 @@ static int jtagmkII_updi_term_keep_alive(const PROGRAMMER *pgm, const AVRPART *p } c = resp[0]; - free(resp); + mmt_free(resp); if (c != RSP_OK) { - pmsg_error("bad response to `get_sync` command: %s\n", jtagmkII_get_rc(c)); + pmsg_error("bad response to get_sync command: %s\n", jtagmkII_get_rc(pgm, c)); return -1; } diff --git a/src/lexer.l b/src/lexer.l index 159853ee..b11928dd 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -97,13 +97,13 @@ INF [Ii][Nn][Ff]([Ii][Nn][Ii][Tt][Yy])? } ["]([^"\\\n]|\\.|\\\n)*["] { - char *str= cfg_strdup("lexer.l", yytext); + char *str= mmt_strdup(yytext); cfg_unescape(str, str+1); size_t len = strlen(str); if(len) str[len-1] = 0; yylval = new_string(str); - free(str); + mmt_free(str); return TKN_STRING; } diff --git a/src/libavrdude.h b/src/libavrdude.h index f0ec95cc..eb6e7722 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -59,6 +59,7 @@ typedef uint32_t pinmask_t; #define LIBAVRDUDE_NOTSUPPORTED (-2) // operation not supported #define LIBAVRDUDE_SOFTFAIL (-3) // returned, eg, by avr_signature() if caller // might proceed with chip erase +#define LIBAVRDUDE_EXIT (-4) // End all operations in this session /* Message system */ /* This functions is supposed to be supplied by the application */ @@ -1093,6 +1094,7 @@ void serialadapter_not_found(const char *sea_id); extern "C" { #endif +void pgm_init_functions(PROGRAMMER *pgm); PROGRAMMER * pgm_new(void); PROGRAMMER * pgm_dup(const PROGRAMMER *src); void pgm_free(PROGRAMMER *p); @@ -1405,10 +1407,9 @@ extern "C" { #endif void *cfg_malloc(const char *funcname, size_t n); - void *cfg_realloc(const char *funcname, void *p, size_t n); - char *cfg_strdup(const char *funcname, const char *s); +void mmt_f_free(void *ptr); int init_config(void); @@ -1531,6 +1532,7 @@ void str_freedata(Str2data *sd); unsigned long long int str_int(const char *str, int type, const char **errpp); int str_membuf(const char *str, int type, unsigned char *buf, int size, const char **errpp); char *str_nexttok(char *buf, const char *delim, char **next); +char *str_frq(double f, int n); int str_levenshtein(const char *str1, const char *str2, int swap, int subst, int add, int del); size_t str_weighted_damerau_levenshtein(const char *str1, const char *str2); diff --git a/src/linuxgpio.c b/src/linuxgpio.c index 89ecdf0c..9095445b 100644 --- a/src/linuxgpio.c +++ b/src/linuxgpio.c @@ -50,6 +50,16 @@ * Licensed under the GPL-2 or later */ +#define N_GPIO (PIN_MAX + 1) + +struct pdata { + int sysfs_fds[N_GPIO]; // Open FDs of /sys/class/gpio/gpioXX/value for needed pins +}; + +// Use private programmer data as if they were a global structure my +#define my (*(struct pdata *)(pgm->cookie)) + + /* * Sysfs GPIO user space helpers * The following functions are acting on an "unsigned gpio" argument, which corresponds to the @@ -140,19 +150,11 @@ static int linuxgpio_sysfs_dir_in(unsigned int gpio) * End of Sysfs GPIO user space helpers */ -#define N_GPIO (PIN_MAX + 1) - /* Delay between checks for successful GPIO export (100ms) */ #define GPIO_SYSFS_OPEN_DELAY 100000 /* Number of retries to check for successful GPIO exports */ #define GPIO_SYSFS_OPEN_RETRIES 10 -/* -* an array which holds open FDs to /sys/class/gpio/gpioXX/value for all needed pins -*/ -static int linuxgpio_sysfs_fds[N_GPIO] ; - - static int linuxgpio_sysfs_setpin(const PROGRAMMER *pgm, int pinfunc, int value) { if(pinfunc < 0 || pinfunc >= N_PINS) return -1; @@ -162,10 +164,10 @@ static int linuxgpio_sysfs_setpin(const PROGRAMMER *pgm, int pinfunc, int value) value = !value; pin &= PIN_MASK; - if (pin > PIN_MAX || linuxgpio_sysfs_fds[pin] < 0) + if (pin > PIN_MAX || my.sysfs_fds[pin] < 0) return -1; - if (write(linuxgpio_sysfs_fds[pin], value? "1": "0", 1) != 1) + if (write(my.sysfs_fds[pin], value? "1": "0", 1) != 1) return -1; if (pgm->ispdelay > 1) @@ -182,14 +184,14 @@ static int linuxgpio_sysfs_getpin(const PROGRAMMER *pgm, int pinfunc) { int invert = !!(pin & PIN_INVERSE); pin &= PIN_MASK; - if(pin > PIN_MAX || linuxgpio_sysfs_fds[pin] < 0) + if(pin > PIN_MAX || my.sysfs_fds[pin] < 0) return -1; - if(lseek(linuxgpio_sysfs_fds[pin], 0, SEEK_SET) < 0) + if(lseek(my.sysfs_fds[pin], 0, SEEK_SET) < 0) return -1; char c; - if(read(linuxgpio_sysfs_fds[pin], &c, 1) != 1) + if(read(my.sysfs_fds[pin], &c, 1) != 1) return -1; return c=='0'? 0+invert: c=='1'? 1-invert: -1; @@ -201,7 +203,7 @@ static int linuxgpio_sysfs_highpulsepin(const PROGRAMMER *pgm, int pinfunc) { unsigned int pin = pgm->pinno[pinfunc] & PIN_MASK; - if (pin > PIN_MAX || linuxgpio_sysfs_fds[pin] < 0 ) + if (pin > PIN_MAX || my.sysfs_fds[pin] < 0 ) return -1; linuxgpio_sysfs_setpin(pgm, pinfunc, 1); @@ -218,19 +220,15 @@ static void linuxgpio_sysfs_display(const PROGRAMMER *pgm, const char *p) { } static void linuxgpio_enable(PROGRAMMER *pgm, const AVRPART *p) { - /* nothing */ } static void linuxgpio_disable(const PROGRAMMER *pgm) { - /* nothing */ } static void linuxgpio_powerup(const PROGRAMMER *pgm) { - /* nothing */ } static void linuxgpio_powerdown(const PROGRAMMER *pgm) { - /* nothing */ } static int linuxgpio_sysfs_open(PROGRAMMER *pgm, const char *port) { @@ -243,7 +241,7 @@ static int linuxgpio_sysfs_open(PROGRAMMER *pgm, const char *port) { for (i=0; ipinno[i] & PIN_MASK) <= PIN_MAX) { @@ -297,8 +295,8 @@ static int linuxgpio_sysfs_open(PROGRAMMER *pgm, const char *port) { return r; } - if ((linuxgpio_sysfs_fds[pin]=linuxgpio_sysfs_openfd(pin)) < 0) - return linuxgpio_sysfs_fds[pin]; + if ((my.sysfs_fds[pin]=linuxgpio_sysfs_openfd(pin)) < 0) + return my.sysfs_fds[pin]; } } @@ -314,22 +312,31 @@ static void linuxgpio_sysfs_close(PROGRAMMER *pgm) //first configure all pins as input, except RESET //this should avoid possible conflicts when AVR firmware starts for (i=0; i= 0 && i != reset_pin) { - close(linuxgpio_sysfs_fds[i]); - linuxgpio_sysfs_fds[i] = -1; + if (my.sysfs_fds[i] >= 0 && i != reset_pin) { + close(my.sysfs_fds[i]); + my.sysfs_fds[i] = -1; linuxgpio_sysfs_dir_in(i); linuxgpio_sysfs_unexport(i); } } //configure RESET as input, if there's external pull up it will go high - if(reset_pin <= PIN_MAX && linuxgpio_sysfs_fds[reset_pin] >= 0) { - close(linuxgpio_sysfs_fds[reset_pin]); - linuxgpio_sysfs_fds[reset_pin] = -1; + if(reset_pin <= PIN_MAX && my.sysfs_fds[reset_pin] >= 0) { + close(my.sysfs_fds[reset_pin]); + my.sysfs_fds[reset_pin] = -1; linuxgpio_sysfs_dir_in(reset_pin); linuxgpio_sysfs_unexport(reset_pin); } } +void linuxgpio_setup(PROGRAMMER *pgm) { + pgm->cookie = mmt_malloc(sizeof(struct pdata)); +} + +void linuxgpio_teardown(PROGRAMMER *pgm) { + mmt_free(pgm->cookie); + pgm->cookie = NULL; +} + // // libgpiod backend for the linuxgpio programmer. @@ -337,6 +344,176 @@ static void linuxgpio_sysfs_close(PROGRAMMER *pgm) #ifdef HAVE_LIBGPIOD +#if !HAVE_LIBGPIOD_V1_6 && !HAVE_LIBGPIOD_V2 + +int gpiod_line_set_direction_input(struct gpiod_line **gpio_line) { + struct gpiod_chip *chip = gpiod_line_get_chip(*gpio_line); + unsigned int gpio_num = gpiod_line_offset(*gpio_line); + + // release to pin first... + gpiod_line_release(*gpio_line); + + // so that we can re-acquire it as input + *gpio_line = gpiod_chip_get_line(chip, gpio_num); + return gpiod_line_request_input(*gpio_line, "avrdude"); +} + +#endif + +#if HAVE_LIBGPIOD_V2 + +struct gpiod_line { + struct gpiod_chip *chip; + struct gpiod_line_request *line_request; + unsigned int gpio_num; +}; + +struct gpiod_line *gpiod_line_get(const char *port, int gpio_num) { + struct gpiod_line *rv; + char abs_port[32]; + + if (snprintf(abs_port, sizeof(abs_port), "/dev/%s", port) >= (int)sizeof(abs_port)) + return NULL; + + rv = mmt_malloc(sizeof(struct gpiod_line)); + rv->gpio_num = gpio_num; + + rv->chip = gpiod_chip_open(abs_port); + if (!rv->chip) { + mmt_free(rv); + return NULL; + } + + return rv; +} + +int gpiod_line_request_input(struct gpiod_line *gpio_line, const char *consumer) { + struct gpiod_line_settings *line_settings = NULL; + struct gpiod_line_config *line_config = NULL; + struct gpiod_request_config *req_cfg = NULL; + int retval = -1; + + line_settings = gpiod_line_settings_new(); + line_config = gpiod_line_config_new(); + req_cfg = gpiod_request_config_new(); + + if (!line_settings || !line_config || !req_cfg) + goto err_out; + + retval = gpiod_line_settings_set_direction(line_settings, GPIOD_LINE_DIRECTION_INPUT); + if (retval != 0) + goto err_out; + + retval = gpiod_line_config_add_line_settings(line_config, &gpio_line->gpio_num, 1, line_settings); + if (retval != 0) + goto err_out; + + gpiod_request_config_set_consumer(req_cfg, consumer); + + gpio_line->line_request = gpiod_chip_request_lines(gpio_line->chip, req_cfg, line_config); + if (!gpio_line->line_request) + goto err_out; + + retval = 0; + +err_out: + gpiod_line_settings_free(line_settings); + gpiod_line_config_free(line_config); + gpiod_request_config_free(req_cfg); + return retval; +} + +int gpiod_line_request_output(struct gpiod_line *gpio_line, const char *consumer, int value) { + struct gpiod_line_settings *line_settings = NULL; + struct gpiod_line_config *line_config = NULL; + struct gpiod_request_config *req_cfg = NULL; + int retval = -1; + + line_settings = gpiod_line_settings_new(); + line_config = gpiod_line_config_new(); + req_cfg = gpiod_request_config_new(); + + if (!line_settings || !line_config || !req_cfg) + goto err_out; + + retval = gpiod_line_settings_set_direction(line_settings, GPIOD_LINE_DIRECTION_OUTPUT); + if (retval != 0) + goto err_out; + + retval = gpiod_line_settings_set_output_value(line_settings, value ? GPIOD_LINE_VALUE_ACTIVE : GPIOD_LINE_VALUE_INACTIVE); + if (retval != 0) + goto err_out; + + retval = gpiod_line_config_add_line_settings(line_config, &gpio_line->gpio_num, 1, line_settings); + if (retval != 0) + goto err_out; + + gpiod_request_config_set_consumer(req_cfg, consumer); + + gpio_line->line_request = gpiod_chip_request_lines(gpio_line->chip, req_cfg, line_config); + if (!gpio_line->line_request) + goto err_out; + + retval = 0; + +err_out: + gpiod_line_settings_free(line_settings); + gpiod_line_config_free(line_config); + gpiod_request_config_free(req_cfg); + return retval; +} + +int gpiod_line_set_direction_input(struct gpiod_line *gpio_line) { + struct gpiod_line_settings *line_settings = NULL; + struct gpiod_line_config *line_config = NULL; + int retval = -1; + + line_settings = gpiod_line_settings_new(); + line_config = gpiod_line_config_new(); + + if (!line_settings || !line_config) + goto err_out; + + retval = gpiod_line_settings_set_direction(line_settings, GPIOD_LINE_DIRECTION_INPUT); + if (retval != 0) + goto err_out; + + retval = gpiod_line_config_add_line_settings(line_config, &gpio_line->gpio_num, 1, line_settings); + if (retval != 0) + goto err_out; + + retval = gpiod_line_request_reconfigure_lines(gpio_line->line_request, line_config); + +err_out: + gpiod_line_settings_free(line_settings); + gpiod_line_config_free(line_config); + return retval; +} + +void gpiod_line_release(struct gpiod_line *gpio_line) { + gpiod_line_request_release(gpio_line->line_request); + gpiod_chip_close(gpio_line->chip); + mmt_free(gpio_line); +} + +static inline int gpiod_line_set_value(struct gpiod_line *gpio_line, int value) { + return gpiod_line_request_set_value(gpio_line->line_request, gpio_line->gpio_num, value); +} + +static inline int gpiod_line_get_value(struct gpiod_line *gpio_line) { + return gpiod_line_request_get_value(gpio_line->line_request, gpio_line->gpio_num); +} + +#endif + +static inline unsigned int linuxgpio_get_gpio_num(struct gpiod_line *gpio_line) { +#if HAVE_LIBGPIOD_V2 + return gpio_line->gpio_num; +#else + return gpiod_line_offset(gpio_line); +#endif +} + struct gpiod_line * linuxgpio_libgpiod_lines[N_PINS]; // Try to tell if libgpiod is going to work. @@ -412,9 +589,14 @@ static void linuxgpio_libgpiod_close(PROGRAMMER *pgm) { // This should avoid possible conflicts when AVR firmware starts. for (i = 0; i < N_PINS; ++i) { if (linuxgpio_libgpiod_lines[i] != NULL && i != PIN_AVR_RESET) { +#if HAVE_LIBGPIOD_V1_6 || HAVE_LIBGPIOD_V2 int r = gpiod_line_set_direction_input(linuxgpio_libgpiod_lines[i]); +#else + int r = gpiod_line_set_direction_input(&linuxgpio_libgpiod_lines[i]); +#endif if (r != 0) { - msg_error("failed to set pin %s to input: %s\n", gpiod_line_name(linuxgpio_libgpiod_lines[i]), strerror(errno)); + msg_error("failed to set pin %u to input: %s\n", + linuxgpio_get_gpio_num(linuxgpio_libgpiod_lines[i]), strerror(errno)); } gpiod_line_release(linuxgpio_libgpiod_lines[i]); linuxgpio_libgpiod_lines[i] = NULL; @@ -423,9 +605,14 @@ static void linuxgpio_libgpiod_close(PROGRAMMER *pgm) { // Configure RESET as input. if (linuxgpio_libgpiod_lines[PIN_AVR_RESET] != NULL) { +#if HAVE_LIBGPIOD_V1_6 || HAVE_LIBGPIOD_V2 int r = gpiod_line_set_direction_input(linuxgpio_libgpiod_lines[PIN_AVR_RESET]); +#else + int r = gpiod_line_set_direction_input(&linuxgpio_libgpiod_lines[PIN_AVR_RESET]); +#endif if (r != 0) { - msg_error("failed to set pin %s to input: %s\n", gpiod_line_name(linuxgpio_libgpiod_lines[PIN_AVR_RESET]), strerror(errno)); + msg_error("failed to set pin %u to input: %s\n", + linuxgpio_get_gpio_num(linuxgpio_libgpiod_lines[PIN_AVR_RESET]), strerror(errno)); } gpiod_line_release(linuxgpio_libgpiod_lines[PIN_AVR_RESET]); linuxgpio_libgpiod_lines[PIN_AVR_RESET] = NULL; @@ -450,7 +637,8 @@ static int linuxgpio_libgpiod_setpin(const PROGRAMMER *pgm, int pinfunc, int val int r = gpiod_line_set_value(linuxgpio_libgpiod_lines[pinfunc], value); if (r != 0) { - msg_error("failed to set value of %s (%s) to %d: %s\n", avr_pin_name(pinfunc), gpiod_line_name(linuxgpio_libgpiod_lines[pinfunc]), value, strerror(errno)); + msg_error("failed to set value of %s (%u) to %d: %s\n", avr_pin_name(pinfunc), + linuxgpio_get_gpio_num(linuxgpio_libgpiod_lines[pinfunc]), value, strerror(errno)); return -1; } @@ -476,7 +664,7 @@ static int linuxgpio_libgpiod_getpin(const PROGRAMMER *pgm, int pinfunc) { int r = gpiod_line_get_value(linuxgpio_libgpiod_lines[pinfunc]); if (r == -1) { - msg_error("failed to read %s: %s\n", gpiod_line_name(linuxgpio_libgpiod_lines[pinfunc]), strerror(errno)); + msg_error("failed to read %u: %s\n", linuxgpio_get_gpio_num(linuxgpio_libgpiod_lines[pinfunc]), strerror(errno)); return -1; } @@ -540,6 +728,8 @@ void linuxgpio_initpgm(PROGRAMMER *pgm) { pgm->highpulsepin = linuxgpio_sysfs_highpulsepin; pgm->read_byte = avr_read_byte_default; pgm->write_byte = avr_write_byte_default; + pgm->setup = linuxgpio_setup; + pgm->teardown = linuxgpio_teardown; #ifdef HAVE_LIBGPIOD if (libgpiod_is_working()) { diff --git a/src/linuxspi.c b/src/linuxspi.c index 270ed0f8..169c1a22 100644 --- a/src/linuxspi.c +++ b/src/linuxspi.c @@ -62,16 +62,14 @@ #define LINUXSPI "linuxspi" -/* - * Private data for this programmer. - */ +// Private data for this programmer struct pdata { int disable_no_cs; + int fd_spidev, fd_gpiochip, fd_linehandle; }; -#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) - -static int fd_spidev, fd_gpiochip, fd_linehandle; +// Use private programmer data as if they were a global structure my +#define my (*(struct pdata *)(pgm->cookie)) /** * @brief Sends/receives a message in full duplex mode @@ -91,7 +89,8 @@ static int linuxspi_spi_duplex(const PROGRAMMER *pgm, const unsigned char *tx, u }; errno = 0; - ret = ioctl(fd_spidev, SPI_IOC_MESSAGE(1), &tr); + + ret = ioctl(my.fd_spidev, SPI_IOC_MESSAGE(1), &tr); if (ret != len) { int ioctl_errno = errno; msg_error("\n"); @@ -105,11 +104,12 @@ static int linuxspi_spi_duplex(const PROGRAMMER *pgm, const unsigned char *tx, u } static void linuxspi_setup(PROGRAMMER *pgm) { - pgm->cookie = cfg_malloc("linuxspi_setup()", sizeof(struct pdata)); + pgm->cookie = mmt_malloc(sizeof(struct pdata)); } static void linuxspi_teardown(PROGRAMMER* pgm) { - free(pgm->cookie); + mmt_free(pgm->cookie); + pgm->cookie = NULL; } static int linuxspi_reset_mcu(const PROGRAMMER *pgm, bool active) { @@ -118,10 +118,10 @@ static int linuxspi_reset_mcu(const PROGRAMMER *pgm, bool active) { /* * Set the reset state and keep it. The pin will be released and set back to - * its initial value, once the fd_gpiochip is closed. + * its initial value, once the my.fd_gpiochip is closed. */ data.values[0] = active ^ !(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE); - ret = ioctl(fd_linehandle, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data); + ret = ioctl(my.fd_linehandle, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data); #ifdef GPIO_V2_LINE_SET_VALUES_IOCTL if (ret == -1) { struct gpio_v2_line_values val; @@ -129,7 +129,7 @@ static int linuxspi_reset_mcu(const PROGRAMMER *pgm, bool active) { val.mask = 1; val.bits = active ^ !(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE); - ret = ioctl(fd_linehandle, GPIO_V2_LINE_SET_VALUES_IOCTL, &val); + ret = ioctl(my.fd_linehandle, GPIO_V2_LINE_SET_VALUES_IOCTL, &val); } #endif if (ret == -1) { @@ -147,7 +147,7 @@ static int linuxspi_open(PROGRAMMER *pgm, const char *pt) { "please use the format /dev/spidev:/dev/gpiochip[:resetno]\n"; char port_default[] = "/dev/spidev0.0:/dev/gpiochip0"; char *spidev, *gpiochip, *reset_pin; - char *port = cfg_strdup("linuxspi_open()", pt); + char *port = mmt_strdup(pt); struct gpiohandle_request req; int ret; @@ -179,26 +179,26 @@ static int linuxspi_open(PROGRAMMER *pgm, const char *pt) { } pgm->port = port; - fd_spidev = open(pgm->port, O_RDWR); - if (fd_spidev < 0) { + my.fd_spidev = open(pgm->port, O_RDWR); + if (my.fd_spidev < 0) { pmsg_ext_error("unable to open the spidev device %s: %s\n", pgm->port, strerror(errno)); return -1; } uint32_t mode = SPI_MODE_0; - if (!PDATA(pgm)->disable_no_cs) + if (!my.disable_no_cs) mode |= SPI_NO_CS; - ret = ioctl(fd_spidev, SPI_IOC_WR_MODE32, &mode); + ret = ioctl(my.fd_spidev, SPI_IOC_WR_MODE32, &mode); if (ret == -1) { int ioctl_errno = errno; pmsg_ext_error("unable to set SPI mode %02X on %s: %s\n", mode, spidev, strerror(errno)); - if(ioctl_errno == EINVAL && !PDATA(pgm)->disable_no_cs) + if(ioctl_errno == EINVAL && !my.disable_no_cs) pmsg_error("try -x disable_no_cs\n"); goto close_spidev; } - fd_gpiochip = open(gpiochip, 0); - if (fd_gpiochip < 0) { + my.fd_gpiochip = open(gpiochip, 0); + if (my.fd_gpiochip < 0) { pmsg_ext_error("unable to open the gpiochip %s: %s\n", gpiochip, strerror(errno)); ret = -1; goto close_spidev; @@ -210,9 +210,9 @@ static int linuxspi_open(PROGRAMMER *pgm, const char *pt) { req.default_values[0] = !!(pgm->pinno[PIN_AVR_RESET] & PIN_INVERSE); req.flags = GPIOHANDLE_REQUEST_OUTPUT; - ret = ioctl(fd_gpiochip, GPIO_GET_LINEHANDLE_IOCTL, &req); + ret = ioctl(my.fd_gpiochip, GPIO_GET_LINEHANDLE_IOCTL, &req); if (ret != -1) - fd_linehandle = req.fd; + my.fd_linehandle = req.fd; #ifdef GPIO_V2_GET_LINE_IOCTL if (ret == -1) { struct gpio_v2_line_request reqv2; @@ -227,9 +227,9 @@ static int linuxspi_open(PROGRAMMER *pgm, const char *pt) { reqv2.config.attrs[0].mask = 1; reqv2.num_lines = 1; - ret = ioctl(fd_gpiochip, GPIO_V2_GET_LINE_IOCTL, &reqv2); + ret = ioctl(my.fd_gpiochip, GPIO_V2_GET_LINE_IOCTL, &reqv2); if (ret != -1) - fd_linehandle = reqv2.fd; + my.fd_linehandle = reqv2.fd; } #endif if (ret == -1) { @@ -254,11 +254,11 @@ static int linuxspi_open(PROGRAMMER *pgm, const char *pt) { return 0; close_out: - close(fd_linehandle); + close(my.fd_linehandle); close_gpiochip: - close(fd_gpiochip); + close(my.fd_gpiochip); close_spidev: - close(fd_spidev); + close(my.fd_spidev); return ret; } @@ -276,9 +276,9 @@ static void linuxspi_close(PROGRAMMER *pgm) { break; } - close(fd_linehandle); - close(fd_spidev); - close(fd_gpiochip); + close(my.fd_linehandle); + close(my.fd_spidev); + close(my.fd_gpiochip); } static void linuxspi_disable(const PROGRAMMER* pgm) { @@ -380,7 +380,7 @@ static int linuxspi_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { } static int linuxspi_parseexitspecs(PROGRAMMER *pgm, const char *sp) { - char *cp, *s, *str = cfg_strdup("linuxspi_parseextitspecs()", sp); + char *cp, *s, *str = mmt_strdup(sp); s = str; while ((cp = strtok(s, ","))) { @@ -393,11 +393,11 @@ static int linuxspi_parseexitspecs(PROGRAMMER *pgm, const char *sp) { pgm->exit_reset = EXIT_RESET_DISABLED; continue; } - free(str); + mmt_free(str); return -1; } - free(str); + mmt_free(str); return 0; } @@ -410,14 +410,14 @@ static int linuxspi_parseextparams(const PROGRAMMER *pgm, const LISTID extparms) extended_param = ldata(ln); if (str_eq(extended_param, "disable_no_cs")) { - PDATA(pgm)->disable_no_cs = 1; + my.disable_no_cs = 1; continue; } if (str_eq(extended_param, "help")) { msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -xdisable_no_cs Do not use the SPI_NO_CS bit for the SPI driver\n"); msg_error(" -xhelp Show this help menu and exit\n"); - exit(0); + return LIBAVRDUDE_EXIT; } pmsg_error("invalid extended parameter '%s'\n", extended_param); diff --git a/src/lists.c b/src/lists.c index 6d3595c2..21f3e0ef 100644 --- a/src/lists.c +++ b/src/lists.c @@ -40,19 +40,15 @@ #include #include +#include "avrdude.h" #include "libavrdude.h" #define MAGIC 0xb05b05b0 #define CHECK_MAGIC 0 /* set to 1 to enable memory overwrite detection */ -#ifdef BOS -#define MALLOC(size,x) kmalloc(size,x) -#define FREE kfree -#else -#define MALLOC(size,x) malloc(size) -#define FREE free -#endif +#define MALLOC(size,x) mmt_malloc(size) +#define FREE mmt_free /*------------------------------------------------------------ @@ -130,8 +126,7 @@ static int insert_ln ( LIST * l, LISTNODE * ln, void * data_ptr ); #if CHECK_MAGIC -static int cknpmagic ( LIST * l ) -{ +static int cknpmagic ( LIST * l ) { NODEPOOL * np; int i; @@ -156,8 +151,7 @@ static int cknpmagic ( LIST * l ) -static int cklnmagic ( LIST * l ) -{ +static int cklnmagic ( LIST * l ) { LISTNODE * ln; int i; @@ -181,8 +175,7 @@ static int cklnmagic ( LIST * l ) } -static int cklmagic ( LIST * l ) -{ +static int cklmagic ( LIST * l ) { CKMAGIC(l); CKNPMAGIC(l); CKLNMAGIC(l); @@ -200,10 +193,7 @@ static int cklmagic ( LIST * l ) | bytes reserved. The first available list node resides at | offset sizeof(NODEPOOL). ------------------------------------------------------------*/ -static -NODEPOOL * -new_nodepool ( LIST * l ) -{ +static NODEPOOL *new_nodepool ( LIST * l ) { NODEPOOL * np; LISTNODE * ln; int i; @@ -286,10 +276,7 @@ new_nodepool ( LIST * l ) | list nodes, another pool of list nodes is allocated. If | that fails, NULL is returned. ------------------------------------------------------------*/ -static -LISTNODE * -get_listnode ( LIST * l ) -{ +static LISTNODE * get_listnode ( LIST * l ) { LISTNODE * ln; NODEPOOL * np; @@ -368,10 +355,7 @@ get_listnode ( LIST * l ) | call to 'get_listnode', with return the most recently | freed one. ------------------------------------------------------------*/ -static -int -free_listnode ( LIST * l, LISTNODE * ln ) -{ +static int free_listnode ( LIST * l, LISTNODE * ln ) { CKLMAGIC(l); /*-------------------------------------------------- @@ -397,13 +381,13 @@ free_listnode ( LIST * l, LISTNODE * ln ) If liststruct is not NULL, it is used to provide the memory space for the list structure instance, otherwise, the necessary memory is - malloc'd. + mmt_malloc'd. If elements is zero, the default poolsize is used, otherwise, - poolsizes of 'elements' elements are malloc'd to obtain the memory + poolsizes of 'elements' elements are mmt_malloc'd to obtain the memory for list nodes. Minimum element count is 5. - The first node pool is not preallocated; instead it is malloc'd at + The first node pool is not preallocated; instead it is mmt_malloc'd at the time of the first use. ----------------------------------------------------------------------*/ LISTID @@ -873,10 +857,7 @@ lget_ln ( LISTID lid, unsigned int n ) | by list manipulation routines within this module, in which ln is | known to point to a valid list node. ----------------------------------------------------------------------*/ -static -int -insert_ln ( LIST * l, LISTNODE * ln, void * data_ptr ) -{ +static int insert_ln ( LIST * l, LISTNODE * ln, void * data_ptr ) { LISTNODE * lnptr; CKLMAGIC(l); @@ -1037,10 +1018,7 @@ lins_ln ( LISTID lid, LNODEID lnid, void * data_ptr ) | routines within this module, in which ln is known to point to a | valid list node. ----------------------------------------------------------------------*/ -static -void * -remove_ln ( LIST * l, LISTNODE * ln ) -{ +static void * remove_ln ( LIST * l, LISTNODE * ln ) { void * r; CKLMAGIC(l); diff --git a/src/main.c b/src/main.c index e6e53734..49dae75f 100644 --- a/src/main.c +++ b/src/main.c @@ -158,13 +158,13 @@ int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, int return 0; rc++; // Accommodate terminating nul - char *p = cfg_malloc(__func__, rc); + char *p = mmt_malloc(rc); va_start(ap, format); rc = vsnprintf(p, rc, format, ap); va_end(ap); if(rc < 0) { - free(p); + mmt_free(p); return 0; } @@ -172,7 +172,7 @@ int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, int fprintf(fp, "%s", p); // Finally: print! bols[bi].bol = p[strlen(p)-1] == '\n'; } - free(p); + mmt_free(p); } if(msgmode & MSG2_FLUSH) @@ -257,7 +257,7 @@ static void usage(void) "\navrdude version %s, https://github.com/avrdudes/avrdude\n", progname, strlen(cfg) < 24? "config file ": "", cfg, AVRDUDE_FULL_VERSION); - free(cfg); + mmt_free(cfg); } @@ -321,7 +321,7 @@ static void list_programmers(FILE *f, const char *prefix, LISTID programmers, in // List programmer if pm or prog_modes uninitialised or if they are compatible otherwise if(!pm || !pgm->prog_modes || (pm & pgm->prog_modes)) { const char *id = ldata(ln2); - char *desc = cfg_strdup("list_programmers()", pgm->desc); + char *desc = mmt_strdup(pgm->desc); const char *modes = avr_prog_modes(pm & pgm->prog_modes); if(pm != ~0) @@ -337,7 +337,7 @@ static void list_programmers(FILE *f, const char *prefix, LISTID programmers, in fprintf(f, " via %s", modes); fprintf(f, "\n"); - free(desc); + mmt_free(desc); } } } @@ -409,7 +409,7 @@ static void exithook(void) static void cleanup_main(void) { if (updates) { - ldestroy_cb(updates, (void(*)(void*))free_update); + ldestroy_cb(updates, (void(*)(void*)) free_update); updates = NULL; } if (extended_params) { @@ -469,7 +469,7 @@ static int suggest_programmers(const char *programmer, LISTID programmers) { nid++; } - pgm_distance *d = cfg_malloc(__func__, nid*sizeof*d); + pgm_distance *d = mmt_malloc(nid*sizeof*d); // Fill d[] struct int idx = 0; @@ -508,7 +508,7 @@ static int suggest_programmers(const char *programmer, LISTID programmers) { if(d[i].common_modes) msg_info(" %-*s = %s\n", pgmid_maxlen, d[i].pgmid, d[i].desc); } - free(d); + mmt_free(d); return n; } @@ -672,7 +672,7 @@ int main(int argc, char * argv []) // Remove trailing .exe if(str_ends(progname, ".exe")) { - progname = cfg_strdup("main()", progname); // Don't write to argv[0] + progname = mmt_strdup(progname); // Don't write to argv[0] progname[strlen(progname)-4] = 0; } @@ -861,7 +861,7 @@ int main(int argc, char * argv []) break; case 'P': - port = cfg_strdup(__func__, optarg); + port = mmt_strdup(optarg); break; case 'q' : /* Quell progress output */ @@ -1062,7 +1062,7 @@ int main(int argc, char * argv []) pmsg_error("unable to process system wide configuration file %s\n", real_sys_config); exit(1); } - free(real_sys_config); + mmt_free(real_sys_config); } if (usr_config[0] != 0 && !no_avrduderc) { @@ -1243,7 +1243,10 @@ int main(int argc, char * argv []) pmsg_error("programmer does not support extended parameter -x %s, option ignored\n", extended_param); } } else { - if (pgm->parseextparams(pgm, extended_params) < 0) { + int rc = pgm->parseextparams(pgm, extended_params); + if(rc == LIBAVRDUDE_EXIT) + exit(0); + if(rc < 0) { pmsg_error("unable to parse extended parameter list\n"); exit(1); } @@ -1254,31 +1257,31 @@ int main(int argc, char * argv []) switch (pgm->conntype) { case CONNTYPE_PARALLEL: - port = cfg_strdup(__func__, default_parallel); + port = mmt_strdup(default_parallel); break; case CONNTYPE_SERIAL: - port = cfg_strdup(__func__, default_serial); + port = mmt_strdup(default_serial); break; case CONNTYPE_USB: - port = cfg_strdup(__func__, DEFAULT_USB); + port = mmt_strdup(DEFAULT_USB); break; case CONNTYPE_SPI: - port = cfg_strdup(__func__, #ifdef HAVE_LINUXSPI - *default_spi? default_spi: + port = mmt_strdup(*default_spi? default_spi: "unknown"); +#else + port = mmt_strdup("unknown"); #endif - "unknown"); break; case CONNTYPE_LINUXGPIO: - port = cfg_strdup(__func__, default_linuxgpio); + port = mmt_strdup(default_linuxgpio); break; default: - port = cfg_strdup(__func__, "unknown"); + port = mmt_strdup("unknown"); break; } @@ -1303,15 +1306,15 @@ int main(int argc, char * argv []) bool print_ports = true; SERIALADAPTER *ser = NULL; if (pgm->conntype == CONNTYPE_SERIAL) { - char *portdup = cfg_strdup(__func__, port); + char *portdup = mmt_strdup(port); char *port_tok[4], *tok = portdup; for(int t = 0, maxt = str_starts(portdup, DEFAULT_USB ":")? 4: 2; t < 4; t++) { char *save = tok && t < maxt? tok: ""; if(t < maxt-1 && tok && (tok = strchr(tok, ':'))) *tok++ = 0; - port_tok[t] = cfg_strdup(__func__, save); + port_tok[t] = mmt_strdup(save); } - free(portdup); + mmt_free(portdup); // Use libserialport to find the actual serial port ser = locate_programmer(programmers, port_tok[0]); @@ -1345,7 +1348,7 @@ int main(int argc, char * argv []) } } for (int i = 0; i < 4; i++) - free(port_tok[i]); + mmt_free(port_tok[i]); if(touch_1200bps && touch_serialport(&port, 1200, touch_1200bps) < 0) goto skipopen; } @@ -1390,6 +1393,11 @@ int main(int argc, char * argv []) rc = pgm->open(pgm, port); if (rc < 0) { + if(rc == LIBAVRDUDE_EXIT) { + exitrc = 0; + goto main_exit; + } + pmsg_error("unable to open port %s for programmer %s\n", port, pgmid); skipopen: if (print_ports && pgm->conntype == CONNTYPE_SERIAL) { @@ -1460,7 +1468,7 @@ skipopen: pmsg_notice2("defaulting memstr in -U %c:%s option to \"%s\"\n", (upd->op == DEVICE_READ)? 'r': (upd->op == DEVICE_WRITE)? 'w': 'v', upd->filename, mtype); - upd->memstr = cfg_strdup("main()", mtype); + upd->memstr = mmt_strdup(mtype); } rc = update_dryrun(p, upd); if (rc && rc != LIBAVRDUDE_SOFTFAIL) @@ -1512,6 +1520,10 @@ skipopen: */ init_ok = (rc = pgm->initialize(pgm, p)) >= 0; if (!init_ok) { + if(rc == LIBAVRDUDE_EXIT) { + exitrc = 0; + goto main_exit; + } pmsg_error("initialization failed, rc=%d\n", rc); if (rc == -2) imsg_error("the programmer ISP clock is too fast for the target\n"); @@ -1549,6 +1561,10 @@ skipopen: usleep(waittime); if (init_ok) { rc = avr_signature(pgm, p); + if (rc == LIBAVRDUDE_EXIT) { + exitrc = 0; + goto main_exit; + } if (rc != LIBAVRDUDE_SUCCESS) { if (rc == LIBAVRDUDE_SOFTFAIL && (p->prog_modes & PM_UPDI) && attempt < 1) { attempt++; diff --git a/src/micronucleus.c b/src/micronucleus.c index 24566c26..beba31a3 100644 --- a/src/micronucleus.c +++ b/src/micronucleus.c @@ -544,23 +544,15 @@ static int micronucleus_start(pdata_t* pdata) //----------------------------------------------------------------------------- -static void micronucleus_setup(PROGRAMMER* pgm) -{ +static void micronucleus_setup(PROGRAMMER *pgm) { pmsg_debug("micronucleus_setup()\n"); - - if ((pgm->cookie = malloc(sizeof(pdata_t))) == 0) - { - pmsg_error("out of memory allocating private data\n"); - exit(1); - } - - memset(pgm->cookie, 0, sizeof(pdata_t)); + pgm->cookie = mmt_malloc(sizeof(pdata_t)); } -static void micronucleus_teardown(PROGRAMMER* pgm) -{ +static void micronucleus_teardown(PROGRAMMER* pgm) { pmsg_debug("micronucleus_teardown()\n"); - free(pgm->cookie); + mmt_free(pgm->cookie); + pgm->cookie = NULL; } static int micronucleus_initialize(const PROGRAMMER *pgm, const AVRPART *p) { @@ -593,13 +585,10 @@ static void micronucleus_powerdown(const PROGRAMMER *pgm) { { pdata->write_last_page = false; - uint8_t* buffer = (unsigned char*)malloc(pdata->page_size); - if (buffer != NULL) - { - memset(buffer, 0xFF, pdata->page_size); - micronucleus_write_page(pdata, pdata->bootloader_start - pdata->page_size, buffer, pdata->page_size); - free(buffer); - } + uint8_t *buffer = (unsigned char *) mmt_malloc(pdata->page_size); + memset(buffer, 0xFF, pdata->page_size); + micronucleus_write_page(pdata, pdata->bootloader_start - pdata->page_size, buffer, pdata->page_size); + mmt_free(buffer); } if (pdata->start_program) @@ -863,12 +852,7 @@ static int micronucleus_paged_write(const PROGRAMMER *pgm, const AVRPART *p, con return -1; } - uint8_t* page_buffer = (uint8_t*)malloc(pdata->page_size); - if (page_buffer == NULL) - { - pmsg_error("unable to allocate memory\n"); - return -1; - } + uint8_t *page_buffer = (uint8_t *) mmt_malloc(pdata->page_size); // Note: Page size reported by the bootloader may be smaller than device page size as configured in avrdude.conf. int result = 0; @@ -889,7 +873,7 @@ static int micronucleus_paged_write(const PROGRAMMER *pgm, const AVRPART *p, con n_bytes -= chunk_size; } - free(page_buffer); + mmt_free(page_buffer); return result; } else @@ -923,7 +907,7 @@ static int micronucleus_parseextparams(const PROGRAMMER *pgm, const LISTID xpara msg_error(" -xwait Wait for the device to be plugged in if not connected\n"); msg_error(" -xwait= Wait [s] for the device to be plugged in if not connected\n"); msg_error(" -xhelp Show this help menu and exit\n"); - exit(0); + return LIBAVRDUDE_EXIT; } else { diff --git a/src/msvc/getopt.c b/src/msvc/getopt.c index 9a0347d4..acc2ebff 100644 --- a/src/msvc/getopt.c +++ b/src/msvc/getopt.c @@ -114,18 +114,14 @@ static const char noarg[] = "option doesn't take an argument -- %.*s"; static const char illoptchar[] = "unknown option -- %c"; static const char illoptstring[] = "unknown option -- %s"; -static void -_vwarnx(const char *fmt,va_list ap) -{ +static void _vwarnx(const char *fmt,va_list ap) { (void)fprintf(stderr,"%s: ",__progname); if (fmt != NULL) (void)vfprintf(stderr,fmt,ap); (void)fprintf(stderr,"\n"); } -static void -warnx(const char *fmt,...) -{ +static void warnx(const char *fmt,...) { va_list ap; va_start(ap,fmt); _vwarnx(fmt,ap); @@ -135,9 +131,7 @@ warnx(const char *fmt,...) /* * Compute the greatest common divisor of a and b. */ -static int -gcd(int a, int b) -{ +static int gcd(int a, int b) { int c; c = a % b; @@ -155,10 +149,7 @@ gcd(int a, int b) * from nonopt_end to opt_end (keeping the same order of arguments * in each block). */ -static void -permute_args(int panonopt_start, int panonopt_end, int opt_end, - char * const *nargv) -{ +static void permute_args(int panonopt_start, int panonopt_end, int opt_end, char * const *nargv) { int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; char *swap; @@ -192,10 +183,9 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end, * Parse long options in argc/argv argument vector. * Returns -1 if short_too is set and the option does not match long_options. */ -static int -parse_long_options(char * const *nargv, const char *options, - const struct option *long_options, int *idx, int short_too) -{ +static int parse_long_options(char * const *nargv, const char *options, + const struct option *long_options, int *idx, int short_too) { + char *current_argv, *has_equal; size_t current_argv_len; int i, ambiguous, match; @@ -320,10 +310,9 @@ parse_long_options(char * const *nargv, const char *options, * getopt_internal -- * Parse argc/argv argument vector. Called by user level routines. */ -static int -getopt_internal(int nargc, char * const *nargv, const char *options, - const struct option *long_options, int *idx, int flags) -{ +static int getopt_internal(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx, int flags) { + char *oli; /* option letter list index */ int optchar, short_too; static int posixly_correct = -1; diff --git a/src/par.c b/src/par.c index 76968569..84630348 100644 --- a/src/par.c +++ b/src/par.c @@ -51,7 +51,7 @@ struct ppipins_t { int inverted; }; -static struct ppipins_t ppipins[] = { +static const struct ppipins_t ppipins[] = { { 1, PPICTRL, 0x01, 1 }, { 2, PPIDATA, 0x01, 0 }, { 3, PPIDATA, 0x02, 0 }, @@ -334,7 +334,7 @@ static void par_close(PROGRAMMER *pgm) { * parse the -E string */ static int par_parseexitspecs(PROGRAMMER *pgm, const char *sp) { - char *cp, *s, *str = cfg_strdup("par_parseexitspecs()", sp); + char *cp, *s, *str = mmt_strdup(sp); s = str; while((cp = strtok(s, ","))) { @@ -357,13 +357,13 @@ static int par_parseexitspecs(PROGRAMMER *pgm, const char *sp) { pgm->exit_datahigh = EXIT_DATAHIGH_DISABLED; else { - free(str); + mmt_free(str); return -1; } s = NULL; // Only call strtok() once with the actual string } - free(str); + mmt_free(str); return 0; } diff --git a/src/pgm.c b/src/pgm.c index da96cd52..4cdae5e6 100644 --- a/src/pgm.c +++ b/src/pgm.c @@ -63,40 +63,7 @@ static void pgm_default_powerup_powerdown(const PROGRAMMER *pgm) { } -PROGRAMMER *pgm_new(void) { - PROGRAMMER *pgm = (PROGRAMMER *) cfg_malloc("pgm_new()", sizeof(*pgm)); - const char *nulp = cache_string(""); - - // Initialise const char * and LISTID entities - pgm->id = lcreat(NULL, 0); - pgm->usbpid = lcreat(NULL, 0); - pgm->hvupdi_support = lcreat(NULL, 0); - pgm->desc = nulp; - pgm->parent_id = nulp; - pgm->usbdev = nulp; - pgm->usbsn = nulp; - pgm->usbvendor = nulp; - pgm->usbproduct = nulp; - pgm->config_file = nulp; - - // Allocate cache structures for flash and EEPROM, *do not* free in pgm_free() - pgm->cp_flash = cfg_malloc("pgm_new()", sizeof(AVR_Cache)); - pgm->cp_eeprom = cfg_malloc("pgm_new()", sizeof(AVR_Cache)); - pgm->cp_bootrow = cfg_malloc("pgm_new()", sizeof(AVR_Cache)); - pgm->cp_usersig = cfg_malloc("pgm_new()", sizeof(AVR_Cache)); - - // Default values - pgm->initpgm = NULL; - pgm->lineno = 0; - pgm->baudrate = 0; - - // Clear pin array - for(int i=0; ipinno[i] = NO_PIN; - pin_clear_all(&(pgm->pin[i])); - } - - pgm->leds = cfg_malloc(__func__, sizeof(leds_t)); +void pgm_init_functions(PROGRAMMER *pgm) { /* * mandatory functions - these are called without checking to see * whether they are assigned or not @@ -146,7 +113,9 @@ PROGRAMMER *pgm_new(void) { pgm->write_setup = NULL; pgm->read_sig_bytes = NULL; pgm->read_sib = NULL; + pgm->read_chip_rev = NULL; pgm->term_keep_alive= NULL; + pgm->end_programming= NULL; pgm->print_parms = NULL; pgm->set_vtarget = NULL; pgm->get_vtarget = NULL; @@ -164,8 +133,47 @@ PROGRAMMER *pgm_new(void) { pgm->parseextparams = NULL; pgm->readonly = NULL; pgm->flash_readhook = NULL; +} - // For allocating "global" memory by the programmer + +PROGRAMMER *pgm_new(void) { + PROGRAMMER *pgm = (PROGRAMMER *) mmt_malloc(sizeof(*pgm)); + const char *nulp = cache_string(""); + + // Initialise const char * and LISTID entities + pgm->id = lcreat(NULL, 0); + pgm->usbpid = lcreat(NULL, 0); + pgm->hvupdi_support = lcreat(NULL, 0); + pgm->desc = nulp; + pgm->parent_id = nulp; + pgm->usbdev = nulp; + pgm->usbsn = nulp; + pgm->usbvendor = nulp; + pgm->usbproduct = nulp; + pgm->config_file = nulp; + + // Allocate cache structures for flash and EEPROM, *do not* free in pgm_free() + pgm->cp_flash = mmt_malloc(sizeof(AVR_Cache)); + pgm->cp_eeprom = mmt_malloc(sizeof(AVR_Cache)); + pgm->cp_bootrow = mmt_malloc(sizeof(AVR_Cache)); + pgm->cp_usersig = mmt_malloc(sizeof(AVR_Cache)); + + // Default values + pgm->initpgm = NULL; + pgm->lineno = 0; + pgm->baudrate = 0; + + // Clear pin array + for(int i=0; ipinno[i] = NO_PIN; + pin_clear_all(&(pgm->pin[i])); + } + + pgm->leds = mmt_malloc(sizeof(leds_t)); + + pgm_init_functions(pgm); + + // For allocating static programmer memory pgm->cookie = NULL; return pgm; @@ -174,22 +182,22 @@ PROGRAMMER *pgm_new(void) { void pgm_free(PROGRAMMER *p) { if(p) { if(p->id) { - ldestroy_cb(p->id, free); + ldestroy_cb(p->id, mmt_f_free); p->id = NULL; } if(p->usbpid) { - ldestroy_cb(p->usbpid, free); + ldestroy_cb(p->usbpid, mmt_f_free); p->usbpid = NULL; } if(p->hvupdi_support) { - ldestroy_cb(p->hvupdi_support, free); + ldestroy_cb(p->hvupdi_support, mmt_f_free); p->hvupdi_support = NULL; } - free(p->leds); p->leds = NULL; + mmt_free(p->leds); p->leds = NULL; // Never free const char *, eg, p->desc, which are set by cache_string() // p->cookie was freed by pgm_teardown // Never free cp_flash, cp_eeprom, cp_bootrow or cp_usersig cache structures - free(p); + mmt_free(p); } } @@ -197,18 +205,18 @@ PROGRAMMER *pgm_dup(const PROGRAMMER *src) { PROGRAMMER *pgm = pgm_new(); if(src) { - ldestroy_cb(pgm->id, free); - ldestroy_cb(pgm->usbpid, free); - ldestroy_cb(pgm->hvupdi_support, free); + ldestroy_cb(pgm->id, mmt_f_free); + ldestroy_cb(pgm->usbpid, mmt_f_free); + ldestroy_cb(pgm->hvupdi_support, mmt_f_free); // There must be only one cache, even though the part is duplicated if(pgm->cp_flash) - free(pgm->cp_flash); + mmt_free(pgm->cp_flash); if(pgm->cp_eeprom) - free(pgm->cp_eeprom); + mmt_free(pgm->cp_eeprom); if(pgm->cp_bootrow) - free(pgm->cp_bootrow); + mmt_free(pgm->cp_bootrow); if(pgm->cp_usersig) - free(pgm->cp_usersig); + mmt_free(pgm->cp_usersig); leds_t *ls = pgm->leds; memcpy(pgm, src, sizeof(*pgm)); @@ -223,13 +231,13 @@ PROGRAMMER *pgm_dup(const PROGRAMMER *src) { // Leave id list empty but copy usbpid and hvupdi_support over if(src->hvupdi_support) for(LNODEID ln = lfirst(src->hvupdi_support); ln; ln = lnext(ln)) { - int *ip = cfg_malloc("pgm_dup()", sizeof(int)); + int *ip = mmt_malloc(sizeof(int)); *ip = *(int *) ldata(ln); ladd(pgm->hvupdi_support, ip); } if(src->usbpid) for(LNODEID ln = lfirst(src->usbpid); ln; ln = lnext(ln)) { - int *ip = cfg_malloc("pgm_dup()", sizeof(int)); + int *ip = mmt_malloc(sizeof(int)); *ip = *(int *) ldata(ln); ladd(pgm->usbpid, ip); } diff --git a/src/pickit2.c b/src/pickit2.c index 5caf07f3..836a11f9 100644 --- a/src/pickit2.c +++ b/src/pickit2.c @@ -95,7 +95,7 @@ static const char *usb_strerror() return ""; } #else -static int usb_open_device(struct usb_dev_handle **dev, int vid, int pid); +static int usb_open_device(PROGRAMMER *pgm, struct usb_dev_handle **dev, int vid, int pid); //#define INVALID_HANDLE_VALUE NULL #define USB_ERROR_NONE 0 #define USB_ERROR_ACCESS 1 @@ -119,7 +119,8 @@ struct pdata #ifdef WIN32 HANDLE usb_handle, write_event, read_event; #else - struct usb_dev_handle *usb_handle; // LIBUSB STUFF + struct usb_dev_handle *usb_handle; // LIBUSB STUFF + int USB_init; // Used in usb_open_device() #endif uint8_t clock_period; // SPI clock period in us int transaction_timeout; // usb trans timeout in ms @@ -160,22 +161,15 @@ struct pdata #define SCR_SPI 0xC3 #define SCR_SPI_LIT_2(v) 0xC7,(v) -static void pickit2_setup(PROGRAMMER * pgm) -{ - if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) - { - pmsg_error("out of memory allocating private data\n"); - exit(1); - } - memset(pgm->cookie, 0, sizeof(struct pdata)); - - PDATA(pgm)->transaction_timeout = 1500; // default value, may be overridden with -x timeout=ms - PDATA(pgm)->clock_period = 10; // default value, may be overridden with -x clockrate=us or -B or -i +static void pickit2_setup(PROGRAMMER *pgm) { + pgm->cookie = mmt_malloc(sizeof(struct pdata)); + PDATA(pgm)->transaction_timeout = 1500; // Can be changed with -x timeout=ms + PDATA(pgm)->clock_period = 10; // Can be changed with -x clockrate=us or -B or -i } -static void pickit2_teardown(PROGRAMMER * pgm) -{ - free(pgm->cookie); +static void pickit2_teardown(PROGRAMMER *pgm) { + mmt_free(pgm->cookie); + pgm->cookie = NULL; } static int pickit2_open(PROGRAMMER *pgm, const char *port) { @@ -192,7 +186,7 @@ static int pickit2_open(PROGRAMMER *pgm, const char *port) { { // Get the device description while we're at it and overlay it on pgm->desc short wbuf[80-1]; - char *cbuf = cfg_malloc("pickit2_open()", sizeof wbuf/sizeof*wbuf + (pgm->desc? strlen(pgm->desc): 0) + 2); + char *cbuf = mmt_malloc(sizeof wbuf/sizeof*wbuf + (pgm->desc? strlen(pgm->desc): 0) + 2); HidD_GetProductString(PDATA(pgm)->usb_handle, wbuf, sizeof wbuf/sizeof*wbuf); if(pgm->desc && *pgm->desc) @@ -202,10 +196,10 @@ static int pickit2_open(PROGRAMMER *pgm, const char *port) { for(size_t i = 0; i < sizeof wbuf/sizeof*wbuf && wbuf[i]; i++) cbuf[i] = (char) wbuf[i]; // TODO what about little/big endian??? pgm->desc = cache_string(cbuf); + mmt_free(cbuf); } #else - if (usb_open_device(&(PDATA(pgm)->usb_handle), PICKIT2_VID, PICKIT2_PID) < 0) - { + if(usb_open_device(pgm, &(PDATA(pgm)->usb_handle), PICKIT2_VID, PICKIT2_PID) < 0) { /* no PICkit2 found */ pmsg_error("cannot find PICkit2 with vid=0x%x pid=0x%x\n", PICKIT2_VID, PICKIT2_PID); return -1; @@ -893,7 +887,7 @@ static HANDLE open_hid(unsigned short vid, unsigned short pid) //Allocate memory for the hDevInfo structure, using the returned Length. - detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length); + detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) mmt_malloc(Length); //Set cbSize in the detailData structure. @@ -989,7 +983,7 @@ static HANDLE open_hid(unsigned short vid, unsigned short pid) //Free the memory used by the detailData structure (no longer needed). - free(detailData); + mmt_free(detailData); } //if (Result != 0) @@ -1080,17 +1074,14 @@ static int pickit2_read_report(const PROGRAMMER *pgm, unsigned char report[65]) #else // WIN32 /* taken (modified) from avrdude usbasp.c */ -static int usb_open_device(struct usb_dev_handle **device, int vendor, int product) -{ +static int usb_open_device(PROGRAMMER *pgm, struct usb_dev_handle **device, int vendor, int product) { struct usb_bus *bus; struct usb_device *dev; usb_dev_handle *handle = NULL; int errorCode = USB_ERROR_NOTFOUND; - static int didUsbInit = 0; - if (!didUsbInit) - { - didUsbInit = 1; + if(!PDATA(pgm)->USB_init) { + PDATA(pgm)->USB_init = 1; usb_init(); } usb_find_busses(); @@ -1200,7 +1191,7 @@ static int pickit2_parseextparams(const PROGRAMMER *pgm, const LISTID extparms) msg_error(" -xclockrate= Set the SPI clocking rate in [Hz]\n"); msg_error(" -xtimeout= Set the timeout for USB read/write to [ms]\n"); msg_error(" -xhelp Show this help menu and exit\n"); - exit(0); + return LIBAVRDUDE_EXIT;; } pmsg_error("invalid extended parameter '%s'\n", extended_param); @@ -1292,4 +1283,3 @@ void pickit2_initpgm(PROGRAMMER *pgm) { #endif /* defined(HAVE_LIBUSB) || defined(WIN32) */ const char pickit2_desc[] = "Microchip's PICkit2 Programmer"; - diff --git a/src/pindefs.c b/src/pindefs.c index df1d98e3..e71c92c8 100644 --- a/src/pindefs.c +++ b/src/pindefs.c @@ -354,7 +354,7 @@ const char * pins_to_str(const struct pindef_t * const pindef) { * This function returns a string of defined pins, eg, ~1, 2, ~4, ~5, 7 or "" * * @param[in] pindef the pin definition for which we want the string representation - * @returns a pointer to a string, which was created by cfg_strdup() + * @returns a pointer to a string, which was created by mmt_strdup() */ char *pins_to_strdup(const struct pindef_t * const pindef) { char buf[6*(PIN_MAX+1)], *p = buf; @@ -369,7 +369,7 @@ char *pins_to_strdup(const struct pindef_t * const pindef) { } } - return cfg_strdup("pins_to_strdup()", buf); + return mmt_strdup(buf); } /** diff --git a/src/ser_posix.c b/src/ser_posix.c index ad5d6987..2147e435 100644 --- a/src/ser_posix.c +++ b/src/ser_posix.c @@ -288,10 +288,7 @@ static int net_open(const char *port, union filedescriptor *fdp) { struct addrinfo hints; struct addrinfo *result, *rp; - if ((hstr = hp = strdup(port)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } + hstr = hp = mmt_strdup(port); /* * As numeric IPv6 addresses use colons as separators, we need to @@ -348,7 +345,7 @@ static int net_open(const char *port, union filedescriptor *fdp) { freeaddrinfo(result); error: - free(hp); + mmt_free(hp); return ret; } diff --git a/src/ser_win32.c b/src/ser_win32.c index e0059d81..18909b38 100644 --- a/src/ser_win32.c +++ b/src/ser_win32.c @@ -164,14 +164,10 @@ static int net_open(const char *port, union filedescriptor *fdp) { return -1; } - if ((hstr = strdup(port)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - + hstr = mmt_strdup(port); if (((pstr = strchr(hstr, ':')) == NULL) || (pstr == hstr)) { pmsg_error("mangled host:port string %s\n", hstr); - free(hstr); + mmt_free(hstr); return -1; } @@ -184,17 +180,17 @@ static int net_open(const char *port, union filedescriptor *fdp) { if ((*pstr == '\0') || (*end != '\0') || (pnum == 0) || (pnum > 65535)) { pmsg_error("bad port number %s\n", pstr); - free(hstr); + mmt_free(hstr); return -1; } if ((hp = gethostbyname(hstr)) == NULL) { pmsg_error("unknown host %s\n", hstr); - free(hstr); + mmt_free(hstr); return -1; } - free(hstr); + mmt_free(hstr); if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { FormatMessage( @@ -256,7 +252,7 @@ static int ser_open(const char *port, union pinfo pinfo, union filedescriptor *f if (str_casestarts(port, "com")) { // prepend "\\\\.\\" to name, required for port # >= 10 - newname = cfg_malloc(__func__, strlen("\\\\.\\") + strlen(port) + 1); + newname = mmt_malloc(strlen("\\\\.\\") + strlen(port) + 1); strcpy(newname, "\\\\.\\"); strcat(newname, port); @@ -305,7 +301,7 @@ static int ser_open(const char *port, union pinfo pinfo, union filedescriptor *f } if (newname != 0) { - free(newname); + mmt_free(newname); } return 0; } diff --git a/src/serialadapter.c b/src/serialadapter.c index dc4f610c..1243cfc3 100644 --- a/src/serialadapter.c +++ b/src/serialadapter.c @@ -46,8 +46,8 @@ static int sa_setport(char **portp, const char *sp_port) { if(portp) { if(*portp) - free(*portp); - *portp = cfg_strdup(__func__, sp_port); + mmt_free(*portp); + *portp = mmt_strdup(sp_port); } return 0; @@ -104,20 +104,20 @@ static SERPORT *get_libserialport_data(int *np) { } int i, j, n; - // Count the number of available ports and allocate space according to the needed size + // Count the number of available ports and allocate space accordingly for(n = 0; port_list[n]; n++) continue; - SERPORT *sp = cfg_malloc(__func__, n*sizeof*sp); + SERPORT *sp = mmt_malloc(n*sizeof*sp); for(j = 0, i = 0; i < n; i++) { // j counts the number of valid ports struct sp_port *p = port_list[i]; char *q; // Fill sp struct with port information if((q = sp_get_port_name(p))) { - sp[j].port = cfg_strdup(__func__, q); + sp[j].port = mmt_strdup(q); if(sp_get_port_usb_vid_pid(p, &sp[j].vid, &sp[j].pid) != SP_OK) sp[j].vid = sp[j].pid = 0; - sp[j].sernum = cfg_strdup(__func__, (q = sp_get_port_usb_serial(p))? q: ""); + sp[j].sernum = mmt_strdup((q = sp_get_port_usb_serial(p))? q: ""); j++; } } @@ -125,7 +125,7 @@ static SERPORT *get_libserialport_data(int *np) { if(j > 0) qsort(sp, j, sizeof*sp, sa_portcmp); else - free(sp), sp = NULL; + mmt_free(sp), sp = NULL; sp_free_port_list(port_list); @@ -137,13 +137,13 @@ static SERPORT *get_libserialport_data(int *np) { // Free memory allocated from get_libserialport_data() static void free_libserialport_data(SERPORT *sp, int n) { for(int k = 0; sp && k < n; k++) - free(sp[k].sernum), free(sp[k].port); - free(sp); + mmt_free(sp[k].sernum), mmt_free(sp[k].port); + mmt_free(sp); } -// Returns a NULL-terminated malloc'd list of items in SERPORT list spa that are not in spb +// Returns a NULL-terminated mmt_malloc'd list of items in SERPORT list spa that are not in spb SERPORT **sa_spa_not_spb(SERPORT *spa, int na, SERPORT *spb, int nb) { - SERPORT **ret = cfg_malloc(__func__, (na+1)*sizeof*ret); + SERPORT **ret = mmt_malloc((na+1)*sizeof*ret); int ia = 0, ib = 0, ir = 0; // Use the comm algorithm on two sorted SERPORT lists @@ -200,10 +200,10 @@ static int sa_unique_by_ids(int vid, int pid, const char *sn, const SERPORT *sp, return sa_num_matches_by_ids(vid, pid, sn, sp, n) == 1 && sa_num_matches_by_ids(vid, pid, sn, sp+i, 1); } -// Return a malloc'd list of -P specifications that uniquely address sp[i] +// Return an mmt_malloc'd list of -P specifications that uniquely address sp[i] static char **sa_list_specs(const SERPORT *sp, int n, int i) { int Pn = 4, Pi = 0; - char **Plist = cfg_malloc(__func__, Pn*sizeof*Plist); + char **Plist = mmt_malloc(Pn*sizeof*Plist); const char *sn = sp[i].sernum, *via = NULL; // Loop though all serial adapters in avrdude.conf @@ -215,7 +215,7 @@ static char **sa_list_specs(const SERPORT *sp, int n, int i) { char *id = ldata(sid); // Put id or id:sn into list if it uniquely matches sp[i] if(sa_unique_by_sea(sea, "", sp, n, i)) - Plist[Pi++] = cfg_strdup(__func__, id); + Plist[Pi++] = mmt_strdup(id); else if(*sn && sa_unique_by_sea(sea, sn, sp, n, i)) Plist[Pi++] = str_sprintf("%s:%s", id, sn); else if(!via && sa_num_matches_by_sea(sea, "", sp+i, 1)) @@ -225,7 +225,7 @@ static char **sa_list_specs(const SERPORT *sp, int n, int i) { if(Pn >= INT_MAX/2) break; Pn *= 2; - Plist = cfg_realloc(__func__, Plist, Pn*sizeof*Plist); + Plist = mmt_realloc(Plist, Pn*sizeof*Plist); } } } @@ -250,11 +250,11 @@ static void sa_print_specs(const SERPORT *sp, int n, int i) { msg_warning(" -P %s", sp[i].port); for(char **Ps = Pspecs; *Ps; Ps++) { msg_warning("%s %s", str_starts(*Ps, "(via ")? "": Ps[1]? ", -P": " or -P", *Ps); - free(*Ps); + mmt_free(*Ps); } msg_warning("\n"); - free(Pspecs); + mmt_free(Pspecs); } // Set the port specs to the port iff sea matches one and only one of the connected SERPORTs @@ -343,12 +343,12 @@ int touch_serialport(char **portp, int baudrate, int nwaits) { if(*diff && diff[0]->port && !diff[1]) { // Exactly one new port sprung up pmsg_notice("new port %s discovered\n", (*diff)->port); if(*portp) - free(*portp); - *portp = cfg_strdup(__func__, (*diff)->port); + mmt_free(*portp); + *portp = mmt_strdup((*diff)->port); msg_info(" %d ms:", (nloops-i+1)*nap + nwaits*400); i = -1; // Leave loop } - free(diff); + mmt_free(diff); free_libserialport_data(sp2, n2); } } @@ -377,8 +377,8 @@ int list_available_serialports(LISTID programmers) { msg_warning("Also note there may be other direct serial ports not listed above.\n"); for(int k = 0; k < n; k++) - free(sp[k].sernum), free(sp[k].port); - free(sp); + mmt_free(sp[k].sernum), mmt_free(sp[k].port); + mmt_free(sp); return 0; } diff --git a/src/serialupdi.c b/src/serialupdi.c index eed28c7f..1664670c 100644 --- a/src/serialupdi.c +++ b/src/serialupdi.c @@ -48,20 +48,15 @@ static int serialupdi_enter_progmode(const PROGRAMMER *pgm); static int serialupdi_leave_progmode(const PROGRAMMER *pgm); -static void serialupdi_setup(PROGRAMMER * pgm) -{ - if ((pgm->cookie = malloc(sizeof(updi_state))) == 0) { - pmsg_error("out of memory allocating private data\n"); - exit(1); - } - memset(pgm->cookie, 0, sizeof(updi_state)); +static void serialupdi_setup(PROGRAMMER *pgm) { + pgm->cookie = mmt_malloc(sizeof(updi_state)); updi_set_rts_mode(pgm, RTS_MODE_DEFAULT); updi_set_datalink_mode(pgm, UPDI_LINK_MODE_16BIT); } -static void serialupdi_teardown(PROGRAMMER * pgm) -{ - free(pgm->cookie); +static void serialupdi_teardown(PROGRAMMER *pgm) { + mmt_free(pgm->cookie); + pgm->cookie = NULL; } static int serialupdi_open(PROGRAMMER *pgm, const char *port) { @@ -1032,7 +1027,7 @@ static int serialupdi_parseextparms(const PROGRAMMER *pgm, const LISTID extparms msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -xrtsdtr=low,high Force RTS/DTR lines low or high state during programming\n"); msg_error(" -xhelp Show this help menu and exit\n"); - exit(0); + return LIBAVRDUDE_EXIT;; } pmsg_error("invalid extended parameter '%s'\n", extended_param); diff --git a/src/stk500.c b/src/stk500.c index 6f7f7156..e580b0cc 100644 --- a/src/stk500.c +++ b/src/stk500.c @@ -489,6 +489,8 @@ static int stk500_initialize(const PROGRAMMER *pgm, const AVRPART *p) { if ((m = avr_locate_eeprom(p))) { buf[11] = m->readback[0]; buf[12] = m->readback[1]; + if(!buf[11] && !buf[12]) // Make default readback values 0xff for eeproms + buf[11] = buf[12] = 0xff; buf[15] = (m->size >> 8) & 0x00ff; buf[16] = m->size & 0x00ff; } else { @@ -799,7 +801,7 @@ static int stk500_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) } msg_error(" -xxtal=[M|k] Set programmer xtal frequency\n"); msg_error(" -xhelp Show this help menu and exit\n"); - exit(0); + return LIBAVRDUDE_EXIT;; } pmsg_error("invalid extended parameter %s\n", extended_param); @@ -1253,7 +1255,7 @@ static int stk500_get_varef(const PROGRAMMER *pgm, unsigned int chan /* unused * static int stk500_set_fosc(const PROGRAMMER *pgm, double v) { unsigned prescale, cmatch, fosc; - static unsigned ps[] = { + static const unsigned ps[] = { 1, 8, 32, 64, 128, 256, 1024 }; size_t idx; @@ -1307,7 +1309,7 @@ static int stk500_set_fosc(const PROGRAMMER *pgm, double v) { static int stk500_get_fosc(const PROGRAMMER *pgm, double *v) { unsigned prescale=0, cmatch=0; - static unsigned ps[] = { + static const unsigned ps[] = { 1, 8, 32, 64, 128, 256, 1024 }; int rc; @@ -1567,13 +1569,8 @@ static void stk500_print_parms(const PROGRAMMER *pgm, FILE *fp) { stk500_print_parms1(pgm, "", fp); } -static void stk500_setup(PROGRAMMER * pgm) -{ - if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) { - pmsg_error("out of memory allocating private data\n"); - return; - } - memset(pgm->cookie, 0, sizeof(struct pdata)); +static void stk500_setup(PROGRAMMER * pgm) { + pgm->cookie = mmt_malloc(sizeof(struct pdata)); PDATA(pgm)->ext_addr_byte = 0xff; PDATA(pgm)->xbeeResetPin = XBEE_DEFAULT_RESET_PIN; // nanoSTK (Arduino Nano HW) uses 16 MHz @@ -1583,9 +1580,8 @@ static void stk500_setup(PROGRAMMER * pgm) PDATA(pgm)->xtal = STK500_XTAL; } -static void stk500_teardown(PROGRAMMER * pgm) -{ - free(pgm->cookie); +static void stk500_teardown(PROGRAMMER * pgm) { + mmt_free(pgm->cookie); pgm->cookie = NULL; } diff --git a/src/stk500.h b/src/stk500.h index 9d42a760..10ff3b39 100644 --- a/src/stk500.h +++ b/src/stk500.h @@ -42,6 +42,7 @@ struct pdata { unsigned char ext_addr_byte; // Record ext-addr byte set in the target device (if used) int retry_attempts; // Number of connection attempts provided by the user int xbeeResetPin; // Piggy back variable used by xbee programmmer + struct serial_device xbee_serdev; // Piggy back device descriptor for XBee framing // Get/set flags for adjustable target voltage bool vtarg_get; diff --git a/src/stk500generic.c b/src/stk500generic.c index d5ce7f73..2aa331be 100644 --- a/src/stk500generic.c +++ b/src/stk500generic.c @@ -41,36 +41,28 @@ #include "stk500.h" #include "stk500v2.h" -static PROGRAMMER *stk500vn; -static void stk500vn_exithook(void) { - if(stk500vn && stk500vn->teardown) - stk500vn->teardown(stk500vn); -} - static int stk500generic_open(PROGRAMMER *pgm, const char *port) { + // First try stk500 v2 programmer stk500v2_initpgm(pgm); if(pgm->setup) pgm->setup(pgm); if(pgm->open(pgm, port) >= 0) { - stk500vn = pgm; - atexit(stk500vn_exithook); - pmsg_info("successfully opened stk500v2 device; please use -c stk500v2\n"); + pmsg_info("successfully opened stk500v2 device\n"); + imsg_info("in future, please use -c stk500v2, so -x parameters are available\n"); return 0; } if(pgm->teardown) pgm->teardown(pgm); - stk500_initpgm(pgm); + pgm_init_functions(pgm); // Overwrite stk500v2_initpgm(pgm) setup + stk500_initpgm(pgm); // Now try engaging the v1 programmer if(pgm->setup) pgm->setup(pgm); if(pgm->open(pgm, port) >= 0) { - stk500vn = pgm; - atexit(stk500vn_exithook); - pmsg_info("successfully opened stk500v1 device; please use -c stk500v1\n"); + pmsg_info("successfully opened stk500v1 device\n"); + imsg_info("in future, please use -c stk500v1, so -x parameters are available\n"); return 0; } - if(pgm->teardown) - pgm->teardown(pgm); pmsg_error("probing stk500v2 failed, as did stk500v1; perhaps try -c stk500v1\n"); return -1; diff --git a/src/stk500v2.c b/src/stk500v2.c index 10c4b685..9014543f 100644 --- a/src/stk500v2.c +++ b/src/stk500v2.c @@ -292,27 +292,17 @@ static void stk600_setup_xprog(PROGRAMMER *pgm); static void stk600_setup_isp(PROGRAMMER *pgm); static int stk600_xprog_program_enable(const PROGRAMMER *pgm, const AVRPART *p); -void stk500v2_setup(PROGRAMMER * pgm) -{ - if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) { - pmsg_error("out of memory allocating private data\n"); - exit(1); - } - memset(pgm->cookie, 0, sizeof(struct pdata)); +void stk500v2_setup(PROGRAMMER *pgm) { + pgm->cookie = mmt_malloc(sizeof(struct pdata)); PDATA(pgm)->command_sequence = 1; PDATA(pgm)->boot_start = ULONG_MAX; PDATA(pgm)->xtal = str_starts(pgmid, "scratchmonkey") ? SCRATCHMONKEY_XTAL : STK500V2_XTAL; } -static void stk500v2_jtagmkII_setup(PROGRAMMER * pgm) -{ +static void stk500v2_jtagmkII_setup(PROGRAMMER *pgm) { void *mycookie, *theircookie; - if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) { - pmsg_error("out of memory allocating private data\n"); - exit(1); - } - memset(pgm->cookie, 0, sizeof(struct pdata)); + pgm->cookie = mmt_malloc(sizeof(struct pdata)); PDATA(pgm)->command_sequence = 1; /* @@ -326,15 +316,10 @@ static void stk500v2_jtagmkII_setup(PROGRAMMER * pgm) PDATA(pgm)->chained_pdata = theircookie; } -static void stk500v2_jtag3_setup(PROGRAMMER * pgm) -{ +static void stk500v2_jtag3_setup(PROGRAMMER *pgm) { void *mycookie, *theircookie; - if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) { - pmsg_error("out of memory allocating private data\n"); - exit(1); - } - memset(pgm->cookie, 0, sizeof(struct pdata)); + pgm->cookie = mmt_malloc(sizeof(struct pdata)); PDATA(pgm)->command_sequence = 1; /* @@ -348,41 +333,40 @@ static void stk500v2_jtag3_setup(PROGRAMMER * pgm) PDATA(pgm)->chained_pdata = theircookie; } -void stk500v2_teardown(PROGRAMMER * pgm) -{ - free(pgm->cookie); +void stk500v2_teardown(PROGRAMMER *pgm) { + mmt_free(pgm->cookie); pgm->cookie = NULL; } -static void stk500v2_jtagmkII_teardown(PROGRAMMER * pgm) -{ - void *mycookie; +static void stk500v2_jtagmkII_teardown(PROGRAMMER *pgm) { + if(pgm->cookie) { + mmt_free(PDATA(pgm)->flash_pagecache); + mmt_free(PDATA(pgm)->eeprom_pagecache); - free(PDATA(pgm)->flash_pagecache); - free(PDATA(pgm)->eeprom_pagecache); + void *mycookie = pgm->cookie; + pgm->cookie = PDATA(pgm)->chained_pdata; + jtagmkII_teardown(pgm); + pgm->cookie = mycookie; + } - mycookie = pgm->cookie; - pgm->cookie = PDATA(pgm)->chained_pdata; - jtagmkII_teardown(pgm); - - free(mycookie); + mmt_free(pgm->cookie); + pgm->cookie = NULL; } -static void stk500v2_jtag3_teardown(PROGRAMMER * pgm) -{ - void *mycookie; +static void stk500v2_jtag3_teardown(PROGRAMMER *pgm) { + if(pgm->cookie) { + void *mycookie = pgm->cookie; + pgm->cookie = PDATA(pgm)->chained_pdata; + jtag3_teardown(pgm); + pgm->cookie = mycookie; + } - mycookie = pgm->cookie; - pgm->cookie = PDATA(pgm)->chained_pdata; - jtag3_teardown(pgm); - - free(mycookie); + mmt_free(pgm->cookie); + pgm->cookie = NULL; } -static unsigned short -b2_to_u16(unsigned char *b) -{ +static unsigned short b2_to_u16(unsigned char *b) { unsigned short l; l = b[0]; l += (unsigned)b[1] << 8; @@ -390,16 +374,12 @@ b2_to_u16(unsigned char *b) return l; } -static void -u16_to_b2(unsigned char *b, unsigned short l) -{ +static void u16_to_b2(unsigned char *b, unsigned short l) { b[0] = l & 0xff; b[1] = (l >> 8) & 0xff; } -static double -f_to_kHz_MHz(double f, const char **unit) -{ +static double f_to_kHz_MHz(double f, const char **unit) { if (f >= 1e6) { f /= 1e6; *unit = "MHz"; @@ -469,10 +449,7 @@ static int stk500v2_jtagmkII_send(const PROGRAMMER *pgm, unsigned char *data, si sz = 3 + data[2]; } - if ((cmdbuf = malloc(len + 3)) == NULL) { - pmsg_error("out of memory for command packet\n"); - exit(1); - } + cmdbuf = mmt_malloc(len + 3); PROGRAMMER *pgmcp = pgm_dup(pgm); pgmcp->cookie = PDATA(pgm)->chained_pdata; cmdbuf[0] = CMND_ISP_PACKET; @@ -480,7 +457,7 @@ static int stk500v2_jtagmkII_send(const PROGRAMMER *pgm, unsigned char *data, si cmdbuf[2] = (sz >> 8) & 0xff; memcpy(cmdbuf + 3, data, len); rv = jtagmkII_send(pgmcp, cmdbuf, len + 3); - free(cmdbuf); + mmt_free(cmdbuf); pgm_free(pgmcp); return rv; @@ -493,17 +470,13 @@ static int stk500v2_jtag3_send(const PROGRAMMER *pgm, unsigned char *data, size_ unsigned char *cmdbuf; int rv; - if ((cmdbuf = malloc(len + 1)) == NULL) { - pmsg_error("out of memory for command packet\n"); - exit(1); - } - + cmdbuf = mmt_malloc(len + 1); PROGRAMMER *pgmcp = pgm_dup(pgm); pgmcp->cookie = PDATA(pgm)->chained_pdata; cmdbuf[0] = SCOPE_AVR_ISP; memcpy(cmdbuf + 1, data, len); rv = jtag3_send(pgmcp, cmdbuf, len + 1); - free(cmdbuf); + mmt_free(cmdbuf); pgm_free(pgmcp); return rv; @@ -596,7 +569,7 @@ static int stk500v2_jtagmkII_recv(const PROGRAMMER *pgm, unsigned char *msg, return -1; } memcpy(msg, jtagmsg + 1, rv - 1); - free(jtagmsg); + mmt_free(jtagmsg); return rv; } @@ -625,11 +598,11 @@ static int stk500v2_jtag3_recv(const PROGRAMMER *pgm, unsigned char *msg, } if (jtagmsg[0] != SCOPE_AVR_ISP) { pmsg_error("message is not AVR ISP: 0x%02x\n", jtagmsg[0]); - free(jtagmsg); + mmt_free(jtagmsg); return -1; } memcpy(msg, jtagmsg + 1, rv - 1); - free(jtagmsg); + mmt_free(jtagmsg); return rv; } @@ -1045,47 +1018,33 @@ static int stk500hvsp_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { return stk500hv_chip_erase(pgm, p, HVSPMODE); } -static struct -{ - unsigned int state; - const char *description; -} connection_status[] = -{ - { STATUS_CONN_FAIL_SDO, "SDO fail" }, - { STATUS_CONN_FAIL_RST, "RST fail" }, - { STATUS_CONN_FAIL_SCK, "SCK fail" }, - { STATUS_TGT_NOT_DETECTED, "Target not detected" }, - { STATUS_TGT_REVERSE_INSERTED, "Target reverse inserted" }, -}; - /* * Max length of returned message is the sum of all the description - * strings in the table above, plus 2 characters for separation. - * Currently, this is 76 chars. + * strings in the table below, plus 2 characters for separation each. + * Currently, this is 74 chars plus the terminating nul. */ -static void -stk500v2_translate_conn_status(unsigned char status, char *msg) -{ - size_t i; - int need_comma; +static void stk500v2_translate_conn_status(unsigned char status, char *msg) { + struct { + unsigned int state; + const char *description; + } const conn_status[] = { + { STATUS_CONN_FAIL_SDO, "SDO fail" }, + { STATUS_CONN_FAIL_RST, "RST fail" }, + { STATUS_CONN_FAIL_SCK, "SCK fail" }, + { STATUS_TGT_NOT_DETECTED, "Target not detected" }, + { STATUS_TGT_REVERSE_INSERTED, "Target reverse inserted" }, + }; - *msg = 0; - need_comma = 0; - - for (i = 0; - i < sizeof connection_status / sizeof connection_status[0]; - i++) - { - if ((status & connection_status[i].state) != 0) - { - if (need_comma) - strcat(msg, ", "); - strcat(msg, connection_status[i].description); - need_comma = 1; - } + *msg = 0; + for(size_t i = 0; i < sizeof conn_status / sizeof *conn_status; i++) { + if(status & conn_status[i].state) { + if(*msg) + strcat(msg, ", "); + strcat(msg, conn_status[i].description); } - if (*msg == 0) - sprintf(msg, "Unknown status 0x%02x", status); + } + if(*msg == 0) + sprintf(msg, "Unknown status 0x%02x", status); } @@ -1158,15 +1117,15 @@ retry: cmd[1] = CMD3_SIGN_ON; cmd[2] = cmd[3] = 0; if (jtag3_command(pgmcp, cmd, 4, &resp, "AVR sign-on") >= 0) { - free(resp); + mmt_free(resp); cmd[1] = CMD3_START_DW_DEBUG; if (jtag3_command(pgmcp, cmd, 4, &resp, "start DW debug") >= 0) { - free(resp); + mmt_free(resp); cmd[1] = CMD3_MONCON_DISABLE; if (jtag3_command(pgmcp, cmd, 3, &resp, "MonCon disable") >= 0) - free(resp); + mmt_free(resp); } } pgm_free(pgmcp); @@ -1353,17 +1312,10 @@ static int stk500v2_initialize(const PROGRAMMER *pgm, const AVRPART *p) { PDATA(pgm)->eeprom_pagesize = m->page_size; } } - free(PDATA(pgm)->flash_pagecache); - free(PDATA(pgm)->eeprom_pagecache); - if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) { - pmsg_error("out of memory\n"); - free(PDATA(pgm)->flash_pagecache); - return -1; - } + mmt_free(PDATA(pgm)->flash_pagecache); + mmt_free(PDATA(pgm)->eeprom_pagecache); + PDATA(pgm)->flash_pagecache = mmt_malloc(PDATA(pgm)->flash_pagesize); + PDATA(pgm)->eeprom_pagecache = mmt_malloc(PDATA(pgm)->eeprom_pagesize); PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; if (p->flags & AVRPART_IS_AT90S1200) { @@ -1421,7 +1373,7 @@ static int stk500v2_jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) { jtag3_send(pgmcp, parm, 2); if (jtag3_recv(pgmcp, &resp) > 0) - free(resp); + mmt_free(resp); // Read or write SUFFER register if (PDATA(pgm)->suffer_get || PDATA(pgm)->suffer_set) { @@ -1478,7 +1430,7 @@ static int stk500v2_jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) { } } - free(pgmcp); + mmt_free(pgmcp); /* * Examine the avrpart's memory definitions, and initialize the page @@ -1501,18 +1453,11 @@ static int stk500v2_jtag3_initialize(const PROGRAMMER *pgm, const AVRPART *p) { PDATA(pgm)->eeprom_pagesize = m->page_size; } } - free(PDATA(pgm)->flash_pagecache); - free(PDATA(pgm)->eeprom_pagecache); - if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) { - pmsg_error("out of memory\n"); - free(PDATA(pgm)->flash_pagecache); - return -1; - } - PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; + mmt_free(PDATA(pgm)->flash_pagecache); + mmt_free(PDATA(pgm)->eeprom_pagecache); + PDATA(pgm)->flash_pagecache = mmt_malloc(PDATA(pgm)->flash_pagesize); + PDATA(pgm)->eeprom_pagecache = mmt_malloc(PDATA(pgm)->eeprom_pagesize); + PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long) -1L; return pgm->program_enable(pgm, p); } @@ -1672,18 +1617,11 @@ static int stk500hv_initialize(const PROGRAMMER *pgm, const AVRPART *p, enum hvm PDATA(pgm)->eeprom_pagesize = m->page_size; } } - free(PDATA(pgm)->flash_pagecache); - free(PDATA(pgm)->eeprom_pagecache); - if ((PDATA(pgm)->flash_pagecache = malloc(PDATA(pgm)->flash_pagesize)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - if ((PDATA(pgm)->eeprom_pagecache = malloc(PDATA(pgm)->eeprom_pagesize)) == NULL) { - pmsg_error("out of memory\n"); - free(PDATA(pgm)->flash_pagecache); - return -1; - } - PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L; + mmt_free(PDATA(pgm)->flash_pagecache); + mmt_free(PDATA(pgm)->eeprom_pagecache); + PDATA(pgm)->flash_pagecache = mmt_malloc(PDATA(pgm)->flash_pagesize); + PDATA(pgm)->eeprom_pagecache = mmt_malloc(PDATA(pgm)->eeprom_pagesize); + PDATA(pgm)->flash_pageaddr = PDATA(pgm)->eeprom_pageaddr = (unsigned long) -1L; return pgm->program_enable(pgm, p); } @@ -1706,9 +1644,9 @@ static void stk500v2_jtag3_disable(const PROGRAMMER *pgm) { unsigned char buf[16]; int result; - free(PDATA(pgm)->flash_pagecache); + mmt_free(PDATA(pgm)->flash_pagecache); PDATA(pgm)->flash_pagecache = NULL; - free(PDATA(pgm)->eeprom_pagecache); + mmt_free(PDATA(pgm)->eeprom_pagecache); PDATA(pgm)->eeprom_pagecache = NULL; buf[0] = CMD_LEAVE_PROGMODE_ISP; @@ -1748,9 +1686,9 @@ static void stk500hv_disable(const PROGRAMMER *pgm, enum hvmode mode) { unsigned char buf[16]; int result; - free(PDATA(pgm)->flash_pagecache); + mmt_free(PDATA(pgm)->flash_pagecache); PDATA(pgm)->flash_pagecache = NULL; - free(PDATA(pgm)->eeprom_pagecache); + mmt_free(PDATA(pgm)->eeprom_pagecache); PDATA(pgm)->eeprom_pagecache = NULL; buf[0] = mode == PPMODE? CMD_LEAVE_PROGMODE_PP: @@ -1980,7 +1918,7 @@ static int stk500v2_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) } msg_error(" -xxtal=[M|k] Set programmer xtal frequency\n"); msg_error(" -xhelp Show this help menu and exit\n"); - exit(0); + return LIBAVRDUDE_EXIT;; } pmsg_error("invalid extended parameter %s\n", extended_param); @@ -2115,7 +2053,7 @@ static int stk500v2_jtag3_parseextparms(const PROGRAMMER *pgm, const LISTID extp if(str_starts(pgmid, "pickit4") || str_starts(pgmid, "snap")) msg_error(" -xmode=avr|pic Set programmer to AVR or PIC mode, then exit\n"); msg_error (" -xhelp Show this help menu and exit\n"); - exit(0); + return LIBAVRDUDE_EXIT;; } pmsg_error("invalid extended parameter %s\n", extended_param); @@ -3292,7 +3230,7 @@ static int stk500v2_get_varef(const PROGRAMMER *pgm, unsigned int chan, double * static int stk500v2_set_fosc(const PROGRAMMER *pgm, double v) { int fosc; unsigned char prescale, cmatch; - static unsigned ps[] = { + const unsigned ps[] = { 1, 8, 32, 64, 128, 256, 1024 }; size_t idx; @@ -3347,7 +3285,7 @@ static int stk500v2_get_fosc(const PROGRAMMER *pgm, double *v) { /* The list of SCK frequencies supported by the AVRISP mkII, as listed * in AVR069 */ -static double avrispmkIIfreqs[] = { +static const double avrispmkIIfreqs[] = { 8000000, 4000000, 2000000, 1000000, 500000, 250000, 125000, 96386, 89888, 84211, 79208, 74767, 70797, 67227, 64000, 61069, 58395, 55945, 51613, 49690, 47905, 46243, 43244, @@ -3369,21 +3307,21 @@ static double avrispmkIIfreqs[] = { 65.0, 61.9, 59.0, 56.3, 53.6, 51.1 }; +#define NavrispmkIIfreqs (sizeof avrispmkIIfreqs / sizeof *avrispmkIIfreqs) + static int stk500v2_set_sck_period_mk2(const PROGRAMMER *pgm, double v) { size_t i; - for (i = 0; i < sizeof(avrispmkIIfreqs) / sizeof(avrispmkIIfreqs[0]); i++) { - if (1 / avrispmkIIfreqs[i] >= v) + for(i = 0; i < NavrispmkIIfreqs; i++) + if(1 / avrispmkIIfreqs[i] >= v) break; - } - if (i >= sizeof(avrispmkIIfreqs) / sizeof(avrispmkIIfreqs[0])) { + if(i >= NavrispmkIIfreqs) { pmsg_error("invalid SCK period: %g\n", v); return -1; } - msg_notice2("Using p = %.2f us for SCK (param = %d)\n", - 1000000 / avrispmkIIfreqs[i], (int) i); + msg_notice2("Using p = %.2f us for SCK (i = %d)\n", 1e6 / avrispmkIIfreqs[i], (int) i); return stk500v2_setparm(pgm, PARAM_SCK_DURATION, i); } @@ -3466,7 +3404,7 @@ static double stk500v2_sck_to_us(const PROGRAMMER *pgm, unsigned char dur) { x = 1.0 / x; x /= 24.0; x *= (double)PDATA(pgm)->xtal; - return 1E6 / x; + return 1e6 / x; } @@ -3797,13 +3735,13 @@ static double stk500v2_sck_duration_value(const PROGRAMMER *pgm) { switch (PDATA(pgm)->pgmtype) { case PGMTYPE_STK500: - stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration); - return stk500v2_sck_to_us(pgm, sck_duration); + return stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration) < 0? 0: + stk500v2_sck_to_us(pgm, sck_duration); case PGMTYPE_AVRISP_MKII: case PGMTYPE_JTAGICE_MKII: - stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration); - return 1.0e6 / avrispmkIIfreqs[sck_duration]; + return stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration) < 0 || + sck_duration >= NavrispmkIIfreqs? 0: 1e6 / avrispmkIIfreqs[sck_duration]; case PGMTYPE_JTAGICE3: { @@ -3811,14 +3749,13 @@ static double stk500v2_sck_duration_value(const PROGRAMMER *pgm) { cmd[0] = CMD_GET_SCK; if (stk500v2_jtag3_send(pgm, cmd, 1) >= 0 && stk500v2_jtag3_recv(pgm, cmd, 4) >= 2) { unsigned int sck = cmd[1] | (cmd[2] << 8); - return (1E6 / (1000.0 * sck)); + return sck? 1E6 / (1000.0 * sck): 0; } return 0; } case PGMTYPE_STK600: - stk500v2_getparm2(pgm, PARAM2_SCK_DURATION, &sck_stk600); - return (sck_stk600 + 1) / 8.0; + return stk500v2_getparm2(pgm, PARAM2_SCK_DURATION, &sck_stk600) < 0? 0: (sck_stk600 + 1) / 8.0; default: return sck_duration * 8.0e6 / PDATA(pgm)->xtal + 0.05; @@ -3883,9 +3820,8 @@ static double stk500v2_fosc_value(const PROGRAMMER *pgm) { case PGMTYPE_AVRISP_MKII: case PGMTYPE_JTAGICE_MKII: - if (stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration) < 0) - return 0.0; - return 1e6 / avrispmkIIfreqs[sck_duration]; + return stk500v2_getparm(pgm, PARAM_SCK_DURATION, &sck_duration) < 0 || + sck_duration >= NavrispmkIIfreqs? 0: 1e6 / avrispmkIIfreqs[sck_duration]; case PGMTYPE_STK600: if (stk500v2_getparm2(pgm, PARAM2_CLOCK_CONF, &clock_conf) < 0) @@ -3954,7 +3890,7 @@ static void stk500v2_print_parms1(const PROGRAMMER *pgm, const char *p, FILE *fp pgmcp->id = lcreat(NULL, 0); // Copy pgm->id contents over to pgmcp->id for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln)) - ladd(pgmcp->id, cfg_strdup("stk500v2_display()", ldata(ln))); + ladd(pgmcp->id, mmt_strdup(ldata(ln))); jtag3_print_parms1(pgmcp, p, fp); pgm_free(pgmcp); } @@ -4319,19 +4255,14 @@ static int stk600_xprog_command(const PROGRAMMER *pgm, unsigned char *b, else s = cmdsize; - if ((newb = malloc(s + 1)) == 0) { - pmsg_error("out of memory\n"); - return -1; - } - + newb = mmt_malloc(s + 1); newb[0] = CMD_XPROG; memcpy(newb + 1, b, cmdsize); rv = stk500v2_command(pgm, newb, cmdsize + 1, responsesize + 1); - if (rv == 0) { + if (rv == 0) memcpy(b, newb + 1, responsesize); - } - free(newb); + mmt_free(newb); return rv; } @@ -4650,13 +4581,9 @@ static int stk600_xprog_paged_load(const PROGRAMMER *pgm, const AVRPART *p, cons offset = addr; addr += mem->offset; - if ((b = malloc(page_size + 2)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - + b = mmt_malloc(page_size + 2); if (stk500v2_loadaddr(pgm, use_ext_addr) < 0) { - free(b); + mmt_free(b); return -1; } @@ -4674,7 +4601,7 @@ static int stk600_xprog_paged_load(const PROGRAMMER *pgm, const AVRPART *p, cons b[7] = page_size; if (stk600_xprog_command(pgm, b, 8, page_size + 2) < 0) { pmsg_error("XPRG_CMD_READ_MEM failed\n"); - free(b); + mmt_free(b); return -1; } memcpy(mem->buf + offset, b + 2, page_size); @@ -4685,7 +4612,7 @@ static int stk600_xprog_paged_load(const PROGRAMMER *pgm, const AVRPART *p, cons addr += page_size; n_bytes -= page_size; } - free(b); + mmt_free(b); return n_bytes_orig; } @@ -4759,13 +4686,9 @@ static int stk600_xprog_paged_write(const PROGRAMMER *pgm, const AVRPART *p, con offset = addr; addr += mem->offset; - if ((b = malloc(page_size + 9)) == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - + b = mmt_malloc(page_size + 9); if (stk500v2_loadaddr(pgm, use_ext_addr) < 0) { - free(b); + mmt_free(b); return -1; } @@ -4786,7 +4709,7 @@ static int stk600_xprog_paged_write(const PROGRAMMER *pgm, const AVRPART *p, con */ if (page_size % 256 != 0) { pmsg_error("page size not multiple of 256\n"); - free(b); + mmt_free(b); return -1; } unsigned int chunk; @@ -4809,7 +4732,7 @@ static int stk600_xprog_paged_write(const PROGRAMMER *pgm, const AVRPART *p, con memcpy(b + 9, mem->buf + offset, writesize); if (stk600_xprog_command(pgm, b, 256 + 9, 2) < 0) { pmsg_error("XPRG_CMD_WRITE_MEM failed\n"); - free(b); + mmt_free(b); return -1; } if (n_bytes < 256) @@ -4842,7 +4765,7 @@ static int stk600_xprog_paged_write(const PROGRAMMER *pgm, const AVRPART *p, con memcpy(b + 9, mem->buf + offset, writesize); if (stk600_xprog_command(pgm, b, page_size + 9, 2) < 0) { pmsg_error("XPRG_CMD_WRITE_MEM failed\n"); - free(b); + mmt_free(b); return -1; } if (n_bytes < page_size) @@ -4853,7 +4776,7 @@ static int stk600_xprog_paged_write(const PROGRAMMER *pgm, const AVRPART *p, con n_bytes -= page_size; } } - free(b); + mmt_free(b); return n_bytes_orig; } diff --git a/src/strutil.c b/src/strutil.c index e8c8c353..63291a2d 100644 --- a/src/strutil.c +++ b/src/strutil.c @@ -27,6 +27,7 @@ #include #include +#include "avrdude.h" #include "libavrdude.h" // Return 1 if str starts with starts, 0 otherwise @@ -228,7 +229,7 @@ int str_is_pattern(const char *str) { } } -// Return a malloc'd string with the sprintf() result +// Return a mmt_malloc'd string with the sprintf() result char *str_sprintf(const char *fmt, ...) { int size = 0; va_list ap; @@ -239,10 +240,10 @@ char *str_sprintf(const char *fmt, ...) { va_end(ap); if(size < 0) - return cfg_strdup(__func__, ""); + return mmt_strdup(""); size++; // For terminating '\0' - char *p = cfg_malloc(__func__, size); + char *p = mmt_malloc(size); va_start(ap, fmt); size = vsnprintf(p, size, fmt, ap); @@ -255,14 +256,14 @@ char *str_sprintf(const char *fmt, ...) { } -// Reads a potentially long line and returns it in a malloc'd buffer +// Reads a potentially long line and returns it in a mmt_malloc'd buffer char *str_fgets(FILE *fp, const char **errpp) { int bs = 1023; // Must be 2^n - 1 - char *ret = (char *) cfg_malloc(__func__, bs); + char *ret = (char *) mmt_malloc(bs); ret[bs-2] = 0; if(!fgets(ret, bs, fp)) { - free(ret); + mmt_free(ret); if(errpp) *errpp = ferror(fp) && !feof(fp)? "I/O error": NULL; return NULL; @@ -270,18 +271,18 @@ char *str_fgets(FILE *fp, const char **errpp) { while(ret[bs-2] != 0 && ret[bs-2] != '\n' && ret[bs-2] != '\r') { if(bs >= INT_MAX/2) { - free(ret); + mmt_free(ret); if(errpp) *errpp = "cannot cope with lines longer than INT_MAX/2 bytes"; return NULL; } int was = bs; bs = 2*bs+1; - ret = cfg_realloc(__func__, ret, bs); + ret = mmt_realloc(ret, bs); ret[was-1] = ret[bs-2] = 0; if(!fgets(ret+was-1, bs-(was-1), fp)) { // EOF? Error? if(ferror(fp)) { - free(ret); + mmt_free(ret); if(errpp) *errpp = "I/O error"; return NULL; @@ -580,13 +581,13 @@ unsigned long long int str_ull(const char *str, char **endptr, int base) { #define Return(...) do { \ sd->errstr = str_sprintf(__VA_ARGS__); \ sd->type = 0; \ - free(str); \ + mmt_free(str); \ return sd; \ } while (0) #define Warning(...) do { \ if(sd->warnstr) \ - free(sd->warnstr); \ + mmt_free(sd->warnstr); \ sd->warnstr = str_sprintf(__VA_ARGS__); \ } while (0) @@ -597,8 +598,8 @@ unsigned long long int str_ull(const char *str, char **endptr, int base) { Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *memstr) { char *end_ptr; - Str2data *sd = cfg_malloc(__func__, sizeof *sd); - char *str = cfg_strdup(__func__, s); + Str2data *sd = mmt_malloc(sizeof *sd); + char *str = mmt_strdup(s); size_t arglen = strlen(str); // Remove trailing comma to allow cut and paste of lists @@ -731,7 +732,7 @@ Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *m Warning("%s out of int64 range (consider U suffix)", stri); sd->type = STR_INTEGER; - free(str); + mmt_free(str); return sd; } } @@ -741,7 +742,7 @@ Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *m if (end_ptr != str && toupper(*end_ptr) == 'D' && end_ptr[1] == 0) { sd->size = 8; sd->type = STR_DOUBLE; - free(str); + mmt_free(str); return sd; } } @@ -756,16 +757,14 @@ Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *m sd->size = 4; if(sd->size) { sd->type = STR_FLOAT; - free(str); + mmt_free(str); return sd; } } if(type & STR_STRING && arglen > 1) { // Try C-style string or single character if((*str == '\'' && str[arglen-1] == '\'') || (*str == '\"' && str[arglen-1] == '\"')) { - char *s = calloc(arglen-1, 1); - if (s == NULL) - Return("out of memory"); + char *s = mmt_malloc(arglen-1); // Strip start and end quotes, and unescape C string strncpy(s, str+1, arglen-2); @@ -777,12 +776,12 @@ Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *m memset(sd->a+1, 0, 7); sd->sigsz = sd->size = 1; sd->type = STR_INTEGER; - free(s); + mmt_free(s); } else { // C-style string sd->str_ptr = s; sd->type = STR_STRING; } - free(str); + mmt_free(str); return sd; } } @@ -825,7 +824,7 @@ Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *m sd->size = rc; avr_free_part(dp); sd->type = STR_FILE; - free(str); + mmt_free(str); return sd; } @@ -836,12 +835,12 @@ Str2data *str_todata(const char *s, int type, const AVRPART *part, const char *m void str_freedata(Str2data *sd) { if(sd) { if(sd->warnstr) - free(sd->warnstr); + mmt_free(sd->warnstr); if(sd->errstr) - free(sd->errstr); + mmt_free(sd->errstr); if(sd->mem) avr_free_mem(sd->mem); - free(sd); + mmt_free(sd); } } @@ -909,11 +908,11 @@ unsigned long long int str_int(const char *str, int type, const char **errpp) { if(sd->warnstr && strstr(sd->warnstr, " out of ")) { // Convert out of range warning into error char *p = strstr(sd->warnstr, "out of "); if(p) { - p = cfg_strdup(__func__, p); + p = mmt_strdup(p); if(strchr(p, ',')) *strchr(p, ',') = 0; err = cache_string(p); - free(p); + mmt_free(p); } else { err = "out of range"; } @@ -929,19 +928,19 @@ unsigned long long int str_int(const char *str, int type, const char **errpp) { if(signd == STR_SIGNED) { // Strictly signed if(sd->ll < smin[lds] || sd->ll > smax[lds]) { err = cache_string(tofree=str_sprintf("out of int%d range", 1<<(3+lds))); - free(tofree); + mmt_free(tofree); goto finished; } } else if(signd == STR_UNSIGNED) { // Strictly unsigned are out of range if u and -u are if(sd->ull > umax[lds] && ~sd->ull+1 > umax[lds]) { err = cache_string(tofree=str_sprintf("out of uint%d range", 1<<(3+lds))); - free(tofree); + mmt_free(tofree); goto finished; } } else { // Neither strictly signed or unsigned if((sd->ll < smin[lds] || sd->ll > smax[lds]) && sd->ull > umax[lds] && ~sd->ull+1 > umax[lds]) { err = cache_string(tofree=str_sprintf("out of int%d and uint%d range", 1<<(3+lds), 1<<(3+lds))); - free(tofree); + mmt_free(tofree); goto finished; } } @@ -1037,6 +1036,16 @@ char *str_nexttok(char *buf, const char *delim, char **next) { return (char *) q; } +// Return mmt_malloc'd string for frequency with n significant digits and xHz unit +char *str_frq(double f, int n) { + struct { double fq; const char *pre; } prefix[] = {{1e9, "G"}, {1e6, "M"}, {1e3, "k"},}; + + for(size_t i = 0; i < sizeof prefix/sizeof*prefix; i++) + if(f >= prefix[i].fq) + return str_sprintf("%.*g %sHz", n, f/prefix[i].fq, prefix[i].pre); + return str_sprintf("%.*g Hz", n, f); +} + /* * From https://github.com/git/git/blob/master/levenshtein.c * @@ -1081,9 +1090,9 @@ int str_levenshtein(const char *str1, const char *str2, int swap, int subst, int add, int del) { int i, j, len1 = strlen(str1), len2 = strlen(str2); - int *row0 = cfg_malloc(__func__, (len2+1)*sizeof*row0); - int *row1 = cfg_malloc(__func__, (len2+1)*sizeof*row1); - int *row2 = cfg_malloc(__func__, (len2+1)*sizeof*row2); + int *row0 = mmt_malloc((len2+1)*sizeof*row0); + int *row1 = mmt_malloc((len2+1)*sizeof*row1); + int *row2 = mmt_malloc((len2+1)*sizeof*row2); for (j = 0; j <= len2; j++) row1[j] = j * add; @@ -1109,9 +1118,9 @@ int str_levenshtein(const char *str1, const char *str2, row2 = temp; } i = row1[len2]; - free(row0); - free(row1); - free(row2); + mmt_free(row0); + mmt_free(row1); + mmt_free(row2); return i; } @@ -1185,9 +1194,9 @@ size_t str_weighted_damerau_levenshtein(const char *s1, const char *s2) { const size_t swap = 3; // Transposing neighbouring letters is an easy mistake to make const size_t subst = 32, add = 32, del = 32; // Must be multiples of 8 size_t i, j, len1 = strlen(s1), len2 = strlen(s2); - size_t *row0 = cfg_malloc(__func__, (len2+1)*sizeof*row0); - size_t *row1 = cfg_malloc(__func__, (len2+1)*sizeof*row1); - size_t *row2 = cfg_malloc(__func__, (len2+1)*sizeof*row2); + size_t *row0 = mmt_malloc((len2+1)*sizeof*row0); + size_t *row1 = mmt_malloc((len2+1)*sizeof*row1); + size_t *row2 = mmt_malloc((len2+1)*sizeof*row2); unsigned char *str1 = (unsigned char *) s1, *str2 = (unsigned char *) s2; for(j = 0; j < len2; j++) @@ -1218,8 +1227,8 @@ size_t str_weighted_damerau_levenshtein(const char *s1, const char *s2) { row2 = temp; } i = row1[len2]; // Last row2[len2] - free(row0); - free(row1); - free(row2); + mmt_free(row0); + mmt_free(row1); + mmt_free(row2); return i; } diff --git a/src/teensy.c b/src/teensy.c index 7da47366..11a2b9f1 100644 --- a/src/teensy.c +++ b/src/teensy.c @@ -177,12 +177,7 @@ static int teensy_write_page(pdata_t* pdata, uint32_t address, const uint8_t* bu } size_t report_size = 1 + 2 + (size_t)pdata->page_size; - uint8_t* report = (uint8_t*)malloc(report_size); - if (report == NULL) - { - pmsg_error("unable to allocate memory\n"); - return -1; - } + uint8_t *report = (uint8_t *) mmt_malloc(report_size); report[0] = 0; // report number if (pdata->page_size <= 256 && pdata->flash_size < 0x10000) @@ -204,7 +199,7 @@ static int teensy_write_page(pdata_t* pdata, uint32_t address, const uint8_t* bu memset(report + 1 + 2 + size, 0xFF, report_size - (1 + 2 + size)); int result = hid_write(pdata->hid_handle, report, report_size); - free(report); + mmt_free(report); if (result < 0) { if (!suppress_warning) @@ -234,23 +229,15 @@ static int teensy_reboot(pdata_t* pdata) //----------------------------------------------------------------------------- -static void teensy_setup(PROGRAMMER* pgm) -{ +static void teensy_setup(PROGRAMMER *pgm) { pmsg_debug("teensy_setup()\n"); - - if ((pgm->cookie = malloc(sizeof(pdata_t))) == NULL) - { - pmsg_error("unable to allocate memory\n"); - exit(1); - } - - memset(pgm->cookie, 0, sizeof(pdata_t)); + pgm->cookie = mmt_malloc(sizeof(pdata_t)); } -static void teensy_teardown(PROGRAMMER* pgm) -{ +static void teensy_teardown(PROGRAMMER *pgm) { pmsg_debug("teensy_teardown()\n"); - free(pgm->cookie); + mmt_free(pgm->cookie); + pgm->cookie = NULL; } static int teensy_initialize(const PROGRAMMER *pgm, const AVRPART *p) { @@ -571,7 +558,7 @@ static int teensy_parseextparams(const PROGRAMMER *pgm, const LISTID xparams) { msg_error(" -xwait Wait for the device to be plugged in if not connected\n"); msg_error(" -xwait= Wait [s] for the device to be plugged in if not connected\n"); msg_error(" -xhelp Show this help menu and exit\n"); - exit(0); + return LIBAVRDUDE_EXIT;; } else { diff --git a/src/term.c b/src/term.c index ea10ada6..4ee0bc73 100644 --- a/src/term.c +++ b/src/term.c @@ -323,12 +323,7 @@ static int cmd_dump(const PROGRAMMER *pgm, const AVRPART *p, int argc, const cha if (read_mem[i].len > maxsize) read_mem[i].len = maxsize; - uint8_t *buf = malloc(read_mem[i].len); - if (buf == NULL) { - pmsg_error("(%s) out of memory\n", cmd); - return -1; - } - + uint8_t *buf = mmt_malloc(read_mem[i].len); if(argc < 4 && verbose) term_out(">>> %s %s 0x%x 0x%x\n", cmd, read_mem[i].mem->desc, read_mem[i].addr, read_mem[i].len); @@ -341,7 +336,7 @@ static int cmd_dump(const PROGRAMMER *pgm, const AVRPART *p, int argc, const cha pmsg_error("(%s) error reading %s address 0x%05lx of part %s\n", cmd, mem->desc, (long) read_mem[i].addr + j, p->desc); if (rc == -1) imsg_error("%*sread operation not supported on memory %s\n", 7, "", mem->desc); - free(buf); + mmt_free(buf); return -1; } report_progress(j, read_mem[i].len, NULL); @@ -351,7 +346,7 @@ static int cmd_dump(const PROGRAMMER *pgm, const AVRPART *p, int argc, const cha hexdump_buf(stdout, mem, read_mem[i].addr, buf, read_mem[i].len); lterm_out(""); - free(buf); + mmt_free(buf); read_mem[i].addr = (read_mem[i].addr + read_mem[i].len) % maxsize; @@ -478,12 +473,7 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch pmsg_error("(write) too large memory request (%lu)\n", (unsigned long) bufsz); return -1; } - unsigned char *buf = calloc(bufsz, 1), *tags = calloc(bufsz, 1); - if(buf == NULL || tags == NULL) { - pmsg_error("(write) out of memory\n"); - return -1; - } - + unsigned char *buf = mmt_malloc(bufsz), *tags = mmt_malloc(bufsz); // Find the first argument to write to flash and how many arguments to parse and write if(str_eq(argv[argc - 1], "...")) { write_mode = WRITE_MODE_FILL; @@ -491,7 +481,7 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch len = str_int(argv[3], STR_INT32, &errptr); if(errptr) { pmsg_error("(write ...) length %s: %s\n", argv[3], errptr); - free(buf); free(tags); + mmt_free(buf); mmt_free(tags); return -1; } @@ -526,7 +516,7 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch sd = str_todata(argv[i], STR_ANY, p, mem->desc); if(!sd->type || sd->errstr) { pmsg_error("(write) data %s: %s\n", argv[i], sd->errstr? sd->errstr: "str_todata"); - free(buf); free(tags); + mmt_free(buf); mmt_free(tags); str_freedata(sd); return -1; } @@ -628,7 +618,7 @@ static int cmd_write(const PROGRAMMER *pgm, const AVRPART *p, int argc, const ch } report_progress(1, 1, NULL); - free(buf); + mmt_free(buf); return 0; } @@ -671,11 +661,11 @@ static int cmd_save(const PROGRAMMER *pgm, const AVRPART *p, int argc, const cha } len -= 2; } - char *filename = memcpy(cfg_malloc(__func__, len+1), fn, len); + char *filename = memcpy(mmt_malloc(len+1), fn, len); mem = avr_dup_mem(omem); int n = argc > 3? (argc-3)/2: 1; - Segment_t *seglist = cfg_malloc(__func__, n*sizeof*seglist); + Segment_t *seglist = mmt_malloc(n*sizeof*seglist); int ret = -1; @@ -734,8 +724,8 @@ static int cmd_save(const PROGRAMMER *pgm, const AVRPART *p, int argc, const cha done: avr_free_mem(mem); - free(seglist); - free(filename); + mmt_free(seglist); + mmt_free(filename); return ret < 0? ret: 0; } @@ -983,7 +973,7 @@ static int getfusel(const PROGRAMMER *pgm, const AVRPART *p, Fusel_t *fl, const (!islock && (cci->t->memoffset < 0 || cci->t->memoffset >= (int) (sizeof fl->fuses/sizeof*fl->fuses)))) { err = cache_string(tofree = str_sprintf("%s's %s has invalid memoffset %d", p->desc, cci->memstr, cci->t->memoffset)); - free(tofree); + mmt_free(tofree); goto back; } @@ -1002,13 +992,13 @@ static int getfusel(const PROGRAMMER *pgm, const AVRPART *p, Fusel_t *fl, const const AVRMEM *mem = avr_locate_mem(p, cci->memstr); if(!mem) { err = cache_string(tofree = str_sprintf("memory %s not defined for part %s", cci->memstr, p->desc)); - free(tofree); + mmt_free(tofree); goto back; } if((islock && mem->size != 4 && mem->size != 1) || (!islock && mem->size != 2 && mem->size != 1)) { err = cache_string(tofree = str_sprintf("%s's %s memory has unexpected size %d", p->desc, mem->desc, mem->size)); - free(tofree); + mmt_free(tofree); goto back; } @@ -1016,7 +1006,7 @@ static int getfusel(const PROGRAMMER *pgm, const AVRPART *p, Fusel_t *fl, const for(int i=0; isize; i++) if(led_read_byte(pgm, p, mem, i, m.b+i) < 0) { err = cache_string(tofree = str_sprintf("cannot read %s's %s memory", p->desc, mem->desc)); - free(tofree); + mmt_free(tofree); goto back; } @@ -1357,8 +1347,8 @@ static int cmd_config(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c } int ret = 0; - cc = cfg_malloc(__func__, sizeof *cc*nc); - fc = cfg_malloc(__func__, sizeof *fc*nc); + cc = mmt_malloc(sizeof *cc*nc); + fc = mmt_malloc(sizeof *fc*nc); AVRMEM *m = avr_locate_lock(p); const char *locktype = m? m->desc: "lock"; @@ -1555,8 +1545,8 @@ static int cmd_config(const PROGRAMMER *pgm, const AVRPART *p, int argc, const c cmd_config(pgm, p, 2, av); finished: - free(cc); - free(fc); + mmt_free(cc); + mmt_free(fc); return ret; } @@ -1750,11 +1740,11 @@ static int cmd_regfile(const PROGRAMMER *pgm, const AVRPART *p, int argc, const return -1; } - char *reg = cfg_strdup(__func__, argc > 1? argv[1]: ""), *rhs = strrchr(reg, '='); + char *reg = mmt_strdup(argc > 1? argv[1]: ""), *rhs = strrchr(reg, '='); if(rhs) // Right-hand side of assignment *rhs++ = 0; // Terminate lhs - // Create malloc'd NULL-terminated list of register pointers + // Create mmt_malloc'd NULL-terminated list of register pointers const Register_file_t *r, **rl, **rlist; rlist = avr_locate_registerlist(rf, nr, reg, str_is_pattern(reg)? str_matched_by: str_contains); @@ -1842,13 +1832,13 @@ static int cmd_regfile(const PROGRAMMER *pgm, const AVRPART *p, int argc, const } success: - free(reg); - free(rlist); + mmt_free(reg); + mmt_free(rlist); return 0; error: - free(reg); - free(rlist); + mmt_free(reg); + mmt_free(rlist); return -1; } @@ -2317,8 +2307,8 @@ static char *tokenize(char *s, int *argcp, const char ***argvp) { if(slen > 2*((INT_MAX - 2*sizeof(char *))/(sizeof(char *)+3))) return NULL; - // Allocate once for pointers and contents, so caller only needs to free(argv) - argv = cfg_malloc(__func__, (nargs+2)*sizeof(char *) + slen + nargs); + // Allocate once for pointers and contents, so caller only needs to mmt_free(argv) + argv = mmt_malloc((nargs+2)*sizeof(char *) + slen + nargs); buf = (char *) (argv+nargs+1); for(n=0, r=s; *r; ) { @@ -2390,7 +2380,7 @@ char *terminal_get_input(const char *prompt) { int len = strlen(input); if(len > 0 && input[len-1] == '\n') input[len-1] = 0; - return cfg_strdup(__func__, input); + return mmt_strdup(input); } return NULL; @@ -2436,7 +2426,7 @@ static int process_line(char *q, const PROGRAMMER *pgm, const AVRPART *p) { imsg_info("allow_subshells = yes; into ~/.config/avrdude/avrdude.rc or ~/.avrduderc\n"); #endif } - free(argv); + mmt_free(argv); return 0; } @@ -2450,7 +2440,7 @@ static int process_line(char *q, const PROGRAMMER *pgm, const AVRPART *p) { led_set(pgm, LED_ERR); led_clr(pgm, LED_PGM); - free(argv); + mmt_free(argv); } while(*q); return rc; @@ -2466,9 +2456,9 @@ static int process_line(char *q, const PROGRAMMER *pgm, const AVRPART *p) { */ int terminal_line(const PROGRAMMER *pgm, const AVRPART *p, const char *line) { - char *ln = cfg_strdup(__func__, line); + char *ln = mmt_strdup(line); int ret = process_line(ln, pgm, p); - free(ln); + mmt_free(ln); return ret; } @@ -2535,7 +2525,7 @@ static void term_gotline(char *cmdstr) { if(process_line(cmdstr, term_pgm, term_p) > 0) term_running = 0; } - free(cmdstr); + mmt_free(cmdstr); /* * This is a workaround for a bug apparently present in the * readline compat layer of libedit which is natively present in @@ -2588,7 +2578,7 @@ int terminal_mode_noninteractive(const PROGRAMMER *pgm, const AVRPART *p) { while((cmdbuf = terminal_get_input("avrdude> "))) { int rc = process_line(cmdbuf, pgm, p); - free(cmdbuf); + mmt_free(cmdbuf); if(rc > 0) break; } @@ -2658,7 +2648,7 @@ static int cmd_include(const PROGRAMMER *pgm, const AVRPART *p, int argc, const return -1; } - for(char *buffer; (buffer = str_fgets(fp, &errstr)); free(buffer)) { + for(char *buffer; (buffer = str_fgets(fp, &errstr)); mmt_free(buffer)) { lineno++; if(echo) { term_out("# "); @@ -2710,15 +2700,15 @@ static void update_progress_tty(int percent, double etime, const char *hdr, int lmsg_info(""); // Print new line unless already done before last = done = 0; // OK, we have a header, start reporting if(header) - free(header); - header = cfg_strdup(__func__, hdr); + mmt_free(header); + header = mmt_strdup(hdr); } percent = percent > 100? 100: percent < 0? 0: percent; if(!done) { if(!header) - header = cfg_strdup(__func__, "report"); + header = mmt_strdup("report"); int showperc = finish >= 0? percent: last; diff --git a/src/update.c b/src/update.c index 7618ae79..c99663ce 100644 --- a/src/update.c +++ b/src/update.c @@ -45,7 +45,7 @@ */ UPDATE *parse_op(const char *s) { // Assume -U [:] first - UPDATE *upd = (UPDATE *) cfg_malloc(__func__, sizeof *upd); + UPDATE *upd = (UPDATE *) mmt_malloc(sizeof *upd); upd->memstr = NULL; // Defaults to flash or application upd->op = DEVICE_WRITE; const char *fn = s; @@ -56,12 +56,12 @@ UPDATE *parse_op(const char *s) { if(!strchr("rwv", fc[1])) { pmsg_error("invalid I/O mode :%c: in -U %s\n", fc[1], s); imsg_error("I/O mode can be r, w or v for read, write or verify device\n"); - free(upd->memstr); - free(upd); + mmt_free(upd->memstr); + mmt_free(upd); return NULL; } - upd->memstr = memcpy(cfg_malloc(__func__, fc-s+1), s, fc-s); + upd->memstr = memcpy(mmt_malloc(fc-s+1), s, fc-s); upd->op = fc[1]=='r'? DEVICE_READ: fc[1]=='w'? DEVICE_WRITE: DEVICE_VERIFY; @@ -83,32 +83,32 @@ UPDATE *parse_op(const char *s) { if(f != FMT_ERROR) imsg_error(" :%c %s\n", c, fileio_fmtstr(f)); } - free(upd->memstr); - free(upd); + mmt_free(upd->memstr); + mmt_free(upd); return NULL; } len -= 2; } - upd->filename = memcpy(cfg_malloc(__func__, len+1), fn, len); + upd->filename = memcpy(mmt_malloc(len+1), fn, len); return upd; } UPDATE *dup_update(const UPDATE *upd) { - UPDATE *u = (UPDATE *) cfg_malloc(__func__, sizeof *u); + UPDATE *u = (UPDATE *) mmt_malloc(sizeof *u); memcpy(u, upd, sizeof*u); - u->memstr = upd->memstr? cfg_strdup(__func__, upd->memstr): NULL; - u->filename = cfg_strdup(__func__, upd->filename); + u->memstr = upd->memstr? mmt_strdup(upd->memstr): NULL; + u->filename = mmt_strdup(upd->filename); return u; } UPDATE *new_update(int op, const char *memstr, int filefmt, const char *fname) { - UPDATE *u = (UPDATE *) cfg_malloc(__func__, sizeof *u); - u->memstr = cfg_strdup(__func__, memstr); - u->filename = cfg_strdup(__func__, fname); + UPDATE *u = (UPDATE *) mmt_malloc(sizeof *u); + u->memstr = mmt_strdup(memstr); + u->filename = mmt_strdup(fname); u->op = op; u->format = filefmt; @@ -116,7 +116,7 @@ UPDATE *new_update(int op, const char *memstr, int filefmt, const char *fname) { } UPDATE *cmd_update(const char *cmd) { - UPDATE *u = (UPDATE *) cfg_malloc(__func__, sizeof *u); + UPDATE *u = (UPDATE *) mmt_malloc(sizeof *u); u->cmdline = cmd; return u; @@ -124,10 +124,10 @@ UPDATE *cmd_update(const char *cmd) { void free_update(UPDATE *u) { if(u) { - free(u->memstr); - free(u->filename); + mmt_free(u->memstr); + mmt_free(u->filename); memset(u, 0, sizeof *u); - free(u); + mmt_free(u); } } @@ -273,7 +273,7 @@ int update_dryrun(const AVRPART *p, UPDATE *upd) { int known, format_detect, ret = LIBAVRDUDE_SUCCESS; if(upd->cmdline) { // Todo: parse terminal command line? - termcmds = realloc(termcmds, sizeof(*termcmds) * (nterms+1)); + termcmds = mmt_realloc(termcmds, sizeof(*termcmds) * (nterms+1)); termcmds[nterms++] = upd->cmdline; return 0; } @@ -342,7 +342,7 @@ int update_dryrun(const AVRPART *p, UPDATE *upd) { ioerror("writeable", upd); ret = LIBAVRDUDE_SOFTFAIL; } else if(upd->filename) { // Record filename (other than stdout) is available for future reads - if(!str_eq(upd->filename, "-") && (wrote = realloc(wrote, sizeof(*wrote) * (nfwritten+1)))) + if(!str_eq(upd->filename, "-") && (wrote = mmt_realloc(wrote, sizeof(*wrote) * (nfwritten+1)))) wrote[nfwritten++] = upd->filename; } } @@ -371,7 +371,7 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, enum updat lmsg_info("\n"); // Ensure an empty line for visual separation of operations pmsg_info("processing %s\n", tofree = update_str(upd)); - free(tofree); + mmt_free(tofree); if(upd->cmdline) { if(!str_eq(upd->cmdline, "interactive terminal")) @@ -388,7 +388,7 @@ int do_op(const PROGRAMMER *pgm, const AVRPART *p, const UPDATE *upd, enum updat } AVRMEM_ALIAS *alias_mem = avr_find_memalias(p, mem); - char *alias_mem_desc = cfg_malloc("do_op()", 2 + (alias_mem && alias_mem->desc? strlen(alias_mem->desc): 0)); + char *alias_mem_desc = mmt_malloc(2 + (alias_mem && alias_mem->desc? strlen(alias_mem->desc): 0)); if(alias_mem && alias_mem->desc && *alias_mem->desc) { *alias_mem_desc = '/'; strcpy(alias_mem_desc+1, alias_mem->desc); diff --git a/src/updi_link.c b/src/updi_link.c index acdcb235..4bd82f51 100644 --- a/src/updi_link.c +++ b/src/updi_link.c @@ -579,12 +579,7 @@ int updi_link_st_ptr_inc16_RSD(const PROGRAMMER *pgm, unsigned char *buffer, uin unsigned int temp_buffer_size = 3 + 3 + 2 + (words * 2) + 3; unsigned int num=0; - unsigned char* temp_buffer = malloc(temp_buffer_size); - - if (temp_buffer == 0) { - pmsg_debug("allocating temporary buffer failed\n"); - return -1; - } + unsigned char* temp_buffer = mmt_malloc(temp_buffer_size); if (blocksize == -1) { blocksize = temp_buffer_size; @@ -608,7 +603,7 @@ int updi_link_st_ptr_inc16_RSD(const PROGRAMMER *pgm, unsigned char *buffer, uin if (blocksize < 10) { if (updi_physical_send(pgm, temp_buffer, 6) < 0) { pmsg_debug("unable to send first package\n"); - free(temp_buffer); + mmt_free(temp_buffer); return -1; } num = 6; @@ -625,13 +620,13 @@ int updi_link_st_ptr_inc16_RSD(const PROGRAMMER *pgm, unsigned char *buffer, uin if (updi_physical_send(pgm, temp_buffer + num, next_package_size) < 0) { pmsg_debug("unable to send package\n"); - free(temp_buffer); + mmt_free(temp_buffer); return -1; } num+=next_package_size; } - free(temp_buffer); + mmt_free(temp_buffer); return 0; } diff --git a/src/urclock.c b/src/urclock.c index 1787ff80..fc0fbe53 100644 --- a/src/urclock.c +++ b/src/urclock.c @@ -1566,7 +1566,7 @@ vblvecfound: uint64_t urclockID; if((rc = readUrclockID(pgm, p, &urclockID)) == -1) return rc; - term_out("%0*lx", 2*ur.idlen, urclockID), first=0; + term_out("%0*llx", 2*ur.idlen, (unsigned long long) urclockID), first=0; } if(havemetadata) { if(ur.showdate || ur.showall) { @@ -1608,7 +1608,7 @@ vblvecfound: term_out(&" %s"[first], ur.uP.name); if(!first) { term_out("\n"); - exit(0); + return LIBAVRDUDE_EXIT;; } alldone: @@ -1803,38 +1803,38 @@ static int ur_readEF(const PROGRAMMER *pgm, const AVRPART *p, uint8_t *buf, uint static int parseUrclockID(const PROGRAMMER *pgm) { if(*ur.iddesc) { // User override of ID, eg, -xid=F.-4.2 for penultimate flash word - char *idstr = cfg_strdup(__func__, ur.iddesc), *idlenp; + char *idstr = mmt_strdup(ur.iddesc), *idlenp; const char *errstr; int ad, lg; if(!(strchr("EF", *idstr) && idstr[1] == '.')) { pmsg_warning("-xid=%s string must start with E. or F.\n", ur.iddesc); - free(idstr); + mmt_free(idstr); return -1; } if(!(idlenp = strchr(idstr+2, '.'))) { pmsg_warning("-xid=%s string must look like [E|F]..\n", ur.iddesc); - free(idstr); + mmt_free(idstr); return -1; } *idlenp++ = 0; ad = str_int(idstr+2, STR_INT32, &errstr); if(errstr) { pmsg_warning("address %s of -xid=%s: %s\n", idstr+2, ur.iddesc, errstr); - free(idstr); + mmt_free(idstr); return -1; } lg = str_int(idlenp, STR_INT32, &errstr); if(errstr) { pmsg_warning("length %s of -xid=%s string: %s\n", idlenp, ur.iddesc, errstr); - free(idstr); + mmt_free(idstr); return -1; } if(!lg || lg > 8) { pmsg_warning("length %s of -xid=%s string must be between 1 and 8\n", idlenp, ur.iddesc); - free(idstr); + mmt_free(idstr); return -1; } @@ -1842,7 +1842,7 @@ static int parseUrclockID(const PROGRAMMER *pgm) { ur.idaddr = ad; ur.idlen = lg; - free(idstr); + mmt_free(idstr); } return 0; @@ -2155,14 +2155,14 @@ static int urclock_chip_erase(const PROGRAMMER *pgm, const AVRPART *p) { AVRMEM *flm = avr_locate_flash(p); int vecsz = ur.uP.flashsize <= 8192? 2: 4; if(flm && flm->page_size >= vecsz) { - unsigned char *page = cfg_malloc(__func__, flm->page_size); + unsigned char *page = mmt_malloc(flm->page_size); memset(page, 0xff, flm->page_size); set_reset(pgm, page, vecsz); if(avr_write_page_default(pgm, p, flm, 0, page) < 0) { - free(page); + mmt_free(page); return -1; } - free(page); + mmt_free(page); } } } @@ -2527,7 +2527,7 @@ static int urclock_parseextparms(const PROGRAMMER *pgm, LISTID extparms) { urmax(0, 16-(int) strlen(options[i].name)-(options[i].assign? 6: 0)), "", options[i].help); } if(rc == 0) - exit(0); + return LIBAVRDUDE_EXIT;; } if(parseUrclockID(pgm) < 0) @@ -2539,7 +2539,7 @@ static int urclock_parseextparms(const PROGRAMMER *pgm, LISTID extparms) { static void urclock_setup(PROGRAMMER *pgm) { // Allocate ur - pgm->cookie = cfg_malloc(__func__, sizeof(Urclock_t)); + pgm->cookie = mmt_malloc(sizeof(Urclock_t)); ur.xvectornum = -1; // Initialise, to ascertain whether user had set to 0 ur.ext_addr_byte = 0xff; // So first memory address will load extended address @@ -2549,7 +2549,7 @@ static void urclock_setup(PROGRAMMER *pgm) { static void urclock_teardown(PROGRAMMER *pgm) { - free(pgm->cookie); + mmt_free(pgm->cookie); pgm->cookie = NULL; } diff --git a/src/usb_hidapi.c b/src/usb_hidapi.c index 78afbf94..07732ff3 100644 --- a/src/usb_hidapi.c +++ b/src/usb_hidapi.c @@ -134,11 +134,11 @@ static int usbhid_open(const char *port, union pinfo pinfo, union filedescriptor if (hid_get_serial_number_string(dev, sn, sizeof(sn)/sizeof(*sn)) == 0) { size_t n = wcstombs(NULL, sn, 0) + 1; if (n) { - char *cn = cfg_malloc(__func__, n); + char *cn = mmt_malloc(n); if (wcstombs(cn, sn, n) != (size_t) -1) if(serdev) serdev->usbsn = cache_string(cn); - free(cn); + mmt_free(cn); } } diff --git a/src/usbasp.c b/src/usbasp.c index 80db2650..22a54bf2 100644 --- a/src/usbasp.c +++ b/src/usbasp.c @@ -65,13 +65,33 @@ #include +// Private data for this programmer +struct pdata { +#ifdef USE_LIBUSB_1_0 + libusb_device_handle *usbhandle; +#else + usb_dev_handle *usbhandle; +#endif + int sckfreq_hz; + unsigned int capabilities; + int use_tpi; + int section_e; + int sck_3mhz; + +#ifdef USE_LIBUSB_1_0 + libusb_context *ctx; + char msg[30]; // Used in errstr() +#endif + int USB_init; // Used in both usbOpenDevice() variants +}; + +#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) + #ifdef USE_LIBUSB_1_0 -static libusb_context *ctx = NULL; - -static const char *errstr(int result) -{ - static char msg[30]; +static const char *errstr(const PROGRAMMER *pgm, int result) { + char *msg = PDATA(pgm)->msg; + size_t msgsiz = sizeof(PDATA(pgm)->msg); int n = 0; switch (result) { @@ -122,7 +142,7 @@ static const char *errstr(int result) n = ENOSYS; break; default: - snprintf(msg, sizeof msg, "Unknown libusb error code %d", result); + snprintf(msg, msgsiz, "Unknown libusb error code %d", result); return msg; } return strerror(n); @@ -131,41 +151,21 @@ static const char *errstr(int result) #endif -/* - * Private data for this programmer. - */ -struct pdata -{ -#ifdef USE_LIBUSB_1_0 - libusb_device_handle *usbhandle; -#else - usb_dev_handle *usbhandle; -#endif - int sckfreq_hz; - unsigned int capabilities; - int use_tpi; - int section_e; - int sck_3mhz; -}; - -#define PDATA(pgm) ((struct pdata *)(pgm->cookie)) -#define IMPORT_PDATA(pgm) struct pdata *pdata = PDATA(pgm) - - - /* Prototypes */ // interface - management -static void usbasp_setup(PROGRAMMER * pgm); -static void usbasp_teardown(PROGRAMMER * pgm); +static void usbasp_setup(PROGRAMMER *pgm); +static void usbasp_teardown(PROGRAMMER *pgm); static int usbasp_parseextparms(const PROGRAMMER *pgm, const LISTID extparms); // internal functions static int usbasp_transmit(const PROGRAMMER *pgm, unsigned char receive, unsigned char functionid, const unsigned char *send, unsigned char *buffer, int buffersize); #ifdef USE_LIBUSB_1_0 -static int usbOpenDevice(libusb_device_handle **device, int vendor, const char *vendorName, int product, const char *productName, const char *port); +static int usbOpenDevice(const PROGRAMMER *pgm, libusb_device_handle **device, int vendor, + const char *vendorName, int product, const char *productName, const char *port); #else -static int usbOpenDevice(usb_dev_handle **device, int vendor, const char *vendorName, int product, const char *productName, const char *port); +static int usbOpenDevice(const PROGRAMMER *pgm, usb_dev_handle **device, int vendor, + const char *vendorName, int product, const char *productName, const char *port); #endif // interface - prog. static int usbasp_open(PROGRAMMER *pgm, const char *port); @@ -272,18 +272,13 @@ static int usbasp_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRM /* Interface - management */ -static void usbasp_setup(PROGRAMMER * pgm) -{ - if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) { - pmsg_error(" out of memory allocating private data\n"); - exit(1); - } - memset(pgm->cookie, 0, sizeof(struct pdata)); +static void usbasp_setup(PROGRAMMER *pgm) { + pgm->cookie = mmt_malloc(sizeof(struct pdata)); } -static void usbasp_teardown(PROGRAMMER * pgm) -{ - free(pgm->cookie); +static void usbasp_teardown(PROGRAMMER *pgm) { + mmt_free(pgm->cookie); + pgm->cookie = NULL; } static int usbasp_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { @@ -303,7 +298,7 @@ static int usbasp_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -xsection_config Erase configuration section only with -e (TPI only)\n"); msg_error(" -xhelp Show this help menu and exit\n"); - exit(0); + return LIBAVRDUDE_EXIT;; } pmsg_error("invalid extended parameter '%s'\n", extended_param); @@ -372,7 +367,7 @@ static int usbasp_transmit(const PROGRAMMER *pgm, buffersize & 0xffff, 5000); if(nbytes < 0){ - pmsg_ext_error("%s\n", errstr(nbytes)); + pmsg_ext_error("%s\n", errstr(pgm, nbytes)); return -1; } #else @@ -428,22 +423,21 @@ static int check_for_port_argument_match(const char *port, char *bus, char *devi * shared VID/PID */ #ifdef USE_LIBUSB_1_0 -static int usbOpenDevice(libusb_device_handle **device, int vendor, const char *vendorName, - int product, const char *productName, const char *port) -{ +static int usbOpenDevice(const PROGRAMMER *pgm, libusb_device_handle **device, int vendor, + const char *vendorName, int product, const char *productName, const char *port) { + libusb_device_handle *handle = NULL; int errorCode = USB_ERROR_NOTFOUND; - static int didUsbInit = 0; int j; int r; - if(!didUsbInit){ - didUsbInit = 1; - libusb_init(&ctx); + if(!PDATA(pgm)->USB_init){ + PDATA(pgm)->USB_init = 1; + libusb_init(&PDATA(pgm)->ctx); } libusb_device **dev_list; - int dev_list_len = libusb_get_device_list(ctx, &dev_list); + int dev_list_len = libusb_get_device_list(PDATA(pgm)->ctx, &dev_list); for (j=0; j%s<\n", string); @@ -477,7 +471,7 @@ static int usbOpenDevice(libusb_device_handle **device, int vendor, const char * if (r < 0) { if ((productName != NULL) && (productName[0] != 0)) { errorCode = USB_ERROR_IO; - pmsg_warning("cannot query product for device: %s\n", errstr(r)); + pmsg_warning("cannot query product for device: %s\n", errstr(pgm, r)); } } else { pmsg_notice2("seen product >%s<\n", string); @@ -510,17 +504,16 @@ static int usbOpenDevice(libusb_device_handle **device, int vendor, const char * return errorCode; } #else -static int usbOpenDevice(usb_dev_handle **device, int vendor, const char *vendorName, - int product, const char *productName, const char *port) -{ -struct usb_bus *bus; -struct usb_device *dev; -usb_dev_handle *handle = NULL; -int errorCode = USB_ERROR_NOTFOUND; -static int didUsbInit = 0; +static int usbOpenDevice(const PROGRAMMER *pgm, usb_dev_handle **device, int vendor, + const char *vendorName, int product, const char *productName, const char *port) { - if(!didUsbInit){ - didUsbInit = 1; + struct usb_bus * bus; + struct usb_device * dev; + usb_dev_handle * handle = NULL; + int errorCode = USB_ERROR_NOTFOUND; + + if(!PDATA(pgm)->USB_init) { + PDATA(pgm)->USB_init = 1; usb_init(); } usb_find_busses(); @@ -608,13 +601,13 @@ static int usbasp_open(PROGRAMMER *pgm, const char *port) { pid = USBASP_SHARED_PID; } vid = pgm->usbvid? pgm->usbvid: USBASP_SHARED_VID; - if (usbOpenDevice(&PDATA(pgm)->usbhandle, vid, pgm->usbvendor, pid, pgm->usbproduct, port) != 0) { + if(usbOpenDevice(pgm, &PDATA(pgm)->usbhandle, vid, pgm->usbvendor, pid, pgm->usbproduct, port) != 0) { /* try alternatives */ if(str_eq(pgmid, "usbasp")) { /* for id usbasp autodetect some variants */ if(str_caseeq(port, "nibobee")) { pmsg_error("using -C usbasp -P nibobee is deprecated, use -C nibobee instead\n"); - if (usbOpenDevice(&PDATA(pgm)->usbhandle, USBASP_NIBOBEE_VID, "www.nicai-systems.com", + if(usbOpenDevice(pgm, &PDATA(pgm)->usbhandle, USBASP_NIBOBEE_VID, "www.nicai-systems.com", USBASP_NIBOBEE_PID, "NIBObee", port) != 0) { pmsg_error("cannot find USB device NIBObee with vid=0x%x pid=0x%x\n", USBASP_NIBOBEE_VID, USBASP_NIBOBEE_PID); @@ -623,7 +616,7 @@ static int usbasp_open(PROGRAMMER *pgm, const char *port) { return 0; } /* check if device with old VID/PID is available */ - if (usbOpenDevice(&PDATA(pgm)->usbhandle, USBASP_OLD_VID, "www.fischl.de", + if(usbOpenDevice(pgm, &PDATA(pgm)->usbhandle, USBASP_OLD_VID, "www.fischl.de", USBASP_OLD_PID, "USBasp", port) == 0) { /* found USBasp with old IDs */ pmsg_error("found USB device USBasp with old VID/PID; please update firmware of USBasp\n"); @@ -668,7 +661,7 @@ static void usbasp_close(PROGRAMMER * pgm) #endif } #ifdef USE_LIBUSB_1_0 - libusb_exit(ctx); + libusb_exit(PDATA(pgm)->ctx); #else /* nothing for usb 0.1 ? */ #endif @@ -677,14 +670,10 @@ static void usbasp_close(PROGRAMMER * pgm) /* Dummy functions */ static void usbasp_disable(const PROGRAMMER *pgm) { - /* Do nothing. */ - return; } static void usbasp_enable(PROGRAMMER *pgm, const AVRPART *p) { - /* Do nothing. */ - return; } @@ -700,7 +689,7 @@ static void usbasp_display(const PROGRAMMER *pgm, const char *p) { static int usbasp_initialize(const PROGRAMMER *pgm, const AVRPART *p) { unsigned char temp[4]; unsigned char res[4]; - IMPORT_PDATA(pgm); + struct pdata *pdata = PDATA(pgm); pmsg_debug("usbasp_initialize()\n"); @@ -945,7 +934,7 @@ static int usbasp_spi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const } /* The list of SCK frequencies in Hz supported by USBasp */ -static struct sckoptions_t usbaspSCKoptions[] = { +static const struct sckoptions_t usbaspSCKoptions[] = { { USBASP_ISP_SCK_3000, 3000000 }, { USBASP_ISP_SCK_1500, 1500000 }, { USBASP_ISP_SCK_750, 750000 }, @@ -1207,12 +1196,12 @@ static int usbasp_tpi_paged_load(const PROGRAMMER *pgm, const AVRPART *p, const return n_bytes; } -static int usbasp_tpi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, +int usbasp_tpi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, unsigned int page_size, unsigned int addr, unsigned int n_bytes) { unsigned char cmd[4]; unsigned char* sptr; - int writed, clen, n; + int written, clen, n; uint16_t pr; @@ -1220,11 +1209,10 @@ static int usbasp_tpi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const sptr = addr + m->buf; pr = addr + m->offset; - writed = 0; + written = 0; /* must erase fuse first, TPI parts only have one fuse */ - if(mem_is_a_fuse(m)) - { + if(mem_is_a_fuse(m)) { // Keep fuse writing ability for backward compatibility /* Set PR */ usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0)); usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1 ); @@ -1246,9 +1234,9 @@ static int usbasp_tpi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1)); usbasp_tpi_send_byte(pgm, (pr >> 8) ); - while(writed < (int) n_bytes) + while(written < (int) n_bytes) { - clen = n_bytes - writed; + clen = n_bytes - written; if(clen > 32) clen = 32; @@ -1264,7 +1252,7 @@ static int usbasp_tpi_paged_write(const PROGRAMMER *pgm, const AVRPART *p, const return -3; } - writed += clen; + written += clen; pr += clen; sptr += clen; } @@ -1281,7 +1269,6 @@ static int usbasp_tpi_read_byte(const PROGRAMMER * pgm, const AVRPART *p, const int n; uint16_t pr; - pmsg_debug("usbasp_tpi_read_byte(\"%s\", 0x%0lx)\n", m->desc, addr); pr = m->offset + addr; @@ -1292,19 +1279,68 @@ static int usbasp_tpi_read_byte(const PROGRAMMER * pgm, const AVRPART *p, const cmd[2] = 0; cmd[3] = 0; n = usbasp_transmit(pgm, 1, USBASP_FUNC_TPI_READBLOCK, cmd, value, 1); - if(n != 1) - { - pmsg_error("wrong reading bytes %x\n", n); + if(n != 1) { + if(n >= 0) + pmsg_error("wrong number %d of bytes read (expected 1)\n", n); return -3; } return 0; } static int usbasp_tpi_write_byte(const PROGRAMMER *pgm, const AVRPART *p, const AVRMEM *m, - unsigned long addr, unsigned char data) { // FIXME: use avr_write_byte_cache() when implemented + unsigned long addr, unsigned char data) { + pmsg_debug("%s(\"%s\", 0x%0lx, 0x%02x)\n", __func__, m->desc, addr, data); - pmsg_error("usbasp_write_byte in TPI mode; all writes have to be done at page level\n"); - return -1; + if(mem_is_flash(m)) { + pmsg_error("cannot write_byte() to %s; use paged_write()\n", m->desc); + return -1; + } + + // Memories left: fuse and lockbits + if(addr != 0) { + pmsg_error("unexpected address 0x%04lx of %s memory\n", addr, m->desc); + return -1; + } + + uint16_t pr = addr + m->offset; + + usbasp_tpi_nvm_waitbusy(pgm); + + // Must erase fuse first, TPI parts only have one fuse + if(mem_is_a_fuse(m)) { // Lockbits are reset during chip erase + // Set pointer register to pr + 1 + usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0)); + usbasp_tpi_send_byte(pgm, (pr & 0xFF) | 1 ); + usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1)); + usbasp_tpi_send_byte(pgm, (pr >> 8) ); + // Select SECTION_ERASE + usbasp_tpi_send_byte(pgm, TPI_OP_SOUT(NVMCMD)); + usbasp_tpi_send_byte(pgm, NVMCMD_SECTION_ERASE); + // Dummy write + usbasp_tpi_send_byte(pgm, TPI_OP_SST_INC); + usbasp_tpi_send_byte(pgm, 0x00); + + usbasp_tpi_nvm_waitbusy(pgm); + } + + // Reset pointer register to pr + usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(0)); + usbasp_tpi_send_byte(pgm, pr & 0xFF); + usbasp_tpi_send_byte(pgm, TPI_OP_SSTPR(1)); + usbasp_tpi_send_byte(pgm, (pr >> 8) ); + // Select word write + usbasp_tpi_send_byte(pgm, TPI_OP_SOUT(NVMCMD)); + usbasp_tpi_send_byte(pgm, NVMCMD_WORD_WRITE); + // Write low byte + usbasp_tpi_send_byte(pgm, TPI_OP_SST_INC); + usbasp_tpi_send_byte(pgm, data); + // Write high byte to start word write + usbasp_tpi_send_byte(pgm, TPI_OP_SST_INC); + usbasp_tpi_send_byte(pgm, 0xff); + + usbasp_tpi_nvm_waitbusy(pgm); + + return 0; } @@ -1358,4 +1394,3 @@ void usbasp_initpgm(PROGRAMMER *pgm) { #endif /* HAVE_LIBUSB */ const char usbasp_desc[] = "USBasp programmer, see http://www.fischl.de/usbasp/"; - diff --git a/src/usbtiny.c b/src/usbtiny.c index 7c673e8c..10b00f54 100644 --- a/src/usbtiny.c +++ b/src/usbtiny.c @@ -76,18 +76,13 @@ struct pdata // ---------------------------------------------------------------------- -static void usbtiny_setup(PROGRAMMER * pgm) -{ - if ((pgm->cookie = malloc(sizeof(struct pdata))) == 0) { - pmsg_error("out of memory allocating private data\n"); - exit(1); - } - memset(pgm->cookie, 0, sizeof(struct pdata)); +static void usbtiny_setup(PROGRAMMER *pgm) { + pgm->cookie = mmt_malloc(sizeof(struct pdata)); } -static void usbtiny_teardown(PROGRAMMER * pgm) -{ - free(pgm->cookie); +static void usbtiny_teardown(PROGRAMMER *pgm) { + mmt_free(pgm->cookie); + pgm->cookie = NULL; } // Wrapper for simple usb_control_msg messages @@ -818,5 +813,4 @@ void usbtiny_initpgm(PROGRAMMER *pgm) { #endif /* HAVE_LIBUSB */ -const char usbtiny_desc[] = "Driver for \"usbtiny\"-type programmers"; - +const char usbtiny_desc[] = "Usbtiny-type programmers incl arduinoisp, arduino_gemma and adafruit_gemma"; diff --git a/src/whereami.c b/src/whereami.c index 7bc23929..d8ff67e0 100644 --- a/src/whereami.c +++ b/src/whereami.c @@ -14,18 +14,23 @@ extern "C" { #if !defined(WAI_MALLOC) || !defined(WAI_FREE) || !defined(WAI_REALLOC) #include +#ifndef PATH_MAX +#define PATH_MAX _MAX_PATH +#endif +#include "avrdude.h" +#include "libavrdude.h" #endif #if !defined(WAI_MALLOC) -#define WAI_MALLOC(size) malloc(size) +#define WAI_MALLOC(size) mmt_malloc(size) #endif #if !defined(WAI_FREE) -#define WAI_FREE(p) free(p) +#define WAI_FREE(p) mmt_free(p) #endif #if !defined(WAI_REALLOC) -#define WAI_REALLOC(p, size) realloc(p, size) +#define WAI_REALLOC(p, size) mmt_realloc(p, size) #endif #ifndef WAI_NOINLINE diff --git a/src/whereami.h b/src/whereami.h index d5edffb8..0eabee7c 100644 --- a/src/whereami.h +++ b/src/whereami.h @@ -23,7 +23,7 @@ extern "C" { * Usage: * - first call `int length = wai_getExecutablePath(NULL, 0, NULL);` to * retrieve the length of the path - * - allocate the destination buffer with `path = (char*)malloc(length + 1);` + * - allocate the destination buffer with `path = (char*) mmt_malloc(length + 1);` * - call `wai_getExecutablePath(path, length, NULL)` again to retrieve the * path * - add a terminal NUL character with `path[length] = '\0';` @@ -45,7 +45,7 @@ int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length); * Usage: * - first call `int length = wai_getModulePath(NULL, 0, NULL);` to retrieve * the length of the path - * - allocate the destination buffer with `path = (char*)malloc(length + 1);` + * - allocate the destination buffer with `path = (char*) mmt_malloc(length + 1);` * - call `wai_getModulePath(path, length, NULL)` again to retrieve the path * - add a terminal NUL character with `path[length] = '\0';` * @@ -64,4 +64,4 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length); } #endif -#endif // #ifndef WHEREAMI_H \ No newline at end of file +#endif // #ifndef WHEREAMI_H diff --git a/src/wiring.c b/src/wiring.c index 6c62354d..60b8f705 100644 --- a/src/wiring.c +++ b/src/wiring.c @@ -69,12 +69,14 @@ static void wiring_setup(PROGRAMMER *pgm) { stk500v2_setup(pgm); // Then prepare our data and store in a safe place for the time being - ((struct pdata *)(pgm->cookie))->chained_pdata = cfg_malloc(__func__, sizeof(struct wiringpdata)); + ((struct pdata *)(pgm->cookie))->chained_pdata = mmt_malloc(sizeof(struct wiringpdata)); } static void wiring_teardown(PROGRAMMER *pgm) { - free(((struct pdata *)(pgm->cookie))->chained_pdata); + if(pgm->cookie) + mmt_free(((struct pdata *)(pgm->cookie))->chained_pdata); stk500v2_teardown(pgm); + pgm->cookie = NULL; } static int wiring_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { @@ -109,7 +111,7 @@ static int wiring_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { msg_error(" -xsnooze= Wait snooze [ms] before protocol sync after port open\n"); msg_error(" -xdelay= Add delay [ms] after reset, can be negative\n"); msg_error(" -xhelp Show this help menu and exit\n"); - exit(0); + return LIBAVRDUDE_EXIT;; } pmsg_error("invalid extended parameter '%s'\n", extended_param); @@ -174,7 +176,7 @@ static void wiring_close(PROGRAMMER * pgm) pgm->fd.ifd = -1; } -const char wiring_desc[] = "http://wiring.org.co/, Basically STK500v2 protocol, with some glue to trigger the bootloader."; +const char wiring_desc[] = "Bootloader using STK500v2 protocol, see http://wiring.org.co"; void wiring_initpgm(PROGRAMMER *pgm) { /* The Wiring bootloader uses a near-complete STK500v2 protocol. */ diff --git a/src/xbee.c b/src/xbee.c index cc16c983..378cfc9d 100644 --- a/src/xbee.c +++ b/src/xbee.c @@ -160,7 +160,7 @@ struct XBeeStaticticsSummary { #define XBEE_STATS_TRANSMIT 2 #define XBEE_STATS_RECEIVE 3 -static const char* groupNames[] = +static const char * const groupNames[] = { "FRAME_LOCAL", "FRAME_REMOTE", @@ -247,8 +247,8 @@ static void xbeeStatsAdd(struct XBeeStaticticsSummary *summary, static void xbeeStatsSummarise(struct XBeeStaticticsSummary const *summary) { - pmsg_notice(" Minimum response time: %lu.%06lu\n", summary->minimum.tv_sec, summary->minimum.tv_usec); - pmsg_notice(" Maximum response time: %lu.%06lu\n", summary->maximum.tv_sec, summary->maximum.tv_usec); + pmsg_notice(" Minimum response time: %lu.%06lu\n", summary->minimum.tv_sec, (unsigned long) summary->minimum.tv_usec); + pmsg_notice(" Maximum response time: %lu.%06lu\n", summary->maximum.tv_sec, (unsigned long) summary->maximum.tv_usec); struct timeval average; @@ -261,7 +261,7 @@ static void xbeeStatsSummarise(struct XBeeStaticticsSummary const *summary) average.tv_sec += usecs / 1000000; average.tv_usec = usecs % 1000000; - pmsg_notice(" Average response time: %lu.%06lu\n", average.tv_sec, average.tv_usec); + pmsg_notice(" Average response time: %lu.%06lu\n", average.tv_sec, (unsigned long) average.tv_usec); } static void XBeeBootSessionInit(struct XBeeBootSession *xbs) { @@ -1036,7 +1036,7 @@ static int xbeeATError(int rc) { static void xbeedev_free(struct XBeeBootSession *xbs) { xbs->serialDevice->close(&xbs->serialDescriptor); - free(xbs); + mmt_free(xbs); } static void xbeedev_close(union filedescriptor *fdp) @@ -1065,12 +1065,7 @@ static int xbeedev_open(const char *port, union pinfo pinfo, return -1; } - struct XBeeBootSession *xbs = malloc(sizeof(struct XBeeBootSession)); - if (xbs == NULL) { - pmsg_error("out of memory\n"); - return -1; - } - + struct XBeeBootSession *xbs = mmt_malloc(sizeof(struct XBeeBootSession)); XBeeBootSessionInit(xbs); char *tty = &ttySeparator[1]; @@ -1107,7 +1102,7 @@ static int xbeedev_open(const char *port, union pinfo pinfo, if (addrIndex != 8 || address != ttySeparator || nybble != -1) { pmsg_error("XBee: bad XBee address, require 16-character hexadecimal address\n"); - free(xbs); + mmt_free(xbs); return -1; } @@ -1174,7 +1169,7 @@ static int xbeedev_open(const char *port, union pinfo pinfo, const int rc = xbs->serialDevice->open(tty, pinfo, &xbs->serialDescriptor); if (rc < 0) { - free(xbs); + mmt_free(xbs); return rc; } } @@ -1499,20 +1494,6 @@ static int xbeedev_set_dtr_rts(const union filedescriptor *fdp, int is_on) return 0; } -/* - * Device descriptor for XBee framing. - */ -static struct serial_device xbee_serdev_frame = { - .open = xbeedev_open, - .close = xbeedev_close, - .rawclose = xbeedev_close, - .send = xbeedev_send, - .recv = xbeedev_recv, - .drain = xbeedev_drain, - .set_dtr_rts = xbeedev_set_dtr_rts, - .flags = SERDEV_FL_NONE, -}; - static int xbee_getsync(const PROGRAMMER *pgm) { unsigned char buf[2], resp[2]; @@ -1562,7 +1543,15 @@ static int xbee_open(PROGRAMMER *pgm, const char *port) { /* Wireless is lossier than normal serial */ serial_recv_timeout = 1000; - serdev = &xbee_serdev_frame; + serdev = &PDATA(pgm)->xbee_serdev; + serdev->open = xbeedev_open; + serdev->close = xbeedev_close; + serdev->rawclose = xbeedev_close; + serdev->send = xbeedev_send; + serdev->recv = xbeedev_recv; + serdev->drain = xbeedev_drain; + serdev->set_dtr_rts = xbeedev_set_dtr_rts; + serdev->flags = SERDEV_FL_NONE; if (serial_open(port, pinfo, &pgm->fd) == -1) { return -1; @@ -1656,7 +1645,7 @@ static int xbee_parseextparms(const PROGRAMMER *pgm, const LISTID extparms) { msg_error("%s -c %s extended options:\n", progname, pgmid); msg_error(" -xxbeeresetpin=<1..7> Set XBee pin DIO<1..7> as reset pin\n"); msg_error(" -xhelp Show this help menu and exit\n"); - exit(0); + return LIBAVRDUDE_EXIT;; } pmsg_error("invalid extended parameter '%s'\n", extended_param);