mirror of
https://github.com/VARCem/ihex.git
synced 2026-09-22 23:14:50 +00:00
Allow using an external write buffer
This commit is contained in:
11
kk_ihex.h
11
kk_ihex.h
@@ -80,6 +80,12 @@
|
||||
* maximum as greater than the line length you'll actually be writing,
|
||||
* e.g., 32 or 16.
|
||||
*
|
||||
* If the write functionality is only occasionally used, you can provide
|
||||
* your own buffer for the duration by defining `IHEX_EXTERNAL_WRITE_BUFFER`
|
||||
* and providing a `char *ihex_write_buffer` which points to valid storage
|
||||
* for at least `IHEX_WRITE_BUFFER_LENGTH` characters from before the first
|
||||
* call to any IHEX write function to until after the last.
|
||||
*
|
||||
* If you are doing both reading and writing, you can define the maximum
|
||||
* output length separately as `IHEX_MAX_OUTPUT_LINE_LENGTH` - this will
|
||||
* decrease the write buffer size, but `struct ihex_state` will still
|
||||
@@ -100,7 +106,7 @@
|
||||
#ifndef KK_IHEX_H
|
||||
#define KK_IHEX_H
|
||||
|
||||
#define KK_IHEX_VERSION "2014-02-24"
|
||||
#define KK_IHEX_VERSION "2014-02-25"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
@@ -128,6 +134,7 @@ typedef struct ihex_state {
|
||||
} kk_ihex_t;
|
||||
|
||||
#define IHEX_FLAG_ADDRESS_OVERFLOW 0x80 // 16-bit address overflow
|
||||
// (Other flags are reserved for internal use!)
|
||||
|
||||
enum ihex_record_type {
|
||||
IHEX_DATA_RECORD,
|
||||
@@ -153,7 +160,7 @@ enum ihex_record_type {
|
||||
// afterwards.
|
||||
//
|
||||
// To implement fully correct segmented addressing, compute the address
|
||||
// of _each byte_ with its index as follows:
|
||||
// of _each byte_ with its index in `data` as follows:
|
||||
//
|
||||
#define IHEX_BYTE_ADDRESS(ihex, byte_index) ((((ihex)->address + (byte_index)) & 0xFFFFU) + (((ihex_address_t)((ihex)->segment)) << 4))
|
||||
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
|
||||
#define IHEX_START ':'
|
||||
|
||||
static const char IHEX_NEWLINE[] = IHEX_NEWLINE_STRING;
|
||||
|
||||
#define ADDRESS_HIGH_MASK ((ihex_address_t) 0xFFFF0000U)
|
||||
#define ADDRESS_HIGH_BYTES(addr) ((addr) >> 16)
|
||||
|
||||
#define HEX_DIGIT(n) ((n) + ( ((n) < 10) ? '0' : ('A' - 10)))
|
||||
|
||||
static char line_buffer[1+2+4+2+(IHEX_MAX_OUTPUT_LINE_LENGTH*2)+2+sizeof(IHEX_NEWLINE)];
|
||||
#ifndef IHEX_EXTERNAL_WRITE_BUFFER
|
||||
static char ihex_write_buffer[IHEX_WRITE_BUFFER_LENGTH];
|
||||
#endif
|
||||
|
||||
#if IHEX_MAX_OUTPUT_LINE_LENGTH > IHEX_LINE_MAX_LENGTH
|
||||
#error "IHEX_MAX_OUTPUT_LINE_LENGTH > IHEX_LINE_MAX_LENGTH"
|
||||
@@ -58,7 +58,7 @@ ihex_buffer_word (char * restrict w, const unsigned int word,
|
||||
|
||||
static char *
|
||||
ihex_buffer_newline (char * restrict w) {
|
||||
const char * restrict r = IHEX_NEWLINE;
|
||||
const char *r = IHEX_NEWLINE_STRING;
|
||||
do {
|
||||
*w++ = *r++;
|
||||
} while (*r);
|
||||
@@ -67,7 +67,7 @@ ihex_buffer_newline (char * restrict w) {
|
||||
|
||||
static void
|
||||
ihex_write_end_of_file (struct ihex_state * const ihex) {
|
||||
char *w = line_buffer;
|
||||
char * restrict w = ihex_write_buffer;
|
||||
*w++ = IHEX_START; // :
|
||||
#if 0
|
||||
for (unsigned int i = 7; i; --i) {
|
||||
@@ -84,14 +84,14 @@ ihex_write_end_of_file (struct ihex_state * const ihex) {
|
||||
w = ihex_buffer_byte(w, ~((unsigned int)IHEX_END_OF_FILE_RECORD) + 1U); // checksum
|
||||
#endif
|
||||
w = ihex_buffer_newline(w);
|
||||
ihex_flush_buffer(ihex, line_buffer, w);
|
||||
ihex_flush_buffer(ihex, ihex_write_buffer, w);
|
||||
}
|
||||
|
||||
static void
|
||||
ihex_write_extended_address (struct ihex_state * const ihex,
|
||||
const ihex_segment_t address,
|
||||
const enum ihex_record_type type) {
|
||||
char *w = line_buffer;
|
||||
char * restrict w = ihex_write_buffer;
|
||||
unsigned int sum = type + 2;
|
||||
|
||||
*w++ = IHEX_START; // :
|
||||
@@ -102,7 +102,7 @@ ihex_write_extended_address (struct ihex_state * const ihex,
|
||||
w = ihex_buffer_word(w, address, &sum); // high bytes of address
|
||||
w = ihex_buffer_byte(w, ~sum + 1); // checksum
|
||||
w = ihex_buffer_newline(w);
|
||||
ihex_flush_buffer(ihex, line_buffer, w);
|
||||
ihex_flush_buffer(ihex, ihex_write_buffer, w);
|
||||
}
|
||||
|
||||
// Write out `ihex->data`
|
||||
@@ -111,7 +111,7 @@ static void
|
||||
ihex_write_data (struct ihex_state * const ihex) {
|
||||
unsigned int len = ihex->length;
|
||||
unsigned int sum = len;
|
||||
char *w = line_buffer;
|
||||
char * restrict w = ihex_write_buffer;
|
||||
|
||||
if (!len) {
|
||||
return;
|
||||
@@ -159,7 +159,7 @@ ihex_write_data (struct ihex_state * const ihex) {
|
||||
w = ihex_buffer_byte(w, ~sum + 1U);
|
||||
|
||||
w = ihex_buffer_newline(w);
|
||||
ihex_flush_buffer(ihex, line_buffer, w);
|
||||
ihex_flush_buffer(ihex, ihex_write_buffer, w);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -48,6 +48,16 @@
|
||||
* both the `struct ihex_state' and the internal write buffer smaller.
|
||||
* For example, 32 or even 16 can be used instead of the default 255.
|
||||
*
|
||||
* If the write functionality is not used all the time and can thus
|
||||
* share its write buffer memory with something else that is inactive
|
||||
* during writing IHEX, you can define `IHEX_EXTERNAL_WRITE_BUFFER` and
|
||||
* provide the buffer as `char *ihex_write_buffer`. The size of the
|
||||
* buffer must be at least `IHEX_WRITE_BUFFER_LENGTH` bytes and it must
|
||||
* be valid for the entire duration from the first call to a write function
|
||||
* until after the last call to `ihex_end_write`. Note that there is
|
||||
* no advantage to this unless something else, mutually exclusive with
|
||||
* IHEX writing, can share the memory.
|
||||
*
|
||||
* If you are reading IHEX as well, then you'll end up limiting the
|
||||
* maximum length of line that can be read. In that case you may wish to
|
||||
* define `IHEX_MAX_OUTPUT_LINE_LENGTH` as smaller to decrease the
|
||||
@@ -79,6 +89,17 @@ extern "C" {
|
||||
#define IHEX_MAX_OUTPUT_LINE_LENGTH IHEX_LINE_MAX_LENGTH
|
||||
#endif
|
||||
|
||||
// Length of the write buffer required
|
||||
#define IHEX_WRITE_BUFFER_LENGTH (1+2+4+2+(IHEX_MAX_OUTPUT_LINE_LENGTH*2)+2+sizeof(IHEX_NEWLINE_STRING))
|
||||
|
||||
#ifdef IHEX_EXTERNAL_WRITE_BUFFER
|
||||
// Define `IHEX_EXTERNAL_WRITE_BUFFER` to provide an external write buffer,
|
||||
// as `char *ihex_write_buffer`, which must point to a valid storage for
|
||||
// at least `IHEX_WRITE_BUFFER_LENGTH` characters whenever any of the
|
||||
// write functionality is used (see above under "CONSERVING MEMORY").
|
||||
extern char *ihex_write_buffer;
|
||||
#endif
|
||||
|
||||
// Initialise the structure `ihex` for writing
|
||||
void ihex_init(struct ihex_state * const ihex);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user