├── .gitignore ├── LICENSE-mit ├── LICENSE-public-domain ├── Makefile ├── README.md ├── atmel_generic.c ├── atmel_generic.h ├── docs ├── html │ ├── annotated.html │ ├── atmel__generic_8h.html │ ├── atmel__generic_8h_source.html │ ├── bc_s.png │ ├── classes.html │ ├── closed.png │ ├── doxygen.css │ ├── doxygen.png │ ├── files.html │ ├── functions.html │ ├── functions_vars.html │ ├── globals.html │ ├── globals_enum.html │ ├── globals_eval.html │ ├── globals_func.html │ ├── globals_type.html │ ├── ihex_8h.html │ ├── ihex_8h_source.html │ ├── index.html │ ├── libGIS.config │ ├── nav_f.png │ ├── nav_h.png │ ├── open.png │ ├── srecord_8h.html │ ├── srecord_8h_source.html │ ├── structAtmelGenericRecord.html │ ├── structIHexRecord.html │ ├── structSRecord.html │ ├── struct__AtmelGenericRecord.html │ ├── struct__IHexRecord.html │ ├── struct__SRecord.html │ ├── tab_a.png │ ├── tab_b.gif │ ├── tab_b.png │ ├── tab_h.png │ ├── tab_l.gif │ ├── tab_r.gif │ ├── tab_s.png │ └── tabs.css └── libGIS-docs-1.0.5.pdf ├── ihex.c ├── ihex.h ├── srecord.c ├── srecord.h └── testGIS.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | testGIS 3 | -------------------------------------------------------------------------------- /LICENSE-mit: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 Ivan A. Sergeev 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /LICENSE-public-domain: -------------------------------------------------------------------------------- 1 | This copy of libGIS is licensed as Public Domain, which is free for any kind of use (personal or commercial), without warranty of any kind, and no requirement for attribution. 2 | 3 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 4 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 6 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 7 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 8 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 9 | THE SOFTWARE. 10 | 11 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC ?= gcc 2 | CFLAGS = -std=c99 -Wpedantic -Wall -Wextra -O3 3 | LDFLAGS= 4 | OBJECTS = atmel_generic.o ihex.o srecord.o testGIS.o 5 | PROGNAME = testGIS 6 | 7 | all: $(PROGNAME) 8 | 9 | $(PROGNAME): $(OBJECTS) 10 | $(CC) $(LDFLAGS) -o $@ $(OBJECTS) 11 | 12 | clean: 13 | rm -rf $(PROGNAME) $(OBJECTS) 14 | 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Note: this project is functional, but no longer maintained. 2 | 3 | ## libGIS - Atmel Generic, Intel HEX, and Motorola S-Record Parser Routines 4 | 5 | **ChangeLog** 6 | 7 | * Release 1.0.5 - 02/05/2011 8 | * Interface change!: write, print, and checksum functions now take a pointer to the record structure instead of a copy, for more efficient use of memory. 9 | * Prettier debug printing of Intel HEX8 and Motorola S-Record records 10 | * Clean up of some of the source code comments and doxygen descriptions 11 | * Release 1.0.4 - 07/08/2010 12 | * No source code changes since version 1.0.3, but I've released libGIS as two packages, one that is licensed as purely public domain, for locations where that applies, and one that is licensed as MIT/X11, for locations where "public domain" has no legal standing. 13 | * Release 1.0.3 - 10/10/2009 14 | * Small bug fix: record reader functions handle newlines in data record lines better, and support for the carriage return character for Windows. 15 | * Bug fix: s-record write function no longer writes an inaccurate space between the record start and record type. 16 | * testGIS.c: a redefine of strcasecmp to stricmp for Windows support. 17 | * Cleaned up some compiler warnings from signed/unsigned comparisons. 18 | * Thanks to Brendan McDonnell for the above four fixes. 19 | * Minor documentation clean up. 20 | * Release 1.0.2 - 06/27/2009 21 | * Small bug fix: record reader functions will now return a newline return code when a lone newline in the file (sometimes found at the end) is encountered instead of erroring out with an invalid record error code. 22 | * Release 1.0.0 - 12/24/2006 23 | * Initial Release 24 | 25 | ---- 26 | 27 | **libGIS README** 28 | 29 | libGIS is a collection of utility functions to create, read, and write Atmel Generic, Intel HEX8, and Motorola S-Record formatted files. libGIS is typically not compiled into a library, since the file formats it supports are so specific, and the source code for each file format is contained in only two files. 30 | 31 | I wrote libGIS was because I wanted a clean, flexible, and easy-to-use set of functions to deal with the nasty parsing of these formatted binary files. libGIS supports Intel HEX8 and Motorola S-Record formatted files, which are undoubtedly the most popular in use with embedded systems. libGIS also supports the Atmel Generic binary format, which may be applicable in projects targetting the Atmel AVR. 32 | 33 | libGIS is very convenient for disassembler, assembler, binary file converter, and other related projects. It is written in C (tested with gcc), but can also be compiled with a C++ compiler (such as g++), which means it can be implemented in any C/C++ projects requiring parsing of such formatted files. libGIS uses the standard C library in its backend. 34 | 35 | libGIS is clean and tiny. Each file format is supported with two files, one is the C source code and the other is the C header file, which makes compiling whichever format you need to support very easy. The interface to the utility functions is very straight forward, as demonstrated by the included testGIS.c program. 36 | 37 | The code of each file format parser has a structure to store record information, and 4-5 basic functions to create, read, write, print, and checksum (for Intel HEX8 and Motorola S-Record) records. The error handling in libGIS will never leave you out of the dark, as the possible error codes and what they mean are clearly defined in the header file of the format parser you're using. 38 | 39 | Remember that libGIS is a low-level interface to formatted binary files, and it will not automatically generate, for example, extended addresses in the Intel HEX8 format, or the header record in the S-Record format. libGIS helps in the actual writing and reading of the raw records, not dealing with the content going into them (but still adhering to the record and field size specifications). 40 | 41 | libGIS is offered with two licensing options. The first is Public Domain, which is free for any kind of use (personal or commercial), without warranty of any kind, and no requirement for attribution. The second is MIT/X11. 42 | 43 | The following function prototypes summarize the interface of libGIS: 44 | 45 | Atmel Generic format: 46 | int New_AtmelGenericRecord(uint32_t address, uint16_t data, AtmelGenericRecord *genericRecord); 47 | int Read_AtmelGenericRecord(AtmelGenericRecord *genericRecord, FILE *in); 48 | int Write_AtmelGenericRecord(const AtmelGenericRecord *genericRecord, FILE *out); 49 | void Print_AtmelGenericRecord(const AtmelGenericRecord *genericRecord); 50 | 51 | Intel HEX8 format: 52 | int New_IHexRecord(int type, uint16_t address, const uint8_t *data, int dataLen, IHexRecord *ihexRecord); 53 | int Read_IHexRecord(IHexRecord *ihexRecord, FILE *in); 54 | int Write_IHexRecord(const IHexRecord *ihexRecord, FILE *out); 55 | void Print_IHexRecord(const IHexRecord *ihexRecord); 56 | uint8_t Checksum_IHexRecord(const IHexRecord *ihexRecord); 57 | 58 | Motorola S-Record format: 59 | int New_SRecord(int type, uint32_t address, const uint8_t *data, int dataLen, SRecord *srec); 60 | int Read_SRecord(SRecord *srec, FILE *in); 61 | int Write_SRecord(const SRecord *srec, FILE *out); 62 | void Print_SRecord(const SRecord *srec); 63 | uint8_t Checksum_SRecord(const SRecord *srec); 64 | 65 | This package includes the parsing for the following formats: 66 | 67 | **Atmel Generic format:** atmel_generic.c and atmel_generic.h 68 | 69 | **Intel HEX8 format:** ihex.c and ihex.h 70 | 71 | **Motorola S-Record format:** srecord.c and srecord.h 72 | 73 | Also included is a test program (testGIS.c, with a Makefile to compile it) that prints all of the records contained in a Atmel Generic, Intel HEX8 or Motorola S-Record formatted file, documentation in PDF and html formats, and the README containing all of this. 74 | 75 | Please email me (vsergeev at gmail dot com) any bugs, problems, or suggestions you encounter with using libGIS, they are highly appreciated. 76 | 77 | -------------------------------------------------------------------------------- /atmel_generic.c: -------------------------------------------------------------------------------- 1 | /* 2 | * atmel_generic.c 3 | * Utility functions to create, read, write, and print Atmel Generic binary records. 4 | * 5 | * Written by Vanya A. Sergeev 6 | * Version 1.0.5 - February 2011 7 | * 8 | */ 9 | 10 | #include "atmel_generic.h" 11 | 12 | /* Initializes a new AtmelGenericRecord structure that the paramater genericRecord points to with the passed 13 | * 24-bit integer address, and 16-bit data word. */ 14 | int New_AtmelGenericRecord(uint32_t address, uint16_t data, AtmelGenericRecord *genericRecord) { 15 | /* Assert genericRecord pointer */ 16 | if (genericRecord == NULL) 17 | return ATMEL_GENERIC_ERROR_INVALID_ARGUMENTS; 18 | 19 | genericRecord->address = address; 20 | genericRecord->data = data; 21 | return ATMEL_GENERIC_OK; 22 | } 23 | 24 | 25 | /* Utility function to read an Atmel Generic record from a file */ 26 | int Read_AtmelGenericRecord(AtmelGenericRecord *genericRecord, FILE *in) { 27 | char recordBuff[ATMEL_GENERIC_RECORD_BUFF_SIZE]; 28 | int i; 29 | 30 | /* Check our record pointer and file pointer */ 31 | if (genericRecord == NULL || in == NULL) 32 | return ATMEL_GENERIC_ERROR_INVALID_ARGUMENTS; 33 | 34 | if (fgets(recordBuff, ATMEL_GENERIC_RECORD_BUFF_SIZE, in) == NULL) { 35 | /* In case we hit EOF, don't report a file error */ 36 | if (feof(in) != 0) 37 | return ATMEL_GENERIC_ERROR_EOF; 38 | else 39 | return ATMEL_GENERIC_ERROR_FILE; 40 | } 41 | /* Null-terminate the string at the first sign of a \r or \n */ 42 | for (i = 0; i < (int)strlen(recordBuff); i++) { 43 | if (recordBuff[i] == '\r' || recordBuff[i] == '\n') { 44 | recordBuff[i] = 0; 45 | break; 46 | } 47 | } 48 | 49 | /* Check if we hit a newline */ 50 | if (strlen(recordBuff) == 0) 51 | return ATMEL_GENERIC_ERROR_NEWLINE; 52 | 53 | /* Size check that the record has the address, data, and start code */ 54 | if (strlen(recordBuff) < ATMEL_GENERIC_ADDRESS_LEN + ATMEL_GENERIC_DATA_LEN + 1) 55 | return ATMEL_GENERIC_ERROR_INVALID_RECORD; 56 | 57 | /* Check for the record "start code" (the colon that separates the address and data */ 58 | if (recordBuff[ATMEL_GENERIC_SEPARATOR_OFFSET] != ATMEL_GENERIC_SEPARATOR) 59 | return ATMEL_GENERIC_ERROR_INVALID_RECORD; 60 | 61 | /* Replace the colon "start code" with a 0 so we can convert the ascii hex encoded 62 | * address up to this point */ 63 | recordBuff[ATMEL_GENERIC_SEPARATOR_OFFSET] = 0; 64 | genericRecord->address = (uint32_t)strtoul(recordBuff, (char **)NULL, 16); 65 | 66 | /* Convert the rest of the data past the colon, this string has been null terminated at 67 | * the end already */ 68 | genericRecord->data = (uint16_t)strtoul(recordBuff+ATMEL_GENERIC_SEPARATOR_OFFSET+1, (char **)NULL, 16); 69 | 70 | return ATMEL_GENERIC_OK; 71 | } 72 | 73 | /* Utility function to write an Atmel Generic record to a file */ 74 | int Write_AtmelGenericRecord(const AtmelGenericRecord *genericRecord, FILE *out) { 75 | /* Check our record pointer and file pointer */ 76 | if (genericRecord == NULL || out == NULL) 77 | return ATMEL_GENERIC_ERROR_INVALID_ARGUMENTS; 78 | 79 | if (fprintf(out, "%2.6X%c%2.4X\r\n", genericRecord->address, ATMEL_GENERIC_SEPARATOR, genericRecord->data) < 0) 80 | return ATMEL_GENERIC_ERROR_FILE; 81 | 82 | return ATMEL_GENERIC_OK; 83 | } 84 | 85 | /* Utility function to print the information stored in an Atmel Generic record */ 86 | void Print_AtmelGenericRecord(const AtmelGenericRecord *genericRecord) { 87 | printf("Atmel Generic Address: \t0x%2.6X\n", genericRecord->address); 88 | printf("Atmel Generic Data: \t0x%2.4X\n", genericRecord->data); 89 | } 90 | 91 | -------------------------------------------------------------------------------- /atmel_generic.h: -------------------------------------------------------------------------------- 1 | #ifndef ATMEL_GENERIC_H 2 | #define ATMEL_GENERIC_H 3 | /** 4 | * \file atmel_generic.h 5 | * \brief Low-level utility functions to create, read, write, and print Atmel Generic binary records. 6 | * \author Vanya A. Sergeev 7 | * \date February 2011 8 | * \version 1.0.5 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | /* General definition of the Atmel Generic record specifications. */ 17 | enum _AtmelGenericDefinitions { 18 | /* 16 should be plenty of space to read in an Atmel Generic record (11 bytes in reality) */ 19 | ATMEL_GENERIC_RECORD_BUFF_SIZE = 16, 20 | /* Offsets and lengths of various fields in an Atmel Generic record */ 21 | ATMEL_GENERIC_ADDRESS_LEN = 6, 22 | ATMEL_GENERIC_DATA_LEN = 4, 23 | /* The separator character, a colon, that separates the data and address fields in the Atmel Generic records */ 24 | ATMEL_GENERIC_SEPARATOR_OFFSET = 6, 25 | ATMEL_GENERIC_SEPARATOR = ':', 26 | }; 27 | 28 | /** 29 | * All of the possible error codes the Atmel Generic record utility functions may return. 30 | */ 31 | enum AtmelGenericErrors { 32 | ATMEL_GENERIC_OK = 0, /**< Error code for success or no error. */ 33 | ATMEL_GENERIC_ERROR_FILE = -1, /**< Error code for error while reading from or writing to a file. You may check errno for the exact error if this error code is encountered. */ 34 | ATMEL_GENERIC_ERROR_EOF = -2, /**< Error code for encountering end-of-file when reading from a file. */ 35 | ATMEL_GENERIC_ERROR_INVALID_RECORD = -3, /**< Error code for error if an invalid record was read. */ 36 | ATMEL_GENERIC_ERROR_INVALID_ARGUMENTS = -4, /**< Error code for error from invalid arguments passed to function. */ 37 | ATMEL_GENERIC_ERROR_NEWLINE = -5, /**< Error code for encountering a newline with no record when reading from a file. */ 38 | }; 39 | 40 | /** 41 | * Structure to hold the fields of an Atmel Generic record. 42 | */ 43 | typedef struct { 44 | uint32_t address; /**< The 24-bit address field of the record. */ 45 | uint16_t data; /**< The 16-bit data field of the record. */ 46 | } AtmelGenericRecord; 47 | 48 | /** 49 | * Sets all of the record fields of an Atmel Generic record structure. 50 | * Note that the Atmel Generic record only supports 24-bit addresses. 51 | * \param address The 24-bit address of the data. 52 | * \param data The 16-bit word of data. 53 | * \param genericRecord A pointer to the target Atmel Generic record structure where these fields will be set. 54 | * \return ATMEL_GENERIC_OK on success, otherwise one of the ATMEL_GENERIC_ERROR_ error codes. 55 | * \retval ATMEL_GENERIC_OK on success. 56 | * \retval ATMEL_GENERIC_ERROR_INVALID_ARGUMENTS if the record pointer is NULL. 57 | */ 58 | int New_AtmelGenericRecord(uint32_t address, uint16_t data, AtmelGenericRecord *genericRecord); 59 | 60 | /** 61 | * Reads an Atmel Generic record from an opened file. 62 | * \param genericRecord A pointer to the Atmel Generic record structure that will store the read record. 63 | * \param in A file pointer to an opened file that can be read. 64 | * \return ATMEL_GENERIC_OK on success, otherwise one of the ATMEL_GENERIC_ERROR_ error codes. 65 | * \retval ATMEL_GENERIC_OK on success. 66 | * \retval ATMEL_GENERIC_ERROR_INVALID_ARGUMENTS if the record pointer or file pointer is NULL. 67 | * \retval ATMEL_GENERIC_ERROR_EOF if end-of-file has been reached. 68 | * \retval ATMEL_GENERIC_ERROR_FILE if a file reading error has occured. 69 | * \retval ATMEL_GENERIC_INVALID_RECORD if the record read is invalid (record did not match specifications). 70 | */ 71 | int Read_AtmelGenericRecord(AtmelGenericRecord *genericRecord, FILE *in); 72 | 73 | /** 74 | * Writes an Atmel Generic record to an opened file. 75 | * Note that the Atmel Generic record only supports 24-bit addresses, so only 24-bits of the address stored in the Atmel Generic record structure that genericRecord points to will be written. 76 | * \param genericRecord A pointer to the Atmel Generic record structure. 77 | * \param out A file pointer to an opened file that can be written to. 78 | * \return ATMEL_GENERIC_OK on success, otherwise one of the ATMEL_GENERIC_ERROR_ error codes. 79 | * \retval ATMEL_GENERIC_OK on success. 80 | * \retval ATMEL_GENERIC_ERROR_INVALID_ARGUMENTS if the record pointer or file pointer is NULL. 81 | * \retval ATMEL_GENERIC_ERROR_FILE if a file writing error has occured. 82 | */ 83 | int Write_AtmelGenericRecord(const AtmelGenericRecord *genericRecord, FILE *out); 84 | 85 | /** 86 | * Prints the contents of an Atmel Generic record structure to stdout. 87 | * The record dump consists of the address and data fields of the record. 88 | * \param genericRecord A pointer to the Atmel Generic record structure. 89 | * \return Always returns ATMEL_GENERIC_OK (success). 90 | * \retval ATMEL_GENERIC_OK on success. 91 | */ 92 | void Print_AtmelGenericRecord(const AtmelGenericRecord *genericRecord); 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /docs/html/annotated.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: Data Structures 6 | 7 | 8 | 9 | 10 | 11 | 26 |
27 |
28 |

Data Structures

29 |
30 |
31 | Here are the data structures with brief descriptions: 32 | 33 | 34 | 35 |
AtmelGenericRecord
IHexRecord
SRecord
36 |
37 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /docs/html/atmel__generic_8h.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: atmel_generic.h File Reference 6 | 7 | 8 | 9 | 10 | 11 | 26 |
27 | 31 |
32 |

atmel_generic.h File Reference

33 |
34 |
35 | 36 |

Low-level utility functions to create, read, write, and print Atmel Generic binary records. 37 | More...

38 | #include <stdio.h>
39 | #include <stdint.h>
40 | #include <stdlib.h>
41 | #include <string.h>
42 | 43 |

Go to the source code of this file.

44 | 45 | 47 | 48 | 50 | 59 | 69 | 71 | 72 | 73 | 74 | 75 |

46 | Data Structures

struct  AtmelGenericRecord

49 | Enumerations

enum  _AtmelGenericDefinitions {
51 |   ATMEL_GENERIC_RECORD_BUFF_SIZE = 16, 52 | ATMEL_GENERIC_ADDRESS_LEN = 6, 53 | ATMEL_GENERIC_DATA_LEN = 4, 54 | ATMEL_GENERIC_SEPARATOR_OFFSET = 6, 55 |
56 |   ATMEL_GENERIC_SEPARATOR = ':' 57 |
58 | }
enum  AtmelGenericErrors {
60 |   ATMEL_GENERIC_OK = 0, 61 | ATMEL_GENERIC_ERROR_FILE = -1, 62 | ATMEL_GENERIC_ERROR_EOF = -2, 63 | ATMEL_GENERIC_ERROR_INVALID_RECORD = -3, 64 |
65 |   ATMEL_GENERIC_ERROR_INVALID_ARGUMENTS = -4, 66 | ATMEL_GENERIC_ERROR_NEWLINE = -5 67 |
68 | }

70 | Functions

int New_AtmelGenericRecord (uint32_t address, uint16_t data, AtmelGenericRecord *genericRecord)
int Read_AtmelGenericRecord (AtmelGenericRecord *genericRecord, FILE *in)
int Write_AtmelGenericRecord (const AtmelGenericRecord *genericRecord, FILE *out)
void Print_AtmelGenericRecord (const AtmelGenericRecord *genericRecord)
76 |

Detailed Description

77 |

Low-level utility functions to create, read, write, and print Atmel Generic binary records.

78 |
Author:
Vanya A. Sergeev <vsergeev@gmail.com>
79 |
Date:
February 2011
80 |
Version:
1.0.5
81 |

Enumeration Type Documentation

82 | 83 |
84 |
85 | 86 | 87 | 88 | 89 |
enum AtmelGenericErrors
90 |
91 |
92 |

All of the possible error codes the Atmel Generic record utility functions may return.

93 |
Enumerator:
94 | 97 | 100 | 103 | 106 | 109 | 112 |
ATMEL_GENERIC_OK  95 |

Error code for success or no error.

96 |
ATMEL_GENERIC_ERROR_FILE  98 |

Error code for error while reading from or writing to a file. You may check errno for the exact error if this error code is encountered.

99 |
ATMEL_GENERIC_ERROR_EOF  101 |

Error code for encountering end-of-file when reading from a file.

102 |
ATMEL_GENERIC_ERROR_INVALID_RECORD  104 |

Error code for error if an invalid record was read.

105 |
ATMEL_GENERIC_ERROR_INVALID_ARGUMENTS  107 |

Error code for error from invalid arguments passed to function.

108 |
ATMEL_GENERIC_ERROR_NEWLINE  110 |

Error code for encountering a newline with no record when reading from a file.

111 |
113 |
114 |
115 | 116 |
117 |
118 |

Function Documentation

119 | 120 |
121 |
122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 |
int New_AtmelGenericRecord (uint32_t  address,
uint16_t  data,
AtmelGenericRecord genericRecord 
)
147 |
148 |
149 |

Sets all of the record fields of an Atmel Generic record structure. Note that the Atmel Generic record only supports 24-bit addresses.

150 |
Parameters:
151 | 152 | 153 | 154 | 155 |
address The 24-bit address of the data.
data The 16-bit word of data.
genericRecord A pointer to the target Atmel Generic record structure where these fields will be set.
156 |
157 |
158 |
Returns:
ATMEL_GENERIC_OK on success, otherwise one of the ATMEL_GENERIC_ERROR_ error codes.
159 |
Return values:
160 | 161 | 162 | 163 |
ATMEL_GENERIC_OK on success.
ATMEL_GENERIC_ERROR_INVALID_ARGUMENTS if the record pointer is NULL.
164 |
165 |
166 | 167 |
168 |
169 | 170 |
171 |
172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 |
void Print_AtmelGenericRecord (const AtmelGenericRecord genericRecord ) 
182 |
183 |
184 |

Prints the contents of an Atmel Generic record structure to stdout. The record dump consists of the address and data fields of the record.

185 |
Parameters:
186 | 187 | 188 |
genericRecord A pointer to the Atmel Generic record structure.
189 |
190 |
191 |
Returns:
Always returns ATMEL_GENERIC_OK (success).
192 |
Return values:
193 | 194 | 195 |
ATMEL_GENERIC_OK on success.
196 |
197 |
198 | 199 |
200 |
201 | 202 |
203 |
204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 |
int Read_AtmelGenericRecord (AtmelGenericRecord genericRecord,
FILE *  in 
)
223 |
224 |
225 |

Reads an Atmel Generic record from an opened file.

226 |
Parameters:
227 | 228 | 229 | 230 |
genericRecord A pointer to the Atmel Generic record structure that will store the read record.
in A file pointer to an opened file that can be read.
231 |
232 |
233 |
Returns:
ATMEL_GENERIC_OK on success, otherwise one of the ATMEL_GENERIC_ERROR_ error codes.
234 |
Return values:
235 | 236 | 237 | 238 | 239 | 240 | 241 |
ATMEL_GENERIC_OK on success.
ATMEL_GENERIC_ERROR_INVALID_ARGUMENTS if the record pointer or file pointer is NULL.
ATMEL_GENERIC_ERROR_EOF if end-of-file has been reached.
ATMEL_GENERIC_ERROR_FILE if a file reading error has occured.
ATMEL_GENERIC_INVALID_RECORD if the record read is invalid (record did not match specifications).
242 |
243 |
244 | 245 |
246 |
247 | 248 |
249 |
250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 |
int Write_AtmelGenericRecord (const AtmelGenericRecord genericRecord,
FILE *  out 
)
269 |
270 |
271 |

Writes an Atmel Generic record to an opened file. Note that the Atmel Generic record only supports 24-bit addresses, so only 24-bits of the address stored in the Atmel Generic record structure that genericRecord points to will be written.

272 |
Parameters:
273 | 274 | 275 | 276 |
genericRecord A pointer to the Atmel Generic record structure.
out A file pointer to an opened file that can be written to.
277 |
278 |
279 |
Returns:
ATMEL_GENERIC_OK on success, otherwise one of the ATMEL_GENERIC_ERROR_ error codes.
280 |
Return values:
281 | 282 | 283 | 284 | 285 |
ATMEL_GENERIC_OK on success.
ATMEL_GENERIC_ERROR_INVALID_ARGUMENTS if the record pointer or file pointer is NULL.
ATMEL_GENERIC_ERROR_FILE if a file writing error has occured.
286 |
287 |
288 | 289 |
290 |
291 |
292 | 295 | 296 | 297 | -------------------------------------------------------------------------------- /docs/html/atmel__generic_8h_source.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: atmel_generic.h Source File 6 | 7 | 8 | 9 | 10 | 11 | 75 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /docs/html/bc_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsergeev/libGIS/f82b9dd3018d479230ad68a02da41fa95cad9123/docs/html/bc_s.png -------------------------------------------------------------------------------- /docs/html/classes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: Alphabetical List 6 | 7 | 8 | 9 | 10 | 11 | 26 |
27 |
28 |

Data Structure Index

29 |
30 |
31 |
A | I | S
32 | 33 |
  A  
34 |
  I  
35 |
IHexRecord   
  S  
36 |
SRecord   
AtmelGenericRecord   
A | I | S
37 |
38 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /docs/html/closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsergeev/libGIS/f82b9dd3018d479230ad68a02da41fa95cad9123/docs/html/closed.png -------------------------------------------------------------------------------- /docs/html/doxygen.css: -------------------------------------------------------------------------------- 1 | /* The standard CSS for doxygen */ 2 | 3 | body, table, div, p, dl { 4 | font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif; 5 | font-size: 12px; 6 | } 7 | 8 | /* @group Heading Levels */ 9 | 10 | h1 { 11 | font-size: 150%; 12 | } 13 | 14 | h2 { 15 | font-size: 120%; 16 | } 17 | 18 | h3 { 19 | font-size: 100%; 20 | } 21 | 22 | dt { 23 | font-weight: bold; 24 | } 25 | 26 | div.multicol { 27 | -moz-column-gap: 1em; 28 | -webkit-column-gap: 1em; 29 | -moz-column-count: 3; 30 | -webkit-column-count: 3; 31 | } 32 | 33 | p.startli, p.startdd, p.starttd { 34 | margin-top: 2px; 35 | } 36 | 37 | p.endli { 38 | margin-bottom: 0px; 39 | } 40 | 41 | p.enddd { 42 | margin-bottom: 4px; 43 | } 44 | 45 | p.endtd { 46 | margin-bottom: 2px; 47 | } 48 | 49 | /* @end */ 50 | 51 | caption { 52 | font-weight: bold; 53 | } 54 | 55 | span.legend { 56 | font-size: 70%; 57 | text-align: center; 58 | } 59 | 60 | h3.version { 61 | font-size: 90%; 62 | text-align: center; 63 | } 64 | 65 | div.qindex, div.navtab{ 66 | background-color: #EBEFF6; 67 | border: 1px solid #A3B4D7; 68 | text-align: center; 69 | margin: 2px; 70 | padding: 2px; 71 | } 72 | 73 | div.qindex, div.navpath { 74 | width: 100%; 75 | line-height: 140%; 76 | } 77 | 78 | div.navtab { 79 | margin-right: 15px; 80 | } 81 | 82 | /* @group Link Styling */ 83 | 84 | a { 85 | color: #3D578C; 86 | font-weight: normal; 87 | text-decoration: none; 88 | } 89 | 90 | .contents a:visited { 91 | color: #4665A2; 92 | } 93 | 94 | a:hover { 95 | text-decoration: underline; 96 | } 97 | 98 | a.qindex { 99 | font-weight: bold; 100 | } 101 | 102 | a.qindexHL { 103 | font-weight: bold; 104 | background-color: #9CAFD4; 105 | color: #ffffff; 106 | border: 1px double #869DCA; 107 | } 108 | 109 | .contents a.qindexHL:visited { 110 | color: #ffffff; 111 | } 112 | 113 | a.el { 114 | font-weight: bold; 115 | } 116 | 117 | a.elRef { 118 | } 119 | 120 | a.code { 121 | color: #4665A2; 122 | } 123 | 124 | a.codeRef { 125 | color: #4665A2; 126 | } 127 | 128 | /* @end */ 129 | 130 | dl.el { 131 | margin-left: -1cm; 132 | } 133 | 134 | .fragment { 135 | font-family: monospace, fixed; 136 | font-size: 105%; 137 | } 138 | 139 | pre.fragment { 140 | border: 1px solid #C4CFE5; 141 | background-color: #FBFCFD; 142 | padding: 4px 6px; 143 | margin: 4px 8px 4px 2px; 144 | overflow: auto; 145 | word-wrap: break-word; 146 | font-size: 9pt; 147 | line-height: 125%; 148 | } 149 | 150 | div.ah { 151 | background-color: black; 152 | font-weight: bold; 153 | color: #ffffff; 154 | margin-bottom: 3px; 155 | margin-top: 3px; 156 | padding: 0.2em; 157 | border: solid thin #333; 158 | border-radius: 0.5em; 159 | -webkit-border-radius: .5em; 160 | -moz-border-radius: .5em; 161 | -webkit-box-shadow: 2px 2px 3px #999; 162 | -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; 163 | background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); 164 | background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); 165 | } 166 | 167 | div.groupHeader { 168 | margin-left: 16px; 169 | margin-top: 12px; 170 | margin-bottom: 6px; 171 | font-weight: bold; 172 | } 173 | 174 | div.groupText { 175 | margin-left: 16px; 176 | font-style: italic; 177 | } 178 | 179 | body { 180 | background: white; 181 | color: black; 182 | margin: 0; 183 | } 184 | 185 | div.contents { 186 | margin-top: 10px; 187 | margin-left: 10px; 188 | margin-right: 10px; 189 | } 190 | 191 | td.indexkey { 192 | background-color: #EBEFF6; 193 | font-weight: bold; 194 | border: 1px solid #C4CFE5; 195 | margin: 2px 0px 2px 0; 196 | padding: 2px 10px; 197 | } 198 | 199 | td.indexvalue { 200 | background-color: #EBEFF6; 201 | border: 1px solid #C4CFE5; 202 | padding: 2px 10px; 203 | margin: 2px 0px; 204 | } 205 | 206 | tr.memlist { 207 | background-color: #EEF1F7; 208 | } 209 | 210 | p.formulaDsp { 211 | text-align: center; 212 | } 213 | 214 | img.formulaDsp { 215 | 216 | } 217 | 218 | img.formulaInl { 219 | vertical-align: middle; 220 | } 221 | 222 | div.center { 223 | text-align: center; 224 | margin-top: 0px; 225 | margin-bottom: 0px; 226 | padding: 0px; 227 | } 228 | 229 | div.center img { 230 | border: 0px; 231 | } 232 | 233 | address.footer { 234 | text-align: right; 235 | padding-right: 12px; 236 | } 237 | 238 | img.footer { 239 | border: 0px; 240 | vertical-align: middle; 241 | } 242 | 243 | /* @group Code Colorization */ 244 | 245 | span.keyword { 246 | color: #008000 247 | } 248 | 249 | span.keywordtype { 250 | color: #604020 251 | } 252 | 253 | span.keywordflow { 254 | color: #e08000 255 | } 256 | 257 | span.comment { 258 | color: #800000 259 | } 260 | 261 | span.preprocessor { 262 | color: #806020 263 | } 264 | 265 | span.stringliteral { 266 | color: #002080 267 | } 268 | 269 | span.charliteral { 270 | color: #008080 271 | } 272 | 273 | span.vhdldigit { 274 | color: #ff00ff 275 | } 276 | 277 | span.vhdlchar { 278 | color: #000000 279 | } 280 | 281 | span.vhdlkeyword { 282 | color: #700070 283 | } 284 | 285 | span.vhdllogic { 286 | color: #ff0000 287 | } 288 | 289 | /* @end */ 290 | 291 | /* 292 | .search { 293 | color: #003399; 294 | font-weight: bold; 295 | } 296 | 297 | form.search { 298 | margin-bottom: 0px; 299 | margin-top: 0px; 300 | } 301 | 302 | input.search { 303 | font-size: 75%; 304 | color: #000080; 305 | font-weight: normal; 306 | background-color: #e8eef2; 307 | } 308 | */ 309 | 310 | td.tiny { 311 | font-size: 75%; 312 | } 313 | 314 | .dirtab { 315 | padding: 4px; 316 | border-collapse: collapse; 317 | border: 1px solid #A3B4D7; 318 | } 319 | 320 | th.dirtab { 321 | background: #EBEFF6; 322 | font-weight: bold; 323 | } 324 | 325 | hr { 326 | height: 0px; 327 | border: none; 328 | border-top: 1px solid #4A6AAA; 329 | } 330 | 331 | hr.footer { 332 | height: 1px; 333 | } 334 | 335 | /* @group Member Descriptions */ 336 | 337 | table.memberdecls { 338 | border-spacing: 0px; 339 | padding: 0px; 340 | } 341 | 342 | .mdescLeft, .mdescRight, 343 | .memItemLeft, .memItemRight, 344 | .memTemplItemLeft, .memTemplItemRight, .memTemplParams { 345 | background-color: #F9FAFC; 346 | border: none; 347 | margin: 4px; 348 | padding: 1px 0 0 8px; 349 | } 350 | 351 | .mdescLeft, .mdescRight { 352 | padding: 0px 8px 4px 8px; 353 | color: #555; 354 | } 355 | 356 | .memItemLeft, .memItemRight, .memTemplParams { 357 | border-top: 1px solid #C4CFE5; 358 | } 359 | 360 | .memItemLeft, .memTemplItemLeft { 361 | white-space: nowrap; 362 | } 363 | 364 | .memTemplParams { 365 | color: #4665A2; 366 | white-space: nowrap; 367 | } 368 | 369 | /* @end */ 370 | 371 | /* @group Member Details */ 372 | 373 | /* Styles for detailed member documentation */ 374 | 375 | .memtemplate { 376 | font-size: 80%; 377 | color: #4665A2; 378 | font-weight: normal; 379 | margin-left: 3px; 380 | } 381 | 382 | .memnav { 383 | background-color: #EBEFF6; 384 | border: 1px solid #A3B4D7; 385 | text-align: center; 386 | margin: 2px; 387 | margin-right: 15px; 388 | padding: 2px; 389 | } 390 | 391 | .memitem { 392 | padding: 0; 393 | margin-bottom: 10px; 394 | } 395 | 396 | .memname { 397 | white-space: nowrap; 398 | font-weight: bold; 399 | margin-left: 6px; 400 | } 401 | 402 | .memproto { 403 | border-top: 1px solid #A8B8D9; 404 | border-left: 1px solid #A8B8D9; 405 | border-right: 1px solid #A8B8D9; 406 | padding: 6px 0px 6px 0px; 407 | color: #253555; 408 | font-weight: bold; 409 | text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); 410 | /* firefox specific markup */ 411 | -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; 412 | -moz-border-radius-topright: 8px; 413 | -moz-border-radius-topleft: 8px; 414 | /* webkit specific markup */ 415 | -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); 416 | -webkit-border-top-right-radius: 8px; 417 | -webkit-border-top-left-radius: 8px; 418 | background-image:url('nav_f.png'); 419 | background-repeat:repeat-x; 420 | background-color: #E2E8F2; 421 | 422 | } 423 | 424 | .memdoc { 425 | border-bottom: 1px solid #A8B8D9; 426 | border-left: 1px solid #A8B8D9; 427 | border-right: 1px solid #A8B8D9; 428 | padding: 2px 5px; 429 | background-color: #FBFCFD; 430 | border-top-width: 0; 431 | /* firefox specific markup */ 432 | -moz-border-radius-bottomleft: 8px; 433 | -moz-border-radius-bottomright: 8px; 434 | -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; 435 | background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7); 436 | /* webkit specific markup */ 437 | -webkit-border-bottom-left-radius: 8px; 438 | -webkit-border-bottom-right-radius: 8px; 439 | -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); 440 | background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7F8FB), to(#EEF1F7)); 441 | } 442 | 443 | .paramkey { 444 | text-align: right; 445 | } 446 | 447 | .paramtype { 448 | white-space: nowrap; 449 | } 450 | 451 | .paramname { 452 | color: #602020; 453 | white-space: nowrap; 454 | } 455 | .paramname em { 456 | font-style: normal; 457 | } 458 | 459 | /* @end */ 460 | 461 | /* @group Directory (tree) */ 462 | 463 | /* for the tree view */ 464 | 465 | .ftvtree { 466 | font-family: sans-serif; 467 | margin: 0px; 468 | } 469 | 470 | /* these are for tree view when used as main index */ 471 | 472 | .directory { 473 | font-size: 9pt; 474 | font-weight: bold; 475 | margin: 5px; 476 | } 477 | 478 | .directory h3 { 479 | margin: 0px; 480 | margin-top: 1em; 481 | font-size: 11pt; 482 | } 483 | 484 | /* 485 | The following two styles can be used to replace the root node title 486 | with an image of your choice. Simply uncomment the next two styles, 487 | specify the name of your image and be sure to set 'height' to the 488 | proper pixel height of your image. 489 | */ 490 | 491 | /* 492 | .directory h3.swap { 493 | height: 61px; 494 | background-repeat: no-repeat; 495 | background-image: url("yourimage.gif"); 496 | } 497 | .directory h3.swap span { 498 | display: none; 499 | } 500 | */ 501 | 502 | .directory > h3 { 503 | margin-top: 0; 504 | } 505 | 506 | .directory p { 507 | margin: 0px; 508 | white-space: nowrap; 509 | } 510 | 511 | .directory div { 512 | display: none; 513 | margin: 0px; 514 | } 515 | 516 | .directory img { 517 | vertical-align: -30%; 518 | } 519 | 520 | /* these are for tree view when not used as main index */ 521 | 522 | .directory-alt { 523 | font-size: 100%; 524 | font-weight: bold; 525 | } 526 | 527 | .directory-alt h3 { 528 | margin: 0px; 529 | margin-top: 1em; 530 | font-size: 11pt; 531 | } 532 | 533 | .directory-alt > h3 { 534 | margin-top: 0; 535 | } 536 | 537 | .directory-alt p { 538 | margin: 0px; 539 | white-space: nowrap; 540 | } 541 | 542 | .directory-alt div { 543 | display: none; 544 | margin: 0px; 545 | } 546 | 547 | .directory-alt img { 548 | vertical-align: -30%; 549 | } 550 | 551 | /* @end */ 552 | 553 | div.dynheader { 554 | margin-top: 8px; 555 | } 556 | 557 | address { 558 | font-style: normal; 559 | color: #2A3D61; 560 | } 561 | 562 | table.doxtable { 563 | border-collapse:collapse; 564 | } 565 | 566 | table.doxtable td, table.doxtable th { 567 | border: 1px solid #2D4068; 568 | padding: 3px 7px 2px; 569 | } 570 | 571 | table.doxtable th { 572 | background-color: #374F7F; 573 | color: #FFFFFF; 574 | font-size: 110%; 575 | padding-bottom: 4px; 576 | padding-top: 5px; 577 | text-align:left; 578 | } 579 | 580 | .tabsearch { 581 | top: 0px; 582 | left: 10px; 583 | height: 36px; 584 | background-image: url('tab_b.png'); 585 | z-index: 101; 586 | overflow: hidden; 587 | font-size: 13px; 588 | } 589 | 590 | .navpath ul 591 | { 592 | font-size: 11px; 593 | background-image:url('tab_b.png'); 594 | background-repeat:repeat-x; 595 | height:30px; 596 | line-height:30px; 597 | color:#8AA0CC; 598 | border:solid 1px #C2CDE4; 599 | overflow:hidden; 600 | margin:0px; 601 | padding:0px; 602 | } 603 | 604 | .navpath li 605 | { 606 | list-style-type:none; 607 | float:left; 608 | padding-left:10px; 609 | padding-right: 15px; 610 | background-image:url('bc_s.png'); 611 | background-repeat:no-repeat; 612 | background-position:right; 613 | color:#364D7C; 614 | } 615 | 616 | .navpath a 617 | { 618 | height:32px; 619 | display:block; 620 | text-decoration: none; 621 | outline: none; 622 | } 623 | 624 | .navpath a:hover 625 | { 626 | color:#6884BD; 627 | } 628 | 629 | div.summary 630 | { 631 | float: right; 632 | font-size: 8pt; 633 | padding-right: 5px; 634 | width: 50%; 635 | text-align: right; 636 | } 637 | 638 | div.summary a 639 | { 640 | white-space: nowrap; 641 | } 642 | 643 | div.header 644 | { 645 | background-image:url('nav_h.png'); 646 | background-repeat:repeat-x; 647 | background-color: #F9FAFC; 648 | margin: 0px; 649 | border-bottom: 1px solid #C4CFE5; 650 | } 651 | 652 | div.headertitle 653 | { 654 | padding: 5px 5px 5px 10px; 655 | } 656 | 657 | -------------------------------------------------------------------------------- /docs/html/doxygen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsergeev/libGIS/f82b9dd3018d479230ad68a02da41fa95cad9123/docs/html/doxygen.png -------------------------------------------------------------------------------- /docs/html/files.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: File Index 6 | 7 | 8 | 9 | 10 | 11 | 26 |
27 |
28 |

File List

29 |
30 |
31 | Here is a list of all documented files with brief descriptions: 32 | 33 | 34 | 35 |
atmel_generic.h [code]Low-level utility functions to create, read, write, and print Atmel Generic binary records
ihex.h [code]Low-level utility functions to create, read, write, and print Intel HEX8 binary records
srecord.h [code]Low-level utility functions to create, read, write, and print Motorola S-Record binary records
36 |
37 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /docs/html/functions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: Data Fields 6 | 7 | 8 | 9 | 10 | 11 | 32 |
33 | Here is a list of all documented struct and union fields with links to the struct/union documentation for each field: 57 |
58 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /docs/html/functions_vars.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: Data Fields - Variables 6 | 7 | 8 | 9 | 10 | 11 | 32 |
33 |   57 |
58 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /docs/html/globals.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: Data Fields 6 | 7 | 8 | 9 | 10 | 11 | 46 |
47 | Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation: 48 | 49 |

- a -

72 | 73 | 74 |

- c -

    75 |
  • Checksum_IHexRecord() 76 | : ihex.h 77 |
  • 78 |
  • Checksum_SRecord() 79 | : srecord.h 80 |
  • 81 |
82 | 83 | 84 |

- i -

    85 |
  • IHEX_ERROR_EOF 86 | : ihex.h 87 |
  • 88 |
  • IHEX_ERROR_FILE 89 | : ihex.h 90 |
  • 91 |
  • IHEX_ERROR_INVALID_ARGUMENTS 92 | : ihex.h 93 |
  • 94 |
  • IHEX_ERROR_INVALID_RECORD 95 | : ihex.h 96 |
  • 97 |
  • IHEX_ERROR_NEWLINE 98 | : ihex.h 99 |
  • 100 |
  • IHEX_OK 101 | : ihex.h 102 |
  • 103 |
  • IHEX_TYPE_00 104 | : ihex.h 105 |
  • 106 |
  • IHEX_TYPE_01 107 | : ihex.h 108 |
  • 109 |
  • IHEX_TYPE_02 110 | : ihex.h 111 |
  • 112 |
  • IHEX_TYPE_03 113 | : ihex.h 114 |
  • 115 |
  • IHEX_TYPE_04 116 | : ihex.h 117 |
  • 118 |
  • IHEX_TYPE_05 119 | : ihex.h 120 |
  • 121 |
  • IHexErrors 122 | : ihex.h 123 |
  • 124 |
  • IHexRecordTypes 125 | : ihex.h 126 |
  • 127 |
128 | 129 | 130 |

- n -

    131 |
  • New_AtmelGenericRecord() 132 | : atmel_generic.h 133 |
  • 134 |
  • New_IHexRecord() 135 | : ihex.h 136 |
  • 137 |
  • New_SRecord() 138 | : srecord.h 139 |
  • 140 |
141 | 142 | 143 |

- p -

    144 |
  • Print_AtmelGenericRecord() 145 | : atmel_generic.h 146 |
  • 147 |
  • Print_IHexRecord() 148 | : ihex.h 149 |
  • 150 |
  • Print_SRecord() 151 | : srecord.h 152 |
  • 153 |
154 | 155 | 156 |

- r -

    157 |
  • Read_AtmelGenericRecord() 158 | : atmel_generic.h 159 |
  • 160 |
  • Read_IHexRecord() 161 | : ihex.h 162 |
  • 163 |
  • Read_SRecord() 164 | : srecord.h 165 |
  • 166 |
167 | 168 | 169 |

- s -

    170 |
  • SRECORD_ERROR_EOF 171 | : srecord.h 172 |
  • 173 |
  • SRECORD_ERROR_FILE 174 | : srecord.h 175 |
  • 176 |
  • SRECORD_ERROR_INVALID_ARGUMENTS 177 | : srecord.h 178 |
  • 179 |
  • SRECORD_ERROR_INVALID_RECORD 180 | : srecord.h 181 |
  • 182 |
  • SRECORD_ERROR_NEWLINE 183 | : srecord.h 184 |
  • 185 |
  • SRECORD_OK 186 | : srecord.h 187 |
  • 188 |
  • SRECORD_TYPE_S0 189 | : srecord.h 190 |
  • 191 |
  • SRECORD_TYPE_S1 192 | : srecord.h 193 |
  • 194 |
  • SRECORD_TYPE_S2 195 | : srecord.h 196 |
  • 197 |
  • SRECORD_TYPE_S3 198 | : srecord.h 199 |
  • 200 |
  • SRECORD_TYPE_S4 201 | : srecord.h 202 |
  • 203 |
  • SRECORD_TYPE_S5 204 | : srecord.h 205 |
  • 206 |
  • SRECORD_TYPE_S6 207 | : srecord.h 208 |
  • 209 |
  • SRECORD_TYPE_S7 210 | : srecord.h 211 |
  • 212 |
  • SRECORD_TYPE_S8 213 | : srecord.h 214 |
  • 215 |
  • SRECORD_TYPE_S9 216 | : srecord.h 217 |
  • 218 |
  • SRecordErrors 219 | : srecord.h 220 |
  • 221 |
  • SRecordTypes 222 | : srecord.h 223 |
  • 224 |
225 | 226 | 227 |

- w -

    228 |
  • Write_AtmelGenericRecord() 229 | : atmel_generic.h 230 |
  • 231 |
  • Write_IHexRecord() 232 | : ihex.h 233 |
  • 234 |
  • Write_SRecord() 235 | : srecord.h 236 |
  • 237 |
238 |
239 | 242 | 243 | 244 | -------------------------------------------------------------------------------- /docs/html/globals_enum.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: Data Fields 6 | 7 | 8 | 9 | 10 | 11 | 34 |
35 |   52 |
53 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /docs/html/globals_eval.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: Data Fields 6 | 7 | 8 | 9 | 10 | 11 | 41 |
42 |   43 | 44 |

- a -

64 | 65 | 66 |

- i -

    67 |
  • IHEX_ERROR_EOF 68 | : ihex.h 69 |
  • 70 |
  • IHEX_ERROR_FILE 71 | : ihex.h 72 |
  • 73 |
  • IHEX_ERROR_INVALID_ARGUMENTS 74 | : ihex.h 75 |
  • 76 |
  • IHEX_ERROR_INVALID_RECORD 77 | : ihex.h 78 |
  • 79 |
  • IHEX_ERROR_NEWLINE 80 | : ihex.h 81 |
  • 82 |
  • IHEX_OK 83 | : ihex.h 84 |
  • 85 |
  • IHEX_TYPE_00 86 | : ihex.h 87 |
  • 88 |
  • IHEX_TYPE_01 89 | : ihex.h 90 |
  • 91 |
  • IHEX_TYPE_02 92 | : ihex.h 93 |
  • 94 |
  • IHEX_TYPE_03 95 | : ihex.h 96 |
  • 97 |
  • IHEX_TYPE_04 98 | : ihex.h 99 |
  • 100 |
  • IHEX_TYPE_05 101 | : ihex.h 102 |
  • 103 |
104 | 105 | 106 |

- s -

    107 |
  • SRECORD_ERROR_EOF 108 | : srecord.h 109 |
  • 110 |
  • SRECORD_ERROR_FILE 111 | : srecord.h 112 |
  • 113 |
  • SRECORD_ERROR_INVALID_ARGUMENTS 114 | : srecord.h 115 |
  • 116 |
  • SRECORD_ERROR_INVALID_RECORD 117 | : srecord.h 118 |
  • 119 |
  • SRECORD_ERROR_NEWLINE 120 | : srecord.h 121 |
  • 122 |
  • SRECORD_OK 123 | : srecord.h 124 |
  • 125 |
  • SRECORD_TYPE_S0 126 | : srecord.h 127 |
  • 128 |
  • SRECORD_TYPE_S1 129 | : srecord.h 130 |
  • 131 |
  • SRECORD_TYPE_S2 132 | : srecord.h 133 |
  • 134 |
  • SRECORD_TYPE_S3 135 | : srecord.h 136 |
  • 137 |
  • SRECORD_TYPE_S4 138 | : srecord.h 139 |
  • 140 |
  • SRECORD_TYPE_S5 141 | : srecord.h 142 |
  • 143 |
  • SRECORD_TYPE_S6 144 | : srecord.h 145 |
  • 146 |
  • SRECORD_TYPE_S7 147 | : srecord.h 148 |
  • 149 |
  • SRECORD_TYPE_S8 150 | : srecord.h 151 |
  • 152 |
  • SRECORD_TYPE_S9 153 | : srecord.h 154 |
  • 155 |
156 |
157 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /docs/html/globals_func.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: Data Fields 6 | 7 | 8 | 9 | 10 | 11 | 34 |
35 |   79 |
80 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /docs/html/globals_type.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: Data Fields 6 | 7 | 8 | 9 | 10 | 11 | 35 |
36 |   47 |
48 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /docs/html/ihex_8h.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: ihex.h File Reference 6 | 7 | 8 | 9 | 10 | 11 | 26 |
27 | 31 |
32 |

ihex.h File Reference

33 |
34 |
35 | 36 |

Low-level utility functions to create, read, write, and print Intel HEX8 binary records. 37 | More...

38 | #include <stdio.h>
39 | #include <stdint.h>
40 | #include <stdlib.h>
41 | #include <string.h>
42 | 43 |

Go to the source code of this file.

44 | 45 | 47 | 48 | 50 | 69 | 79 | 89 | 91 | 92 | 93 | 94 | 95 | 96 |

46 | Data Structures

struct  IHexRecord

49 | Enumerations

enum  _IHexDefinitions {
51 |   IHEX_RECORD_BUFF_SIZE = 768, 52 | IHEX_COUNT_OFFSET = 1, 53 | IHEX_COUNT_LEN = 2, 54 | IHEX_ADDRESS_OFFSET = 3, 55 |
56 |   IHEX_ADDRESS_LEN = 4, 57 | IHEX_TYPE_OFFSET = 7, 58 | IHEX_TYPE_LEN = 2, 59 | IHEX_DATA_OFFSET = 9, 60 |
61 |   IHEX_CHECKSUM_LEN = 2, 62 | IHEX_MAX_DATA_LEN = 512, 63 | IHEX_ASCII_HEX_BYTE_LEN = 2, 64 | IHEX_START_CODE_OFFSET = 0, 65 |
66 |   IHEX_START_CODE = ':' 67 |
68 | }
enum  IHexErrors {
70 |   IHEX_OK = 0, 71 | IHEX_ERROR_FILE = -1, 72 | IHEX_ERROR_EOF = -2, 73 | IHEX_ERROR_INVALID_RECORD = -3, 74 |
75 |   IHEX_ERROR_INVALID_ARGUMENTS = -4, 76 | IHEX_ERROR_NEWLINE = -5 77 |
78 | }
enum  IHexRecordTypes {
80 |   IHEX_TYPE_00 = 0, 81 | IHEX_TYPE_01, 82 | IHEX_TYPE_02, 83 | IHEX_TYPE_03, 84 |
85 |   IHEX_TYPE_04, 86 | IHEX_TYPE_05 87 |
88 | }

90 | Functions

int New_IHexRecord (int type, uint16_t address, const uint8_t *data, int dataLen, IHexRecord *ihexRecord)
int Read_IHexRecord (IHexRecord *ihexRecord, FILE *in)
int Write_IHexRecord (const IHexRecord *ihexRecord, FILE *out)
void Print_IHexRecord (const IHexRecord *ihexRecord)
uint8_t Checksum_IHexRecord (const IHexRecord *ihexRecord)
97 |

Detailed Description

98 |

Low-level utility functions to create, read, write, and print Intel HEX8 binary records.

99 |
Author:
Vanya A. Sergeev <vsergeev@gmail.com>
100 |
Date:
February 2011
101 |
Version:
1.0.5
102 |

Enumeration Type Documentation

103 | 104 |
105 |
106 | 107 | 108 | 109 | 110 |
enum IHexErrors
111 |
112 |
113 |

All possible error codes the Intel HEX8 record utility functions may return.

114 |
Enumerator:
115 | 118 | 121 | 124 | 127 | 130 | 133 |
IHEX_OK  116 |

Error code for success or no error.

117 |
IHEX_ERROR_FILE  119 |

Error code for error while reading from or writing to a file. You may check errno for the exact error if this error code is encountered.

120 |
IHEX_ERROR_EOF  122 |

Error code for encountering end-of-file when reading from a file.

123 |
IHEX_ERROR_INVALID_RECORD  125 |

Error code for error if an invalid record was read.

126 |
IHEX_ERROR_INVALID_ARGUMENTS  128 |

Error code for error from invalid arguments passed to function.

129 |
IHEX_ERROR_NEWLINE  131 |

Error code for encountering a newline with no record when reading from a file.

132 |
134 |
135 |
136 | 137 |
138 |
139 | 140 |
141 |
142 | 143 | 144 | 145 | 146 |
enum IHexRecordTypes
147 |
148 |
149 |

Intel HEX8 Record Types 00-05

150 |
Enumerator:
151 | 154 | 157 | 160 | 163 | 166 | 169 |
IHEX_TYPE_00  152 |

Data Record

153 |
IHEX_TYPE_01  155 |

End of File Record

156 |
IHEX_TYPE_02  158 |

Extended Segment Address Record

159 |
IHEX_TYPE_03  161 |

Start Segment Address Record

162 |
IHEX_TYPE_04  164 |

Extended Linear Address Record

165 |
IHEX_TYPE_05  167 |

Start Linear Address Record

168 |
170 |
171 |
172 | 173 |
174 |
175 |

Function Documentation

176 | 177 |
178 |
179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 |
uint8_t Checksum_IHexRecord (const IHexRecord ihexRecord ) 
189 |
190 |
191 |

Calculates the checksum of an Intel HEX8 IHexRecord structure. See the Intel HEX8 specifications for more details on the checksum calculation.

192 |
Parameters:
193 | 194 | 195 |
ihexRecord A pointer to the Intel HEX8 record structure.
196 |
197 |
198 |
Returns:
The 8-bit checksum.
199 | 200 |
201 |
202 | 203 |
204 |
205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 |
int New_IHexRecord (int  type,
uint16_t  address,
const uint8_t *  data,
int  dataLen,
IHexRecord ihexRecord 
)
242 |
243 |
244 |

Sets all of the record fields of an Intel HEX8 record structure.

245 |
Parameters:
246 | 247 | 248 | 249 | 250 | 251 | 252 |
type The Intel HEX8 record type (integer value of 0 through 5).
address The 16-bit address of the data.
data A point to the 8-bit array of data.
dataLen The size of the 8-bit data array.
ihexRecord A pointer to the target Intel HEX8 record structure where these fields will be set.
253 |
254 |
255 |
Returns:
IHEX_OK on success, otherwise one of the IHEX_ERROR_ error codes.
256 |
Return values:
257 | 258 | 259 | 260 |
IHEX_OK on success.
IHEX_ERROR_INVALID_ARGUMENTS if the record pointer is NULL, or if the length of the 8-bit data array is out of range (less than zero or greater than the maximum data length allowed by record specifications, see IHexRecord.data).
261 |
262 |
263 | 264 |
265 |
266 | 267 |
268 |
269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 |
void Print_IHexRecord (const IHexRecord ihexRecord ) 
279 |
280 |
281 |

Prints the contents of an Intel HEX8 record structure to stdout. The record dump consists of the type, address, entire data array, and checksum fields of the record.

282 |
Parameters:
283 | 284 | 285 |
ihexRecord A pointer to the Intel HEX8 record structure.
286 |
287 |
288 |
Returns:
Always returns IHEX_OK (success).
289 |
Return values:
290 | 291 | 292 |
IHEX_OK on success.
293 |
294 |
295 | 296 |
297 |
298 | 299 |
300 |
301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 |
int Read_IHexRecord (IHexRecord ihexRecord,
FILE *  in 
)
320 |
321 |
322 |

Reads an Intel HEX8 record from an opened file.

323 |
Parameters:
324 | 325 | 326 | 327 |
ihexRecord A pointer to the Intel HEX8 record structure that will store the read record.
in A file pointer to an opened file that can be read.
328 |
329 |
330 |
Returns:
IHEX_OK on success, otherwise one of the IHEX_ERROR_ error codes.
331 |
Return values:
332 | 333 | 334 | 335 | 336 | 337 | 338 |
IHEX_OK on success.
IHEX_ERROR_INVALID_ARGUMENTS if the record pointer or file pointer is NULL.
IHEX_ERROR_EOF if end-of-file has been reached.
IHEX_ERROR_FILE if a file reading error has occured.
IHEX_INVALID_RECORD if the record read is invalid (record did not match specifications or record checksum was invalid).
339 |
340 |
341 | 342 |
343 |
344 | 345 |
346 |
347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 |
int Write_IHexRecord (const IHexRecord ihexRecord,
FILE *  out 
)
366 |
367 |
368 |

Writes an Intel HEX8 record to an opened file.

369 |
Parameters:
370 | 371 | 372 | 373 |
ihexRecord A pointer to the Intel HEX8 record structure.
out A file pointer to an opened file that can be written to.
374 |
375 |
376 |
Returns:
IHEX_OK on success, otherwise one of the IHEX_ERROR_ error codes.
377 |
Return values:
378 | 379 | 380 | 381 | 382 | 383 |
IHEX_OK on success.
IHEX_ERROR_INVALID_ARGUMENTS if the record pointer or file pointer is NULL.
IHEX_ERROR_INVALID_RECORD if the record's data length is out of range (greater than the maximum data length allowed by record specifications, see IHexRecord.data).
IHEX_ERROR_FILE if a file writing error has occured.
384 |
385 |
386 | 387 |
388 |
389 |
390 | 393 | 394 | 395 | -------------------------------------------------------------------------------- /docs/html/ihex_8h_source.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: ihex.h Source File 6 | 7 | 8 | 9 | 10 | 11 | 98 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /docs/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: Main Page 6 | 7 | 8 | 9 | 10 | 11 | 20 |
21 |
22 |

libGIS Documentation

23 |
24 |
25 |

1.0.5

26 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /docs/html/nav_f.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsergeev/libGIS/f82b9dd3018d479230ad68a02da41fa95cad9123/docs/html/nav_f.png -------------------------------------------------------------------------------- /docs/html/nav_h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsergeev/libGIS/f82b9dd3018d479230ad68a02da41fa95cad9123/docs/html/nav_h.png -------------------------------------------------------------------------------- /docs/html/open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsergeev/libGIS/f82b9dd3018d479230ad68a02da41fa95cad9123/docs/html/open.png -------------------------------------------------------------------------------- /docs/html/srecord_8h_source.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: srecord.h Source File 6 | 7 | 8 | 9 | 10 | 11 | 103 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /docs/html/structAtmelGenericRecord.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: AtmelGenericRecord Struct Reference 6 | 7 | 8 | 9 | 10 | 11 | 26 |
27 | 29 |
30 |

AtmelGenericRecord Struct Reference

31 |
32 |
33 | 34 |

#include <atmel_generic.h>

35 | 36 | 38 | 39 | 40 |

37 | Data Fields

uint32_t address
uint16_t data
41 |

Detailed Description

42 |

Structure to hold the fields of an Atmel Generic record.

43 |

Field Documentation

44 | 45 |
46 |
47 | 48 | 49 | 50 | 51 |
uint32_t AtmelGenericRecord::address
52 |
53 |
54 |

The 24-bit address field of the record.

55 | 56 |
57 |
58 | 59 |
60 |
61 | 62 | 63 | 64 | 65 |
uint16_t AtmelGenericRecord::data
66 |
67 |
68 |

The 16-bit data field of the record.

69 | 70 |
71 |
72 |
The documentation for this struct was generated from the following file: 75 |
76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /docs/html/structIHexRecord.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: IHexRecord Struct Reference 6 | 7 | 8 | 9 | 10 | 11 | 26 |
27 | 29 |
30 |

IHexRecord Struct Reference

31 |
32 |
33 | 34 |

#include <ihex.h>

35 | 36 | 38 | 39 | 40 | 41 | 42 | 43 |

37 | Data Fields

uint16_t address
uint8_t data [IHEX_MAX_DATA_LEN/2]
int dataLen
int type
uint8_t checksum
44 |

Detailed Description

45 |

Structure to hold the fields of an Intel HEX8 record.

46 |

Field Documentation

47 | 48 |
49 |
50 | 51 | 52 | 53 | 54 |
uint16_t IHexRecord::address
55 |
56 |
57 |

The 16-bit address field.

58 | 59 |
60 |
61 | 62 |
63 |
64 | 65 | 66 | 67 | 68 |
uint8_t IHexRecord::checksum
69 |
70 |
71 |

The checksum of this record.

72 | 73 |
74 |
75 | 76 |
77 |
78 | 79 | 80 | 81 | 82 |
uint8_t IHexRecord::data[IHEX_MAX_DATA_LEN/2]
83 |
84 |
85 |

The 8-bit array data field, which has a maximum size of 256 bytes.

86 | 87 |
88 |
89 | 90 |
91 |
92 | 93 | 94 | 95 | 96 |
int IHexRecord::dataLen
97 |
98 |
99 |

The number of bytes of data stored in this record.

100 | 101 |
102 |
103 | 104 |
105 |
106 | 107 | 108 | 109 | 110 |
int IHexRecord::type
111 |
112 |
113 |

The Intel HEX8 record type of this record.

114 | 115 |
116 |
117 |
The documentation for this struct was generated from the following file: 120 |
121 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /docs/html/structSRecord.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: SRecord Struct Reference 6 | 7 | 8 | 9 | 10 | 11 | 26 |
27 | 29 |
30 |

SRecord Struct Reference

31 |
32 |
33 | 34 |

#include <srecord.h>

35 | 36 | 38 | 39 | 40 | 41 | 42 | 43 |

37 | Data Fields

uint32_t address
uint8_t data [SRECORD_MAX_DATA_LEN/2]
int dataLen
int type
uint8_t checksum
44 |

Detailed Description

45 |

Structure to hold the fields of a Motorola S-Record record.

46 |

Field Documentation

47 | 48 |
49 |
50 | 51 | 52 | 53 | 54 |
uint32_t SRecord::address
55 |
56 |
57 |

The address field. This can be 16, 24, or 32 bits depending on the record type.

58 | 59 |
60 |
61 | 62 |
63 |
64 | 65 | 66 | 67 | 68 |
uint8_t SRecord::checksum
69 |
70 |
71 |

The checksum of this record.

72 | 73 |
74 |
75 | 76 |
77 |
78 | 79 | 80 | 81 | 82 |
uint8_t SRecord::data[SRECORD_MAX_DATA_LEN/2]
83 |
84 |
85 |

The 8-bit array data field, which has a maximum size of 32 bytes.

86 | 87 |
88 |
89 | 90 |
91 |
92 | 93 | 94 | 95 | 96 |
int SRecord::dataLen
97 |
98 |
99 |

The number of bytes of data stored in this record.

100 | 101 |
102 |
103 | 104 |
105 |
106 | 107 | 108 | 109 | 110 |
int SRecord::type
111 |
112 |
113 |

The Motorola S-Record type of this record (S0-S9).

114 | 115 |
116 |
117 |
The documentation for this struct was generated from the following file: 120 |
121 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /docs/html/struct__AtmelGenericRecord.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: _AtmelGenericRecord Struct Reference 6 | 7 | 8 | 9 | 10 | 11 | 26 |
27 | 29 |
30 |

_AtmelGenericRecord Struct Reference

31 |
32 |
33 | 34 |

#include <atmel_generic.h>

35 | 36 | 38 | 39 | 40 |

37 | Data Fields

uint32_t address
uint16_t data
41 |

Detailed Description

42 |

Structure to hold the fields of an Atmel Generic record.

43 |

Field Documentation

44 | 45 |
46 |
47 | 48 | 49 | 50 | 51 |
uint32_t _AtmelGenericRecord::address
52 |
53 |
54 |

The 24-bit address field of the record.

55 | 56 |
57 |
58 | 59 |
60 |
61 | 62 | 63 | 64 | 65 |
uint16_t _AtmelGenericRecord::data
66 |
67 |
68 |

The 16-bit data field of the record.

69 | 70 |
71 |
72 |
The documentation for this struct was generated from the following file: 75 |
76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /docs/html/struct__IHexRecord.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: _IHexRecord Struct Reference 6 | 7 | 8 | 9 | 10 | 11 | 26 |
27 | 29 |
30 |

_IHexRecord Struct Reference

31 |
32 |
33 | 34 |

#include <ihex.h>

35 | 36 | 38 | 39 | 40 | 41 | 42 | 43 |

37 | Data Fields

uint16_t address
uint8_t data [IHEX_MAX_DATA_LEN/2]
int dataLen
int type
uint8_t checksum
44 |

Detailed Description

45 |

Structure to hold the fields of an Intel HEX8 record.

46 |

Field Documentation

47 | 48 |
49 |
50 | 51 | 52 | 53 | 54 |
uint16_t _IHexRecord::address
55 |
56 |
57 |

The 16-bit address field.

58 | 59 |
60 |
61 | 62 |
63 |
64 | 65 | 66 | 67 | 68 |
uint8_t _IHexRecord::checksum
69 |
70 |
71 |

The checksum of this record.

72 | 73 |
74 |
75 | 76 |
77 |
78 | 79 | 80 | 81 | 82 |
uint8_t _IHexRecord::data[IHEX_MAX_DATA_LEN/2]
83 |
84 |
85 |

The 8-bit array data field, which has a maximum size of 256 bytes.

86 | 87 |
88 |
89 | 90 |
91 |
92 | 93 | 94 | 95 | 96 |
int _IHexRecord::dataLen
97 |
98 |
99 |

The number of bytes of data stored in this record.

100 | 101 |
102 |
103 | 104 |
105 |
106 | 107 | 108 | 109 | 110 |
int _IHexRecord::type
111 |
112 |
113 |

The Intel Hex record type of this record.

114 | 115 |
116 |
117 |
The documentation for this struct was generated from the following file: 120 |
121 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /docs/html/struct__SRecord.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | libGIS: _SRecord Struct Reference 6 | 7 | 8 | 9 | 10 | 11 | 26 |
27 | 29 |
30 |

_SRecord Struct Reference

31 |
32 |
33 | 34 |

#include <srecord.h>

35 | 36 | 38 | 39 | 40 | 41 | 42 | 43 |

37 | Data Fields

uint32_t address
uint8_t data [SRECORD_MAX_DATA_LEN/2]
int dataLen
int type
uint8_t checksum
44 |

Detailed Description

45 |

Structure to hold the fields of a Motorola S-Record record.

46 |

Field Documentation

47 | 48 |
49 |
50 | 51 | 52 | 53 | 54 |
uint32_t _SRecord::address
55 |
56 |
57 |

The address field. This can be 16, 24, or 32 bits depending on the record type.

58 | 59 |
60 |
61 | 62 |
63 |
64 | 65 | 66 | 67 | 68 |
uint8_t _SRecord::checksum
69 |
70 |
71 |

The checksum of this record.

72 | 73 |
74 |
75 | 76 |
77 |
78 | 79 | 80 | 81 | 82 |
uint8_t _SRecord::data[SRECORD_MAX_DATA_LEN/2]
83 |
84 |
85 |

The 8-bit array data field, which has a maximum size of 32 bytes.

86 | 87 |
88 |
89 | 90 |
91 |
92 | 93 | 94 | 95 | 96 |
int _SRecord::dataLen
97 |
98 |
99 |

The number of bytes of data stored in this record.

100 | 101 |
102 |
103 | 104 |
105 |
106 | 107 | 108 | 109 | 110 |
int _SRecord::type
111 |
112 |
113 |

The Motorola S-Record type of this record (S0-S9).

114 | 115 |
116 |
117 |
The documentation for this struct was generated from the following file: 120 |
121 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /docs/html/tab_a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsergeev/libGIS/f82b9dd3018d479230ad68a02da41fa95cad9123/docs/html/tab_a.png -------------------------------------------------------------------------------- /docs/html/tab_b.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsergeev/libGIS/f82b9dd3018d479230ad68a02da41fa95cad9123/docs/html/tab_b.gif -------------------------------------------------------------------------------- /docs/html/tab_b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsergeev/libGIS/f82b9dd3018d479230ad68a02da41fa95cad9123/docs/html/tab_b.png -------------------------------------------------------------------------------- /docs/html/tab_h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsergeev/libGIS/f82b9dd3018d479230ad68a02da41fa95cad9123/docs/html/tab_h.png -------------------------------------------------------------------------------- /docs/html/tab_l.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsergeev/libGIS/f82b9dd3018d479230ad68a02da41fa95cad9123/docs/html/tab_l.gif -------------------------------------------------------------------------------- /docs/html/tab_r.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsergeev/libGIS/f82b9dd3018d479230ad68a02da41fa95cad9123/docs/html/tab_r.gif -------------------------------------------------------------------------------- /docs/html/tab_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsergeev/libGIS/f82b9dd3018d479230ad68a02da41fa95cad9123/docs/html/tab_s.png -------------------------------------------------------------------------------- /docs/html/tabs.css: -------------------------------------------------------------------------------- 1 | .tabs, .tabs2, .tabs3 { 2 | background-image: url('tab_b.png'); 3 | width: 100%; 4 | z-index: 101; 5 | font-size: 13px; 6 | } 7 | 8 | .tabs2 { 9 | font-size: 10px; 10 | } 11 | .tabs3 { 12 | font-size: 9px; 13 | } 14 | 15 | .tablist { 16 | margin: 0; 17 | padding: 0; 18 | display: table; 19 | } 20 | 21 | .tablist li { 22 | float: left; 23 | display: table-cell; 24 | background-image: url('tab_b.png'); 25 | line-height: 36px; 26 | list-style: none; 27 | } 28 | 29 | .tablist a { 30 | display: block; 31 | padding: 0 20px; 32 | font-weight: bold; 33 | background-image:url('tab_s.png'); 34 | background-repeat:no-repeat; 35 | background-position:right; 36 | color: #283A5D; 37 | text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); 38 | text-decoration: none; 39 | outline: none; 40 | } 41 | 42 | .tabs3 .tablist a { 43 | padding: 0 10px; 44 | } 45 | 46 | .tablist a:hover { 47 | background-image: url('tab_h.png'); 48 | background-repeat:repeat-x; 49 | color: #fff; 50 | text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); 51 | text-decoration: none; 52 | } 53 | 54 | .tablist li.current a { 55 | background-image: url('tab_a.png'); 56 | background-repeat:repeat-x; 57 | color: #fff; 58 | text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); 59 | } 60 | -------------------------------------------------------------------------------- /docs/libGIS-docs-1.0.5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vsergeev/libGIS/f82b9dd3018d479230ad68a02da41fa95cad9123/docs/libGIS-docs-1.0.5.pdf -------------------------------------------------------------------------------- /ihex.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ihex.c 3 | * Utility functions to create, read, write, and print Intel HEX8 binary records. 4 | * 5 | * Written by Vanya A. Sergeev 6 | * Version 1.0.5 - February 2011 7 | * 8 | */ 9 | 10 | #include "ihex.h" 11 | 12 | /* Initializes a new IHexRecord structure that the paramater ihexRecord points to with the passed 13 | * record type, 16-bit integer address, 8-bit data array, and size of 8-bit data array. */ 14 | int New_IHexRecord(int type, uint16_t address, const uint8_t *data, int dataLen, IHexRecord *ihexRecord) { 15 | /* Data length size check, assertion of ihexRecord pointer */ 16 | if (dataLen < 0 || dataLen > IHEX_MAX_DATA_LEN/2 || ihexRecord == NULL) 17 | return IHEX_ERROR_INVALID_ARGUMENTS; 18 | 19 | ihexRecord->type = type; 20 | ihexRecord->address = address; 21 | memcpy(ihexRecord->data, data, (unsigned int)dataLen); 22 | ihexRecord->dataLen = dataLen; 23 | ihexRecord->checksum = Checksum_IHexRecord(ihexRecord); 24 | 25 | return IHEX_OK; 26 | } 27 | 28 | /* Utility function to read an Intel HEX8 record from a file */ 29 | int Read_IHexRecord(IHexRecord *ihexRecord, FILE *in) { 30 | char recordBuff[IHEX_RECORD_BUFF_SIZE]; 31 | /* A temporary buffer to hold ASCII hex encoded data, set to the maximum length we would ever need */ 32 | char hexBuff[IHEX_ADDRESS_LEN+1]; 33 | int dataCount, i; 34 | 35 | /* Check our record pointer and file pointer */ 36 | if (ihexRecord == NULL || in == NULL) 37 | return IHEX_ERROR_INVALID_ARGUMENTS; 38 | 39 | if (fgets(recordBuff, IHEX_RECORD_BUFF_SIZE, in) == NULL) { 40 | /* In case we hit EOF, don't report a file error */ 41 | if (feof(in) != 0) 42 | return IHEX_ERROR_EOF; 43 | else 44 | return IHEX_ERROR_FILE; 45 | } 46 | /* Null-terminate the string at the first sign of a \r or \n */ 47 | for (i = 0; i < (int)strlen(recordBuff); i++) { 48 | if (recordBuff[i] == '\r' || recordBuff[i] == '\n') { 49 | recordBuff[i] = 0; 50 | break; 51 | } 52 | } 53 | 54 | 55 | /* Check if we hit a newline */ 56 | if (strlen(recordBuff) == 0) 57 | return IHEX_ERROR_NEWLINE; 58 | 59 | /* Size check for start code, count, addess, and type fields */ 60 | if (strlen(recordBuff) < (unsigned int)(1+IHEX_COUNT_LEN+IHEX_ADDRESS_LEN+IHEX_TYPE_LEN)) 61 | return IHEX_ERROR_INVALID_RECORD; 62 | 63 | /* Check the for colon start code */ 64 | if (recordBuff[IHEX_START_CODE_OFFSET] != IHEX_START_CODE) 65 | return IHEX_ERROR_INVALID_RECORD; 66 | 67 | /* Copy the ASCII hex encoding of the count field into hexBuff, convert it to a usable integer */ 68 | strncpy(hexBuff, recordBuff+IHEX_COUNT_OFFSET, IHEX_COUNT_LEN); 69 | hexBuff[IHEX_COUNT_LEN] = 0; 70 | dataCount = (int)strtoul(hexBuff, (char **)NULL, 16); 71 | 72 | /* Copy the ASCII hex encoding of the address field into hexBuff, convert it to a usable integer */ 73 | strncpy(hexBuff, recordBuff+IHEX_ADDRESS_OFFSET, IHEX_ADDRESS_LEN); 74 | hexBuff[IHEX_ADDRESS_LEN] = 0; 75 | ihexRecord->address = (uint16_t)strtoul(hexBuff, (char **)NULL, 16); 76 | 77 | /* Copy the ASCII hex encoding of the address field into hexBuff, convert it to a usable integer */ 78 | strncpy(hexBuff, recordBuff+IHEX_TYPE_OFFSET, IHEX_TYPE_LEN); 79 | hexBuff[IHEX_TYPE_LEN] = 0; 80 | ihexRecord->type = (int)strtoul(hexBuff, (char **)NULL, 16); 81 | 82 | /* Size check for start code, count, address, type, data and checksum fields */ 83 | if (strlen(recordBuff) < (unsigned int)(1+IHEX_COUNT_LEN+IHEX_ADDRESS_LEN+IHEX_TYPE_LEN+dataCount*2+IHEX_CHECKSUM_LEN)) 84 | return IHEX_ERROR_INVALID_RECORD; 85 | 86 | /* Loop through each ASCII hex byte of the data field, pull it out into hexBuff, 87 | * convert it and store the result in the data buffer of the Intel HEX8 record */ 88 | for (i = 0; i < dataCount; i++) { 89 | /* Times two i because every byte is represented by two ASCII hex characters */ 90 | strncpy(hexBuff, recordBuff+IHEX_DATA_OFFSET+2*i, IHEX_ASCII_HEX_BYTE_LEN); 91 | hexBuff[IHEX_ASCII_HEX_BYTE_LEN] = 0; 92 | ihexRecord->data[i] = (uint8_t)strtoul(hexBuff, (char **)NULL, 16); 93 | } 94 | ihexRecord->dataLen = dataCount; 95 | 96 | /* Copy the ASCII hex encoding of the checksum field into hexBuff, convert it to a usable integer */ 97 | strncpy(hexBuff, recordBuff+IHEX_DATA_OFFSET+dataCount*2, IHEX_CHECKSUM_LEN); 98 | hexBuff[IHEX_CHECKSUM_LEN] = 0; 99 | ihexRecord->checksum = (uint8_t)strtoul(hexBuff, (char **)NULL, 16); 100 | 101 | if (ihexRecord->checksum != Checksum_IHexRecord(ihexRecord)) 102 | return IHEX_ERROR_INVALID_RECORD; 103 | 104 | return IHEX_OK; 105 | } 106 | 107 | /* Utility function to write an Intel HEX8 record to a file */ 108 | int Write_IHexRecord(const IHexRecord *ihexRecord, FILE *out) { 109 | int i; 110 | 111 | /* Check our record pointer and file pointer */ 112 | if (ihexRecord == NULL || out == NULL) 113 | return IHEX_ERROR_INVALID_ARGUMENTS; 114 | 115 | /* Check that the data length is in range */ 116 | if (ihexRecord->dataLen > IHEX_MAX_DATA_LEN/2) 117 | return IHEX_ERROR_INVALID_RECORD; 118 | 119 | /* Write the start code, data count, address, and type fields */ 120 | if (fprintf(out, "%c%2.2X%2.4X%2.2X", IHEX_START_CODE, ihexRecord->dataLen, ihexRecord->address, ihexRecord->type) < 0) 121 | return IHEX_ERROR_FILE; 122 | 123 | /* Write the data bytes */ 124 | for (i = 0; i < ihexRecord->dataLen; i++) { 125 | if (fprintf(out, "%2.2X", ihexRecord->data[i]) < 0) 126 | return IHEX_ERROR_FILE; 127 | } 128 | 129 | /* Calculate and write the checksum field */ 130 | if (fprintf(out, "%2.2X\r\n", Checksum_IHexRecord(ihexRecord)) < 0) 131 | return IHEX_ERROR_FILE; 132 | 133 | return IHEX_OK; 134 | } 135 | 136 | /* Utility function to print the information stored in an Intel HEX8 record */ 137 | void Print_IHexRecord(const IHexRecord *ihexRecord) { 138 | int i; 139 | printf("Intel HEX8 Record Type: \t%d\n", ihexRecord->type); 140 | printf("Intel HEX8 Record Address: \t0x%2.4X\n", ihexRecord->address); 141 | printf("Intel HEX8 Record Data: \t{"); 142 | for (i = 0; i < ihexRecord->dataLen; i++) { 143 | if (i+1 < ihexRecord->dataLen) 144 | printf("0x%02X, ", ihexRecord->data[i]); 145 | else 146 | printf("0x%02X", ihexRecord->data[i]); 147 | } 148 | printf("}\n"); 149 | printf("Intel HEX8 Record Checksum: \t0x%2.2X\n", ihexRecord->checksum); 150 | } 151 | 152 | /* Utility function to calculate the checksum of an Intel HEX8 record */ 153 | uint8_t Checksum_IHexRecord(const IHexRecord *ihexRecord) { 154 | uint8_t checksum; 155 | int i; 156 | 157 | /* Add the data count, type, address, and data bytes together */ 158 | checksum = (uint8_t)ihexRecord->dataLen; 159 | checksum += (uint8_t)ihexRecord->type; 160 | checksum += (uint8_t)ihexRecord->address; 161 | checksum += (uint8_t)((ihexRecord->address & 0xFF00)>>8); 162 | for (i = 0; i < ihexRecord->dataLen; i++) 163 | checksum += (uint8_t)ihexRecord->data[i]; 164 | 165 | /* Two's complement on checksum */ 166 | checksum = ~checksum + 1; 167 | 168 | return checksum; 169 | } 170 | 171 | -------------------------------------------------------------------------------- /ihex.h: -------------------------------------------------------------------------------- 1 | #ifndef INTEL_HEX_H 2 | #define INTEL_HEX_H 3 | /** 4 | * \file ihex.h 5 | * \brief Low-level utility functions to create, read, write, and print Intel HEX8 binary records. 6 | * \author Vanya A. Sergeev 7 | * \date February 2011 8 | * \version 1.0.5 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | /* General definition of the Intel HEX8 specification */ 17 | enum _IHexDefinitions { 18 | /* 768 should be plenty of space to read in a Intel HEX8 record */ 19 | IHEX_RECORD_BUFF_SIZE = 768, 20 | /* Offsets and lengths of various fields in an Intel HEX8 record */ 21 | IHEX_COUNT_OFFSET = 1, 22 | IHEX_COUNT_LEN = 2, 23 | IHEX_ADDRESS_OFFSET = 3, 24 | IHEX_ADDRESS_LEN = 4, 25 | IHEX_TYPE_OFFSET = 7, 26 | IHEX_TYPE_LEN = 2, 27 | IHEX_DATA_OFFSET = 9, 28 | IHEX_CHECKSUM_LEN = 2, 29 | IHEX_MAX_DATA_LEN = 512, 30 | /* Ascii hex encoded length of a single byte */ 31 | IHEX_ASCII_HEX_BYTE_LEN = 2, 32 | /* Start code offset and value */ 33 | IHEX_START_CODE_OFFSET = 0, 34 | IHEX_START_CODE = ':', 35 | }; 36 | 37 | /** 38 | * All possible error codes the Intel HEX8 record utility functions may return. 39 | */ 40 | enum IHexErrors { 41 | IHEX_OK = 0, /**< Error code for success or no error. */ 42 | IHEX_ERROR_FILE = -1, /**< Error code for error while reading from or writing to a file. You may check errno for the exact error if this error code is encountered. */ 43 | IHEX_ERROR_EOF = -2, /**< Error code for encountering end-of-file when reading from a file. */ 44 | IHEX_ERROR_INVALID_RECORD = -3, /**< Error code for error if an invalid record was read. */ 45 | IHEX_ERROR_INVALID_ARGUMENTS = -4, /**< Error code for error from invalid arguments passed to function. */ 46 | IHEX_ERROR_NEWLINE = -5, /**< Error code for encountering a newline with no record when reading from a file. */ 47 | }; 48 | 49 | /** 50 | * Intel HEX8 Record Types 00-05 51 | */ 52 | enum IHexRecordTypes { 53 | IHEX_TYPE_00 = 0, /**< Data Record */ 54 | IHEX_TYPE_01, /**< End of File Record */ 55 | IHEX_TYPE_02, /**< Extended Segment Address Record */ 56 | IHEX_TYPE_03, /**< Start Segment Address Record */ 57 | IHEX_TYPE_04, /**< Extended Linear Address Record */ 58 | IHEX_TYPE_05, /**< Start Linear Address Record */ 59 | }; 60 | 61 | /** 62 | * Structure to hold the fields of an Intel HEX8 record. 63 | */ 64 | typedef struct { 65 | uint16_t address; /**< The 16-bit address field. */ 66 | uint8_t data[IHEX_MAX_DATA_LEN/2]; /**< The 8-bit array data field, which has a maximum size of 256 bytes. */ 67 | int dataLen; /**< The number of bytes of data stored in this record. */ 68 | int type; /**< The Intel HEX8 record type of this record. */ 69 | uint8_t checksum; /**< The checksum of this record. */ 70 | } IHexRecord; 71 | 72 | /** 73 | * Sets all of the record fields of an Intel HEX8 record structure. 74 | * \param type The Intel HEX8 record type (integer value of 0 through 5). 75 | * \param address The 16-bit address of the data. 76 | * \param data A point to the 8-bit array of data. 77 | * \param dataLen The size of the 8-bit data array. 78 | * \param ihexRecord A pointer to the target Intel HEX8 record structure where these fields will be set. 79 | * \return IHEX_OK on success, otherwise one of the IHEX_ERROR_ error codes. 80 | * \retval IHEX_OK on success. 81 | * \retval IHEX_ERROR_INVALID_ARGUMENTS if the record pointer is NULL, or if the length of the 8-bit data array is out of range (less than zero or greater than the maximum data length allowed by record specifications, see IHexRecord.data). 82 | */ 83 | int New_IHexRecord(int type, uint16_t address, const uint8_t *data, int dataLen, IHexRecord *ihexRecord); 84 | 85 | /** 86 | * Reads an Intel HEX8 record from an opened file. 87 | * \param ihexRecord A pointer to the Intel HEX8 record structure that will store the read record. 88 | * \param in A file pointer to an opened file that can be read. 89 | * \return IHEX_OK on success, otherwise one of the IHEX_ERROR_ error codes. 90 | * \retval IHEX_OK on success. 91 | * \retval IHEX_ERROR_INVALID_ARGUMENTS if the record pointer or file pointer is NULL. 92 | * \retval IHEX_ERROR_EOF if end-of-file has been reached. 93 | * \retval IHEX_ERROR_FILE if a file reading error has occured. 94 | * \retval IHEX_INVALID_RECORD if the record read is invalid (record did not match specifications or record checksum was invalid). 95 | */ 96 | int Read_IHexRecord(IHexRecord *ihexRecord, FILE *in); 97 | 98 | /** 99 | * Writes an Intel HEX8 record to an opened file. 100 | * \param ihexRecord A pointer to the Intel HEX8 record structure. 101 | * \param out A file pointer to an opened file that can be written to. 102 | * \return IHEX_OK on success, otherwise one of the IHEX_ERROR_ error codes. 103 | * \retval IHEX_OK on success. 104 | * \retval IHEX_ERROR_INVALID_ARGUMENTS if the record pointer or file pointer is NULL. 105 | * \retval IHEX_ERROR_INVALID_RECORD if the record's data length is out of range (greater than the maximum data length allowed by record specifications, see IHexRecord.data). 106 | * \retval IHEX_ERROR_FILE if a file writing error has occured. 107 | */ 108 | int Write_IHexRecord(const IHexRecord *ihexRecord, FILE *out); 109 | 110 | /** 111 | * Prints the contents of an Intel HEX8 record structure to stdout. 112 | * The record dump consists of the type, address, entire data array, and checksum fields of the record. 113 | * \param ihexRecord A pointer to the Intel HEX8 record structure. 114 | * \return Always returns IHEX_OK (success). 115 | * \retval IHEX_OK on success. 116 | */ 117 | void Print_IHexRecord(const IHexRecord *ihexRecord); 118 | 119 | /** 120 | * Calculates the checksum of an Intel HEX8 IHexRecord structure. 121 | * See the Intel HEX8 specifications for more details on the checksum calculation. 122 | * \param ihexRecord A pointer to the Intel HEX8 record structure. 123 | * \return The 8-bit checksum. 124 | */ 125 | uint8_t Checksum_IHexRecord(const IHexRecord *ihexRecord); 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /srecord.c: -------------------------------------------------------------------------------- 1 | /* 2 | * srecord.h 3 | * Utility functions to create, read, write, and print Motorola S-Record binary records. 4 | * 5 | * Written by Vanya A. Sergeev 6 | * Version 1.0.5 - February 2011 7 | * 8 | */ 9 | 10 | #include "srecord.h" 11 | 12 | /* Lengths of the ASCII hex encoded address fields of different SRecord types */ 13 | static int SRecord_Address_Lengths[] = { 14 | 4, // S0 15 | 4, // S1 16 | 6, // S2 17 | 8, // S3 18 | 8, // S4 19 | 4, // S5 20 | 6, // S6 21 | 8, // S7 22 | 6, // S8 23 | 4, // S9 24 | }; 25 | 26 | /* Initializes a new SRecord structure that the paramater srec points to with the passed 27 | * S-Record type, up to 32-bit integer address, 8-bit data array, and size of 8-bit data array. */ 28 | int New_SRecord(int type, uint32_t address, const uint8_t *data, int dataLen, SRecord *srec) { 29 | /* Data length size check, assertion of srec pointer */ 30 | if (dataLen < 0 || dataLen > SRECORD_MAX_DATA_LEN/2 || srec == NULL) 31 | return SRECORD_ERROR_INVALID_ARGUMENTS; 32 | 33 | srec->type = type; 34 | srec->address = address; 35 | memcpy(srec->data, data, (unsigned int)dataLen); 36 | srec->dataLen = dataLen; 37 | srec->checksum = Checksum_SRecord(srec); 38 | 39 | return SRECORD_OK; 40 | } 41 | 42 | 43 | /* Utility function to read an S-Record from a file */ 44 | int Read_SRecord(SRecord *srec, FILE *in) { 45 | char recordBuff[SRECORD_RECORD_BUFF_SIZE]; 46 | /* A temporary buffer to hold ASCII hex encoded data, set to the maximum length we would ever need */ 47 | char hexBuff[SRECORD_MAX_ADDRESS_LEN+1]; 48 | int asciiAddressLen, asciiDataLen, dataOffset, fieldDataCount, i; 49 | 50 | /* Check our record pointer and file pointer */ 51 | if (srec == NULL || in == NULL) 52 | return SRECORD_ERROR_INVALID_ARGUMENTS; 53 | 54 | if (fgets(recordBuff, SRECORD_RECORD_BUFF_SIZE, in) == NULL) { 55 | /* In case we hit EOF, don't report a file error */ 56 | if (feof(in) != 0) 57 | return SRECORD_ERROR_EOF; 58 | else 59 | return SRECORD_ERROR_FILE; 60 | } 61 | /* Null-terminate the string at the first sign of a \r or \n */ 62 | for (i = 0; i < (int)strlen(recordBuff); i++) { 63 | if (recordBuff[i] == '\r' || recordBuff[i] == '\n') { 64 | recordBuff[i] = 0; 65 | break; 66 | } 67 | } 68 | 69 | /* Check if we hit a newline */ 70 | if (strlen(recordBuff) == 0) 71 | return SRECORD_ERROR_NEWLINE; 72 | 73 | /* Size check for type and count fields */ 74 | if (strlen(recordBuff) < SRECORD_TYPE_LEN + SRECORD_COUNT_LEN) 75 | return SRECORD_ERROR_INVALID_RECORD; 76 | 77 | /* Check for the S-Record start code at the beginning of every record */ 78 | if (recordBuff[SRECORD_START_CODE_OFFSET] != SRECORD_START_CODE) 79 | return SRECORD_ERROR_INVALID_RECORD; 80 | 81 | /* Copy the ASCII hex encoding of the type field into hexBuff, convert it into a usable integer */ 82 | strncpy(hexBuff, recordBuff+SRECORD_TYPE_OFFSET, SRECORD_TYPE_LEN); 83 | hexBuff[SRECORD_TYPE_LEN] = 0; 84 | srec->type = (int)strtoul(hexBuff, (char **)NULL, 16); 85 | 86 | /* Copy the ASCII hex encoding of the count field into hexBuff, convert it to a usable integer */ 87 | strncpy(hexBuff, recordBuff+SRECORD_COUNT_OFFSET, SRECORD_COUNT_LEN); 88 | hexBuff[SRECORD_COUNT_LEN] = 0; 89 | fieldDataCount = (int)strtoul(hexBuff, (char **)NULL, 16); 90 | 91 | /* Check that our S-Record type is valid */ 92 | if (srec->type < SRECORD_TYPE_S0 || srec->type > SRECORD_TYPE_S9) 93 | return SRECORD_ERROR_INVALID_RECORD; 94 | /* Get the ASCII hex address length of this particular S-Record type */ 95 | asciiAddressLen = SRecord_Address_Lengths[srec->type]; 96 | 97 | /* Size check for address field */ 98 | if (strlen(recordBuff) < (unsigned int)(SRECORD_ADDRESS_OFFSET+asciiAddressLen)) 99 | return SRECORD_ERROR_INVALID_RECORD; 100 | 101 | /* Copy the ASCII hex encoding of the count field into hexBuff, convert it to a usable integer */ 102 | strncpy(hexBuff, recordBuff+SRECORD_ADDRESS_OFFSET, (unsigned int)asciiAddressLen); 103 | hexBuff[asciiAddressLen] = 0; 104 | srec->address = (uint32_t)strtoul(hexBuff, (char **)NULL, 16); 105 | 106 | /* Compute the ASCII hex data length by subtracting the remaining field lengths from the S-Record 107 | * count field (times 2 to account for the number of characters used in ASCII hex encoding) */ 108 | asciiDataLen = (fieldDataCount*2) - asciiAddressLen - SRECORD_CHECKSUM_LEN; 109 | /* Bailout if we get an invalid data length */ 110 | if (asciiDataLen < 0 || asciiDataLen > SRECORD_MAX_DATA_LEN) 111 | return SRECORD_ERROR_INVALID_RECORD; 112 | 113 | /* Size check for final data field and checksum field */ 114 | if (strlen(recordBuff) < (unsigned int)(SRECORD_ADDRESS_OFFSET+asciiAddressLen+asciiDataLen+SRECORD_CHECKSUM_LEN)) 115 | return SRECORD_ERROR_INVALID_RECORD; 116 | 117 | dataOffset = SRECORD_ADDRESS_OFFSET+asciiAddressLen; 118 | 119 | /* Loop through each ASCII hex byte of the data field, pull it out into hexBuff, 120 | * convert it and store the result in the data buffer of the S-Record */ 121 | for (i = 0; i < asciiDataLen/2; i++) { 122 | /* Times two i because every byte is represented by two ASCII hex characters */ 123 | strncpy(hexBuff, recordBuff+dataOffset+2*i, SRECORD_ASCII_HEX_BYTE_LEN); 124 | hexBuff[SRECORD_ASCII_HEX_BYTE_LEN] = 0; 125 | srec->data[i] = (uint8_t)strtoul(hexBuff, (char **)NULL, 16); 126 | } 127 | /* Real data len is divided by two because every byte is represented by two ASCII hex characters */ 128 | srec->dataLen = asciiDataLen/2; 129 | 130 | /* Copy out the checksum ASCII hex encoded byte, and convert it back to a usable integer */ 131 | strncpy(hexBuff, recordBuff+dataOffset+asciiDataLen, SRECORD_CHECKSUM_LEN); 132 | hexBuff[SRECORD_CHECKSUM_LEN] = 0; 133 | srec->checksum = (uint8_t)strtoul(hexBuff, (char **)NULL, 16); 134 | 135 | if (srec->checksum != Checksum_SRecord(srec)) 136 | return SRECORD_ERROR_INVALID_RECORD; 137 | 138 | return SRECORD_OK; 139 | } 140 | 141 | /* Utility function to write an S-Record to a file */ 142 | int Write_SRecord(const SRecord *srec, FILE *out) { 143 | char strAddress[SRECORD_MAX_ADDRESS_LEN+1]; 144 | int asciiAddressLen, asciiAddressOffset, fieldDataCount, i; 145 | 146 | /* Check our record pointer and file pointer */ 147 | if (srec == NULL || out == NULL) 148 | return SRECORD_ERROR_INVALID_ARGUMENTS; 149 | 150 | /* Check that the type and data length is within range */ 151 | if (srec->type < SRECORD_TYPE_S0 || srec->type > SRECORD_TYPE_S9 || srec->dataLen > SRECORD_MAX_DATA_LEN/2) 152 | return SRECORD_ERROR_INVALID_RECORD; 153 | 154 | /* Compute the record count, address and checksum lengths are halved because record count 155 | * is the number of bytes left in the record, not the length of the ASCII hex representation */ 156 | fieldDataCount = SRecord_Address_Lengths[srec->type]/2 + srec->dataLen + SRECORD_CHECKSUM_LEN/2; 157 | 158 | asciiAddressLen = SRecord_Address_Lengths[srec->type]; 159 | /* The offset of the ASCII hex encoded address from zero, this is used so we only write as 160 | * many bytes of the address as permitted by the S-Record type. */ 161 | asciiAddressOffset = SRECORD_MAX_ADDRESS_LEN-asciiAddressLen; 162 | 163 | if (fprintf(out, "%c%1.1X%2.2X", SRECORD_START_CODE, srec->type, fieldDataCount) < 0) 164 | return SRECORD_ERROR_FILE; 165 | 166 | /* Write the ASCII hex representation of the address, starting from the offset to only 167 | * write as much of the address as permitted by the S-Record type (calculated above). */ 168 | /* Fix the hex to be 8 hex digits of precision, to fit all 32-bits, including zeros */ 169 | snprintf(strAddress, sizeof(strAddress), "%2.8X", srec->address); 170 | if (fprintf(out, "%s", strAddress+asciiAddressOffset) < 0) 171 | return SRECORD_ERROR_FILE; 172 | 173 | /* Write each byte of the data, guaranteed to be two hex ASCII characters each since 174 | * srec->data[i] has the type of uint8_t */ 175 | for (i = 0; i < srec->dataLen; i++) { 176 | if (fprintf(out, "%2.2X", srec->data[i]) < 0) 177 | return SRECORD_ERROR_FILE; 178 | } 179 | 180 | /* Last but not least, the checksum */ 181 | if (fprintf(out, "%2.2X\r\n", Checksum_SRecord(srec)) < 0) 182 | return SRECORD_ERROR_FILE; 183 | 184 | return SRECORD_OK; 185 | } 186 | 187 | /* Utility function to print the information stored in an S-Record */ 188 | void Print_SRecord(const SRecord *srec) { 189 | int i; 190 | printf("S-Record Type: \t\tS%d\n", srec->type); 191 | printf("S-Record Address: \t0x%2.8X\n", srec->address); 192 | printf("S-Record Data: \t\t{"); 193 | for (i = 0; i < srec->dataLen; i++) { 194 | if (i+1 < srec->dataLen) 195 | printf("0x%02X, ", srec->data[i]); 196 | else 197 | printf("0x%02X", srec->data[i]); 198 | } 199 | printf("}\n"); 200 | printf("S-Record Checksum: \t0x%2.2X\n", srec->checksum); 201 | } 202 | 203 | /* Utility function to calculate the checksum of an S-Record */ 204 | uint8_t Checksum_SRecord(const SRecord *srec) { 205 | uint8_t checksum; 206 | int fieldDataCount, i; 207 | 208 | /* Compute the record count, address and checksum lengths are halved because record count 209 | * is the number of bytes left in the record, not the length of the ASCII hex representation */ 210 | fieldDataCount = SRecord_Address_Lengths[srec->type]/2 + srec->dataLen + SRECORD_CHECKSUM_LEN/2; 211 | 212 | /* Add the count, address, and data fields together */ 213 | checksum = (uint8_t)fieldDataCount; 214 | /* Add each byte of the address individually */ 215 | checksum += (uint8_t)(srec->address & 0x000000FF); 216 | checksum += (uint8_t)((srec->address & 0x0000FF00) >> 8); 217 | checksum += (uint8_t)((srec->address & 0x00FF0000) >> 16); 218 | checksum += (uint8_t)((srec->address & 0xFF000000) >> 24); 219 | for (i = 0; i < srec->dataLen; i++) 220 | checksum += (uint8_t)srec->data[i]; 221 | 222 | /* One's complement the checksum */ 223 | checksum = ~checksum; 224 | 225 | return checksum; 226 | } 227 | 228 | -------------------------------------------------------------------------------- /srecord.h: -------------------------------------------------------------------------------- 1 | #ifndef SRECORD_H 2 | #define SRECORD_H 3 | /** 4 | * \file srecord.h 5 | * \brief Low-level utility functions to create, read, write, and print Motorola S-Record binary records. 6 | * \author Vanya A. Sergeev 7 | * \date February 2011 8 | * \version 1.0.5 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | /* General definition of the S-Record specification */ 17 | enum _SRecordDefinitions { 18 | /* 768 should be plenty of space to read in an S-Record */ 19 | SRECORD_RECORD_BUFF_SIZE = 768, 20 | /* Offsets and lengths of various fields in an S-Record record */ 21 | SRECORD_TYPE_OFFSET = 1, 22 | SRECORD_TYPE_LEN = 1, 23 | SRECORD_COUNT_OFFSET = 2, 24 | SRECORD_COUNT_LEN = 2, 25 | SRECORD_ADDRESS_OFFSET = 4, 26 | SRECORD_CHECKSUM_LEN = 2, 27 | /* Maximum ascii hex length of the S-Record data field */ 28 | SRECORD_MAX_DATA_LEN = 254*2, 29 | /* Maximum ascii hex length of the S-Record address field */ 30 | SRECORD_MAX_ADDRESS_LEN = 8, 31 | /* Ascii hex length of a single byte */ 32 | SRECORD_ASCII_HEX_BYTE_LEN = 2, 33 | /* Start code offset and value */ 34 | SRECORD_START_CODE_OFFSET = 0, 35 | SRECORD_START_CODE = 'S', 36 | }; 37 | 38 | /** 39 | * All possible error codes the Motorola S-Record utility functions may return. 40 | */ 41 | enum SRecordErrors { 42 | SRECORD_OK = 0, /**< Error code for success or no error. */ 43 | SRECORD_ERROR_FILE = -1, /**< Error code for error while reading from or writing to a file. You may check errno for the exact error if this error code is encountered. */ 44 | SRECORD_ERROR_EOF = -2, /**< Error code for encountering end-of-file when reading from a file. */ 45 | SRECORD_ERROR_INVALID_RECORD = -3, /**< Error code for error if an invalid record was read. */ 46 | SRECORD_ERROR_INVALID_ARGUMENTS = -4, /**< Error code for error from invalid arguments passed to function. */ 47 | SRECORD_ERROR_NEWLINE = -5, /**< Error code for encountering a newline with no record when reading from a file. */ 48 | }; 49 | 50 | /** 51 | * Motorola S-Record Types S0-S9 52 | */ 53 | enum SRecordTypes { 54 | SRECORD_TYPE_S0 = 0, /**< Header record, although there is an official format it is often made proprietary by third-parties. 16-bit address normally set to 0x0000 and header information is stored in the data field. This record is unnecessary and commonly not used. */ 55 | SRECORD_TYPE_S1, /**< Data record with 16-bit address */ 56 | SRECORD_TYPE_S2, /**< Data record with 24-bit address */ 57 | SRECORD_TYPE_S3, /**< Data record with 32-bit address */ 58 | SRECORD_TYPE_S4, /**< Extension by LSI Logic, Inc. See their specification for more details. */ 59 | SRECORD_TYPE_S5, /**< 16-bit address field that contains the number of S1, S2, and S3 (all data) records transmitted. No data field. */ 60 | SRECORD_TYPE_S6, /**< 24-bit address field that contains the number of S1, S2, and S3 (all data) records transmitted. No data field. */ 61 | SRECORD_TYPE_S7, /**< Termination record for S3 data records. 32-bit address field contains address of the entry point after the S-Record file has been processed. No data field. */ 62 | SRECORD_TYPE_S8, /**< Termination record for S2 data records. 24-bit address field contains address of the entry point after the S-Record file has been processed. No data field. */ 63 | SRECORD_TYPE_S9, /**< Termination record for S1 data records. 16-bit address field contains address of the entry point after the S-Record file has been processed. No data field. */ 64 | }; 65 | 66 | /** 67 | * Structure to hold the fields of a Motorola S-Record record. 68 | */ 69 | typedef struct { 70 | uint32_t address; /**< The address field. This can be 16, 24, or 32 bits depending on the record type. */ 71 | uint8_t data[SRECORD_MAX_DATA_LEN/2]; /**< The 8-bit array data field, which has a maximum size of 32 bytes. */ 72 | int dataLen; /**< The number of bytes of data stored in this record. */ 73 | int type; /**< The Motorola S-Record type of this record (S0-S9). */ 74 | uint8_t checksum; /**< The checksum of this record. */ 75 | } SRecord; 76 | 77 | /** 78 | * Sets all of the record fields of a Motorola S-Record structure. 79 | * \param type The Motorola S-Record type (integer value of 0 through 9). 80 | * \param address The 32-bit address of the data. The actual size of the address (16-,24-, or 32-bits) when written to a file depends on the S-Record type. 81 | * \param data A pointer to the 8-bit array of data. 82 | * \param dataLen The size of the 8-bit data array. 83 | * \param srec A pointer to the target Motorola S-Record structure where these fields will be set. 84 | * \return SRECORD_OK on success, otherwise one of the SRECORD_ERROR_ error codes. 85 | * \retval SRECORD_OK on success. 86 | * \retval SRECORD_ERROR_INVALID_ARGUMENTS if the record pointer is NULL, or if the length of the 8-bit data array is out of range (less than zero or greater than the maximum data length allowed by record specifications, see SRecord.data). 87 | */ 88 | int New_SRecord(int type, uint32_t address, const uint8_t *data, int dataLen, SRecord *srec); 89 | 90 | /** 91 | * Reads a Motorola S-Record record from an opened file. 92 | * \param srec A pointer to the Motorola S-Record structure that will store the read record. 93 | * \param in A file pointer to an opened file that can be read. 94 | * \return SRECORD_OK on success, otherwise one of the SRECORD_ERROR_ error codes. 95 | * \retval SRECORD_OK on success. 96 | * \retval SRECORD_ERROR_INVALID_ARGUMENTS if the record pointer or file pointer is NULL. 97 | * \retval SRECORD_ERROR_EOF if end-of-file has been reached. 98 | * \retval SRECORD_ERROR_FILE if a file reading error has occured. 99 | * \retval SRECORD_INVALID_RECORD if the record read is invalid (record did not match specifications or record checksum was invalid). 100 | */ 101 | int Read_SRecord(SRecord *srec, FILE *in); 102 | 103 | /** 104 | * Writes a Motorola S-Record to an opened file. 105 | * \param srec A pointer to the Motorola S-Record structure. 106 | * \param out A file pointer to an opened file that can be written to. 107 | * \return SRECORD_OK on success, otherwise one of the SRECORD_ERROR_ error codes. 108 | * \retval SRECORD_OK on success. 109 | * \retval SRECORD_ERROR_INVALID_ARGUMENTS if the record pointer or file pointer is NULL. 110 | * \retval SRECORD_ERROR_INVALID_RECORD if the record's data length (the SRecord.dataLen variable of the record) is out of range (greater than the maximum data length allowed by record specifications, see SRecord.data). 111 | * \retval SRECORD_ERROR_FILE if a file writing error has occured. 112 | */ 113 | int Write_SRecord(const SRecord *srec, FILE *out); 114 | 115 | /** 116 | * Prints the contents of a Motorola S-Record structure to stdout. 117 | * The record dump consists of the type, address, entire data array, and checksum fields of the record. 118 | * \param srec A pointer to the Motorola S-Record structure. 119 | * \return Always returns SRECORD_OK (success). 120 | * \retval SRECORD_OK on success. 121 | */ 122 | void Print_SRecord(const SRecord *srec); 123 | 124 | /** 125 | * Calculates the checksum of a Motorola S-Record SRecord structure. 126 | * See the Motorola S-Record specifications for more details on the checksum calculation. 127 | * \param srec A pointer to the Motorola S-Record structure. 128 | * \return The 8-bit checksum. 129 | */ 130 | uint8_t Checksum_SRecord(const SRecord *srec); 131 | 132 | #endif 133 | -------------------------------------------------------------------------------- /testGIS.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program prints all of the records stored in an Atmel Generic, Intel HEX, or Motorola S-Record formatted file. 3 | * Author: Vanya A. Sergeev 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "srecord.h" 11 | #include "atmel_generic.h" 12 | #include "ihex.h" 13 | 14 | /* Windows doesn't have 'strcasecmp' but does have stricmp */ 15 | #ifdef _WIN32 16 | #define strcasecmp stricmp 17 | #endif 18 | 19 | int main (int argc, const char * argv[]) { 20 | FILE *fp; 21 | AtmelGenericRecord arec; 22 | IHexRecord irec; 23 | SRecord srec; 24 | 25 | if (argc < 3) { 26 | fprintf(stderr, "Usage: %s \n", argv[0]); 27 | fprintf(stderr, "This program will print the records saved in a generic,\nIntel HEX, or Motorola S-Record formatted file.\n\n"); 28 | fprintf(stderr, " can be generic, ihex, or srecord.\n"); 29 | fprintf(stderr, " is the path to the file containing the records.\n"); 30 | return -1; 31 | } 32 | 33 | fp = fopen(argv[2], "r"); 34 | if (fp == NULL) { 35 | perror("Error opening file!"); 36 | return -1; 37 | } 38 | 39 | if (strcasecmp(argv[1], "generic") == 0) { 40 | while (Read_AtmelGenericRecord(&arec, fp) == ATMEL_GENERIC_OK) { 41 | Print_AtmelGenericRecord(&arec); 42 | printf("\n"); 43 | } 44 | } else if (strcasecmp(argv[1], "ihex") == 0) { 45 | while (Read_IHexRecord(&irec, fp) == IHEX_OK) { 46 | Print_IHexRecord(&irec); 47 | printf("\n"); 48 | } 49 | } else if (strcasecmp(argv[1], "srecord") == 0) { 50 | while (Read_SRecord(&srec, fp) == SRECORD_OK) { 51 | Print_SRecord(&srec); 52 | printf("\n"); 53 | } 54 | } else { 55 | fprintf(stderr, "Invalid file format specified!\n"); 56 | fclose(fp); 57 | return -1; 58 | } 59 | 60 | fclose(fp); 61 | return 0; 62 | } 63 | 64 | --------------------------------------------------------------------------------