diff --git a/kk_ihex.h b/kk_ihex.h index 9d08440..830970b 100644 --- a/kk_ihex.h +++ b/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 #include @@ -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)) diff --git a/kk_ihex_write.c b/kk_ihex_write.c index f04c1d5..69d272c 100644 --- a/kk_ihex_write.c +++ b/kk_ihex_write.c @@ -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 diff --git a/kk_ihex_write.h b/kk_ihex_write.h index 407ca8d..823d859 100644 --- a/kk_ihex_write.h +++ b/kk_ihex_write.h @@ -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);