diff --git a/core/sysparam.c b/core/sysparam.c
index d6fd4b1..8f9415d 100644
--- a/core/sysparam.c
+++ b/core/sysparam.c
@@ -5,28 +5,60 @@
 #include <espressif/spi_flash.h>
 
 //TODO: make this properly threadsafe
-//FIXME: reduce stack usage
-//TODO: make stderr work for debug output
+//TODO: reduce stack usage
+//FIXME: CRC calculations/checking
+
+/* The "magic" values that indicate the start of a sysparam region in flash.
+ * Note that SYSPARAM_STALE_MAGIC is written over SYSPARAM_ACTIVE_MAGIC, so it
+ * must not contain any set bits which are not set in SYSPARAM_ACTIVE_MAGIC
+ * (that is, going from SYSPARAM_ACTIVE_MAGIC to SYSPARAM_STALE_MAGIC must only
+ * clear bits, not set them)
+ */
+#define SYSPARAM_ACTIVE_MAGIC 0x70524f45 // "EORp" in little-endian
+#define SYSPARAM_STALE_MAGIC  0x40524f45 // "EOR@" in little-endian
+
+/* The size of the initial buffer created by sysparam_iter_start, etc, to hold
+ * returned key-value pairs.  Setting this too small may result in a lot of
+ * unnecessary reallocs.  Setting it too large will waste memory when iterating
+ * through entries.
+ */
+#define DEFAULT_ITER_BUF_SIZE 64
+
+/* The size of the buffer (in words) used by `sysparam_create_area` when
+ * scanning a potential area to make sure it's currently empty.  Note that this
+ * space is taken from the stack, so it should not be too large.
+ */
+#define SCAN_BUFFER_SIZE 8 // words
+
+/* Size of region/entry headers.  These should not normally need tweaking (and
+ * will probably require some code changes if they are tweaked).
+ */
+#define REGION_HEADER_SIZE 4 // NOTE: Must be multiple of 4
+#define ENTRY_HEADER_SIZE 4  // NOTE: Must be multiple of 4
+
+/* Maximum value that can be used for a key_id.  This is limited by the format
+ * to 0x7e (0x7f would produce a corresponding value ID of 0xff, which is
+ * invalid)
+ */
+#define MAX_KEY_ID 0x7e
 
 #ifndef SYSPARAM_DEBUG
 #define SYSPARAM_DEBUG 0
 #endif
 
-#define debug(level, format, ...) if (SYSPARAM_DEBUG >= (level)) { printf("%s" format "\n", "sysparam: ", ## __VA_ARGS__); }
-
-#define SYSPARAM_MAGIC 0x70524f45 // "EORp" in little-endian
-#define SYSPARAM_STALEMAGIC 0x40524f45 // "EOR@" in little-endian
-#define REGION_HEADER_SIZE 4 // NOTE: Must be multiple of 4
-#define ENTRY_HEADER_SIZE 4 // NOTE: Must be multiple of 4
-#define DEFAULT_ITER_BUF_SIZE 64
-#define MAX_KEY_ID 0x7e
-#define SCAN_BUFFER_SIZE 8 // words
+/******************************* Useful Macros *******************************/
 
 #define ROUND_TO_WORD_BOUNDARY(x) (((x) + 3) & 0xfffffffc)
 #define ENTRY_SIZE(payload_len) (ENTRY_HEADER_SIZE + ROUND_TO_WORD_BOUNDARY(payload_len))
 
+#define max(x, y) ((x) > (y) ? (x) : (y))
+#define min(x, y) ((x) < (y) ? (x) : (y))
+
+#define debug(level, format, ...) if (SYSPARAM_DEBUG >= (level)) { printf("%s" format "\n", "sysparam: ", ## __VA_ARGS__); }
+
 #define CHECK_FLASH_OP(x) do { int __x = (x); if ((__x) != SPI_FLASH_RESULT_OK) { debug(1, "FLASH ERR: %d", __x); return SYSPARAM_ERR_IO; } } while (0);
 
+/********************* Internal datatypes and structures *********************/
 
 struct entry_header {
     uint8_t prev_len;
@@ -43,21 +75,19 @@ struct sysparam_context {
     uint8_t max_key_id;
 };
 
-/* Internal data structures */
+/*************************** Global variables/data ***************************/
 
-struct {
+static struct {
     uint32_t cur_base;
     uint32_t alt_base;
     uint32_t end_addr;
     size_t region_size;
-} sysparam_info;
+} _sysparam_info;
 
-/* Internal routines */
+/***************************** Internal routines *****************************/
 
-#define max(x, y) ((x) > (y) ? (x) : (y))
-#define min(x, y) ((x) < (y) ? (x) : (y))
-
-static sysparam_status_t format_region(uint32_t addr) {
+/** Erase the sectors of a region */
+static sysparam_status_t _format_region(uint32_t addr) {
     uint16_t sector = addr / sdk_flashchip.sector_size;
     int i;
 
@@ -67,30 +97,38 @@ static sysparam_status_t format_region(uint32_t addr) {
     return SYSPARAM_OK;
 }
 
-static inline sysparam_status_t write_region_header(uint32_t addr, bool active) {
-    uint32_t magic = active ? SYSPARAM_MAGIC : SYSPARAM_STALEMAGIC;
+/** Write the magic value at the beginning of a region */
+static inline sysparam_status_t _write_region_header(uint32_t addr, bool active) {
+    uint32_t magic = active ? SYSPARAM_ACTIVE_MAGIC : SYSPARAM_STALE_MAGIC;
     debug(3, "write region header (0x%08x) @ 0x%08x", magic, addr);
     CHECK_FLASH_OP(sdk_spi_flash_write(addr, &magic, 4));
     return SYSPARAM_OK;
 }
 
-static void init_context(struct sysparam_context *ctx) {
+/** Initialize a context structure at the beginning of the active region */
+static void _init_context(struct sysparam_context *ctx) {
     memset(ctx, 0, sizeof(*ctx));
-    ctx->addr = sysparam_info.cur_base;
+    ctx->addr = _sysparam_info.cur_base;
 }
 
+/** Initialize a context structure at the end of the active region */
 static sysparam_status_t init_write_context(struct sysparam_context *ctx) {
     memset(ctx, 0, sizeof(*ctx));
-    ctx->addr = sysparam_info.end_addr;
+    ctx->addr = _sysparam_info.end_addr;
     debug(3, "read entry header @ 0x%08x", ctx->addr);
     CHECK_FLASH_OP(sdk_spi_flash_read(ctx->addr, &ctx->entry, ENTRY_HEADER_SIZE));
     return SYSPARAM_OK;
 }
 
-static sysparam_status_t find_entry(struct sysparam_context *ctx, uint8_t match_id) {
+/** Search through the region for an entry matching the specified id
+ *
+ *  @param match_id  The id to match, or 0 to match any key, or 0xff to scan
+ *                   to the end.
+ */
+static sysparam_status_t _find_entry(struct sysparam_context *ctx, uint8_t match_id) {
     uint8_t prev_len;
 
-    while (ctx->addr + ENTRY_SIZE(ctx->entry.len) < sysparam_info.end_addr) {
+    while (ctx->addr + ENTRY_SIZE(ctx->entry.len) < _sysparam_info.end_addr) {
         prev_len = ctx->entry.len;
         ctx->addr += ENTRY_SIZE(ctx->entry.len);
 
@@ -102,7 +140,7 @@ static sysparam_status_t find_entry(struct sysparam_context *ctx, uint8_t match_
             // been corrupted and we don't even know if we're in the right
             // place anymore.  We have to bail out.
             debug(1, "prev_len mismatch at 0x%08x (%d != %d)", ctx->addr, ctx->entry.prev_len, prev_len);
-            ctx->addr = sysparam_info.end_addr;
+            ctx->addr = _sysparam_info.end_addr;
             return SYSPARAM_ERR_CORRUPT;
         }
 
@@ -132,28 +170,28 @@ static sysparam_status_t find_entry(struct sysparam_context *ctx, uint8_t match_
     return SYSPARAM_NOTFOUND;
 }
 
-static inline sysparam_status_t read_payload(struct sysparam_context *ctx, uint8_t *buffer, size_t buffer_size) {
+/** Read the payload from the current entry pointed to by `ctx` */
+static inline sysparam_status_t _read_payload(struct sysparam_context *ctx, uint8_t *buffer, size_t buffer_size) {
     debug(3, "read payload (%d) @ 0x%08x", min(buffer_size, ctx->entry.len), ctx->addr);
     CHECK_FLASH_OP(sdk_spi_flash_read(ctx->addr + ENTRY_HEADER_SIZE, buffer, min(buffer_size, ctx->entry.len)));
     //FIXME: check crc
     return SYSPARAM_OK;
 }
 
-// Scan through the region to find the location of the key entry matching the
-// specified name.
-static sysparam_status_t find_key(struct sysparam_context *ctx, const char *key, uint8_t key_len, uint8_t *buffer) {
+/** Find the entry corresponding to the specified key name */
+static sysparam_status_t _find_key(struct sysparam_context *ctx, const char *key, uint8_t key_len, uint8_t *buffer) {
     sysparam_status_t status;
 
     while (true) {
         // Find the next key entry
-        status = find_entry(ctx, 0);
+        status = _find_entry(ctx, 0);
         if (status != SYSPARAM_OK) return status;
         if (!key) {
             // We're looking for the next (any) key, so we're done.
             break;
         }
         if (ctx->entry.len == key_len) {
-            status = read_payload(ctx, buffer, key_len);
+            status = _read_payload(ctx, buffer, key_len);
             if (status < 0) return status;
             if (!memcmp(key, buffer, key_len)) {
                 // We have a match
@@ -165,7 +203,8 @@ static sysparam_status_t find_key(struct sysparam_context *ctx, const char *key,
     return SYSPARAM_OK;
 }
 
-static inline sysparam_status_t write_entry(uint32_t addr, uint8_t id, const uint8_t *payload, uint8_t len, uint8_t prev_len) {
+/** Write an entry at the specified address */
+static inline sysparam_status_t _write_entry(uint32_t addr, uint8_t id, const uint8_t *payload, uint8_t len, uint8_t prev_len) {
     struct entry_header entry;
 
     debug(2, "Writing entry 0x%02x @ 0x%08x", id, addr);
@@ -181,7 +220,10 @@ static inline sysparam_status_t write_entry(uint32_t addr, uint8_t id, const uin
     return SYSPARAM_OK;
 }
 
-static inline sysparam_status_t write_entry_tail(uint32_t addr, uint8_t prev_len) {
+/** Write the "tail" entry on the end of the region
+ *  (this entry just contains the `prev_len` field with all others set to 0xff)
+ */
+static inline sysparam_status_t _write_entry_tail(uint32_t addr, uint8_t prev_len) {
     struct entry_header entry;
 
     entry.prev_len = prev_len;
@@ -194,7 +236,8 @@ static inline sysparam_status_t write_entry_tail(uint32_t addr, uint8_t prev_len
     return SYSPARAM_OK;
 }
 
-static inline sysparam_status_t delete_entry(uint32_t addr) {
+/** Mark an entry as "deleted" so it won't be considered in future reads */
+static inline sysparam_status_t _delete_entry(uint32_t addr) {
     struct entry_header entry;
 
     debug(2, "Deleting entry @ 0x%08x", addr);
@@ -208,16 +251,28 @@ static inline sysparam_status_t delete_entry(uint32_t addr) {
     return SYSPARAM_OK;
 }
 
-static sysparam_status_t compact_params(struct sysparam_context *ctx, uint8_t *key_id) {
-    uint32_t new_base = sysparam_info.alt_base;
+/** Compact the current region, removing all deleted/unused entries, and write
+ *  the result to the alternate region, then make the new alternate region the
+ *  active one.
+ *
+ *  @param key_id  A pointer to the "current" key ID.
+ *
+ *  NOTE: The value corresponding to the passed key ID will not be written to
+ *  the output (because it is assumed it will be overwritten as the next step
+ *  in `sysparam_set_data` anyway).  When compacting, this routine will
+ *  automatically update *key_id to contain the ID of this key in the new
+ *  compacted result as well.
+ */
+static sysparam_status_t _compact_params(struct sysparam_context *ctx, uint8_t *key_id) {
+    uint32_t new_base = _sysparam_info.alt_base;
     sysparam_status_t status;
     uint32_t addr = new_base + REGION_HEADER_SIZE;
     uint8_t current_key_id = 0;
     sysparam_iter_t iter;
     uint8_t prev_len = 0;
 
-    debug(1, "compacting region (current size %d, expect to recover %d%s bytes)...", sysparam_info.end_addr - sysparam_info.cur_base, ctx->compactable, (ctx->unused_keys[0] || ctx->unused_keys[1]) ? "+ (unused keys present)" : "");
-    status = format_region(new_base);
+    debug(1, "compacting region (current size %d, expect to recover %d%s bytes)...", _sysparam_info.end_addr - _sysparam_info.cur_base, ctx->compactable, (ctx->unused_keys[0] || ctx->unused_keys[1]) ? "+ (unused keys present)" : "");
+    status = _format_region(new_base);
     if (status < 0) return status;
     status = sysparam_iter_start(&iter);
     if (status < 0) return status;
@@ -230,7 +285,7 @@ static sysparam_status_t compact_params(struct sysparam_context *ctx, uint8_t *k
 
         // Write the key to the new region
         debug(2, "writing %d key @ 0x%08x", current_key_id, addr);
-        status = write_entry(addr, current_key_id, (uint8_t *)iter.key, iter.key_len, prev_len);
+        status = _write_entry(addr, current_key_id, (uint8_t *)iter.key, iter.key_len, prev_len);
         if (status < 0) break;
         prev_len = iter.key_len;
         addr += ENTRY_SIZE(iter.key_len);
@@ -245,7 +300,7 @@ static sysparam_status_t compact_params(struct sysparam_context *ctx, uint8_t *k
 
         // Copy the value to the new region
         debug(2, "writing %d value @ 0x%08x", current_key_id, addr);
-        status = write_entry(addr, current_key_id | 0x80, iter.value, iter.value_len, prev_len);
+        status = _write_entry(addr, current_key_id | 0x80, iter.value, iter.value_len, prev_len);
         if (status < 0) break;
         prev_len = iter.value_len;
         addr += ENTRY_SIZE(iter.value_len);
@@ -253,7 +308,7 @@ static sysparam_status_t compact_params(struct sysparam_context *ctx, uint8_t *k
     sysparam_iter_end(&iter);
 
     if (status >= 0) {
-        status = write_entry_tail(addr, prev_len);
+        status = _write_entry_tail(addr, prev_len);
     }
 
     // If we broke out with an error, return the error instead of continuing.
@@ -263,14 +318,14 @@ static sysparam_status_t compact_params(struct sysparam_context *ctx, uint8_t *k
     }
 
     // Switch to officially using the new region.
-    status = write_region_header(new_base, true);
+    status = _write_region_header(new_base, true);
     if (status < 0) return status;
-    status = write_region_header(sysparam_info.cur_base, false);
+    status = _write_region_header(_sysparam_info.cur_base, false);
     if (status < 0) return status;
 
-    sysparam_info.alt_base = sysparam_info.cur_base;
-    sysparam_info.cur_base = new_base;
-    sysparam_info.end_addr = addr;
+    _sysparam_info.alt_base = _sysparam_info.cur_base;
+    _sysparam_info.cur_base = new_base;
+    _sysparam_info.end_addr = addr;
 
     // Fix up ctx so it doesn't point to invalid stuff
     memset(ctx, 0, sizeof(*ctx));
@@ -278,38 +333,38 @@ static sysparam_status_t compact_params(struct sysparam_context *ctx, uint8_t *k
     ctx->entry.prev_len = prev_len;
     ctx->max_key_id = current_key_id;
 
-    debug(1, "done compacting (current size %d)", sysparam_info.end_addr - sysparam_info.cur_base);
+    debug(1, "done compacting (current size %d)", _sysparam_info.end_addr - _sysparam_info.cur_base);
 
     return SYSPARAM_OK;
 }
 
-/* Public Functions */
+/***************************** Public Functions ******************************/
 
 sysparam_status_t sysparam_init(uint32_t base_addr) {
     sysparam_status_t status;
     uint32_t magic0, magic1;
     struct sysparam_context ctx;
 
-    sysparam_info.region_size = SYSPARAM_REGION_SECTORS * sdk_flashchip.sector_size;
+    _sysparam_info.region_size = SYSPARAM_REGION_SECTORS * sdk_flashchip.sector_size;
     // First, see if we can find an existing one.
     debug(3, "read magic @ 0x%08x", base_addr);
     CHECK_FLASH_OP(sdk_spi_flash_read(base_addr, &magic0, 4));
-    debug(3, "read magic @ 0x%08x", base_addr + sysparam_info.region_size);
-    CHECK_FLASH_OP(sdk_spi_flash_read(base_addr + sysparam_info.region_size, &magic1, 4));
-    if (magic0 == SYSPARAM_MAGIC && magic1 == SYSPARAM_STALEMAGIC) {
+    debug(3, "read magic @ 0x%08x", base_addr + _sysparam_info.region_size);
+    CHECK_FLASH_OP(sdk_spi_flash_read(base_addr + _sysparam_info.region_size, &magic1, 4));
+    if (magic0 == SYSPARAM_ACTIVE_MAGIC && magic1 == SYSPARAM_STALE_MAGIC) {
         // Sysparam area found, first region is active
-        sysparam_info.cur_base = base_addr;
-        sysparam_info.alt_base = base_addr + sysparam_info.region_size;
-    } else if (magic0 == SYSPARAM_STALEMAGIC && magic1 == SYSPARAM_MAGIC) {
+        _sysparam_info.cur_base = base_addr;
+        _sysparam_info.alt_base = base_addr + _sysparam_info.region_size;
+    } else if (magic0 == SYSPARAM_STALE_MAGIC && magic1 == SYSPARAM_ACTIVE_MAGIC) {
         // Sysparam area found, second region is active
-        sysparam_info.cur_base = base_addr + sysparam_info.region_size;
-        sysparam_info.alt_base = base_addr;
-    } else if (magic0 == SYSPARAM_MAGIC && magic1 == SYSPARAM_MAGIC) {
+        _sysparam_info.cur_base = base_addr + _sysparam_info.region_size;
+        _sysparam_info.alt_base = base_addr;
+    } else if (magic0 == SYSPARAM_ACTIVE_MAGIC && magic1 == SYSPARAM_ACTIVE_MAGIC) {
         // Both regions are marked as active.  Not sure which to use.
         // This can theoretically happen if something goes wrong at exactly the
         // wrong time during compacting.
         return SYSPARAM_ERR_CORRUPT;
-    } else if (magic0 == SYSPARAM_STALEMAGIC && magic1 == SYSPARAM_STALEMAGIC) {
+    } else if (magic0 == SYSPARAM_STALE_MAGIC && magic1 == SYSPARAM_STALE_MAGIC) {
         // Both regions are marked as inactive.  This shouldn't ever happen.
         return SYSPARAM_ERR_CORRUPT;
     } else {
@@ -318,17 +373,17 @@ sysparam_status_t sysparam_init(uint32_t base_addr) {
     }
 
     // Find the actual end
-    sysparam_info.end_addr = sysparam_info.cur_base + sysparam_info.region_size;
-    init_context(&ctx);
-    status = find_entry(&ctx, 0xff);
+    _sysparam_info.end_addr = _sysparam_info.cur_base + _sysparam_info.region_size;
+    _init_context(&ctx);
+    status = _find_entry(&ctx, 0xff);
     if (status < 0) {
-        sysparam_info.cur_base = 0;
-        sysparam_info.alt_base = 0;
-        sysparam_info.end_addr = 0;
+        _sysparam_info.cur_base = 0;
+        _sysparam_info.alt_base = 0;
+        _sysparam_info.end_addr = 0;
         return status;
     }
     if (status == SYSPARAM_OK) {
-        sysparam_info.end_addr = ctx.addr;
+        _sysparam_info.end_addr = ctx.addr;
     }
 
     return SYSPARAM_OK;
@@ -356,21 +411,21 @@ sysparam_status_t sysparam_create_area(uint32_t base_addr, bool force) {
         }
     }
 
-    if (sysparam_info.cur_base == base_addr || sysparam_info.alt_base == base_addr) {
+    if (_sysparam_info.cur_base == base_addr || _sysparam_info.alt_base == base_addr) {
         // We're reformating the same region we're already using.
         // De-initialize everything to force the caller to do a clean
         // `sysparam_init()` afterwards.
-        memset(&sysparam_info, 0, sizeof(sysparam_info));
+        memset(&_sysparam_info, 0, sizeof(_sysparam_info));
     }
-    status = format_region(base_addr);
+    status = _format_region(base_addr);
     if (status < 0) return status;
-    status = format_region(base_addr + region_size);
+    status = _format_region(base_addr + region_size);
     if (status < 0) return status;
-    status = write_entry_tail(base_addr + REGION_HEADER_SIZE, 0);
+    status = _write_entry_tail(base_addr + REGION_HEADER_SIZE, 0);
     if (status < 0) return status;
-    status = write_region_header(base_addr + region_size, false);
+    status = _write_region_header(base_addr + region_size, false);
     if (status < 0) return status;
-    status = write_region_header(base_addr, true);
+    status = _write_region_header(base_addr, true);
     if (status < 0) return status;
 
     return SYSPARAM_OK;
@@ -382,24 +437,24 @@ sysparam_status_t sysparam_get_data(const char *key, uint8_t **destptr, size_t *
     size_t key_len = strlen(key);
     uint8_t *buffer;
    
-    if (!sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT;
+    if (!_sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT;
 
     buffer = malloc(key_len + 2);
     if (!buffer) return SYSPARAM_ERR_NOMEM;
     do {
-        init_context(&ctx);
-        status = find_key(&ctx, key, key_len, buffer);
+        _init_context(&ctx);
+        status = _find_key(&ctx, key, key_len, buffer);
         if (status != SYSPARAM_OK) break;
 
         // Find the associated value
-        status = find_entry(&ctx, ctx.entry.id | 0x80);
+        status = _find_entry(&ctx, ctx.entry.id | 0x80);
         if (status != SYSPARAM_OK) break;
 
         buffer = realloc(buffer, ctx.entry.len + 1);
         if (!buffer) {
             return SYSPARAM_ERR_NOMEM;
         }
-        status = read_payload(&ctx, buffer, ctx.entry.len);
+        status = _read_payload(&ctx, buffer, ctx.entry.len);
         if (status != SYSPARAM_OK) break;
 
         // Zero-terminate the result, just in case (doesn't hurt anything for
@@ -413,7 +468,6 @@ sysparam_status_t sysparam_get_data(const char *key, uint8_t **destptr, size_t *
     } while (false);
 
     free(buffer);
-    *destptr = NULL;
     if (actual_length) *actual_length = 0;
     return status;
 }
@@ -423,7 +477,7 @@ sysparam_status_t sysparam_get_data_static(const char *key, uint8_t *buffer, siz
     sysparam_status_t status = SYSPARAM_OK;
     size_t key_len = strlen(key);
 
-    if (!sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT;
+    if (!_sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT;
 
     // Supplied buffer must be at least as large as the key, or 2 bytes,
     // whichever is larger.
@@ -431,12 +485,12 @@ sysparam_status_t sysparam_get_data_static(const char *key, uint8_t *buffer, siz
 
     if (actual_length) *actual_length = 0;
 
-    init_context(&ctx);
-    status = find_key(&ctx, key, key_len, buffer);
+    _init_context(&ctx);
+    status = _find_key(&ctx, key, key_len, buffer);
     if (status != SYSPARAM_OK) return status;
-    status = find_entry(&ctx, ctx.entry.id | 0x80);
+    status = _find_entry(&ctx, ctx.entry.id | 0x80);
     if (status != SYSPARAM_OK) return status;
-    status = read_payload(&ctx, buffer, buffer_size);
+    status = _read_payload(&ctx, buffer, buffer_size);
     if (status != SYSPARAM_OK) return status;
 
     if (actual_length) *actual_length = ctx.entry.len;
@@ -450,54 +504,59 @@ sysparam_status_t sysparam_get_string(const char *key, char **destptr) {
 }
 
 sysparam_status_t sysparam_get_int(const char *key, int32_t *result) {
-    char buffer[32];
-    size_t len;
+    char *buffer;
     char *endptr;
     int32_t value;
     sysparam_status_t status;
 
-    status = sysparam_get_data_static(key, (uint8_t *)buffer, 12, &len);
+    status = sysparam_get_string(key, &buffer);
     if (status != SYSPARAM_OK) return status;
-    if (len > 31) return SYSPARAM_PARSEFAILED;
-    buffer[len] = 0;
     value = strtol(buffer, &endptr, 0);
-    if (*endptr) return SYSPARAM_PARSEFAILED;
+    if (*endptr) {
+        // There was extra crap at the end of the string.
+        free(buffer);
+        return SYSPARAM_PARSEFAILED;
+    }
 
     *result = value;
+    free(buffer);
     return SYSPARAM_OK;
 }
 
 sysparam_status_t sysparam_get_bool(const char *key, bool *result) {
-    char buffer[6];
-    size_t len;
+    char *buffer;
     int i;
     sysparam_status_t status;
 
-    status = sysparam_get_data_static(key, (uint8_t *)buffer, 12, &len);
+    status = sysparam_get_string(key, &buffer);
     if (status != SYSPARAM_OK) return status;
-    if (len > 5) return SYSPARAM_PARSEFAILED;
-    buffer[len] = 0;
-    for (i = 0; i < len; i++) {
-        // Quick and dirty tolower().  Not perfect, but works for our purposes,
-        // and avoids needing to pull in additional libc modules.
-        if (buffer[i] >= 0x41) buffer[i] |= 0x20;
-    }
-    if (!strcmp(buffer, "t")) {
-        *result = true;
-    } else if (!strcmp(buffer, "f")) {
-        *result = false;
-    } else if (!strcmp(buffer, "true")) {
-        *result = true;
-    } else if (!strcmp(buffer, "false")) {
-        *result = false;
-    } else if (!strcmp(buffer, "0")) {
-        *result = true;
-    } else if (!strcmp(buffer, "1")) {
-        *result = false;
-    } else {
-        return SYSPARAM_PARSEFAILED;
-    }
-    return SYSPARAM_OK;
+    do {
+        for (i = 0; buffer[i]; i++) {
+            // Quick-and-dirty tolower().  Not perfect, but works for our
+            // purposes, and avoids needing to pull in additional libc stuff.
+            if (buffer[i] >= 0x41) buffer[i] |= 0x20;
+        }
+        if (!strcmp(buffer, "y")    ||
+            !strcmp(buffer, "yes")  ||
+            !strcmp(buffer, "t")    ||
+            !strcmp(buffer, "true") ||
+            !strcmp(buffer, "1")) {
+                *result = true;
+                break;
+        }
+        if (!strcmp(buffer, "n")     ||
+            !strcmp(buffer, "no")    ||
+            !strcmp(buffer, "f")     ||
+            !strcmp(buffer, "false") ||
+            !strcmp(buffer, "0")) {
+                *result = false;
+                break;
+        }
+        status = SYSPARAM_PARSEFAILED;
+    } while (0);
+
+    free(buffer);
+    return status;
 }
 
 sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_t value_len) {
@@ -512,7 +571,7 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_
     uint8_t key_id = 0;
     uint32_t old_value_addr = 0;
    
-    if (!sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT;
+    if (!_sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT;
     if (!key_len) return SYSPARAM_ERR_BADVALUE;
     if (value_len > 0xff) return SYSPARAM_ERR_BADVALUE;
 
@@ -525,7 +584,7 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_
         value = buffer;
         free_value = true;
     }
-    // Create a working buffer for `find_key` to use.
+    // Create a working buffer for `_find_key` to use.
     buffer = malloc(key_len);
     if (!buffer) {
         if (free_value) free((void *)value);
@@ -533,12 +592,12 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_
     }
 
     do {
-        init_context(&ctx);
-        status = find_key(&ctx, key, key_len, buffer);
+        _init_context(&ctx);
+        status = _find_key(&ctx, key, key_len, buffer);
         if (status == SYSPARAM_OK) {
             // Key already exists, see if there's a current value.
             key_id = ctx.entry.id;
-            status = find_entry(&ctx, key_id | 0x80);
+            status = _find_entry(&ctx, key_id | 0x80);
             if (status == SYSPARAM_OK) {
                 old_value_addr = ctx.addr;
             }
@@ -553,7 +612,7 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_
                         buffer = realloc(buffer, value_len);
                         if (!buffer) return SYSPARAM_ERR_NOMEM;
                     }
-                    status = read_payload(&ctx, buffer, value_len);
+                    status = _read_payload(&ctx, buffer, value_len);
                     if (status == SYSPARAM_ERR_CORRUPT) {
                         // If the CRC check failed, don't worry about it.  We're
                         // going to be deleting this entry anyway.
@@ -575,7 +634,7 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_
 
             // Append new value to the end, but first make sure we have enough
             // space.
-            free_space = sysparam_info.cur_base + sysparam_info.region_size - sysparam_info.end_addr - 4;
+            free_space = _sysparam_info.cur_base + _sysparam_info.region_size - _sysparam_info.end_addr - 4;
             needed_space = ENTRY_SIZE(value_len);
             if (!key_id) {
                 // We did not find a previous key entry matching this key.  We
@@ -587,10 +646,10 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_
                 // Can we compact things?
                 // First, scan all remaining entries up to the end so we can
                 // get a reasonably accurate "compactable" reading.
-                find_entry(&ctx, 0xff);
+                _find_entry(&ctx, 0xff);
                 if (needed_space <= free_space + ctx.compactable) {
                     // We should be able to get enough space by compacting.
-                    status = compact_params(&ctx, &key_id);
+                    status = _compact_params(&ctx, &key_id);
                     if (status < 0) break;
                     old_value_addr = 0;
                 } else if (ctx.unused_keys[0] || ctx.unused_keys[1]) {
@@ -598,11 +657,11 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_
                     // there are some keys that can be omitted too, but we
                     // don't know exactly how much that will gain, so all we
                     // can do is give it a try and see if it gives us enough.
-                    status = compact_params(&ctx, &key_id);
+                    status = _compact_params(&ctx, &key_id);
                     if (status < 0) break;
                     old_value_addr = 0;
                 }
-                free_space = sysparam_info.cur_base + sysparam_info.region_size - sysparam_info.end_addr - 4;
+                free_space = _sysparam_info.cur_base + _sysparam_info.region_size - _sysparam_info.end_addr - 4;
             }
             if (needed_space > free_space) {
                 // Nothing we can do here.. We're full.
@@ -617,14 +676,14 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_
 
             if (!key_id) {
                 // We need to write a key entry for a new key.
-                // If we didn't find the key, then we already know find_entry
+                // If we didn't find the key, then we already know _find_entry
                 // has gone through the entire contents, and thus
                 // ctx.max_key_id has the largest key_id found in the whole
                 // region.
                 key_id = ctx.max_key_id + 1;
                 if (key_id > MAX_KEY_ID) {
                     if (ctx.unused_keys[0] || ctx.unused_keys[1]) {
-                        status = compact_params(&ctx, &key_id);
+                        status = _compact_params(&ctx, &key_id);
                         if (status < 0) break;
                         old_value_addr = 0;
                     } else {
@@ -633,24 +692,24 @@ sysparam_status_t sysparam_set_data(const char *key, const uint8_t *value, size_
                         break;
                     }
                 }
-                status = write_entry(write_ctx.addr, key_id, (uint8_t *)key, key_len, write_ctx.entry.prev_len);
+                status = _write_entry(write_ctx.addr, key_id, (uint8_t *)key, key_len, write_ctx.entry.prev_len);
                 if (status < 0) break;
                 write_ctx.addr += ENTRY_SIZE(key_len);
                 write_ctx.entry.prev_len = key_len;
             }
 
             // Write new value
-            status = write_entry(write_ctx.addr, key_id | 0x80, value, value_len, write_ctx.entry.prev_len);
+            status = _write_entry(write_ctx.addr, key_id | 0x80, value, value_len, write_ctx.entry.prev_len);
             if (status < 0) break;
             write_ctx.addr += ENTRY_SIZE(value_len);
-            status = write_entry_tail(write_ctx.addr, value_len);
+            status = _write_entry_tail(write_ctx.addr, value_len);
             if (status < 0) break;
-            sysparam_info.end_addr = write_ctx.addr;
+            _sysparam_info.end_addr = write_ctx.addr;
         }
 
         // Delete old value (if present) by setting it's id to 0x00
         if (old_value_addr) {
-            status = delete_entry(old_value_addr);
+            status = _delete_entry(old_value_addr);
             if (status < 0) break;
         }
     } while (false);
@@ -675,12 +734,12 @@ sysparam_status_t sysparam_set_int(const char *key, int32_t value) {
 sysparam_status_t sysparam_set_bool(const char *key, bool value) {
     uint8_t buf[4] = {0xff, 0xff, 0xff, 0xff};
 
-    buf[0] = value ? 't' : 'f';
+    buf[0] = value ? 'y' : 'n';
     return sysparam_set_data(key, buf, 1);
 }
 
 sysparam_status_t sysparam_iter_start(sysparam_iter_t *iter) {
-    if (!sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT;
+    if (!_sysparam_info.cur_base) return SYSPARAM_ERR_NOINIT;
 
     iter->bufsize = DEFAULT_ITER_BUF_SIZE;
     iter->key = malloc(iter->bufsize);
@@ -696,7 +755,7 @@ sysparam_status_t sysparam_iter_start(sysparam_iter_t *iter) {
         iter->bufsize = 0;
         return SYSPARAM_ERR_NOMEM;
     }
-    init_context(iter->ctx);
+    _init_context(iter->ctx);
 
     return SYSPARAM_OK;
 }
@@ -710,11 +769,11 @@ sysparam_status_t sysparam_iter_next(sysparam_iter_t *iter) {
     size_t key_space;
 
     while (true) {
-        status = find_key(ctx, NULL, 0, buffer);
+        status = _find_key(ctx, NULL, 0, buffer);
         if (status != SYSPARAM_OK) return status;
         memcpy(&value_ctx, ctx, sizeof(value_ctx));
 
-        status = find_entry(&value_ctx, ctx->entry.id | 0x80);
+        status = _find_entry(&value_ctx, ctx->entry.id | 0x80);
         if (status < 0) return status;
         if (status == SYSPARAM_NOTFOUND) continue;
 
@@ -729,14 +788,14 @@ sysparam_status_t sysparam_iter_next(sysparam_iter_t *iter) {
             iter->bufsize = required_len;
         }
 
-        status = read_payload(ctx, (uint8_t *)iter->key, iter->bufsize);
+        status = _read_payload(ctx, (uint8_t *)iter->key, iter->bufsize);
         if (status < 0) return status;
         // Null-terminate the key
         iter->key[ctx->entry.len] = 0;
         iter->key_len = ctx->entry.len;
 
         iter->value = (uint8_t *)(iter->key + key_space);
-        status = read_payload(&value_ctx, iter->value, iter->bufsize - key_space);
+        status = _read_payload(&value_ctx, iter->value, iter->bufsize - key_space);
         if (status < 0) return status;
         // Null-terminate the value (just in case)
         iter->value[value_ctx.entry.len] = 0;