summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-06-15 12:07:27 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-06-15 12:07:27 -0600
commit2fba86a7717ecd534d94189fdf8734bf8d3ec91f (patch)
treeac8b2b6b18816b4d4e04c41dc43b3379ea860e46
parent4d332f0bcc2f1feeec8b3344e694e66095b61080 (diff)
downloadnuttx-2fba86a7717ecd534d94189fdf8734bf8d3ec91f.tar.gz
nuttx-2fba86a7717ecd534d94189fdf8734bf8d3ec91f.tar.bz2
nuttx-2fba86a7717ecd534d94189fdf8734bf8d3ec91f.zip
Add conversion of Intel HEX to binary
-rw-r--r--apps/include/hex2bin.h204
-rw-r--r--apps/nshlib/nsh_fscmds.c5
-rw-r--r--apps/system/Kconfig4
-rw-r--r--apps/system/Make.defs4
-rw-r--r--apps/system/Makefile6
-rw-r--r--apps/system/hex2bin/.gitignore11
-rw-r--r--apps/system/hex2bin/Kconfig53
-rw-r--r--apps/system/hex2bin/Makefile108
-rw-r--r--apps/system/hex2bin/hex2bin.c685
-rw-r--r--apps/system/hex2bin/hex2bin_main.c266
-rw-r--r--apps/system/inifile/Makefile2
11 files changed, 1342 insertions, 6 deletions
diff --git a/apps/include/hex2bin.h b/apps/include/hex2bin.h
new file mode 100644
index 000000000..13fcfc8f4
--- /dev/null
+++ b/apps/include/hex2bin.h
@@ -0,0 +1,204 @@
+/****************************************************************************
+ * apps/include/hex2bin.h
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __APPS_INCLUDE_INIFILE_H
+#define __APPS_INCLUDE_INIFILE_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#ifdef CONFIG_SYSTEM_HEX2BIN
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_SYSTEM_HEX2BIN_BASEADDR
+# define CONFIG_SYSTEM_HEX2BIN_BASEADDR 0x00000000
+#endif
+
+#ifndef CONFIG_SYSTEM_HEX2BIN_ENDPADDR
+# define CONFIG_SYSTEM_HEX2BIN_ENDPADDR 0x00000000
+#endif
+
+#ifndef CONFIG_SYSTEM_HEX2BIN_SWAP
+# define CONFIG_SYSTEM_HEX2BIN_SWAP 0
+#endif
+
+/* Some environments may return CR as end-of-line, others LF, and others
+ * both. If not specified, the logic here assumes either (but not both) as
+ * the default.
+ */
+
+#if defined(CONFIG_EOL_IS_CR)
+# undef CONFIG_EOL_IS_LF
+# undef CONFIG_EOL_IS_BOTH_CRLF
+# undef CONFIG_EOL_IS_EITHER_CRLF
+#elif defined(CONFIG_EOL_IS_LF)
+# undef CONFIG_EOL_IS_CR
+# undef CONFIG_EOL_IS_BOTH_CRLF
+# undef CONFIG_EOL_IS_EITHER_CRLF
+#elif defined(CONFIG_EOL_IS_BOTH_CRLF)
+# undef CONFIG_EOL_IS_CR
+# undef CONFIG_EOL_IS_LF
+# undef CONFIG_EOL_IS_EITHER_CRLF
+#elif defined(CONFIG_EOL_IS_EITHER_CRLF)
+# undef CONFIG_EOL_IS_CR
+# undef CONFIG_EOL_IS_LF
+# undef CONFIG_EOL_IS_BOTH_CRLF
+#else
+# undef CONFIG_EOL_IS_CR
+# undef CONFIG_EOL_IS_LF
+# undef CONFIG_EOL_IS_BOTH_CRLF
+# define CONFIG_EOL_IS_EITHER_CRLF 1
+#endif
+
+/* Debug from hex2bin code */
+
+#ifdef CONFIG_CPP_HAVE_VARARGS
+# ifdef CONFIG_SYSTEM_HEX2BIN_DEBUG
+# define hex2bin_debug(format, ...) \
+ fprintf(stderr, EXTRA_FMT format EXTRA_ARG, ##__VA_ARGS__)
+# else
+# define lldbg(x...)
+# endif
+#else
+# ifdef CONFIG_SYSTEM_HEX2BIN_DEBUG
+# define hex2bin_debug printf
+# else
+# define hex2bin_debug (void)
+# endif
+#endif
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+/* Intel HEX data steams are normally in big endian order. The following
+ * enumeration selects other ordering.
+ */
+
+enum hex2bin_swap_e
+{
+ HEX2BIN_NOSWAP = 0, /* No swap, stream is the correct byte order */
+ HEX2BIN_SWAP16 = 1, /* Swap bytes in 16-bit values */
+ HEX2BIN_SWAP32 = 2 /* Swap bytes in 32-bit values */
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: hex2bin
+ *
+ * Description:
+ * Read the Intel HEX ASCII data provided on the serial IN stream and write
+ * the binary to the seek-able serial OUT stream.
+ *
+ * These streams may be files or, in another usage example, the IN stream
+ * could be a serial port and the OUT stream could be a memory stream. This
+ * would decode and write the serial input to memory.
+ *
+ * Input Parameters:
+ * instream - The incoming stream from which Intel HEX data will be
+ * received.
+ * outstream - The outgoing stream in which binary data will be written.
+ * baseaddr - The base address of the outgoing stream. Seeking in the
+ * output stream will be relative to this address.
+ * endpaddr - The end address (plus 1) of the outgoing stream. This
+ * value is used only for range checking. endpaddr must
+ * be larger than baseaddr. A zero value for endpaddr
+ * disables range checking.
+ * swap - Controls byte ordering. See enum hex2bin_swap_e for
+ * description of the values.
+ *
+ * Returned Value
+ * Zero (OK) is returned on success; a negated errno value is returned on
+ * failure.
+ *
+ ****************************************************************************/
+
+struct lib_instream_s;
+struct lib_sostream_s;
+int hex2bin(FAR struct lib_instream_s *instream,
+ FAR struct lib_sostream_s *outstream, uint32_t baseaddr,
+ uint32_t endpaddr, enum hex2bin_swap_e swap);
+
+/****************************************************************************
+ * Name: hex2bin_main
+ *
+ * Description:
+ * Main entry point when hex2bin is built as an NSH built-in task.
+ *
+ * Input Parameters:
+ * Standard task inputs
+ *
+ * Returned Value
+ * EXIT_SUCESS on success; EXIT_FAILURE on failure
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SYSTEM_HEX2BIN_BUILTIN
+
+int hex2bin_main(int argc, char **argv);
+
+#endif /* CONFIG_SYSTEM_HEX2BIN_BUILTIN */
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CONFIG_SYSTEM_HEX2BIN */
+#endif /* __APPS_INCLUDE_INIFILE_H */
diff --git a/apps/nshlib/nsh_fscmds.c b/apps/nshlib/nsh_fscmds.c
index 14e174243..550e80ac5 100644
--- a/apps/nshlib/nsh_fscmds.c
+++ b/apps/nshlib/nsh_fscmds.c
@@ -373,7 +373,7 @@ static int ls_handler(FAR struct nsh_vtbl_s *vtbl, FAR const char *dirpath,
* Name: ls_recursive
****************************************************************************/
-#if CONFIG_NFILE_DESCRIPTORS > 0
+#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_NSH_DISABLE_LS)
static int ls_recursive(FAR struct nsh_vtbl_s *vtbl, const char *dirpath,
struct dirent *entryp, void *pvarg)
{
@@ -405,7 +405,8 @@ static int ls_recursive(FAR struct nsh_vtbl_s *vtbl, const char *dirpath,
}
return ret;
}
-#endif
+
+#endif /* CONFIG_NFILE_DESCRIPTORS > 0 && !CONFIG_NSH_DISABLE_LS */
/****************************************************************************
* Name: cat_common
diff --git a/apps/system/Kconfig b/apps/system/Kconfig
index 5b6c4102b..382ef3476 100644
--- a/apps/system/Kconfig
+++ b/apps/system/Kconfig
@@ -19,6 +19,10 @@ menu "FLASH Erase-all Command"
source "$APPSDIR/system/flash_eraseall/Kconfig"
endmenu
+menu "Intel HEX to binary conversion"
+source "$APPSDIR/system/hex2bin/Kconfig"
+endmenu
+
menu "I2C tool"
source "$APPSDIR/system/i2c/Kconfig"
endmenu
diff --git a/apps/system/Make.defs b/apps/system/Make.defs
index 5242dd977..44c584252 100644
--- a/apps/system/Make.defs
+++ b/apps/system/Make.defs
@@ -46,6 +46,10 @@ ifeq ($(CONFIG_SYSTEM_FREE),y)
CONFIGURED_APPS += system/free
endif
+ifeq ($(CONFIG_SYSTEM_HEX2BIN),y)
+CONFIGURED_APPS += system/hex2bin
+endif
+
ifeq ($(CONFIG_SYSTEM_I2CTOOL),y)
CONFIGURED_APPS += system/i2c
endif
diff --git a/apps/system/Makefile b/apps/system/Makefile
index 149c7a4ab..c39cfae9f 100644
--- a/apps/system/Makefile
+++ b/apps/system/Makefile
@@ -37,9 +37,9 @@
# Sub-directories containing system task
-SUBDIRS = cdcacm cle composite flash_eraseall free i2c inifile install
-SUBDIRS += nxplayer poweroff ramtest ramtron readline sdcard stackmonitor
-SUBDIRS += sysinfo usbmonitor usbmsc vi zmodem
+SUBDIRS = cdcacm cle composite flash_eraseall free i2c hex2bin inifile
+SUBDIRS += install nxplayer poweroff ramtest ramtron readline sdcard
+SUBDIRS += stackmonitor sysinfo usbmonitor usbmsc vi zmodem
# Create the list of installed runtime modules (INSTALLED_DIRS)
diff --git a/apps/system/hex2bin/.gitignore b/apps/system/hex2bin/.gitignore
new file mode 100644
index 000000000..83bd7b811
--- /dev/null
+++ b/apps/system/hex2bin/.gitignore
@@ -0,0 +1,11 @@
+/Make.dep
+/.depend
+/.built
+/*.asm
+/*.rel
+/*.lst
+/*.sym
+/*.adb
+/*.lib
+/*.src
+/*.obj
diff --git a/apps/system/hex2bin/Kconfig b/apps/system/hex2bin/Kconfig
new file mode 100644
index 000000000..ae01cfed2
--- /dev/null
+++ b/apps/system/hex2bin/Kconfig
@@ -0,0 +1,53 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+config SYSTEM_HEX2BIN
+ bool "Intel HEX Convertion"
+ default n
+ ---help---
+ Enable support for a logic to convert Intel HEX format to binary.
+
+if SYSTEM_HEX2BIN
+
+config SYSTEM_HEX2BIN_BUILTIN
+ bool "NSH Built-In"
+ default n
+ depends on NSH_BUILTIN_APPS
+ ---help---
+ By default, a flexible hex2bin library function built. An NSH
+ builtin function can also be generated to convert Intel HEX file
+ to binary files.
+
+if SYSTEM_HEX2BIN_BUILTIN
+
+config SYSTEM_HEX2BIN_BASEADDR
+ hex "Binary base address"
+ default 0x00000000
+ ---help---
+ The default value of the base address argument. Saves typing.
+
+config SYSTEM_HEX2BIN_ENDPADDR
+ hex "Binary base address"
+ default 0x00000000
+ ---help---
+ The default value of the end (plus 1) address argument. Saves typing.
+
+config SYSTEM_HEX2BIN_SWAP
+ int "Binary base address"
+ default 0
+ range 0 2
+ ---help---
+ The default value of the swap argument. (0) No swap, (1) swap bytes
+ in 16-bit values, or (2) swap tbytes in 32-bit values.
+
+endif # SYSTEM_HEX2BIN_BUILTIN
+
+config SYSTEM_HEX2BIN_DEBUG
+ bool "Hex2bin detailed error output"
+ default n
+ ---help---
+ Enable extended error output.
+
+endif # SYSTEM_HEX2BIN
diff --git a/apps/system/hex2bin/Makefile b/apps/system/hex2bin/Makefile
new file mode 100644
index 000000000..ce50879b1
--- /dev/null
+++ b/apps/system/hex2bin/Makefile
@@ -0,0 +1,108 @@
+############################################################################
+# apps/system/hex2bin/Makefile
+#
+# Copyright (C) 2014 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt <gnutt@nuttx.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+# used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+# I2C tool
+
+ASRCS =
+CSRCS = hex2bin.c hex2bin_main.c
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS)
+OBJS = $(AOBJS) $(COBJS)
+
+ifeq ($(CONFIG_WINDOWS_NATIVE),y)
+ BIN = ..\..\libapps$(LIBEXT)
+else
+ifeq ($(WINTOOL),y)
+ BIN = ..\\..\\libapps$(LIBEXT)
+else
+ BIN = ../../libapps$(LIBEXT)
+endif
+endif
+
+ROOTDEPPATH = --dep-path .
+VPATH =
+
+PRIORITY = SCHED_PRIORITY_DEFAULT
+STACKSIZE = 768
+
+# Build targets
+
+all: .built
+.PHONY: context .depend depend clean distclean
+
+$(AOBJS): %$(OBJEXT): %.S
+ $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+.built: $(OBJS)
+ $(call ARCHIVE, $(BIN), $(OBJS))
+ $(Q) touch .built
+
+# Register application
+
+ifeq ($(CONFIG_SYSTEM_HEX2BIN_BUILTINS),y)
+$(BUILTIN_REGISTRY)$(DELIM)hex2bin.bdat: $(DEPCONFIG) Makefile
+ $(call REGISTER,"hex2bin",$(PRIORITY),$(STACKSIZE),hex2bin_main)
+
+context: $(BUILTIN_REGISTRY)$(DELIM)hex2bin.bdat
+else
+context:
+endif
+
+.depend: Makefile $(SRCS)
+ $(Q) $(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
+ $(Q) touch $@
+
+depend: .depend
+
+clean:
+ $(call DELFILE, .built)
+ $(call CLEAN)
+
+distclean: clean
+ $(call DELFILE, Make.dep)
+ $(call DELFILE, .depend)
+
+-include Make.dep
+
diff --git a/apps/system/hex2bin/hex2bin.c b/apps/system/hex2bin/hex2bin.c
new file mode 100644
index 000000000..28eb9df50
--- /dev/null
+++ b/apps/system/hex2bin/hex2bin.c
@@ -0,0 +1,685 @@
+/****************************************************************************
+ * apps/system/hex2bin.c
+ * Reference: http://en.wikipedia.org/wiki/Intel_HEX
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdint.h>
+#include <errno.h>
+
+#include <nuttx/streams.h>
+#include <apps/hex2bin.h>
+
+#ifdef CONFIG_SYSTEM_HEX2BIN
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* ASCII record sizes */
+
+#define BYTECOUNT_ASCSIZE 2
+#define ADDRESS_ASCSIZE 4
+#define RECTYPE_ASCSIZE 2
+
+#define BYTECOUNT_LINENDX (0)
+#define ADDRESS_LINENDX (BYTECOUNT_LINENDX + BYTECOUNT_ASCSIZE)
+#define RECTYPE_LINENDX (ADDRESS_LINENDX + ADDRESS_ASCSIZE)
+#define DATA_LINENDX (RECTYPE_LINENDX + RECTYPE_ASCSIZE)
+#define HEADER_ASCSIZE DATA_LINENDX
+
+#define CHECKSUM_ASCSIZE 2
+#define TRAILER_SIZE (CHECKSUM_ASCSIZE)
+
+#define MAXDATA_BINSIZE 255
+#define RECORD_ASCSIZE(n) (HEADER_ASCSIZE + TRAILER_SIZE + 2*(n))
+#define MAXRECORD_ASCSIZE RECORD_ASCSIZE(MAXDATA_BINSIZE)
+#define MINRECORD_ASCSIZE RECORD_ASCSIZE(0)
+#define LINE_ALLOC MAXRECORD_ASCSIZE
+
+/* Binary record sizes */
+
+#define BYTECOUNT_BINSIZE 1
+#define ADDRESS_BINSIZE 2
+#define RECTYPE_BINSIZE 1
+
+#define BYTECOUNT_BINNDX (0)
+#define ADDRESS_BINNDX (BYTECOUNT_BINNDX + BYTECOUNT_BINSIZE)
+#define RECTYPE_BINNDX (ADDRESS_BINNDX + ADDRESS_BINSIZE)
+#define DATA_BINNDX (RECTYPE_BINNDX + RECTYPE_BINSIZE)
+#define HEADER_BINSIZE DATA_BINNDX
+
+#define CHECKSUM_BINSIZE 1
+#define TRAILER_BINSIZE CHECKSUM_BINSIZE
+
+#define RECORD_BINSIZE(n) (HEADER_BINSIZE + TRAILER_BINSIZE + (n))
+#define MAXRECORD_BINSIZE RECORD_ASCSIZE(MAXDATA_BINSIZE)
+#define MINRECORD_BKINSIZE RECORD_ASCSIZE(0)
+#define BIN_ALLOC MAXRECORD_BINSIZE
+
+/* Record start code */
+
+#define RECORD_STARTCODE ':'
+
+/* Record Types */
+
+#define RECORD_DATA 0 /* Data */
+#define RECORD_EOF 1 /* End of file */
+#define RECORD_EXT_SEGADDR 2 /* Extended segment address record */
+#define RECORD_START_SEGADDR 3 /* Start segment address record */
+#define RECORD_EXT_LINADDR 4 /* Extended linear address record */
+#define RECORD_START_LINADDR 5 /* Start linear address record */
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: nibble2bin
+ ****************************************************************************/
+
+static int nibble2bin(uint8_t ascii)
+{
+ if (ascii >= '0' && ascii <= '9')
+ {
+ return (ascii - 0x30);
+ }
+ else if (ascii >= 'a' && ascii <= 'f')
+ {
+ return (ascii - 'a' + 10);
+ }
+ else if (ascii >= 'A' && ascii <= 'F')
+ {
+ return (ascii - 'A' + 10);
+ }
+
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: byte2bin
+ ****************************************************************************/
+
+static int byte2bin(FAR const uint8_t *ascii)
+{
+ int nibble;
+ int byte;
+
+ /* Get the MS nibble (big endian order) */
+
+ nibble = nibble2bin(*ascii++);
+ if (nibble < 0)
+ {
+ return nibble;
+ }
+
+ byte = (nibble << 4);
+
+ /* Get the MS nibble */
+
+ nibble = nibble2bin(*ascii);
+ if (nibble < 0)
+ {
+ return nibble;
+ }
+
+ byte |= nibble;
+ return byte;
+}
+
+/****************************************************************************
+ * Name: word2bin
+ ****************************************************************************/
+
+#if 0 /* Not used */
+static int word2bin(FAR const char *ascii)
+{
+ int byte;
+ int word;
+
+ /* Get the MS byte (big endian order) */
+
+ byte = word2bin(ascii);
+ if (byte < 0)
+ {
+ return byte;
+ }
+
+ word = (byte << 8);
+
+ /* Get the MS byte */
+
+ byte = word2bin(ascii + 2);
+ if (byte < 0)
+ {
+ return byte;
+ }
+
+ word |= byte;
+ return word;
+}
+#endif
+
+/****************************************************************************
+ * Name: data2bin
+ ****************************************************************************/
+
+int data2bin(FAR uint8_t* dest, FAR const uint8_t *src, int nbytes)
+{
+ int byte;
+
+ /* An even number of source bytes is expected */
+
+ if ((nbytes & 1) != 0)
+ {
+ return -EINVAL;
+ }
+
+ /* Convert src bytes in groups of 2, writing one byte to the output on each
+ * pass through the loop. */
+
+ while (nbytes-- > 0)
+ {
+ /* Get the MS nibble (big endian order) */
+
+ byte = byte2bin(src);
+ if (byte < 0)
+ {
+ return byte;
+ }
+
+ src += 2;
+
+ /* And write the byte to the destination */
+
+ *dest++ = byte;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: readstream
+ ****************************************************************************/
+
+static int readstream(FAR struct lib_instream_s *instream,
+ FAR uint8_t *line, unsigned int lineno)
+{
+ int ch = instream->get(instream);
+ int nbytes = 0;
+
+ /* Skip until the beginning of line start code is encountered */
+
+ while (ch != RECORD_STARTCODE && ch != EOF)
+ {
+ ch = instream->get(instream);
+ }
+
+ /* Read until the end of line is encountered */
+
+ while (ch != EOF && nbytes < (MAXRECORD_ASCSIZE-1))
+ {
+#if defined(CONFIG_EOL_IS_LF)
+ if (ch == '\n')
+ {
+ *line = '\0';
+ return nbytes;
+ }
+
+#elif defined(CONFIG_EOL_IS_BOTH_CRLF)
+ if (ch == '\r')
+ {
+ continue;
+ }
+ else if (ch == '\n')
+ {
+ *line = '\0';
+ return nbytes;
+ }
+#elif defined(CONFIG_EOL_IS_CR)
+ if (ch == '\r')
+ {
+ *line = '\0';
+ return nbytes;
+ }
+#elif CONFIG_EOL_IS_EITHER_CRLF
+ if (ch == '\n' || ch == '\r')
+ {
+ *line = '\0';
+ return nbytes;
+ }
+#endif
+ /* Only hex data goes into the line buffer */
+
+ else if (isxdigit(ch))
+ {
+ *line++ = ch;
+ nbytes++;
+ }
+ else
+ {
+ hex2bin_debug("Line %u ERROR: Unexpected character %c[%02x] in stream\n",
+ lineno, isprint(ch) ? ch : '.', ch);
+ break;
+ }
+ }
+
+ /* Some error occurred: Unexpected EOF, line too long, or bad character in
+ * stream
+ */
+
+ hex2bin_debug("Line %u ERROR: Failed to read line. %d characters read\n",
+ lineno, nbytes);
+ return EOF;
+}
+
+/****************************************************************************
+ * Name: hex2bin_swap16 and hex2bin_swap32
+ ****************************************************************************/
+
+static inline void hex2bin_swap16(FAR uint8_t *bin, int bytecount)
+{
+ for (; bytecount > 0; bytecount -= 2)
+ {
+ uint8_t b0 = bin[0];
+ uint8_t b1 = bin[1];
+
+ *bin++ = b1;
+ *bin++ = b0;
+ }
+}
+
+static inline void hex2bin_swap32(FAR uint8_t *bin, int bytecount)
+{
+ for (; bytecount > 0; bytecount -= 4)
+ {
+ uint8_t b0 = bin[0];
+ uint8_t b1 = bin[1];
+ uint8_t b2 = bin[2];
+ uint8_t b3 = bin[3];
+
+ *bin++ = b3;
+ *bin++ = b2;
+ *bin++ = b1;
+ *bin++ = b0;
+ }
+}
+
+/****************************************************************************
+ * Name: writedata
+ ****************************************************************************/
+
+static inline void writedata(FAR struct lib_sostream_s *outstream,
+ FAR uint8_t *bin, int bytecount)
+{
+ for (; bytecount > 0; bytecount--)
+ {
+ outstream->put(outstream, *bin++);
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: hex2bin
+ *
+ * Description:
+ * Read the Intel HEX ASCII data provided on the serial IN stream and write
+ * the binary to the seek-able serial OUT stream.
+ *
+ * These streams may be files or, in another usage example, the IN stream
+ * could be a serial port and the OUT stream could be a memory stream. This
+ * would decode and write the serial input to memory.
+ *
+ * Input Parameters:
+ * instream - The incoming stream from which Intel HEX data will be
+ * received.
+ * outstream - The outgoing stream in which binary data will be written.
+ * baseaddr - The base address of the outgoing stream. Seeking in the
+ * output stream will be relative to this address.
+ * endpaddr - The end address (plus 1) of the outgoing stream. This
+ * value is used only for range checking. endpaddr must
+ * be larger than baseaddr. A zero value for endpaddr
+ * disables range checking.
+ * swap - Controls byte ordering. See enum hex2bin_swap_e for
+ * description of the values.
+ *
+ * Returned Value
+ * Zero (OK) is returned on success; a negated errno value is returned on
+ * failure.
+ *
+ ****************************************************************************/
+
+int hex2bin(FAR struct lib_instream_s *instream,
+ FAR struct lib_sostream_s *outstream, uint32_t baseaddr,
+ uint32_t endpaddr, enum hex2bin_swap_e swap)
+{
+ FAR uint8_t *alloc;
+ FAR uint8_t *line;
+ FAR uint8_t *bin;
+ int nbytes;
+ int bytecount;
+ uint32_t address;
+ uint32_t expected;
+ uint16_t extension;
+ uint16_t address16;
+ uint8_t checksum;
+ unsigned int lineno;
+ int i;
+ int ret = OK;
+
+ /* Allocate buffer memory */
+
+ alloc = (FAR uint8_t *)malloc(LINE_ALLOC + BIN_ALLOC);
+ if (alloc == NULL)
+ {
+ hex2bin_debug("ERROR: Failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ line = alloc;
+ bin = &alloc[LINE_ALLOC];
+
+ extension = 0;
+ expected = 0;
+ lineno = 0;
+
+ while ((nbytes = readstream(instream, line, lineno)) != EOF)
+ {
+ /* Increment the line number */
+
+ lineno++;
+
+ /* Did we read enough data to do anything? */
+
+ if (nbytes < MINRECORD_ASCSIZE)
+ {
+ hex2bin_debug("Line %u ERROR: Record too short: %d\n",
+ lineno, nbytes);
+ goto errout_with_einval;
+ }
+
+ /* We should always read an even number of bytes */
+
+ if ((nbytes & 1) != 0)
+ {
+ hex2bin_debug("Line %u ERROR: Record length is odd: %d\n",
+ lineno, nbytes);
+ goto errout_with_einval;
+ }
+
+ /* Get the data byte count */
+
+ bytecount = byte2bin(&line[BYTECOUNT_LINENDX]);
+ if (bytecount < 0)
+ {
+ hex2bin_debug("Line %u ERROR: Failed to read bytecount: %d\n",
+ lineno, bytecount);
+ ret = bytecount;
+ goto errout_with_buffers;
+ }
+
+ /* Verify that the bytecount matches the length of the record */
+
+ if (RECORD_ASCSIZE(bytecount) != nbytes)
+ {
+ hex2bin_debug("Line %u ERROR: Expected %d bytes, read %d\n",
+ lineno, RECORD_ASCSIZE(bytecount), nbytes);
+ goto errout_with_einval;
+ }
+
+ /* Convert the entire line to binary. We need to do this for
+ * checksum calculation which includes the entire line (minus
+ * the start code and the checksum at the end of the line itself)
+ */
+
+ ret = data2bin(line, bin, nbytes);
+ if (ret < 0)
+ {
+ hex2bin_debug("Line %u ERROR: Failed to convert line to binary: %d\n",
+ lineno, ret);
+ goto errout_with_buffers;
+ }
+
+ /* Calculate and verify the checksum over all of the data */
+
+ checksum = 0;
+ for (i = 0; i < bytecount; i++)
+ {
+ checksum += bin[i];
+ }
+
+ if (checksum != 0)
+ {
+ hex2bin_debug("Line %u ERROR: Bad checksum %02x\n",
+ lineno, checksum);
+ goto errout_with_einval;
+ }
+
+ /* Get the 16-bit (unextended) address from the record */
+
+ address16 = (uint16_t)bin[ADDRESS_BINNDX] << 8 |
+ (uint16_t)bin[ADDRESS_BINNDX+1];
+
+ /* Handle the record by its record type */
+
+ switch (bin[RECTYPE_BINNDX])
+ {
+ case RECORD_DATA: /* Data */
+ {
+ /* Swap data in place in the binary buffer as required */
+
+ switch (swap)
+ {
+ case HEX2BIN_NOSWAP: /* No swap, stream is the correct byte order */
+ break;
+
+ case HEX2BIN_SWAP16: /* Swap bytes in 16-bit values */
+ {
+ if ((bytecount & 1) != 0)
+ {
+ hex2bin_debug("Line %d ERROR: Byte count %d is not a multiple of 2\n",
+ lineno, bytecount);
+ goto errout_with_einval;
+ }
+
+ /* Do the byte swap */
+
+ hex2bin_swap16(bin, bytecount);
+ }
+ break;
+
+ case HEX2BIN_SWAP32: /* Swap bytes in 32-bit values */
+ {
+ if ((bytecount & 3) != 0)
+ {
+ hex2bin_debug("Line %d ERROR: Byte count %d is not a multiple of 4\n",
+ lineno, bytecount);
+ goto errout_with_einval;
+ }
+
+ /* Do the byte swap */
+
+ hex2bin_swap32(bin, bytecount);
+ }
+ break;
+
+ default:
+ {
+ hex2bin_debug("ERROR: Invalid swap argument: %d\n", swap);
+ goto errout_with_einval;
+ }
+ }
+
+ /* Get and verify the full 32-bit address */
+
+ address = ((uint32_t)extension << 16) | (uint32_t)address16;
+ if (address < baseaddr || (endpaddr != 0 && address >= endpaddr))
+ {
+ hex2bin_debug("Line %d ERROR: Extended address %08lx is out of range\n",
+ lineno, (unsigned long)address);
+ goto errout_with_einval;
+ }
+
+ /* Seek to the correct position in the OUT stream */
+
+ if (address != expected)
+ {
+ off_t pos = outstream->seek(outstream, address - baseaddr, SEEK_SET);
+ if (pos == (off_t)-1)
+ {
+ hex2bin_debug("Line %u ERROR: Seek to address %08lu failed\n",
+ lineno, (unsigned long)address);
+ ret = -ESPIPE;
+ goto errout_with_buffers;
+ }
+ }
+
+ /* Transfer data to the OUT stream */
+
+ writedata(outstream, bin, bytecount);
+ }
+ break;
+
+ case RECORD_EOF: /* End of file */
+ /* End Of File record. Must occur exactly once per file in the
+ * last line of the file. The byte count is 00 and the data field
+ * is empty. Usually the address field is also 0000.
+ */
+
+ if (bytecount == 0)
+ {
+ ret = OK;
+ goto exit_with_buffers;
+ }
+
+ hex2bin_debug("Line %u ERROR: Nonzero bytecount %d in EOF\n",
+ lineno, bytecount);
+ goto errout_with_einval;
+
+ case RECORD_EXT_SEGADDR: /* Extended segment address record */
+ /* The address specified by the data field is multiplied by 16
+ * (shifted 4 bits left) and added to the subsequent data record
+ * addresses. This allows addressing of up to a megabyte of
+ * address space. The address field of this record has to be
+ * 0000, the byte count is 02 (the segment is 16-bit). The
+ * least significant hex digit of the segment address is always
+ * 0.
+ */
+
+ if (bytecount != 2 || address16 != 0 || bin[1] != 0)
+ {
+ hex2bin_debug("Line %u ERROR: Invalid segment address\n",
+ lineno);
+ hex2bin_debug(" bytecount=%d address=%04x segment=%02x%02x\n",
+ bytecount, address16, bin[0], bin[1]);
+ goto errout_with_einval;
+ }
+
+ extension = (uint16_t)bin[0];
+ break;
+
+ case RECORD_START_SEGADDR: /* Start segment address record */
+ /* For 80x86 processors, it specifies the initial content of
+ * the CS:IP registers. The address field is 0000, the byte
+ * count is 04, the first two bytes are the CS value, the
+ * latter two are the IP value.
+ */
+
+ break;
+
+ case RECORD_EXT_LINADDR: /* Extended linear address record */
+ /* The address field is 0000, the byte count is 02. The two
+ * data bytes (two hex digit pairs in big endian order)
+ * represent the upper 16 bits of the 32 bit address for
+ * all subsequent 00 type records until the next 04 type
+ * record comes. If there is not a 04 type record, the
+ * upper 16 bits default to 0000. To get the absolute
+ * address for subsequent 00 type records, the address
+ * specified by the data field of the most recent 04 record
+ * is added to the 00 record addresses.
+ */
+
+ if (bytecount != 2 || address16 != 0)
+ {
+ hex2bin_debug("Line %u ERROR: Invalid linear address\n",
+ lineno);
+ hex2bin_debug(" bytecount=%d address=%04x\n",
+ bytecount, address16);
+ goto errout_with_einval;
+ }
+
+ extension = (uint16_t)bin[0] << 8 | (uint16_t)bin[1];
+ break;
+
+ case RECORD_START_LINADDR: /* Start linear address record */
+ /* The address field is 0000, the byte count is 04. The 4
+ * data bytes represent the 32-bit value loaded into the EIP
+ * register of the 80386 and higher CPU.
+ */
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ hex2bin_debug("ERROR: No EOF record found\n");
+
+errout_with_einval:
+ ret = -EINVAL;
+
+errout_with_buffers:
+exit_with_buffers:
+ free(alloc);
+ return -ret;
+}
+
+#endif /* CONFIG_SYSTEM_HEX2BIN */
diff --git a/apps/system/hex2bin/hex2bin_main.c b/apps/system/hex2bin/hex2bin_main.c
new file mode 100644
index 000000000..660cd5723
--- /dev/null
+++ b/apps/system/hex2bin/hex2bin_main.c
@@ -0,0 +1,266 @@
+/****************************************************************************
+ * apps/system/hex2bin_main.c
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <nuttx/streams.h>
+#include <apps/hex2bin.h>
+
+#ifdef CONFIG_SYSTEM_HEX2BIN_BUILTIN
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: show_usage
+ ****************************************************************************/
+
+void show_usage(FAR const char *progname, int exitcode)
+{
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr, "\t%s [OPTIONS] <hexfile> <binfile>\n");
+ fprintf(stderr, "\t%s -h\n");
+ fprintf(stderr, "Where:\n");
+ fprintf(stderr, "\t<hexfile>:\n");
+ fprintf(stderr, "\t\tThe file containing the Intel HEX data to be converted.\n");
+ fprintf(stderr, "\t<binfile>:\n");
+ fprintf(stderr, "\t\tThe output file to be created contained the converted\n");
+ fprintf(stderr, "\t\tbinary data.\n");
+ fprintf(stderr, "\t-h:\n");
+ fprintf(stderr, "\t\tPrints this message and exits\n");
+ fprintf(stderr, "And [OPTIONS] include:\n");
+ fprintf(stderr, "\t-s <start address>\n");
+ fprintf(stderr, "\t\tSets the start address of the binary output. This value\n");
+ fprintf(stderr, "\t\tis used to (1) calculate offsets into the output stream,\n");
+ fprintf(stderr, "\t\tand (2) for error checking. Default: 0x%08x\n",
+ CONFIG_SYSTEM_HEX2BIN_BASEADDR);
+ fprintf(stderr, "\t-e <end address>\n");
+ fprintf(stderr, "\t\tSets the maximum address (plus 1) of the binary output.\n");
+ fprintf(stderr, "\t\tThis value is used to only for error checking. Default:\n");
+ fprintf(stderr, "\t\t0x%08x\n", CONFIG_SYSTEM_HEX2BIN_ENDPADDR);
+ fprintf(stderr, "\t\tno error checking\n");
+ fprintf(stderr, "\t-w <swap code>\n");
+ fprintf(stderr, "\t\t(0) No swap, (1) swap bytes in 16-bit values, or (3) swap\n");
+ fprintf(stderr, "\t\tbytes in 32-bit values. Default: %d\n",
+ CONFIG_SYSTEM_HEX2BIN_SWAP);
+ exit(exitcode);
+}
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name:
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: hex2bin_main
+ *
+ * Description:
+ * Main entry point when hex2bin is built as an NSH built-in task.
+ *
+ * Input Parameters:
+ * Standard task inputs
+ *
+ * Returned Value
+ * EXIT_SUCESS on success; EXIT_FAILURE on failure
+ *
+ ****************************************************************************/
+
+int hex2bin_main(int argc, char **argv)
+{
+ struct lib_stdinstream_s stdinstream;
+ struct lib_stdsostream_s stdoutstream;
+ FAR const char *hexfile;
+ FAR const char *binfile;
+ FAR char *endptr;
+ FAR FILE *instream;
+ FAR FILE *outstream;
+ unsigned long baseaddr;
+ unsigned long endpaddr;
+ unsigned long swap;
+ int option;
+ int ret;
+
+ /* Parse the command line options */
+
+ baseaddr = CONFIG_SYSTEM_HEX2BIN_BASEADDR;
+ endpaddr = CONFIG_SYSTEM_HEX2BIN_ENDPADDR;
+ swap = CONFIG_SYSTEM_HEX2BIN_SWAP;
+
+ while ((option = getopt(argc, argv, ":hs:e:w:")) != ERROR)
+ {
+ switch (option)
+ {
+ case 'h':
+ show_usage(argv[0], EXIT_SUCCESS);
+ break;
+
+ case 's':
+ baseaddr = strtoul(optarg, &endptr, 16);
+ if (endptr == optarg)
+ {
+ fprintf(stderr, "ERROR: Invalid argument to the -s option\n");
+ show_usage(argv[0], EXIT_FAILURE);
+ }
+ break;
+
+ case 'e':
+ endpaddr = strtoul(optarg, &endptr, 16);
+ if (endptr == optarg)
+ {
+ fprintf(stderr, "ERROR: Invalid argument to the -e option\n");
+ show_usage(argv[0], EXIT_FAILURE);
+ }
+ break;
+
+ case 'w':
+ swap = strtoul(optarg, &endptr, 16);
+ if (endptr == optarg || swap > (unsigned long)HEX2BIN_SWAP32)
+ {
+ fprintf(stderr, "ERROR: Invalid argument to the -w option\n");
+ show_usage(argv[0], EXIT_FAILURE);
+ }
+ break;
+
+ case ':':
+ fprintf(stderr, "ERROR: Missing required argument\n");
+ show_usage(argv[0], EXIT_FAILURE);
+ break;
+
+ default:
+ case '?':
+ fprintf(stderr, "ERROR: Unrecognized option\n");
+ show_usage(argv[0], EXIT_FAILURE);
+ break;
+ }
+ }
+
+ /* There should be two final parameters remaining on the command line */
+
+ if (optind >= argc)
+ {
+ printf("ERROR: Missing required <hexfile> and <binfile> arguments\n");
+ show_usage(argv[0], EXIT_FAILURE);
+ }
+
+ hexfile = argv[optind];
+ optind++;
+
+ if (optind >= argc)
+ {
+ printf("ERROR: Missing required <binfile> argument\n");
+ show_usage(argv[0], EXIT_FAILURE);
+ }
+
+ binfile = argv[optind];
+ optind++;
+
+ if (optind < argc)
+ {
+ printf("ERROR: Garbage at end of command line\n");
+ show_usage(argv[0], EXIT_FAILURE);
+ }
+
+ /* Open the HEX file for reading */
+
+ instream = fopen(hexfile, "r");
+ if (instream == NULL)
+ {
+ int errcode = errno;
+ DEBUGASSERT(errcode > 0);
+
+ fprintf(stderr, "ERROR: Failed to open \"%s\" for reading: %d\n",
+ hexfile, errcode);
+ return -errcode;
+ }
+
+ /* Open the BIN file for reading */
+
+ outstream = fopen(binfile, "wb");
+ if (outstream == NULL)
+ {
+ int errcode = errno;
+ DEBUGASSERT(errcode > 0);
+
+ fprintf(stderr, "ERROR: Failed to open \"%s\" for writing: %d\n",
+ binfile, errcode);
+ fclose(instream);
+ return -errcode;
+ }
+
+ /* Wrap the FILE streams as standard streams */
+
+ lib_stdinstream(&stdinstream, instream);
+ lib_stdsostream(&stdoutstream, outstream);
+
+ /* And do the deed */
+
+ ret = hex2bin(&stdinstream.public, &stdoutstream.public,
+ (uint32_t)baseaddr, (uint32_t)endpaddr,
+ (enum hex2bin_swap_e)swap);
+ if (ret < 0)
+ {
+ fprintf(stderr, "ERROR: Failed to convert \"%s\" to binary: %d\n",
+ ret);
+ }
+
+ /* Clean up and return */
+
+ fclose(instream);
+ fclose(outstream);
+ return ret < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+#endif /* CONFIG_SYSTEM_HEX2BIN_BUILTIN */
diff --git a/apps/system/inifile/Makefile b/apps/system/inifile/Makefile
index d7611b4dd..d51ba1b7d 100644
--- a/apps/system/inifile/Makefile
+++ b/apps/system/inifile/Makefile
@@ -1,5 +1,5 @@
############################################################################
-# apps/system/initfile/Makefile
+# apps/system/inifile/Makefile
#
# Copyright (C) 2014 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>