Add conversion of Intel HEX to binary
This commit is contained in:
parent
36b3106564
commit
2b01e7c297
204
include/hex2bin.h
Normal file
204
include/hex2bin.h
Normal file
@ -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 */
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
11
system/hex2bin/.gitignore
vendored
Normal file
11
system/hex2bin/.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/Make.dep
|
||||
/.depend
|
||||
/.built
|
||||
/*.asm
|
||||
/*.rel
|
||||
/*.lst
|
||||
/*.sym
|
||||
/*.adb
|
||||
/*.lib
|
||||
/*.src
|
||||
/*.obj
|
53
system/hex2bin/Kconfig
Normal file
53
system/hex2bin/Kconfig
Normal file
@ -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
|
108
system/hex2bin/Makefile
Normal file
108
system/hex2bin/Makefile
Normal file
@ -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
|
||||
|
685
system/hex2bin/hex2bin.c
Normal file
685
system/hex2bin/hex2bin.c
Normal file
@ -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 */
|
266
system/hex2bin/hex2bin_main.c
Normal file
266
system/hex2bin/hex2bin_main.c
Normal file
@ -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 */
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user