From 8772f98903448029dc202b757d8ff482b0a5b6bc Mon Sep 17 00:00:00 2001 From: sogo Date: Mon, 15 Dec 2025 18:50:57 -0500 Subject: [PATCH 1/7] fix the comment at the top of eeprom_directory.h --- middleware/include/eeprom_directory.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/middleware/include/eeprom_directory.h b/middleware/include/eeprom_directory.h index a60d2720..06fa7ce5 100644 --- a/middleware/include/eeprom_directory.h +++ b/middleware/include/eeprom_directory.h @@ -1,5 +1,5 @@ /** - * @file eepromdirectory.h + * @file eeprom_directory.h * @brief EEPROM Directory Management * * This file provides functions to initialize and manage an EEPROM directory with partitions. From d154fa3520f7a3ecae61b74bc260d0b4e1a9709f Mon Sep 17 00:00:00 2001 From: sogo Date: Fri, 2 Jan 2026 12:36:44 -0500 Subject: [PATCH 2/7] re-implement eeprom directory --- middleware/include/eeprom_alloc.h | 84 ++++++++ middleware/include/eeprom_directory.h | 147 ++++++++------ middleware/include/eeprom_directory_struct.h | 105 ++++++++++ middleware/include/eeprom_status.h | 1 + middleware/include/eeprom_storage.h | 85 ++++++++ middleware/include/m24c32_eeprom_directory.h | 47 ----- middleware/src/eeprom_alloc.c | 89 +++++++++ middleware/src/eeprom_directory.c | 196 ++++++++++++++----- middleware/src/eeprom_storage.c | 131 +++++++++++++ middleware/src/m24c32_eeprom_directory.c | 58 ------ 10 files changed, 729 insertions(+), 214 deletions(-) create mode 100644 middleware/include/eeprom_alloc.h create mode 100644 middleware/include/eeprom_directory_struct.h create mode 100644 middleware/include/eeprom_storage.h delete mode 100644 middleware/include/m24c32_eeprom_directory.h create mode 100644 middleware/src/eeprom_alloc.c create mode 100644 middleware/src/eeprom_storage.c delete mode 100644 middleware/src/m24c32_eeprom_directory.c diff --git a/middleware/include/eeprom_alloc.h b/middleware/include/eeprom_alloc.h new file mode 100644 index 00000000..3f19b1b5 --- /dev/null +++ b/middleware/include/eeprom_alloc.h @@ -0,0 +1,84 @@ +/** + * @file eeprom_alloc.h + * @author Sogo Nishihara (sogonishi@gmail.com) + * @brief EEPROM Block Allocation Management + * @version 0.1 + * @date 2026-01-02 + * + * This file provides functions for managing data block allocation in the EEPROM. + * It maintains a bit-vector allocation table to track which blocks are in use. + * + */ + +#ifndef EEPROM_ALLOC_H +#define EEPROM_ALLOC_H + +#include + +#include "eeprom_directory_struct.h" + +/** + * @brief Initialize allocation table by loading it from EEPROM memory. + * + * This function reads the allocation table from EEPROM and populates the directory's + * alloc_table structure in memory. + * + * @param directory Pointer to the initialized directory structure. + * + * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure. + * + * @retval EEPROM_ERROR If EEPROM read operation fails. + */ +eeprom_status_t init_alloc_table(eeprom_directory_t *directory); + +/** + * @brief Print the allocation table in a human-readable format. + * + * This function prints the allocation table showing which blocks are allocated (1) + * and which are free (0). The output is formatted with 8 bits per group and + * 64 bits per line. + * + * @param directory Pointer to the initialized directory structure. + */ +void print_alloc_table(eeprom_directory_t *directory); + +/** + * @brief Allocate a single block from the EEPROM. + * + * This function finds the first free block in the allocation table, marks it as + * allocated in both local memory and EEPROM, and returns its ID. + * + * @param directory Pointer to the initialized directory structure. + * + * @return uint16_t Returns the allocated block ID on success, or BLOCK_COUNT if allocation fails. + * + * @retval BLOCK_COUNT If no free blocks are available or EEPROM update fails. + */ +uint16_t alloc_block(eeprom_directory_t *directory); + +/** + * @brief Free one or more blocks in the EEPROM. + * + * This function marks the specified blocks as free in both local memory and EEPROM. + * If a block is already freed, this function does nothing for that block. + * + * @param directory Pointer to the initialized directory structure. + * @param ids Array of block IDs to free. + * @param size Number of block IDs in the array. + */ +void free_block(eeprom_directory_t *directory, uint16_t *ids, uint8_t size); + +/** + * @brief Check if a block is allocated. + * + * This function checks the allocation table to determine if a specific block is + * currently allocated or free. + * + * @param directory Pointer to the initialized directory structure. + * @param id Block ID to check. + * + * @return int Returns 1 if the block is allocated, 0 if it is free. + */ +int is_allocated(eeprom_directory_t *directory, uint16_t id); + +#endif diff --git a/middleware/include/eeprom_directory.h b/middleware/include/eeprom_directory.h index 06fa7ce5..5df5813f 100644 --- a/middleware/include/eeprom_directory.h +++ b/middleware/include/eeprom_directory.h @@ -1,83 +1,118 @@ /** * @file eeprom_directory.h - * @brief EEPROM Directory Management + * @author Sogo Nishihara (sogonishi@gmail.com) + * @brief EEPROM Directory Management API * - * This file provides functions to initialize and manage an EEPROM directory with partitions. - * Functions return `eeprom_status_t` error codes, which are defined in `eeprom_status.h`. + * This file defines the public API for a simple key-value directory + * stored on EEPROM device. * - */ + * The directory provides block-based persistent storage, managing + * allocation, lookup, insertion, and deletion of values associated + * with fixed-size (4-byte) keys. + * + * All functions return eeprom_status_t error codes defined in + * eeprom_status.h. */ #ifndef EEPROM_DIRECTORY_H #define EEPROM_DIRECTORY_H -#include "eeprom_status.h" -#include -#include - -struct partition_cfg { - const char *id; /* The ID of the partition */ - uint16_t size; /* The size of the partition in bytes */ - uint16_t address; - uint16_t head_address; -}; +#include +#include +#include -typedef struct { - struct partition_cfg *partitions; - size_t num_partitions; -} eeprom_directory_t; +#include "m24c32.h" +#include "eeprom_status.h" +#include "eeprom_directory_struct.h" +#include "eeprom_alloc.h" +#include "eeprom_storage.h" /** - * @brief Initializes an EEPROM directory with partition IDs and sizes. + * @brief Initialize the EEPROM directory structure. * - * This function sets up partition configurations within the EEPROM memory. - * The total allocated address space is calculated based on the provided partitions. - * - * @param directory Pointer to the EEPROM directory structure. - * @param partitions Array of partition configurations, including IDs and sizes. - * @param num_partitions Number of partitions to create. - * @return eeprom_status_t Returns EEPROM_OK on success or an error code on failure. + * This function initializes the directory structure with the provided device interface, + * loads the allocation table and key map from EEPROM memory. + * + * @param device Pointer to the M24C32 device interface structure. + * @param directory Pointer to the directory structure to initialize. Must be allocated by caller. + * + * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure. + * + * @retval EEPROM_ERROR_NULL_POINTER If device or directory is NULL. + * @retval EEPROM_ERROR If initialization of alloc table or storage fails. */ -eeprom_status_t directory_init(eeprom_directory_t *directory, - const struct partition_cfg partitions[], - size_t num_partitions); +eeprom_status_t directory_init( + m24c32_t *device, + eeprom_directory_t *directory +); /** - * @brief Get the address of the beginning of a partition. - * - * This function searches for a partition by its name and returns its starting address. + * @brief Retrieve a value from the directory by key. + * + * This function looks up a key in the directory and retrieves the associated data. + * The output buffer is allocated by this function and must be freed by the caller. * - * @param directory Pointer to the EEPROM directory structure. - * @param key Name of the partition. - * @param address Pointer to store the retrieved base address. - * @return eeprom_status_t Returns EEPROM_OK on success or an error code if the partition is not found. + * @param directory Pointer to the initialized directory structure. + * @param key Pointer to a 4-byte key (not null-terminated). + * @param out Pointer to a pointer that will receive the allocated output buffer. + * The caller is responsible for freeing this buffer. + * @param out_size Pointer to store the size of the output data in bytes. + * + * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure. + * + * @retval EEPROM_ERROR_NULL_POINTER If directory, key, out, or out_size is NULL. + * @retval EEPROM_ERROR_NOT_FOUND If the key does not exist in the directory. + * @retval EEPROM_ERROR_ALLOCATION If memory allocation fails. */ -eeprom_status_t eeprom_get_base_address(const eeprom_directory_t *directory, - const char *key, uint16_t *address); +eeprom_status_t get_directory_value( + eeprom_directory_t *directory, + const uint8_t *key, + uint8_t **out, + uint16_t *out_size +); /** - * @brief Get the current read/write head of a partition. - * - * This function provides the address of the next location available for writing within the partition. + * @brief Store a value in the directory with the specified key. + * + * This function stores data in the directory. If the key already exists, the old value + * is deleted first. The data is stored in blocks of BLOCK_SIZE bytes, with remaining + * bytes padded with zeros. + * + * @param directory Pointer to the initialized directory structure. + * @param key Pointer to a 4-byte key (not null-terminated). + * @param value Pointer to the data to store. + * @param value_size Size of the data in bytes (maximum 16 bytes, i.e., 4 blocks). * - * @param directory Pointer to EEPROM directory struct. - * @param key Name of the partition. - * @param address Pointer to store the retrieved head address. - * @return eeprom_status_t Returns EEPROM_OK on success or an error code if the partition is not found. + * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure. + * + * @retval EEPROM_ERROR_NULL_POINTER If directory or value is NULL. + * @retval EEPROM_ERROR If value_size is 0. + * @retval EEPROM_ERROR_TOO_BIG If value_size exceeds 16 bytes (4 blocks). + * @retval EEPROM_ERROR_ALLOCATION If block allocation fails. */ -eeprom_status_t eeprom_get_head_address(const eeprom_directory_t *directory, - const char *key, uint16_t *address); +eeprom_status_t set_directory_value( + eeprom_directory_t *directory, + const uint8_t *key, + uint8_t *value, + const uint16_t value_size +); /** - * @brief Get the size of a partition - * - * This function returns the allocated size of a specific partition in bytes. + * @brief Delete a value from the directory by key. + * + * This function removes a key-value pair from the directory and frees the associated + * blocks. The blocks are marked as available for reuse. + * + * @param directory Pointer to the initialized directory structure. + * @param key Pointer to a 4-byte key (not null-terminated). + * + * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure. * - * @param directory Pointer to EEPROM directory struct. - * @param key Name of a partition. - * @param size Pointer to store the partition size. - * @return eeprom_status_t Returns EEPROM_OK on success or an error code if the partition is not found. + * @retval EEPROM_ERROR_NULL_POINTER If directory or key is NULL. + * @retval EEPROM_ERROR_NOT_FOUND If the key does not exist in the directory. */ -eeprom_status_t eeprom_get_size(const eeprom_directory_t *directory, - const char *key, uint16_t *size); +eeprom_status_t delete_directory_value( + eeprom_directory_t *directory, + const uint8_t *key +); #endif // EEPROM_DIRECTORY_H \ No newline at end of file diff --git a/middleware/include/eeprom_directory_struct.h b/middleware/include/eeprom_directory_struct.h new file mode 100644 index 00000000..5f5be10c --- /dev/null +++ b/middleware/include/eeprom_directory_struct.h @@ -0,0 +1,105 @@ +/** + * @file eeprom_directory_struct.h + * @author Sogo Nishihara (sogonishi@gmail.com) + * @brief EEPROM Directory Data Structures and Constants + * @version 0.1 + * @date 2026-01-02 + * + * This file defines the data structures and constants used for the EEPROM directory system. + * It includes memory layout definitions, block allocation parameters, and structure definitions. + * + * EEPROM Memory Layout (Total: 4096 bytes) + * + * Address + * 0x0000 + * +--------------------------------------------------+ + * | Allocation Table | + * | - Bit map (1 bit per data block) | + * | - Size : ALLOC_TABLE_SIZE bytes | + * | - Blocks : BLOCK_COUNT | + * +--------------------------------------------------+ + * | Key Map Table | + * | - Array of directory_key_map_t | + * | - Entry size : KEY_MAP_STRUCT_SIZE bytes | + * | - Entry count: KEY_MAP_COUNT | + * | - Total size : KEY_MAP_SIZE bytes | + * +--------------------------------------------------+ + * | Data Space | + * | - Data blocks | + * | - Block size : BLOCK_SIZE bytes | + * | - Block count: BLOCK_COUNT | + * | | + * | +------------------+ | + * | | Block 0 | | + * | +------------------+ | + * | | Block 1 | | + * | +------------------+ | + * | | ... | | + * | +------------------+ | + * | | Block N | | + * | +------------------+ | + * +--------------------------------------------------+ + * 0x0FFF + */ + +#ifndef EEPROM_DIRECTORY_STRUCT +#define EEPROM_DIRECTORY_STRUCT + +/** @brief Size of a single key-map entry structure in bytes (4-byte key + 8-byte IDs array). */ +#define KEY_MAP_STRUCT_SIZE 12 + +/** @brief Maximum number of key-value pairs that can be stored in the directory. */ +#define KEY_MAP_COUNT 128 + +/** @brief Size of a data block in bytes. */ +#define BLOCK_SIZE 4 + +/** @brief Total number of data blocks available in the EEPROM. */ +#define BLOCK_COUNT 512 + +/** @brief Starting address of the allocation table in EEPROM. */ +#define ALLOC_TABLE_BEGIN 0 + +/** @brief Size of the allocation table in bytes (one bit per block). */ +#define ALLOC_TABLE_SIZE (BLOCK_COUNT / 8) + +/** @brief Starting address of the key-map table in EEPROM. */ +#define KEY_MAP_BEGIN (ALLOC_TABLE_BEGIN + ALLOC_TABLE_SIZE) + +/** @brief Total size of the key-map table in bytes. */ +#define KEY_MAP_SIZE (KEY_MAP_STRUCT_SIZE * KEY_MAP_COUNT) + +/** @brief Starting address of the data space in EEPROM. */ +#define DATA_SPACE_BEGIN (KEY_MAP_BEGIN + KEY_MAP_SIZE) + +/** @brief Total size of the EEPROM in bytes. */ +#define EEPROM_SIZE 4096 + +#include + +#include "m24c32.h" + +/** + * @brief Key-value mapping structure. + * + * This structure maps a 4-byte key to up to 4 block IDs. Each block ID points to + * a BLOCK_SIZE-byte data block in the EEPROM data space. + */ +typedef struct { + uint8_t key[4]; /** 4-byte key (not null-terminated). */ + uint16_t ids[4]; /** Array of up to 4 block IDs (BLOCK_COUNT indicates end). */ +} directory_key_map_t; + +/** + * @brief Main EEPROM directory structure. + * + * This structure contains all the state information for the EEPROM directory, + * including the device interface, allocation table, and key map. + */ +typedef struct { + m24c32_t *device; /** Pointer to the M24C32 device interface. */ + uint8_t alloc_table[ALLOC_TABLE_SIZE]; /** Bit-vector allocation table (one bit per block). */ + directory_key_map_t key_map[KEY_MAP_COUNT]; /** Array of key-value mappings. */ +} eeprom_directory_t; + +#endif \ No newline at end of file diff --git a/middleware/include/eeprom_status.h b/middleware/include/eeprom_status.h index 94c3f186..2764c586 100644 --- a/middleware/include/eeprom_status.h +++ b/middleware/include/eeprom_status.h @@ -19,6 +19,7 @@ typedef enum { EEPROM_ERROR_NULL_POINTER = -5, EEPROM_ERROR_ALLOCATION = -6, EEPROM_ERROR_COMMS = -7, + EEPROM_ERROR_TOO_BIG = -8 } eeprom_status_t; diff --git a/middleware/include/eeprom_storage.h b/middleware/include/eeprom_storage.h new file mode 100644 index 00000000..1788756f --- /dev/null +++ b/middleware/include/eeprom_storage.h @@ -0,0 +1,85 @@ +/** + * @file eeprom_storage.h + * @author Sogo Nishihara (sogonishi@gmail.com) + * @brief EEPROM Storage Management + * + * This file provides functions for managing data storage in the EEPROM directory. + * Functions handle reading, writing, and deleting data blocks associated with block IDs. + * + */ + +#ifndef EEPROM_STORAGE +#define EEPROM_STORAGE + +#include + +#include "eeprom_directory_struct.h" +#include "eeprom_alloc.h" + +/** + * @brief Initialize storage by loading key-map table from EEPROM memory. + * + * This function reads the key-map table from EEPROM and populates the directory's + * key_map structure in memory. + * + * @param directory Pointer to the initialized directory structure. + * + * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure. + * + * @retval EEPROM_ERROR_ALLOCATION If memory allocation fails. + * @retval EEPROM_ERROR If EEPROM read operation fails. + */ +eeprom_status_t init_storage(eeprom_directory_t *directory); + +/** + * @brief Retrieve data from EEPROM using block IDs. + * + * This function reads data from multiple blocks in EEPROM and allocates a buffer + * to store the result. The caller is responsible for freeing the output buffer. + * + * @param directory Pointer to the initialized directory structure. + * @param ids Array of block IDs (up to 4, terminated by BLOCK_COUNT). + * @param out Pointer to a pointer that will receive the allocated output buffer. + * The caller must free this buffer. + * @param out_size Pointer to store the size of the output data in bytes. + * + * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure. + * + * @retval EEPROM_ERROR_ALLOCATION If memory allocation fails. + * @retval EEPROM_ERROR_NOT_FOUND If any block ID is not allocated. + * @retval EEPROM_ERROR If EEPROM read operation fails. + */ +eeprom_status_t get_data(eeprom_directory_t *directory, const uint16_t *ids, uint8_t **out, uint16_t *out_size); + +/** + * @brief Store data in EEPROM using block IDs. + * + * This function writes data to multiple blocks in EEPROM. Each block is BLOCK_SIZE bytes. + * If the data size is smaller than the total block size, remaining bytes are padded with zeros. + * + * @param directory Pointer to the initialized directory structure. + * @param ids Array of block IDs (up to 4, terminated by BLOCK_COUNT). + * @param value Pointer to the data to write. + * @param value_size Size of the data in bytes. + * + * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure. + * + * @retval EEPROM_ERROR_ALLOCATION If memory allocation for block buffer fails. + * @retval EEPROM_ERROR If EEPROM write operation fails. + */ +eeprom_status_t put_data(eeprom_directory_t *directory, const uint16_t *ids, uint8_t *value, uint16_t value_size); + +/** + * @brief Delete data blocks from EEPROM. + * + * This function frees the blocks associated with the given IDs, making them available + * for reuse. The blocks are marked as free in the allocation table. + * + * @param directory Pointer to the initialized directory structure. + * @param ids Array of block IDs to free (up to 4, terminated by BLOCK_COUNT). + * + * @return eeprom_status_t Returns EEPROM_OK on success. + */ +eeprom_status_t delete_data(eeprom_directory_t *directory, uint16_t *ids); + +#endif diff --git a/middleware/include/m24c32_eeprom_directory.h b/middleware/include/m24c32_eeprom_directory.h deleted file mode 100644 index 5835a634..00000000 --- a/middleware/include/m24c32_eeprom_directory.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -/** - * @file m24c32_eeprom_directory.h - * @brief EEPROM Partitioned Read/Write Interface - * - * This file provides an interface for reading and writing to specific partitions - * within an EEPROM using a directory-based approach. - * - */ - -#include "m24c32.h" -#include "eeprom_directory.h" - -/** - * @brief Write to a section of the EEPROM. Writes that overflow the size of the partition - * will wrap to the head of the partition. - * - * @param directory Pointer to the EEPROM directory structure. - * @param eeprom Pointer to the EEPROM device structure. - * @param id ID of eeprom partition to write to. - * @param data Data to write. - * @param len Length of data to write in Bytes. - * @param offset Offset from partition base address in Bytes. - * @return eeprom_status_t Returns EEPROM_OK on success or an error code on failure. - */ -eeprom_status_t m24c32_directory_write(const eeprom_directory_t *directory, - m24c32_t *eeprom, const char *id, - uint8_t *data, uint16_t len, - uint16_t offset); - -/** - * @brief Read a section of the EEPROM. Reads that overflow the size of the partition - * will wrap to the head of the partition. - * - * @param directory Pointer to the EEPROM directory structure. - * @param eeprom Pointer to the EEPROM device structure. - * @param id ID of eeprom partition to read from. - * @param data Read output. - * @param len Length of data to write in Bytes. - * @param offset Offset from partition base address in Bytes. - * @return eeprom_status_t Returns EEPROM_OK on success or an error code on failure. - */ -eeprom_status_t m24c32_directory_read(const eeprom_directory_t *directory, - m24c32_t *eeprom, const char *id, - uint8_t *data, uint16_t len, - uint16_t offset); \ No newline at end of file diff --git a/middleware/src/eeprom_alloc.c b/middleware/src/eeprom_alloc.c new file mode 100644 index 00000000..f6f33565 --- /dev/null +++ b/middleware/src/eeprom_alloc.c @@ -0,0 +1,89 @@ +#include "eeprom_alloc.h" + +#define byte_index(n) ((n) / 8) +#define bit_index(n) ((n) % 8) +#define nth_bit_mask(n) (1 << (n)) + + +static int get_alloc_table(uint8_t *table, uint16_t id) { + return (table[byte_index(id)] >> bit_index(id)) & 1; +} + +static void put_alloc_table(uint8_t *table, uint16_t id, uint8_t val) { + uint8_t bit_mask = nth_bit_mask(bit_index(id)); + + if (val) { + table[byte_index(id)] |= bit_mask; + } else { + bit_mask = ~bit_mask; + table[byte_index(id)] &= bit_mask; + } +} + +static eeprom_status_t update_eeprom_alloc_table(eeprom_directory_t *directory, uint16_t id) { + uint16_t data_index = byte_index(id); + m24c32_t *device = directory->device; + uint16_t addr = ALLOC_TABLE_BEGIN + data_index; + uint8_t *data = directory->alloc_table + data_index; + + return m24c32_write(device, addr, data, 1); +} + + +eeprom_status_t init_alloc_table(eeprom_directory_t *directory) { + m24c32_t *device = directory->device; + + return m24c32_read(device, ALLOC_TABLE_BEGIN, directory->alloc_table, ALLOC_TABLE_SIZE); +} + +void print_alloc_table(eeprom_directory_t *directory) { + uint8_t *alloc_table = directory->alloc_table; + + for (int id = 0; id < BLOCK_COUNT; id++) { + putchar(get_alloc_table(alloc_table, id) ? '1' : '0'); + + if ((id + 1) % 64 == 0) { + putchar('\n'); + } else if ((id + 1) % 8 == 0) { + putchar(' '); + } + } + putchar('\n'); +} + +uint16_t alloc_block(eeprom_directory_t *directory) { + uint8_t *alloc_table = directory->alloc_table; + + for (uint16_t id = 0; id < BLOCK_COUNT; id++) { + if (get_alloc_table(alloc_table, id) == 0) { + put_alloc_table(alloc_table, id, 1); + eeprom_status_t ret = update_eeprom_alloc_table(directory, id); + if (ret != EEPROM_OK) { + printf("ERROR: failed to update eeprom alloc table.\n"); + put_alloc_table(alloc_table, id, 0); + return BLOCK_COUNT; + } + return id; + } + } + return BLOCK_COUNT; +} + +void free_block(eeprom_directory_t *directory, uint16_t *ids, uint8_t size) { + uint8_t *alloc_table = directory->alloc_table; + + for (int i = 0; i < size; i++) { + uint16_t id = ids[i]; + put_alloc_table(alloc_table, id, 0); + eeprom_status_t ret = update_eeprom_alloc_table(directory, id); + if (ret != EEPROM_OK) { + printf("ERROR: failed to update eeprom allo table.\n"); + } + } +} + +int is_allocated(eeprom_directory_t *directory, uint16_t id) { + uint8_t *alloc_table = directory->alloc_table; + + return get_alloc_table(alloc_table, id); +} diff --git a/middleware/src/eeprom_directory.c b/middleware/src/eeprom_directory.c index 19042ee7..bcd94efb 100644 --- a/middleware/src/eeprom_directory.c +++ b/middleware/src/eeprom_directory.c @@ -1,88 +1,178 @@ #include "eeprom_directory.h" -#include -#include -#include +static uint16_t *get_ids(eeprom_directory_t *directory, const uint8_t *key) { + directory_key_map_t *key_map = directory->key_map; -#define BASE_ADDR 0 + for (int i = 0; i < KEY_MAP_COUNT; i++) { + // Keys are fixed 4-byte arrays, not null-terminated strings + if (memcmp(key_map[i].key, key, 4) == 0) { + return key_map[i].ids; + } + } + return NULL; +} -eeprom_status_t directory_init(eeprom_directory_t *directory, - const struct partition_cfg partitions[], - size_t num_partitions) -{ - if ((directory == NULL) || (partitions == NULL)) { - return EEPROM_ERROR_NULL_POINTER; +static eeprom_status_t set_key(eeprom_directory_t *directory, const uint8_t *key, uint16_t *ids) { + m24c32_t *device = directory->device; + directory_key_map_t *key_map = directory->key_map; + + for (int i = 0; i < KEY_MAP_COUNT; i++) { + if ((char)key_map[i].key[0] == '\0') { + memcpy(key_map[i].key, key, 4); + memcpy(key_map[i].ids, ids, 8); + + uint16_t addr = KEY_MAP_BEGIN + i * KEY_MAP_STRUCT_SIZE; + return m24c32_write(device, addr, (uint8_t *)&key_map[i], KEY_MAP_STRUCT_SIZE); + } } + return EEPROM_ERROR_ALLOCATION; +} - directory->partitions = - malloc(sizeof(struct partition_cfg) * num_partitions); +static eeprom_status_t delete_key(eeprom_directory_t *directory, const uint8_t *key) { + m24c32_t *device = directory->device; + directory_key_map_t *key_map = directory->key_map; - if (directory->partitions == NULL) { - return EEPROM_ERROR_ALLOCATION; + for (int i = 0; i < KEY_MAP_COUNT; i++) { + // Keys are fixed 4-byte arrays, not null-terminated strings + if (memcmp(key_map[i].key, key, 4) == 0) { + memset(&key_map[i], 0, KEY_MAP_STRUCT_SIZE); + + uint16_t addr = KEY_MAP_BEGIN + i * KEY_MAP_STRUCT_SIZE; + return m24c32_write(device, addr, (uint8_t *)&key_map[i], KEY_MAP_STRUCT_SIZE); + } } + return EEPROM_ERROR_NOT_FOUND; +} - /* Accumulator that gives the address of the start of the partition */ - size_t addr_acc = BASE_ADDR; - for (int i = 0; i < num_partitions; i++) { - directory->partitions[i] = partitions[i]; - directory->partitions[i].address = addr_acc; - directory->partitions[i].head_address = addr_acc; - addr_acc += partitions[i].size; +eeprom_status_t directory_init( + m24c32_t *device, + eeprom_directory_t *directory +) { + if (directory == NULL || device == NULL) { + return EEPROM_ERROR_NULL_POINTER; } - directory->num_partitions = num_partitions; - + directory->device = device; + eeprom_status_t res; + res = init_alloc_table(directory); + if (res != EEPROM_OK) { + return res; + } + res = init_storage(directory); + if (res != EEPROM_OK) { + return res; + } return EEPROM_OK; } -eeprom_status_t eeprom_get_base_address(const eeprom_directory_t *directory, - const char *key, uint16_t *address) -{ - if ((directory == NULL) || (key == NULL)) { +eeprom_status_t get_directory_value( + eeprom_directory_t *directory, + const uint8_t *key, + uint8_t **out, + uint16_t *out_size +) { + if (directory == NULL || key == NULL || out == NULL || out_size == NULL) { return EEPROM_ERROR_NULL_POINTER; } - for (int i = 0; i < directory->num_partitions; i++) { - if (strcmp(directory->partitions[i].id, key) == 0) { - *address = directory->partitions[i].address; - return EEPROM_OK; - } + uint16_t *ids = get_ids(directory, key); + if (ids == NULL) { + return EEPROM_ERROR_NOT_FOUND; } - return EEPROM_ERROR_NOT_FOUND; + return get_data(directory, ids, out, out_size); } -eeprom_status_t eeprom_get_head_address(const eeprom_directory_t *directory, - const char *key, uint16_t *address) -{ - if ((directory == NULL) || (key == NULL)) { +eeprom_status_t set_directory_value( + eeprom_directory_t *directory, + const uint8_t *key, + uint8_t *value, + const uint16_t value_size +) { + if (directory == NULL || value == NULL) { return EEPROM_ERROR_NULL_POINTER; } + if (value_size <= 0) { + return EEPROM_ERROR; + } - for (int i = 0; i < directory->num_partitions; i++) { - if (strcmp(directory->partitions[i].id, key) == 0) { - *address = directory->partitions[i].head_address; - return EEPROM_OK; + uint16_t *existing_ids = get_ids(directory, key); + + // If key already exists, delete it first + if (existing_ids != NULL) { + eeprom_status_t res = delete_directory_value(directory, key); + if (res != EEPROM_OK) { + return res; + } + } + + // Allocate new blocks for the value + int block_count = (value_size - 1) / BLOCK_SIZE + 1; + if (block_count > 4) { + return EEPROM_ERROR_TOO_BIG; + } + + uint16_t *ids = malloc(sizeof(uint16_t) * 4); + if (ids == NULL) { + return EEPROM_ERROR_ALLOCATION; + } + + for (int block_idx = 0; block_idx < block_count; block_idx++) { + uint16_t id = alloc_block(directory); + if (id == BLOCK_COUNT) { + // Free already allocated blocks on failure + for (int j = 0; j < block_idx; j++) { + free_block(directory, &ids[j], 1); + } + free(ids); + return EEPROM_ERROR_ALLOCATION; } + ids[block_idx] = id; + } + for (int block_idx = block_count; block_idx < 4; block_idx++) { + ids[block_idx] = BLOCK_COUNT; } - return EEPROM_ERROR_NOT_FOUND; + eeprom_status_t res; + res = set_key(directory, key, ids); + if (res != EEPROM_OK) { + // Free allocated blocks on failure + free_block(directory, ids, block_count); + free(ids); + return res; + } + + res = put_data(directory, ids, value, value_size); + if (res != EEPROM_OK) { + // Free allocated blocks and remove key on failure + free_block(directory, ids, block_count); + delete_key(directory, key); + free(ids); + return res; + } + + free(ids); + return EEPROM_OK; } -eeprom_status_t eeprom_get_size(const eeprom_directory_t *directory, - const char *key, uint16_t *size) -{ - if ((directory == NULL) || (key == NULL)) { +eeprom_status_t delete_directory_value( + eeprom_directory_t *directory, + const uint8_t *key +) { + if (directory == NULL || key == NULL) { return EEPROM_ERROR_NULL_POINTER; } - for (int i = 0; i < directory->num_partitions; i++) { - if (strcmp(directory->partitions[i].id, key) == 0) { - *size = directory->partitions[i].size; - return EEPROM_OK; - } + uint16_t *ids = get_ids(directory, key); + if (ids == NULL) { + return EEPROM_ERROR_NOT_FOUND; } - return EEPROM_ERROR_NOT_FOUND; -} \ No newline at end of file + eeprom_status_t res; + res = delete_data(directory, ids); + if (res != EEPROM_OK) { + return res; + } + return delete_key(directory, key); +} diff --git a/middleware/src/eeprom_storage.c b/middleware/src/eeprom_storage.c new file mode 100644 index 00000000..f80da5af --- /dev/null +++ b/middleware/src/eeprom_storage.c @@ -0,0 +1,131 @@ +#include "eeprom_storage.h" +#include + +static uint8_t get_id_count(const uint16_t *ids) { + uint8_t count = 0; + + for (int i = 0; i < 4; i++) { + if (ids[i] >= BLOCK_COUNT) { + break; + } + count++; + } + return count; +} + +static uint16_t get_addr_for_data(const uint16_t id) { + return DATA_SPACE_BEGIN + id * BLOCK_SIZE; +} + + +eeprom_status_t init_storage(eeprom_directory_t *directory) { + m24c32_t *device = directory->device; + directory_key_map_t *key_map = directory->key_map; + uint8_t *data = malloc(KEY_MAP_SIZE); + if (data == NULL) { + return EEPROM_ERROR_ALLOCATION; + } + + eeprom_status_t res = m24c32_read(device, KEY_MAP_BEGIN, data, KEY_MAP_SIZE); + if (res != EEPROM_OK) { + free(data); + return res; + } + + for (int i = 0; i < KEY_MAP_COUNT; i++) { + uint8_t *entry = data + (i * KEY_MAP_STRUCT_SIZE); + + // key[4] + memcpy(key_map[i].key, entry, 4); + + // ids[4] + for (int j = 0; j < 4; j++) { + key_map[i].ids[j] = (uint16_t)entry[4 + j * 2] | ((uint16_t)entry[4 + j * 2 + 1] << 8); + } + } + free(data); + return EEPROM_OK; +} + +eeprom_status_t get_data(eeprom_directory_t *directory, const uint16_t *ids, uint8_t **out, uint16_t *out_size) { + uint8_t id_count = get_id_count(ids); + *out_size = BLOCK_SIZE * id_count; + + // Free existing buffer if provided + if (*out) { + free(*out); + *out = NULL; + } + + // Allocate new buffer + *out = malloc(*out_size); + if (*out == NULL) { + return EEPROM_ERROR_ALLOCATION; + } + + for (int i = 0; i < id_count; i++) { + uint16_t id = ids[i]; + if (!is_allocated(directory, id)) { + free(*out); + *out = NULL; + return EEPROM_ERROR_NOT_FOUND; + } + + uint16_t addr = get_addr_for_data(id); + uint8_t *data_ptr = *out + BLOCK_SIZE * i; + eeprom_status_t res; + + res = m24c32_read(directory->device, addr, data_ptr, BLOCK_SIZE); + if (res != EEPROM_OK) { + free(*out); + *out = NULL; + return res; + } + } + return EEPROM_OK; +} + +eeprom_status_t put_data(eeprom_directory_t *directory, const uint16_t *ids, uint8_t *value, uint16_t value_size) { + uint8_t id_count = get_id_count(ids); + uint8_t *block_buffer = malloc(BLOCK_SIZE); + if (block_buffer == NULL) { + return EEPROM_ERROR_ALLOCATION; + } + + for (int i = 0; i < id_count; i++) { + uint16_t id = ids[i]; + uint16_t addr = get_addr_for_data(id); + + // Calculate how many bytes to copy for this block + uint16_t offset = i * BLOCK_SIZE; + uint16_t bytes_to_copy = BLOCK_SIZE; + if (offset + BLOCK_SIZE > value_size) { + bytes_to_copy = value_size - offset; + } + + // Clear the block buffer + memset(block_buffer, 0, BLOCK_SIZE); + + // Copy the actual data + if (bytes_to_copy > 0) { + memcpy(block_buffer, value + offset, bytes_to_copy); + } + + // Write the entire block (BLOCK_SIZE bytes) to EEPROM + eeprom_status_t res = m24c32_write(directory->device, addr, block_buffer, BLOCK_SIZE); + if (res != EEPROM_OK) { + free(block_buffer); + return res; + } + } + + free(block_buffer); + return EEPROM_OK; +} + +eeprom_status_t delete_data(eeprom_directory_t *directory, uint16_t *ids) { + uint8_t id_count = get_id_count(ids); + + free_block(directory, ids, id_count); + return EEPROM_OK; +} diff --git a/middleware/src/m24c32_eeprom_directory.c b/middleware/src/m24c32_eeprom_directory.c deleted file mode 100644 index 87eaf82c..00000000 --- a/middleware/src/m24c32_eeprom_directory.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "m24c32_eeprom_directory.h" - -eeprom_status_t m24c32_directory_write(const eeprom_directory_t *directory, - m24c32_t *eeprom, const char *id, - uint8_t *data, uint16_t len, - uint16_t offset) -{ - uint16_t base; - eeprom_status_t status = eeprom_get_base_address(directory, id, &base); - - if (status != EEPROM_OK) { - return status; // Invalid ID - } - - uint16_t size; - status = eeprom_get_size(directory, id, &size); - if (status != EEPROM_OK) { - return status; - } - - if (offset >= size) { - return EEPROM_ERROR_OUT_OF_BOUNDS; // Invalid Offset - } - - if (offset + len > size) { - return EEPROM_ERROR_ALIGNMENT; // Overwrting next partition - } - - return m24c32_write(eeprom, base + offset, data, len); -} - -eeprom_status_t m24c32_directory_read(const eeprom_directory_t *directory, - m24c32_t *eeprom, const char *id, - uint8_t *data, uint16_t len, - uint16_t offset) -{ - uint16_t base; - eeprom_status_t status = eeprom_get_base_address(directory, id, &base); - if (status != EEPROM_OK) { - return status; // Invalid ID - } - - uint16_t size; - status = eeprom_get_size(directory, id, &size); - if (status != EEPROM_OK) { - return status; - } - - if (offset >= size) { - return EEPROM_ERROR_OUT_OF_BOUNDS; // Invalid Offset - } - - if (offset + len > size) { - return EEPROM_ERROR_ALIGNMENT; // Reading beyond current partition - } - - return m24c32_read(eeprom, base + offset, data, len); -} \ No newline at end of file From 51c4efd9ac5c295a0c1f955c33f92e129e60ba3f Mon Sep 17 00:00:00 2001 From: sogo Date: Fri, 2 Jan 2026 19:24:57 -0500 Subject: [PATCH 3/7] refactor for clang-format --- middleware/include/eeprom_directory.h | 30 +++------ middleware/include/eeprom_directory_struct.h | 10 +-- middleware/include/eeprom_storage.h | 8 ++- middleware/src/eeprom_alloc.c | 34 ++++++---- middleware/src/eeprom_directory.c | 71 ++++++++++---------- middleware/src/eeprom_storage.c | 47 ++++++++----- 6 files changed, 109 insertions(+), 91 deletions(-) diff --git a/middleware/include/eeprom_directory.h b/middleware/include/eeprom_directory.h index 5df5813f..17f6d64e 100644 --- a/middleware/include/eeprom_directory.h +++ b/middleware/include/eeprom_directory.h @@ -40,10 +40,8 @@ * @retval EEPROM_ERROR_NULL_POINTER If device or directory is NULL. * @retval EEPROM_ERROR If initialization of alloc table or storage fails. */ -eeprom_status_t directory_init( - m24c32_t *device, - eeprom_directory_t *directory -); +eeprom_status_t directory_init(m24c32_t *device, + eeprom_directory_t *directory); /** * @brief Retrieve a value from the directory by key. @@ -63,12 +61,9 @@ eeprom_status_t directory_init( * @retval EEPROM_ERROR_NOT_FOUND If the key does not exist in the directory. * @retval EEPROM_ERROR_ALLOCATION If memory allocation fails. */ -eeprom_status_t get_directory_value( - eeprom_directory_t *directory, - const uint8_t *key, - uint8_t **out, - uint16_t *out_size -); +eeprom_status_t get_directory_value(eeprom_directory_t *directory, + const uint8_t *key, uint8_t **out, + uint16_t *out_size); /** * @brief Store a value in the directory with the specified key. @@ -89,12 +84,9 @@ eeprom_status_t get_directory_value( * @retval EEPROM_ERROR_TOO_BIG If value_size exceeds 16 bytes (4 blocks). * @retval EEPROM_ERROR_ALLOCATION If block allocation fails. */ -eeprom_status_t set_directory_value( - eeprom_directory_t *directory, - const uint8_t *key, - uint8_t *value, - const uint16_t value_size -); +eeprom_status_t set_directory_value(eeprom_directory_t *directory, + const uint8_t *key, uint8_t *value, + const uint16_t value_size); /** * @brief Delete a value from the directory by key. @@ -110,9 +102,7 @@ eeprom_status_t set_directory_value( * @retval EEPROM_ERROR_NULL_POINTER If directory or key is NULL. * @retval EEPROM_ERROR_NOT_FOUND If the key does not exist in the directory. */ -eeprom_status_t delete_directory_value( - eeprom_directory_t *directory, - const uint8_t *key -); +eeprom_status_t delete_directory_value(eeprom_directory_t *directory, + const uint8_t *key); #endif // EEPROM_DIRECTORY_H \ No newline at end of file diff --git a/middleware/include/eeprom_directory_struct.h b/middleware/include/eeprom_directory_struct.h index 5f5be10c..95d48b6d 100644 --- a/middleware/include/eeprom_directory_struct.h +++ b/middleware/include/eeprom_directory_struct.h @@ -86,8 +86,8 @@ * a BLOCK_SIZE-byte data block in the EEPROM data space. */ typedef struct { - uint8_t key[4]; /** 4-byte key (not null-terminated). */ - uint16_t ids[4]; /** Array of up to 4 block IDs (BLOCK_COUNT indicates end). */ + uint8_t key[4]; /** 4-byte key (not null-terminated). */ + uint16_t ids[4]; /** Array of up to 4 block IDs (BLOCK_COUNT indicates end). */ } directory_key_map_t; /** @@ -97,9 +97,9 @@ typedef struct { * including the device interface, allocation table, and key map. */ typedef struct { - m24c32_t *device; /** Pointer to the M24C32 device interface. */ - uint8_t alloc_table[ALLOC_TABLE_SIZE]; /** Bit-vector allocation table (one bit per block). */ - directory_key_map_t key_map[KEY_MAP_COUNT]; /** Array of key-value mappings. */ + m24c32_t *device; /** Pointer to the M24C32 device interface. */ + uint8_t alloc_table[ALLOC_TABLE_SIZE]; /** Bit-vector allocation table (one bit per block). */ + directory_key_map_t key_map[KEY_MAP_COUNT]; /** Array of key-value mappings. */ } eeprom_directory_t; #endif \ No newline at end of file diff --git a/middleware/include/eeprom_storage.h b/middleware/include/eeprom_storage.h index 1788756f..8e48fb1c 100644 --- a/middleware/include/eeprom_storage.h +++ b/middleware/include/eeprom_storage.h @@ -49,7 +49,9 @@ eeprom_status_t init_storage(eeprom_directory_t *directory); * @retval EEPROM_ERROR_NOT_FOUND If any block ID is not allocated. * @retval EEPROM_ERROR If EEPROM read operation fails. */ -eeprom_status_t get_data(eeprom_directory_t *directory, const uint16_t *ids, uint8_t **out, uint16_t *out_size); +eeprom_status_t get_data(eeprom_directory_t *directory, + const uint16_t *ids, uint8_t **out, + uint16_t *out_size); /** * @brief Store data in EEPROM using block IDs. @@ -67,7 +69,9 @@ eeprom_status_t get_data(eeprom_directory_t *directory, const uint16_t *ids, uin * @retval EEPROM_ERROR_ALLOCATION If memory allocation for block buffer fails. * @retval EEPROM_ERROR If EEPROM write operation fails. */ -eeprom_status_t put_data(eeprom_directory_t *directory, const uint16_t *ids, uint8_t *value, uint16_t value_size); +eeprom_status_t put_data(eeprom_directory_t *directory, + const uint16_t *ids, uint8_t *value, + uint16_t value_size); /** * @brief Delete data blocks from EEPROM. diff --git a/middleware/src/eeprom_alloc.c b/middleware/src/eeprom_alloc.c index f6f33565..2348e63a 100644 --- a/middleware/src/eeprom_alloc.c +++ b/middleware/src/eeprom_alloc.c @@ -4,12 +4,13 @@ #define bit_index(n) ((n) % 8) #define nth_bit_mask(n) (1 << (n)) - -static int get_alloc_table(uint8_t *table, uint16_t id) { +static int get_alloc_table(uint8_t *table, uint16_t id) +{ return (table[byte_index(id)] >> bit_index(id)) & 1; } -static void put_alloc_table(uint8_t *table, uint16_t id, uint8_t val) { +static void put_alloc_table(uint8_t *table, uint16_t id, uint8_t val) +{ uint8_t bit_mask = nth_bit_mask(bit_index(id)); if (val) { @@ -20,7 +21,9 @@ static void put_alloc_table(uint8_t *table, uint16_t id, uint8_t val) { } } -static eeprom_status_t update_eeprom_alloc_table(eeprom_directory_t *directory, uint16_t id) { +static eeprom_status_t update_eeprom_alloc_table(eeprom_directory_t *directory, + uint16_t id) +{ uint16_t data_index = byte_index(id); m24c32_t *device = directory->device; uint16_t addr = ALLOC_TABLE_BEGIN + data_index; @@ -29,16 +32,17 @@ static eeprom_status_t update_eeprom_alloc_table(eeprom_directory_t *directory, return m24c32_write(device, addr, data, 1); } - -eeprom_status_t init_alloc_table(eeprom_directory_t *directory) { +eeprom_status_t init_alloc_table(eeprom_directory_t *directory) +{ m24c32_t *device = directory->device; - return m24c32_read(device, ALLOC_TABLE_BEGIN, directory->alloc_table, ALLOC_TABLE_SIZE); + return m24c32_read(device, ALLOC_TABLE_BEGIN, + directory->alloc_table, ALLOC_TABLE_SIZE); } -void print_alloc_table(eeprom_directory_t *directory) { +void print_alloc_table(eeprom_directory_t *directory) +{ uint8_t *alloc_table = directory->alloc_table; - for (int id = 0; id < BLOCK_COUNT; id++) { putchar(get_alloc_table(alloc_table, id) ? '1' : '0'); @@ -51,13 +55,15 @@ void print_alloc_table(eeprom_directory_t *directory) { putchar('\n'); } -uint16_t alloc_block(eeprom_directory_t *directory) { +uint16_t alloc_block(eeprom_directory_t *directory) +{ uint8_t *alloc_table = directory->alloc_table; for (uint16_t id = 0; id < BLOCK_COUNT; id++) { if (get_alloc_table(alloc_table, id) == 0) { put_alloc_table(alloc_table, id, 1); - eeprom_status_t ret = update_eeprom_alloc_table(directory, id); + eeprom_status_t ret = + update_eeprom_alloc_table(directory, id); if (ret != EEPROM_OK) { printf("ERROR: failed to update eeprom alloc table.\n"); put_alloc_table(alloc_table, id, 0); @@ -69,7 +75,8 @@ uint16_t alloc_block(eeprom_directory_t *directory) { return BLOCK_COUNT; } -void free_block(eeprom_directory_t *directory, uint16_t *ids, uint8_t size) { +void free_block(eeprom_directory_t *directory, uint16_t *ids, uint8_t size) +{ uint8_t *alloc_table = directory->alloc_table; for (int i = 0; i < size; i++) { @@ -82,7 +89,8 @@ void free_block(eeprom_directory_t *directory, uint16_t *ids, uint8_t size) { } } -int is_allocated(eeprom_directory_t *directory, uint16_t id) { +int is_allocated(eeprom_directory_t *directory, uint16_t id) +{ uint8_t *alloc_table = directory->alloc_table; return get_alloc_table(alloc_table, id); diff --git a/middleware/src/eeprom_directory.c b/middleware/src/eeprom_directory.c index bcd94efb..818e21c1 100644 --- a/middleware/src/eeprom_directory.c +++ b/middleware/src/eeprom_directory.c @@ -1,6 +1,7 @@ #include "eeprom_directory.h" -static uint16_t *get_ids(eeprom_directory_t *directory, const uint8_t *key) { +static uint16_t *get_ids(eeprom_directory_t *directory, const uint8_t *key) +{ directory_key_map_t *key_map = directory->key_map; for (int i = 0; i < KEY_MAP_COUNT; i++) { @@ -12,7 +13,9 @@ static uint16_t *get_ids(eeprom_directory_t *directory, const uint8_t *key) { return NULL; } -static eeprom_status_t set_key(eeprom_directory_t *directory, const uint8_t *key, uint16_t *ids) { +static eeprom_status_t set_key(eeprom_directory_t *directory, + const uint8_t *key, uint16_t *ids) +{ m24c32_t *device = directory->device; directory_key_map_t *key_map = directory->key_map; @@ -20,15 +23,19 @@ static eeprom_status_t set_key(eeprom_directory_t *directory, const uint8_t *key if ((char)key_map[i].key[0] == '\0') { memcpy(key_map[i].key, key, 4); memcpy(key_map[i].ids, ids, 8); - + uint16_t addr = KEY_MAP_BEGIN + i * KEY_MAP_STRUCT_SIZE; - return m24c32_write(device, addr, (uint8_t *)&key_map[i], KEY_MAP_STRUCT_SIZE); + return m24c32_write(device, addr, + (uint8_t *)&key_map[i], + KEY_MAP_STRUCT_SIZE); } } return EEPROM_ERROR_ALLOCATION; } -static eeprom_status_t delete_key(eeprom_directory_t *directory, const uint8_t *key) { +static eeprom_status_t delete_key(eeprom_directory_t *directory, + const uint8_t *key) +{ m24c32_t *device = directory->device; directory_key_map_t *key_map = directory->key_map; @@ -38,17 +45,17 @@ static eeprom_status_t delete_key(eeprom_directory_t *directory, const uint8_t * memset(&key_map[i], 0, KEY_MAP_STRUCT_SIZE); uint16_t addr = KEY_MAP_BEGIN + i * KEY_MAP_STRUCT_SIZE; - return m24c32_write(device, addr, (uint8_t *)&key_map[i], KEY_MAP_STRUCT_SIZE); + return m24c32_write(device, addr, + (uint8_t *)&key_map[i], + KEY_MAP_STRUCT_SIZE); } } return EEPROM_ERROR_NOT_FOUND; } - -eeprom_status_t directory_init( - m24c32_t *device, - eeprom_directory_t *directory -) { +eeprom_status_t directory_init(m24c32_t *device, + eeprom_directory_t *directory) +{ if (directory == NULL || device == NULL) { return EEPROM_ERROR_NULL_POINTER; } @@ -66,13 +73,12 @@ eeprom_status_t directory_init( return EEPROM_OK; } -eeprom_status_t get_directory_value( - eeprom_directory_t *directory, - const uint8_t *key, - uint8_t **out, - uint16_t *out_size -) { - if (directory == NULL || key == NULL || out == NULL || out_size == NULL) { +eeprom_status_t get_directory_value(eeprom_directory_t *directory, + const uint8_t *key, uint8_t **out, + uint16_t *out_size) +{ + if (directory == NULL || key == NULL || out == NULL || + out_size == NULL) { return EEPROM_ERROR_NULL_POINTER; } @@ -84,12 +90,10 @@ eeprom_status_t get_directory_value( return get_data(directory, ids, out, out_size); } -eeprom_status_t set_directory_value( - eeprom_directory_t *directory, - const uint8_t *key, - uint8_t *value, - const uint16_t value_size -) { +eeprom_status_t set_directory_value(eeprom_directory_t *directory, + const uint8_t *key, uint8_t *value, + const uint16_t value_size) +{ if (directory == NULL || value == NULL) { return EEPROM_ERROR_NULL_POINTER; } @@ -98,7 +102,7 @@ eeprom_status_t set_directory_value( } uint16_t *existing_ids = get_ids(directory, key); - + // If key already exists, delete it first if (existing_ids != NULL) { eeprom_status_t res = delete_directory_value(directory, key); @@ -106,18 +110,18 @@ eeprom_status_t set_directory_value( return res; } } - + // Allocate new blocks for the value int block_count = (value_size - 1) / BLOCK_SIZE + 1; if (block_count > 4) { return EEPROM_ERROR_TOO_BIG; } - + uint16_t *ids = malloc(sizeof(uint16_t) * 4); if (ids == NULL) { return EEPROM_ERROR_ALLOCATION; } - + for (int block_idx = 0; block_idx < block_count; block_idx++) { uint16_t id = alloc_block(directory); if (id == BLOCK_COUNT) { @@ -142,7 +146,7 @@ eeprom_status_t set_directory_value( free(ids); return res; } - + res = put_data(directory, ids, value, value_size); if (res != EEPROM_OK) { // Free allocated blocks and remove key on failure @@ -151,15 +155,14 @@ eeprom_status_t set_directory_value( free(ids); return res; } - + free(ids); return EEPROM_OK; } -eeprom_status_t delete_directory_value( - eeprom_directory_t *directory, - const uint8_t *key -) { +eeprom_status_t delete_directory_value(eeprom_directory_t *directory, + const uint8_t *key) +{ if (directory == NULL || key == NULL) { return EEPROM_ERROR_NULL_POINTER; } diff --git a/middleware/src/eeprom_storage.c b/middleware/src/eeprom_storage.c index f80da5af..9563e85c 100644 --- a/middleware/src/eeprom_storage.c +++ b/middleware/src/eeprom_storage.c @@ -1,7 +1,8 @@ #include "eeprom_storage.h" #include -static uint8_t get_id_count(const uint16_t *ids) { +static uint8_t get_id_count(const uint16_t *ids) +{ uint8_t count = 0; for (int i = 0; i < 4; i++) { @@ -13,12 +14,13 @@ static uint8_t get_id_count(const uint16_t *ids) { return count; } -static uint16_t get_addr_for_data(const uint16_t id) { +static uint16_t get_addr_for_data(const uint16_t id) +{ return DATA_SPACE_BEGIN + id * BLOCK_SIZE; } - -eeprom_status_t init_storage(eeprom_directory_t *directory) { +eeprom_status_t init_storage(eeprom_directory_t *directory) +{ m24c32_t *device = directory->device; directory_key_map_t *key_map = directory->key_map; uint8_t *data = malloc(KEY_MAP_SIZE); @@ -40,23 +42,28 @@ eeprom_status_t init_storage(eeprom_directory_t *directory) { // ids[4] for (int j = 0; j < 4; j++) { - key_map[i].ids[j] = (uint16_t)entry[4 + j * 2] | ((uint16_t)entry[4 + j * 2 + 1] << 8); + key_map[i].ids[j] = + (uint16_t)entry[4 + j * 2] | + ((uint16_t)entry[4 + j * 2 + 1] << 8); } } free(data); return EEPROM_OK; } -eeprom_status_t get_data(eeprom_directory_t *directory, const uint16_t *ids, uint8_t **out, uint16_t *out_size) { +eeprom_status_t get_data(eeprom_directory_t *directory, + const uint16_t *ids, uint8_t **out, + uint16_t *out_size) +{ uint8_t id_count = get_id_count(ids); *out_size = BLOCK_SIZE * id_count; - + // Free existing buffer if provided if (*out) { free(*out); *out = NULL; } - + // Allocate new buffer *out = malloc(*out_size); if (*out == NULL) { @@ -75,7 +82,8 @@ eeprom_status_t get_data(eeprom_directory_t *directory, const uint16_t *ids, uin uint8_t *data_ptr = *out + BLOCK_SIZE * i; eeprom_status_t res; - res = m24c32_read(directory->device, addr, data_ptr, BLOCK_SIZE); + res = m24c32_read(directory->device, addr, data_ptr, + BLOCK_SIZE); if (res != EEPROM_OK) { free(*out); *out = NULL; @@ -85,7 +93,10 @@ eeprom_status_t get_data(eeprom_directory_t *directory, const uint16_t *ids, uin return EEPROM_OK; } -eeprom_status_t put_data(eeprom_directory_t *directory, const uint16_t *ids, uint8_t *value, uint16_t value_size) { +eeprom_status_t put_data(eeprom_directory_t *directory, + const uint16_t *ids, uint8_t *value, + uint16_t value_size) +{ uint8_t id_count = get_id_count(ids); uint8_t *block_buffer = malloc(BLOCK_SIZE); if (block_buffer == NULL) { @@ -95,35 +106,37 @@ eeprom_status_t put_data(eeprom_directory_t *directory, const uint16_t *ids, uin for (int i = 0; i < id_count; i++) { uint16_t id = ids[i]; uint16_t addr = get_addr_for_data(id); - + // Calculate how many bytes to copy for this block uint16_t offset = i * BLOCK_SIZE; uint16_t bytes_to_copy = BLOCK_SIZE; if (offset + BLOCK_SIZE > value_size) { bytes_to_copy = value_size - offset; } - + // Clear the block buffer memset(block_buffer, 0, BLOCK_SIZE); - + // Copy the actual data if (bytes_to_copy > 0) { memcpy(block_buffer, value + offset, bytes_to_copy); } - + // Write the entire block (BLOCK_SIZE bytes) to EEPROM - eeprom_status_t res = m24c32_write(directory->device, addr, block_buffer, BLOCK_SIZE); + eeprom_status_t res = m24c32_write(directory->device, addr, + block_buffer, BLOCK_SIZE); if (res != EEPROM_OK) { free(block_buffer); return res; } } - + free(block_buffer); return EEPROM_OK; } -eeprom_status_t delete_data(eeprom_directory_t *directory, uint16_t *ids) { +eeprom_status_t delete_data(eeprom_directory_t *directory, uint16_t *ids) +{ uint8_t id_count = get_id_count(ids); free_block(directory, ids, id_count); From 8e52deb94e0b84eac1d6cec5bf83733840deef6b Mon Sep 17 00:00:00 2001 From: sogo Date: Fri, 2 Jan 2026 19:28:07 -0500 Subject: [PATCH 4/7] additional code formatting --- middleware/include/eeprom_directory.h | 6 ++++-- middleware/include/eeprom_directory_struct.h | 8 ++++---- middleware/include/eeprom_storage.h | 6 ++++-- middleware/src/eeprom_alloc.c | 7 ++++--- middleware/src/eeprom_directory.c | 12 ++++++++---- middleware/src/eeprom_storage.c | 11 +++++++---- 6 files changed, 31 insertions(+), 19 deletions(-) diff --git a/middleware/include/eeprom_directory.h b/middleware/include/eeprom_directory.h index 17f6d64e..af4dd2ab 100644 --- a/middleware/include/eeprom_directory.h +++ b/middleware/include/eeprom_directory.h @@ -41,7 +41,8 @@ * @retval EEPROM_ERROR If initialization of alloc table or storage fails. */ eeprom_status_t directory_init(m24c32_t *device, - eeprom_directory_t *directory); + eeprom_directory_t *directory +); /** * @brief Retrieve a value from the directory by key. @@ -103,6 +104,7 @@ eeprom_status_t set_directory_value(eeprom_directory_t *directory, * @retval EEPROM_ERROR_NOT_FOUND If the key does not exist in the directory. */ eeprom_status_t delete_directory_value(eeprom_directory_t *directory, - const uint8_t *key); + const uint8_t *key +); #endif // EEPROM_DIRECTORY_H \ No newline at end of file diff --git a/middleware/include/eeprom_directory_struct.h b/middleware/include/eeprom_directory_struct.h index 95d48b6d..1528dc9e 100644 --- a/middleware/include/eeprom_directory_struct.h +++ b/middleware/include/eeprom_directory_struct.h @@ -86,8 +86,8 @@ * a BLOCK_SIZE-byte data block in the EEPROM data space. */ typedef struct { - uint8_t key[4]; /** 4-byte key (not null-terminated). */ - uint16_t ids[4]; /** Array of up to 4 block IDs (BLOCK_COUNT indicates end). */ + uint8_t key[4]; /** 4-byte key (not null-terminated). */ + uint16_t ids[4]; /** Array of up to 4 block IDs (BLOCK_COUNT indicates end). */ } directory_key_map_t; /** @@ -97,8 +97,8 @@ typedef struct { * including the device interface, allocation table, and key map. */ typedef struct { - m24c32_t *device; /** Pointer to the M24C32 device interface. */ - uint8_t alloc_table[ALLOC_TABLE_SIZE]; /** Bit-vector allocation table (one bit per block). */ + m24c32_t *device; /** Pointer to the M24C32 device interface. */ + uint8_t alloc_table[ALLOC_TABLE_SIZE]; /** Bit-vector allocation table (one bit per block). */ directory_key_map_t key_map[KEY_MAP_COUNT]; /** Array of key-value mappings. */ } eeprom_directory_t; diff --git a/middleware/include/eeprom_storage.h b/middleware/include/eeprom_storage.h index 8e48fb1c..a50b7dc8 100644 --- a/middleware/include/eeprom_storage.h +++ b/middleware/include/eeprom_storage.h @@ -51,7 +51,8 @@ eeprom_status_t init_storage(eeprom_directory_t *directory); */ eeprom_status_t get_data(eeprom_directory_t *directory, const uint16_t *ids, uint8_t **out, - uint16_t *out_size); + uint16_t *out_size +); /** * @brief Store data in EEPROM using block IDs. @@ -71,7 +72,8 @@ eeprom_status_t get_data(eeprom_directory_t *directory, */ eeprom_status_t put_data(eeprom_directory_t *directory, const uint16_t *ids, uint8_t *value, - uint16_t value_size); + uint16_t value_size +); /** * @brief Delete data blocks from EEPROM. diff --git a/middleware/src/eeprom_alloc.c b/middleware/src/eeprom_alloc.c index 2348e63a..5f0ffb8e 100644 --- a/middleware/src/eeprom_alloc.c +++ b/middleware/src/eeprom_alloc.c @@ -1,7 +1,7 @@ #include "eeprom_alloc.h" -#define byte_index(n) ((n) / 8) -#define bit_index(n) ((n) % 8) +#define byte_index(n) ((n) / 8) +#define bit_index(n) ((n) % 8) #define nth_bit_mask(n) (1 << (n)) static int get_alloc_table(uint8_t *table, uint16_t id) @@ -37,7 +37,8 @@ eeprom_status_t init_alloc_table(eeprom_directory_t *directory) m24c32_t *device = directory->device; return m24c32_read(device, ALLOC_TABLE_BEGIN, - directory->alloc_table, ALLOC_TABLE_SIZE); + directory->alloc_table, ALLOC_TABLE_SIZE +); } void print_alloc_table(eeprom_directory_t *directory) diff --git a/middleware/src/eeprom_directory.c b/middleware/src/eeprom_directory.c index 818e21c1..40a80587 100644 --- a/middleware/src/eeprom_directory.c +++ b/middleware/src/eeprom_directory.c @@ -27,14 +27,16 @@ static eeprom_status_t set_key(eeprom_directory_t *directory, uint16_t addr = KEY_MAP_BEGIN + i * KEY_MAP_STRUCT_SIZE; return m24c32_write(device, addr, (uint8_t *)&key_map[i], - KEY_MAP_STRUCT_SIZE); + KEY_MAP_STRUCT_SIZE +); } } return EEPROM_ERROR_ALLOCATION; } static eeprom_status_t delete_key(eeprom_directory_t *directory, - const uint8_t *key) + const uint8_t *key +) { m24c32_t *device = directory->device; directory_key_map_t *key_map = directory->key_map; @@ -47,14 +49,16 @@ static eeprom_status_t delete_key(eeprom_directory_t *directory, uint16_t addr = KEY_MAP_BEGIN + i * KEY_MAP_STRUCT_SIZE; return m24c32_write(device, addr, (uint8_t *)&key_map[i], - KEY_MAP_STRUCT_SIZE); + KEY_MAP_STRUCT_SIZE +); } } return EEPROM_ERROR_NOT_FOUND; } eeprom_status_t directory_init(m24c32_t *device, - eeprom_directory_t *directory) + eeprom_directory_t *directory +) { if (directory == NULL || device == NULL) { return EEPROM_ERROR_NULL_POINTER; diff --git a/middleware/src/eeprom_storage.c b/middleware/src/eeprom_storage.c index 9563e85c..97266bf6 100644 --- a/middleware/src/eeprom_storage.c +++ b/middleware/src/eeprom_storage.c @@ -28,7 +28,8 @@ eeprom_status_t init_storage(eeprom_directory_t *directory) return EEPROM_ERROR_ALLOCATION; } - eeprom_status_t res = m24c32_read(device, KEY_MAP_BEGIN, data, KEY_MAP_SIZE); + eeprom_status_t res = m24c32_read(device, KEY_MAP_BEGIN, data, + KEY_MAP_SIZE); if (res != EEPROM_OK) { free(data); return res; @@ -39,7 +40,7 @@ eeprom_status_t init_storage(eeprom_directory_t *directory) // key[4] memcpy(key_map[i].key, entry, 4); - + // ids[4] for (int j = 0; j < 4; j++) { key_map[i].ids[j] = @@ -53,7 +54,8 @@ eeprom_status_t init_storage(eeprom_directory_t *directory) eeprom_status_t get_data(eeprom_directory_t *directory, const uint16_t *ids, uint8_t **out, - uint16_t *out_size) + uint16_t *out_size +) { uint8_t id_count = get_id_count(ids); *out_size = BLOCK_SIZE * id_count; @@ -95,7 +97,8 @@ eeprom_status_t get_data(eeprom_directory_t *directory, eeprom_status_t put_data(eeprom_directory_t *directory, const uint16_t *ids, uint8_t *value, - uint16_t value_size) + uint16_t value_size +) { uint8_t id_count = get_id_count(ids); uint8_t *block_buffer = malloc(BLOCK_SIZE); From e40ada31922107f19626f48b2c6f3d797f8919d8 Mon Sep 17 00:00:00 2001 From: sogo Date: Fri, 2 Jan 2026 19:35:08 -0500 Subject: [PATCH 5/7] additional code formatting --- middleware/include/eeprom_directory.h | 6 ++---- middleware/include/eeprom_directory_struct.h | 6 +++--- middleware/include/eeprom_storage.h | 6 ++---- middleware/src/eeprom_alloc.c | 4 ++-- middleware/src/eeprom_directory.c | 12 ++++-------- middleware/src/eeprom_storage.c | 6 ++---- 6 files changed, 15 insertions(+), 25 deletions(-) diff --git a/middleware/include/eeprom_directory.h b/middleware/include/eeprom_directory.h index af4dd2ab..17f6d64e 100644 --- a/middleware/include/eeprom_directory.h +++ b/middleware/include/eeprom_directory.h @@ -41,8 +41,7 @@ * @retval EEPROM_ERROR If initialization of alloc table or storage fails. */ eeprom_status_t directory_init(m24c32_t *device, - eeprom_directory_t *directory -); + eeprom_directory_t *directory); /** * @brief Retrieve a value from the directory by key. @@ -104,7 +103,6 @@ eeprom_status_t set_directory_value(eeprom_directory_t *directory, * @retval EEPROM_ERROR_NOT_FOUND If the key does not exist in the directory. */ eeprom_status_t delete_directory_value(eeprom_directory_t *directory, - const uint8_t *key -); + const uint8_t *key); #endif // EEPROM_DIRECTORY_H \ No newline at end of file diff --git a/middleware/include/eeprom_directory_struct.h b/middleware/include/eeprom_directory_struct.h index 1528dc9e..3f2aff75 100644 --- a/middleware/include/eeprom_directory_struct.h +++ b/middleware/include/eeprom_directory_struct.h @@ -86,8 +86,8 @@ * a BLOCK_SIZE-byte data block in the EEPROM data space. */ typedef struct { - uint8_t key[4]; /** 4-byte key (not null-terminated). */ - uint16_t ids[4]; /** Array of up to 4 block IDs (BLOCK_COUNT indicates end). */ + uint8_t key[4]; /** 4-byte key (not null-terminated). */ + uint16_t ids[4]; /** Array of up to 4 block IDs (BLOCK_COUNT indicates end). */ } directory_key_map_t; /** @@ -98,7 +98,7 @@ typedef struct { */ typedef struct { m24c32_t *device; /** Pointer to the M24C32 device interface. */ - uint8_t alloc_table[ALLOC_TABLE_SIZE]; /** Bit-vector allocation table (one bit per block). */ + uint8_t alloc_table[ALLOC_TABLE_SIZE]; /** Bit-vector allocation table (one bit per block). */ directory_key_map_t key_map[KEY_MAP_COUNT]; /** Array of key-value mappings. */ } eeprom_directory_t; diff --git a/middleware/include/eeprom_storage.h b/middleware/include/eeprom_storage.h index a50b7dc8..8e48fb1c 100644 --- a/middleware/include/eeprom_storage.h +++ b/middleware/include/eeprom_storage.h @@ -51,8 +51,7 @@ eeprom_status_t init_storage(eeprom_directory_t *directory); */ eeprom_status_t get_data(eeprom_directory_t *directory, const uint16_t *ids, uint8_t **out, - uint16_t *out_size -); + uint16_t *out_size); /** * @brief Store data in EEPROM using block IDs. @@ -72,8 +71,7 @@ eeprom_status_t get_data(eeprom_directory_t *directory, */ eeprom_status_t put_data(eeprom_directory_t *directory, const uint16_t *ids, uint8_t *value, - uint16_t value_size -); + uint16_t value_size); /** * @brief Delete data blocks from EEPROM. diff --git a/middleware/src/eeprom_alloc.c b/middleware/src/eeprom_alloc.c index 5f0ffb8e..6618610a 100644 --- a/middleware/src/eeprom_alloc.c +++ b/middleware/src/eeprom_alloc.c @@ -37,8 +37,8 @@ eeprom_status_t init_alloc_table(eeprom_directory_t *directory) m24c32_t *device = directory->device; return m24c32_read(device, ALLOC_TABLE_BEGIN, - directory->alloc_table, ALLOC_TABLE_SIZE -); + directory->alloc_table, + ALLOC_TABLE_SIZE); } void print_alloc_table(eeprom_directory_t *directory) diff --git a/middleware/src/eeprom_directory.c b/middleware/src/eeprom_directory.c index 40a80587..27e5a6d6 100644 --- a/middleware/src/eeprom_directory.c +++ b/middleware/src/eeprom_directory.c @@ -27,16 +27,14 @@ static eeprom_status_t set_key(eeprom_directory_t *directory, uint16_t addr = KEY_MAP_BEGIN + i * KEY_MAP_STRUCT_SIZE; return m24c32_write(device, addr, (uint8_t *)&key_map[i], - KEY_MAP_STRUCT_SIZE -); + KEY_MAP_STRUCT_SIZE); } } return EEPROM_ERROR_ALLOCATION; } static eeprom_status_t delete_key(eeprom_directory_t *directory, - const uint8_t *key -) + const uint8_t *key) { m24c32_t *device = directory->device; directory_key_map_t *key_map = directory->key_map; @@ -49,16 +47,14 @@ static eeprom_status_t delete_key(eeprom_directory_t *directory, uint16_t addr = KEY_MAP_BEGIN + i * KEY_MAP_STRUCT_SIZE; return m24c32_write(device, addr, (uint8_t *)&key_map[i], - KEY_MAP_STRUCT_SIZE -); + KEY_MAP_STRUCT_SIZE); } } return EEPROM_ERROR_NOT_FOUND; } eeprom_status_t directory_init(m24c32_t *device, - eeprom_directory_t *directory -) + eeprom_directory_t *directory) { if (directory == NULL || device == NULL) { return EEPROM_ERROR_NULL_POINTER; diff --git a/middleware/src/eeprom_storage.c b/middleware/src/eeprom_storage.c index 97266bf6..d24e1b75 100644 --- a/middleware/src/eeprom_storage.c +++ b/middleware/src/eeprom_storage.c @@ -54,8 +54,7 @@ eeprom_status_t init_storage(eeprom_directory_t *directory) eeprom_status_t get_data(eeprom_directory_t *directory, const uint16_t *ids, uint8_t **out, - uint16_t *out_size -) + uint16_t *out_size) { uint8_t id_count = get_id_count(ids); *out_size = BLOCK_SIZE * id_count; @@ -97,8 +96,7 @@ eeprom_status_t get_data(eeprom_directory_t *directory, eeprom_status_t put_data(eeprom_directory_t *directory, const uint16_t *ids, uint8_t *value, - uint16_t value_size -) + uint16_t value_size) { uint8_t id_count = get_id_count(ids); uint8_t *block_buffer = malloc(BLOCK_SIZE); From 861d6c352a4bbfbb01c7d1c7d4c9c3abf648d76d Mon Sep 17 00:00:00 2001 From: sogo Date: Fri, 2 Jan 2026 19:42:25 -0500 Subject: [PATCH 6/7] formatting --- middleware/include/eeprom_alloc.h | 58 ++-- middleware/include/eeprom_directory.h | 101 +++--- middleware/include/eeprom_directory_struct.h | 36 ++- middleware/include/eeprom_status.h | 26 +- middleware/include/eeprom_storage.h | 82 ++--- middleware/src/eeprom_alloc.c | 140 ++++----- middleware/src/eeprom_directory.c | 310 +++++++++---------- middleware/src/eeprom_storage.c | 249 +++++++-------- 8 files changed, 496 insertions(+), 506 deletions(-) diff --git a/middleware/include/eeprom_alloc.h b/middleware/include/eeprom_alloc.h index 3f19b1b5..adca5e6a 100644 --- a/middleware/include/eeprom_alloc.h +++ b/middleware/include/eeprom_alloc.h @@ -4,10 +4,11 @@ * @brief EEPROM Block Allocation Management * @version 0.1 * @date 2026-01-02 - * - * This file provides functions for managing data block allocation in the EEPROM. - * It maintains a bit-vector allocation table to track which blocks are in use. - * + * + * This file provides functions for managing data block allocation in the + * EEPROM. It maintains a bit-vector allocation table to track which blocks are + * in use. + * */ #ifndef EEPROM_ALLOC_H @@ -19,49 +20,52 @@ /** * @brief Initialize allocation table by loading it from EEPROM memory. - * - * This function reads the allocation table from EEPROM and populates the directory's - * alloc_table structure in memory. - * + * + * This function reads the allocation table from EEPROM and populates the + * directory's alloc_table structure in memory. + * * @param directory Pointer to the initialized directory structure. - * - * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure. - * + * + * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on + * failure. + * * @retval EEPROM_ERROR If EEPROM read operation fails. */ eeprom_status_t init_alloc_table(eeprom_directory_t *directory); /** * @brief Print the allocation table in a human-readable format. - * - * This function prints the allocation table showing which blocks are allocated (1) - * and which are free (0). The output is formatted with 8 bits per group and + * + * This function prints the allocation table showing which blocks are allocated + * (1) and which are free (0). The output is formatted with 8 bits per group and * 64 bits per line. - * + * * @param directory Pointer to the initialized directory structure. */ void print_alloc_table(eeprom_directory_t *directory); /** * @brief Allocate a single block from the EEPROM. - * + * * This function finds the first free block in the allocation table, marks it as * allocated in both local memory and EEPROM, and returns its ID. - * + * * @param directory Pointer to the initialized directory structure. - * - * @return uint16_t Returns the allocated block ID on success, or BLOCK_COUNT if allocation fails. - * + * + * @return uint16_t Returns the allocated block ID on success, or BLOCK_COUNT if + * allocation fails. + * * @retval BLOCK_COUNT If no free blocks are available or EEPROM update fails. */ uint16_t alloc_block(eeprom_directory_t *directory); /** * @brief Free one or more blocks in the EEPROM. - * - * This function marks the specified blocks as free in both local memory and EEPROM. - * If a block is already freed, this function does nothing for that block. - * + * + * This function marks the specified blocks as free in both local memory and + * EEPROM. If a block is already freed, this function does nothing for that + * block. + * * @param directory Pointer to the initialized directory structure. * @param ids Array of block IDs to free. * @param size Number of block IDs in the array. @@ -70,13 +74,13 @@ void free_block(eeprom_directory_t *directory, uint16_t *ids, uint8_t size); /** * @brief Check if a block is allocated. - * + * * This function checks the allocation table to determine if a specific block is * currently allocated or free. - * + * * @param directory Pointer to the initialized directory structure. * @param id Block ID to check. - * + * * @return int Returns 1 if the block is allocated, 0 if it is free. */ int is_allocated(eeprom_directory_t *directory, uint16_t id); diff --git a/middleware/include/eeprom_directory.h b/middleware/include/eeprom_directory.h index 17f6d64e..61914426 100644 --- a/middleware/include/eeprom_directory.h +++ b/middleware/include/eeprom_directory.h @@ -2,10 +2,10 @@ * @file eeprom_directory.h * @author Sogo Nishihara (sogonishi@gmail.com) * @brief EEPROM Directory Management API - * + * * This file defines the public API for a simple key-value directory * stored on EEPROM device. - * + * * The directory provides block-based persistent storage, managing * allocation, lookup, insertion, and deletion of values associated * with fixed-size (4-byte) keys. @@ -16,93 +16,100 @@ #ifndef EEPROM_DIRECTORY_H #define EEPROM_DIRECTORY_H -#include #include +#include #include -#include "m24c32.h" -#include "eeprom_status.h" -#include "eeprom_directory_struct.h" #include "eeprom_alloc.h" +#include "eeprom_directory_struct.h" +#include "eeprom_status.h" #include "eeprom_storage.h" +#include "m24c32.h" /** * @brief Initialize the EEPROM directory structure. - * - * This function initializes the directory structure with the provided device interface, - * loads the allocation table and key map from EEPROM memory. - * + * + * This function initializes the directory structure with the provided device + * interface, loads the allocation table and key map from EEPROM memory. + * * @param device Pointer to the M24C32 device interface structure. - * @param directory Pointer to the directory structure to initialize. Must be allocated by caller. - * - * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure. - * + * @param directory Pointer to the directory structure to initialize. Must be + * allocated by caller. + * + * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on + * failure. + * * @retval EEPROM_ERROR_NULL_POINTER If device or directory is NULL. * @retval EEPROM_ERROR If initialization of alloc table or storage fails. */ -eeprom_status_t directory_init(m24c32_t *device, - eeprom_directory_t *directory); +eeprom_status_t directory_init(m24c32_t *device, eeprom_directory_t *directory); /** * @brief Retrieve a value from the directory by key. - * - * This function looks up a key in the directory and retrieves the associated data. - * The output buffer is allocated by this function and must be freed by the caller. - * + * + * This function looks up a key in the directory and retrieves the associated + * data. The output buffer is allocated by this function and must be freed by + * the caller. + * * @param directory Pointer to the initialized directory structure. * @param key Pointer to a 4-byte key (not null-terminated). - * @param out Pointer to a pointer that will receive the allocated output buffer. - * The caller is responsible for freeing this buffer. + * @param out Pointer to a pointer that will receive the allocated output + * buffer. The caller is responsible for freeing this buffer. * @param out_size Pointer to store the size of the output data in bytes. - * - * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure. - * - * @retval EEPROM_ERROR_NULL_POINTER If directory, key, out, or out_size is NULL. + * + * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on + * failure. + * + * @retval EEPROM_ERROR_NULL_POINTER If directory, key, out, or out_size is + * NULL. * @retval EEPROM_ERROR_NOT_FOUND If the key does not exist in the directory. * @retval EEPROM_ERROR_ALLOCATION If memory allocation fails. */ eeprom_status_t get_directory_value(eeprom_directory_t *directory, - const uint8_t *key, uint8_t **out, - uint16_t *out_size); + const uint8_t *key, uint8_t **out, + uint16_t *out_size); /** * @brief Store a value in the directory with the specified key. - * - * This function stores data in the directory. If the key already exists, the old value - * is deleted first. The data is stored in blocks of BLOCK_SIZE bytes, with remaining - * bytes padded with zeros. - * + * + * This function stores data in the directory. If the key already exists, the + * old value is deleted first. The data is stored in blocks of BLOCK_SIZE bytes, + * with remaining bytes padded with zeros. + * * @param directory Pointer to the initialized directory structure. * @param key Pointer to a 4-byte key (not null-terminated). * @param value Pointer to the data to store. - * @param value_size Size of the data in bytes (maximum 16 bytes, i.e., 4 blocks). - * - * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure. - * + * @param value_size Size of the data in bytes (maximum 16 bytes, i.e., 4 + * blocks). + * + * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on + * failure. + * * @retval EEPROM_ERROR_NULL_POINTER If directory or value is NULL. * @retval EEPROM_ERROR If value_size is 0. * @retval EEPROM_ERROR_TOO_BIG If value_size exceeds 16 bytes (4 blocks). * @retval EEPROM_ERROR_ALLOCATION If block allocation fails. */ eeprom_status_t set_directory_value(eeprom_directory_t *directory, - const uint8_t *key, uint8_t *value, - const uint16_t value_size); + const uint8_t *key, uint8_t *value, + const uint16_t value_size); /** * @brief Delete a value from the directory by key. - * - * This function removes a key-value pair from the directory and frees the associated - * blocks. The blocks are marked as available for reuse. - * + * + * This function removes a key-value pair from the directory and frees the + * associated blocks. The blocks are marked as available for reuse. + * * @param directory Pointer to the initialized directory structure. * @param key Pointer to a 4-byte key (not null-terminated). - * - * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure. - * + * + * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on + * failure. + * * @retval EEPROM_ERROR_NULL_POINTER If directory or key is NULL. * @retval EEPROM_ERROR_NOT_FOUND If the key does not exist in the directory. */ eeprom_status_t delete_directory_value(eeprom_directory_t *directory, - const uint8_t *key); + const uint8_t *key); #endif // EEPROM_DIRECTORY_H \ No newline at end of file diff --git a/middleware/include/eeprom_directory_struct.h b/middleware/include/eeprom_directory_struct.h index 3f2aff75..37fe633a 100644 --- a/middleware/include/eeprom_directory_struct.h +++ b/middleware/include/eeprom_directory_struct.h @@ -4,10 +4,11 @@ * @brief EEPROM Directory Data Structures and Constants * @version 0.1 * @date 2026-01-02 - * - * This file defines the data structures and constants used for the EEPROM directory system. - * It includes memory layout definitions, block allocation parameters, and structure definitions. - * + * + * This file defines the data structures and constants used for the EEPROM + * directory system. It includes memory layout definitions, block allocation + * parameters, and structure definitions. + * * EEPROM Memory Layout (Total: 4096 bytes) * * Address @@ -45,10 +46,12 @@ #ifndef EEPROM_DIRECTORY_STRUCT #define EEPROM_DIRECTORY_STRUCT -/** @brief Size of a single key-map entry structure in bytes (4-byte key + 8-byte IDs array). */ +/** @brief Size of a single key-map entry structure in bytes (4-byte key + + * 8-byte IDs array). */ #define KEY_MAP_STRUCT_SIZE 12 -/** @brief Maximum number of key-value pairs that can be stored in the directory. */ +/** @brief Maximum number of key-value pairs that can be stored in the + * directory. */ #define KEY_MAP_COUNT 128 /** @brief Size of a data block in bytes. */ @@ -81,25 +84,28 @@ /** * @brief Key-value mapping structure. - * - * This structure maps a 4-byte key to up to 4 block IDs. Each block ID points to - * a BLOCK_SIZE-byte data block in the EEPROM data space. + * + * This structure maps a 4-byte key to up to 4 block IDs. Each block ID points + * to a BLOCK_SIZE-byte data block in the EEPROM data space. */ typedef struct { - uint8_t key[4]; /** 4-byte key (not null-terminated). */ - uint16_t ids[4]; /** Array of up to 4 block IDs (BLOCK_COUNT indicates end). */ + uint8_t key[4]; /** 4-byte key (not null-terminated). */ + uint16_t + ids[4]; /** Array of up to 4 block IDs (BLOCK_COUNT indicates end). */ } directory_key_map_t; /** * @brief Main EEPROM directory structure. - * + * * This structure contains all the state information for the EEPROM directory, * including the device interface, allocation table, and key map. */ typedef struct { - m24c32_t *device; /** Pointer to the M24C32 device interface. */ - uint8_t alloc_table[ALLOC_TABLE_SIZE]; /** Bit-vector allocation table (one bit per block). */ - directory_key_map_t key_map[KEY_MAP_COUNT]; /** Array of key-value mappings. */ + m24c32_t *device; /** Pointer to the M24C32 device interface. */ + uint8_t alloc_table[ALLOC_TABLE_SIZE]; /** Bit-vector allocation table (one + bit per block). */ + directory_key_map_t + key_map[KEY_MAP_COUNT]; /** Array of key-value mappings. */ } eeprom_directory_t; #endif \ No newline at end of file diff --git a/middleware/include/eeprom_status.h b/middleware/include/eeprom_status.h index 2764c586..e9dad29b 100644 --- a/middleware/include/eeprom_status.h +++ b/middleware/include/eeprom_status.h @@ -1,25 +1,25 @@ /** * @file eeprom_status.h * @brief EEPROM Standardized Error Codes - * - * This file defines the `eeprom_status_t` enumeration, which provides standardized - * error codes for all EEPROM-related operations. - * + * + * This file defines the `eeprom_status_t` enumeration, which provides + * standardized error codes for all EEPROM-related operations. + * */ #ifndef EEPROM_STATUS #define EEPROM_STATUS typedef enum { - EEPROM_OK = 0, - EEPROM_ERROR = -1, - EEPROM_ERROR_NOT_FOUND = -2, - EEPROM_ERROR_OUT_OF_BOUNDS = -3, - EEPROM_ERROR_ALIGNMENT = -4, - EEPROM_ERROR_NULL_POINTER = -5, - EEPROM_ERROR_ALLOCATION = -6, - EEPROM_ERROR_COMMS = -7, - EEPROM_ERROR_TOO_BIG = -8 + EEPROM_OK = 0, + EEPROM_ERROR = -1, + EEPROM_ERROR_NOT_FOUND = -2, + EEPROM_ERROR_OUT_OF_BOUNDS = -3, + EEPROM_ERROR_ALIGNMENT = -4, + EEPROM_ERROR_NULL_POINTER = -5, + EEPROM_ERROR_ALLOCATION = -6, + EEPROM_ERROR_COMMS = -7, + EEPROM_ERROR_TOO_BIG = -8 } eeprom_status_t; diff --git a/middleware/include/eeprom_storage.h b/middleware/include/eeprom_storage.h index 8e48fb1c..c54537cb 100644 --- a/middleware/include/eeprom_storage.h +++ b/middleware/include/eeprom_storage.h @@ -2,10 +2,11 @@ * @file eeprom_storage.h * @author Sogo Nishihara (sogonishi@gmail.com) * @brief EEPROM Storage Management - * - * This file provides functions for managing data storage in the EEPROM directory. - * Functions handle reading, writing, and deleting data blocks associated with block IDs. - * + * + * This file provides functions for managing data storage in the EEPROM + * directory. Functions handle reading, writing, and deleting data blocks + * associated with block IDs. + * */ #ifndef EEPROM_STORAGE @@ -13,19 +14,20 @@ #include -#include "eeprom_directory_struct.h" #include "eeprom_alloc.h" +#include "eeprom_directory_struct.h" /** * @brief Initialize storage by loading key-map table from EEPROM memory. - * - * This function reads the key-map table from EEPROM and populates the directory's - * key_map structure in memory. - * + * + * This function reads the key-map table from EEPROM and populates the + * directory's key_map structure in memory. + * * @param directory Pointer to the initialized directory structure. - * - * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure. - * + * + * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on + * failure. + * * @retval EEPROM_ERROR_ALLOCATION If memory allocation fails. * @retval EEPROM_ERROR If EEPROM read operation fails. */ @@ -33,55 +35,57 @@ eeprom_status_t init_storage(eeprom_directory_t *directory); /** * @brief Retrieve data from EEPROM using block IDs. - * - * This function reads data from multiple blocks in EEPROM and allocates a buffer - * to store the result. The caller is responsible for freeing the output buffer. - * + * + * This function reads data from multiple blocks in EEPROM and allocates a + * buffer to store the result. The caller is responsible for freeing the output + * buffer. + * * @param directory Pointer to the initialized directory structure. * @param ids Array of block IDs (up to 4, terminated by BLOCK_COUNT). - * @param out Pointer to a pointer that will receive the allocated output buffer. - * The caller must free this buffer. + * @param out Pointer to a pointer that will receive the allocated output + * buffer. The caller must free this buffer. * @param out_size Pointer to store the size of the output data in bytes. - * - * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure. - * + * + * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on + * failure. + * * @retval EEPROM_ERROR_ALLOCATION If memory allocation fails. * @retval EEPROM_ERROR_NOT_FOUND If any block ID is not allocated. * @retval EEPROM_ERROR If EEPROM read operation fails. */ -eeprom_status_t get_data(eeprom_directory_t *directory, - const uint16_t *ids, uint8_t **out, - uint16_t *out_size); +eeprom_status_t get_data(eeprom_directory_t *directory, const uint16_t *ids, + uint8_t **out, uint16_t *out_size); /** * @brief Store data in EEPROM using block IDs. - * - * This function writes data to multiple blocks in EEPROM. Each block is BLOCK_SIZE bytes. - * If the data size is smaller than the total block size, remaining bytes are padded with zeros. - * + * + * This function writes data to multiple blocks in EEPROM. Each block is + * BLOCK_SIZE bytes. If the data size is smaller than the total block size, + * remaining bytes are padded with zeros. + * * @param directory Pointer to the initialized directory structure. * @param ids Array of block IDs (up to 4, terminated by BLOCK_COUNT). * @param value Pointer to the data to write. * @param value_size Size of the data in bytes. - * - * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure. - * + * + * @return eeprom_status_t Returns EEPROM_OK on success, or an error code on + * failure. + * * @retval EEPROM_ERROR_ALLOCATION If memory allocation for block buffer fails. * @retval EEPROM_ERROR If EEPROM write operation fails. */ -eeprom_status_t put_data(eeprom_directory_t *directory, - const uint16_t *ids, uint8_t *value, - uint16_t value_size); +eeprom_status_t put_data(eeprom_directory_t *directory, const uint16_t *ids, + uint8_t *value, uint16_t value_size); /** * @brief Delete data blocks from EEPROM. - * - * This function frees the blocks associated with the given IDs, making them available - * for reuse. The blocks are marked as free in the allocation table. - * + * + * This function frees the blocks associated with the given IDs, making them + * available for reuse. The blocks are marked as free in the allocation table. + * * @param directory Pointer to the initialized directory structure. * @param ids Array of block IDs to free (up to 4, terminated by BLOCK_COUNT). - * + * * @return eeprom_status_t Returns EEPROM_OK on success. */ eeprom_status_t delete_data(eeprom_directory_t *directory, uint16_t *ids); diff --git a/middleware/src/eeprom_alloc.c b/middleware/src/eeprom_alloc.c index 6618610a..2804aa6c 100644 --- a/middleware/src/eeprom_alloc.c +++ b/middleware/src/eeprom_alloc.c @@ -1,98 +1,88 @@ #include "eeprom_alloc.h" -#define byte_index(n) ((n) / 8) -#define bit_index(n) ((n) % 8) +#define byte_index(n) ((n) / 8) +#define bit_index(n) ((n) % 8) #define nth_bit_mask(n) (1 << (n)) -static int get_alloc_table(uint8_t *table, uint16_t id) -{ - return (table[byte_index(id)] >> bit_index(id)) & 1; +static int get_alloc_table(uint8_t *table, uint16_t id) { + return (table[byte_index(id)] >> bit_index(id)) & 1; } -static void put_alloc_table(uint8_t *table, uint16_t id, uint8_t val) -{ - uint8_t bit_mask = nth_bit_mask(bit_index(id)); +static void put_alloc_table(uint8_t *table, uint16_t id, uint8_t val) { + uint8_t bit_mask = nth_bit_mask(bit_index(id)); - if (val) { - table[byte_index(id)] |= bit_mask; - } else { - bit_mask = ~bit_mask; - table[byte_index(id)] &= bit_mask; - } + if (val) { + table[byte_index(id)] |= bit_mask; + } else { + bit_mask = ~bit_mask; + table[byte_index(id)] &= bit_mask; + } } static eeprom_status_t update_eeprom_alloc_table(eeprom_directory_t *directory, - uint16_t id) -{ - uint16_t data_index = byte_index(id); - m24c32_t *device = directory->device; - uint16_t addr = ALLOC_TABLE_BEGIN + data_index; - uint8_t *data = directory->alloc_table + data_index; - - return m24c32_write(device, addr, data, 1); + uint16_t id) { + uint16_t data_index = byte_index(id); + m24c32_t *device = directory->device; + uint16_t addr = ALLOC_TABLE_BEGIN + data_index; + uint8_t *data = directory->alloc_table + data_index; + + return m24c32_write(device, addr, data, 1); } -eeprom_status_t init_alloc_table(eeprom_directory_t *directory) -{ - m24c32_t *device = directory->device; +eeprom_status_t init_alloc_table(eeprom_directory_t *directory) { + m24c32_t *device = directory->device; - return m24c32_read(device, ALLOC_TABLE_BEGIN, - directory->alloc_table, - ALLOC_TABLE_SIZE); + return m24c32_read(device, ALLOC_TABLE_BEGIN, directory->alloc_table, + ALLOC_TABLE_SIZE); } -void print_alloc_table(eeprom_directory_t *directory) -{ - uint8_t *alloc_table = directory->alloc_table; - for (int id = 0; id < BLOCK_COUNT; id++) { - putchar(get_alloc_table(alloc_table, id) ? '1' : '0'); - - if ((id + 1) % 64 == 0) { - putchar('\n'); - } else if ((id + 1) % 8 == 0) { - putchar(' '); - } - } - putchar('\n'); +void print_alloc_table(eeprom_directory_t *directory) { + uint8_t *alloc_table = directory->alloc_table; + for (int id = 0; id < BLOCK_COUNT; id++) { + putchar(get_alloc_table(alloc_table, id) ? '1' : '0'); + + if ((id + 1) % 64 == 0) { + putchar('\n'); + } else if ((id + 1) % 8 == 0) { + putchar(' '); + } + } + putchar('\n'); } -uint16_t alloc_block(eeprom_directory_t *directory) -{ - uint8_t *alloc_table = directory->alloc_table; - - for (uint16_t id = 0; id < BLOCK_COUNT; id++) { - if (get_alloc_table(alloc_table, id) == 0) { - put_alloc_table(alloc_table, id, 1); - eeprom_status_t ret = - update_eeprom_alloc_table(directory, id); - if (ret != EEPROM_OK) { - printf("ERROR: failed to update eeprom alloc table.\n"); - put_alloc_table(alloc_table, id, 0); - return BLOCK_COUNT; - } - return id; - } - } - return BLOCK_COUNT; +uint16_t alloc_block(eeprom_directory_t *directory) { + uint8_t *alloc_table = directory->alloc_table; + + for (uint16_t id = 0; id < BLOCK_COUNT; id++) { + if (get_alloc_table(alloc_table, id) == 0) { + put_alloc_table(alloc_table, id, 1); + eeprom_status_t ret = update_eeprom_alloc_table(directory, id); + if (ret != EEPROM_OK) { + printf("ERROR: failed to update eeprom alloc table.\n"); + put_alloc_table(alloc_table, id, 0); + return BLOCK_COUNT; + } + return id; + } + } + return BLOCK_COUNT; } -void free_block(eeprom_directory_t *directory, uint16_t *ids, uint8_t size) -{ - uint8_t *alloc_table = directory->alloc_table; - - for (int i = 0; i < size; i++) { - uint16_t id = ids[i]; - put_alloc_table(alloc_table, id, 0); - eeprom_status_t ret = update_eeprom_alloc_table(directory, id); - if (ret != EEPROM_OK) { - printf("ERROR: failed to update eeprom allo table.\n"); - } - } +void free_block(eeprom_directory_t *directory, uint16_t *ids, uint8_t size) { + uint8_t *alloc_table = directory->alloc_table; + + for (int i = 0; i < size; i++) { + uint16_t id = ids[i]; + put_alloc_table(alloc_table, id, 0); + eeprom_status_t ret = update_eeprom_alloc_table(directory, id); + if (ret != EEPROM_OK) { + printf("ERROR: failed to update eeprom allo table.\n"); + } + } } -int is_allocated(eeprom_directory_t *directory, uint16_t id) -{ - uint8_t *alloc_table = directory->alloc_table; +int is_allocated(eeprom_directory_t *directory, uint16_t id) { + uint8_t *alloc_table = directory->alloc_table; - return get_alloc_table(alloc_table, id); + return get_alloc_table(alloc_table, id); } diff --git a/middleware/src/eeprom_directory.c b/middleware/src/eeprom_directory.c index 27e5a6d6..b2c02acd 100644 --- a/middleware/src/eeprom_directory.c +++ b/middleware/src/eeprom_directory.c @@ -1,181 +1,171 @@ #include "eeprom_directory.h" -static uint16_t *get_ids(eeprom_directory_t *directory, const uint8_t *key) -{ - directory_key_map_t *key_map = directory->key_map; - - for (int i = 0; i < KEY_MAP_COUNT; i++) { - // Keys are fixed 4-byte arrays, not null-terminated strings - if (memcmp(key_map[i].key, key, 4) == 0) { - return key_map[i].ids; - } - } - return NULL; +static uint16_t *get_ids(eeprom_directory_t *directory, const uint8_t *key) { + directory_key_map_t *key_map = directory->key_map; + + for (int i = 0; i < KEY_MAP_COUNT; i++) { + // Keys are fixed 4-byte arrays, not null-terminated strings + if (memcmp(key_map[i].key, key, 4) == 0) { + return key_map[i].ids; + } + } + return NULL; } static eeprom_status_t set_key(eeprom_directory_t *directory, - const uint8_t *key, uint16_t *ids) -{ - m24c32_t *device = directory->device; - directory_key_map_t *key_map = directory->key_map; - - for (int i = 0; i < KEY_MAP_COUNT; i++) { - if ((char)key_map[i].key[0] == '\0') { - memcpy(key_map[i].key, key, 4); - memcpy(key_map[i].ids, ids, 8); - - uint16_t addr = KEY_MAP_BEGIN + i * KEY_MAP_STRUCT_SIZE; - return m24c32_write(device, addr, - (uint8_t *)&key_map[i], - KEY_MAP_STRUCT_SIZE); - } - } - return EEPROM_ERROR_ALLOCATION; + const uint8_t *key, uint16_t *ids) { + m24c32_t *device = directory->device; + directory_key_map_t *key_map = directory->key_map; + + for (int i = 0; i < KEY_MAP_COUNT; i++) { + if ((char)key_map[i].key[0] == '\0') { + memcpy(key_map[i].key, key, 4); + memcpy(key_map[i].ids, ids, 8); + + uint16_t addr = KEY_MAP_BEGIN + i * KEY_MAP_STRUCT_SIZE; + return m24c32_write(device, addr, (uint8_t *)&key_map[i], + KEY_MAP_STRUCT_SIZE); + } + } + return EEPROM_ERROR_ALLOCATION; } static eeprom_status_t delete_key(eeprom_directory_t *directory, - const uint8_t *key) -{ - m24c32_t *device = directory->device; - directory_key_map_t *key_map = directory->key_map; - - for (int i = 0; i < KEY_MAP_COUNT; i++) { - // Keys are fixed 4-byte arrays, not null-terminated strings - if (memcmp(key_map[i].key, key, 4) == 0) { - memset(&key_map[i], 0, KEY_MAP_STRUCT_SIZE); - - uint16_t addr = KEY_MAP_BEGIN + i * KEY_MAP_STRUCT_SIZE; - return m24c32_write(device, addr, - (uint8_t *)&key_map[i], - KEY_MAP_STRUCT_SIZE); - } - } - return EEPROM_ERROR_NOT_FOUND; + const uint8_t *key) { + m24c32_t *device = directory->device; + directory_key_map_t *key_map = directory->key_map; + + for (int i = 0; i < KEY_MAP_COUNT; i++) { + // Keys are fixed 4-byte arrays, not null-terminated strings + if (memcmp(key_map[i].key, key, 4) == 0) { + memset(&key_map[i], 0, KEY_MAP_STRUCT_SIZE); + + uint16_t addr = KEY_MAP_BEGIN + i * KEY_MAP_STRUCT_SIZE; + return m24c32_write(device, addr, (uint8_t *)&key_map[i], + KEY_MAP_STRUCT_SIZE); + } + } + return EEPROM_ERROR_NOT_FOUND; } eeprom_status_t directory_init(m24c32_t *device, - eeprom_directory_t *directory) -{ - if (directory == NULL || device == NULL) { - return EEPROM_ERROR_NULL_POINTER; - } - - directory->device = device; - eeprom_status_t res; - res = init_alloc_table(directory); - if (res != EEPROM_OK) { - return res; - } - res = init_storage(directory); - if (res != EEPROM_OK) { - return res; - } - return EEPROM_OK; + eeprom_directory_t *directory) { + if (directory == NULL || device == NULL) { + return EEPROM_ERROR_NULL_POINTER; + } + + directory->device = device; + eeprom_status_t res; + res = init_alloc_table(directory); + if (res != EEPROM_OK) { + return res; + } + res = init_storage(directory); + if (res != EEPROM_OK) { + return res; + } + return EEPROM_OK; } eeprom_status_t get_directory_value(eeprom_directory_t *directory, - const uint8_t *key, uint8_t **out, - uint16_t *out_size) -{ - if (directory == NULL || key == NULL || out == NULL || - out_size == NULL) { - return EEPROM_ERROR_NULL_POINTER; - } - - uint16_t *ids = get_ids(directory, key); - if (ids == NULL) { - return EEPROM_ERROR_NOT_FOUND; - } - - return get_data(directory, ids, out, out_size); + const uint8_t *key, uint8_t **out, + uint16_t *out_size) { + if (directory == NULL || key == NULL || out == NULL || out_size == NULL) { + return EEPROM_ERROR_NULL_POINTER; + } + + uint16_t *ids = get_ids(directory, key); + if (ids == NULL) { + return EEPROM_ERROR_NOT_FOUND; + } + + return get_data(directory, ids, out, out_size); } eeprom_status_t set_directory_value(eeprom_directory_t *directory, - const uint8_t *key, uint8_t *value, - const uint16_t value_size) -{ - if (directory == NULL || value == NULL) { - return EEPROM_ERROR_NULL_POINTER; - } - if (value_size <= 0) { - return EEPROM_ERROR; - } - - uint16_t *existing_ids = get_ids(directory, key); - - // If key already exists, delete it first - if (existing_ids != NULL) { - eeprom_status_t res = delete_directory_value(directory, key); - if (res != EEPROM_OK) { - return res; - } - } - - // Allocate new blocks for the value - int block_count = (value_size - 1) / BLOCK_SIZE + 1; - if (block_count > 4) { - return EEPROM_ERROR_TOO_BIG; - } - - uint16_t *ids = malloc(sizeof(uint16_t) * 4); - if (ids == NULL) { - return EEPROM_ERROR_ALLOCATION; - } - - for (int block_idx = 0; block_idx < block_count; block_idx++) { - uint16_t id = alloc_block(directory); - if (id == BLOCK_COUNT) { - // Free already allocated blocks on failure - for (int j = 0; j < block_idx; j++) { - free_block(directory, &ids[j], 1); - } - free(ids); - return EEPROM_ERROR_ALLOCATION; - } - ids[block_idx] = id; - } - for (int block_idx = block_count; block_idx < 4; block_idx++) { - ids[block_idx] = BLOCK_COUNT; - } - - eeprom_status_t res; - res = set_key(directory, key, ids); - if (res != EEPROM_OK) { - // Free allocated blocks on failure - free_block(directory, ids, block_count); - free(ids); - return res; - } - - res = put_data(directory, ids, value, value_size); - if (res != EEPROM_OK) { - // Free allocated blocks and remove key on failure - free_block(directory, ids, block_count); - delete_key(directory, key); - free(ids); - return res; - } - - free(ids); - return EEPROM_OK; + const uint8_t *key, uint8_t *value, + const uint16_t value_size) { + if (directory == NULL || value == NULL) { + return EEPROM_ERROR_NULL_POINTER; + } + if (value_size <= 0) { + return EEPROM_ERROR; + } + + uint16_t *existing_ids = get_ids(directory, key); + + // If key already exists, delete it first + if (existing_ids != NULL) { + eeprom_status_t res = delete_directory_value(directory, key); + if (res != EEPROM_OK) { + return res; + } + } + + // Allocate new blocks for the value + int block_count = (value_size - 1) / BLOCK_SIZE + 1; + if (block_count > 4) { + return EEPROM_ERROR_TOO_BIG; + } + + uint16_t *ids = malloc(sizeof(uint16_t) * 4); + if (ids == NULL) { + return EEPROM_ERROR_ALLOCATION; + } + + for (int block_idx = 0; block_idx < block_count; block_idx++) { + uint16_t id = alloc_block(directory); + if (id == BLOCK_COUNT) { + // Free already allocated blocks on failure + for (int j = 0; j < block_idx; j++) { + free_block(directory, &ids[j], 1); + } + free(ids); + return EEPROM_ERROR_ALLOCATION; + } + ids[block_idx] = id; + } + for (int block_idx = block_count; block_idx < 4; block_idx++) { + ids[block_idx] = BLOCK_COUNT; + } + + eeprom_status_t res; + res = set_key(directory, key, ids); + if (res != EEPROM_OK) { + // Free allocated blocks on failure + free_block(directory, ids, block_count); + free(ids); + return res; + } + + res = put_data(directory, ids, value, value_size); + if (res != EEPROM_OK) { + // Free allocated blocks and remove key on failure + free_block(directory, ids, block_count); + delete_key(directory, key); + free(ids); + return res; + } + + free(ids); + return EEPROM_OK; } eeprom_status_t delete_directory_value(eeprom_directory_t *directory, - const uint8_t *key) -{ - if (directory == NULL || key == NULL) { - return EEPROM_ERROR_NULL_POINTER; - } - - uint16_t *ids = get_ids(directory, key); - if (ids == NULL) { - return EEPROM_ERROR_NOT_FOUND; - } - - eeprom_status_t res; - res = delete_data(directory, ids); - if (res != EEPROM_OK) { - return res; - } - return delete_key(directory, key); + const uint8_t *key) { + if (directory == NULL || key == NULL) { + return EEPROM_ERROR_NULL_POINTER; + } + + uint16_t *ids = get_ids(directory, key); + if (ids == NULL) { + return EEPROM_ERROR_NOT_FOUND; + } + + eeprom_status_t res; + res = delete_data(directory, ids); + if (res != EEPROM_OK) { + return res; + } + return delete_key(directory, key); } diff --git a/middleware/src/eeprom_storage.c b/middleware/src/eeprom_storage.c index d24e1b75..cfd70ba8 100644 --- a/middleware/src/eeprom_storage.c +++ b/middleware/src/eeprom_storage.c @@ -1,145 +1,134 @@ #include "eeprom_storage.h" #include -static uint8_t get_id_count(const uint16_t *ids) -{ - uint8_t count = 0; - - for (int i = 0; i < 4; i++) { - if (ids[i] >= BLOCK_COUNT) { - break; - } - count++; - } - return count; +static uint8_t get_id_count(const uint16_t *ids) { + uint8_t count = 0; + + for (int i = 0; i < 4; i++) { + if (ids[i] >= BLOCK_COUNT) { + break; + } + count++; + } + return count; } -static uint16_t get_addr_for_data(const uint16_t id) -{ - return DATA_SPACE_BEGIN + id * BLOCK_SIZE; +static uint16_t get_addr_for_data(const uint16_t id) { + return DATA_SPACE_BEGIN + id * BLOCK_SIZE; } -eeprom_status_t init_storage(eeprom_directory_t *directory) -{ - m24c32_t *device = directory->device; - directory_key_map_t *key_map = directory->key_map; - uint8_t *data = malloc(KEY_MAP_SIZE); - if (data == NULL) { - return EEPROM_ERROR_ALLOCATION; - } - - eeprom_status_t res = m24c32_read(device, KEY_MAP_BEGIN, data, - KEY_MAP_SIZE); - if (res != EEPROM_OK) { - free(data); - return res; - } - - for (int i = 0; i < KEY_MAP_COUNT; i++) { - uint8_t *entry = data + (i * KEY_MAP_STRUCT_SIZE); - - // key[4] - memcpy(key_map[i].key, entry, 4); - - // ids[4] - for (int j = 0; j < 4; j++) { - key_map[i].ids[j] = - (uint16_t)entry[4 + j * 2] | - ((uint16_t)entry[4 + j * 2 + 1] << 8); - } - } - free(data); - return EEPROM_OK; +eeprom_status_t init_storage(eeprom_directory_t *directory) { + m24c32_t *device = directory->device; + directory_key_map_t *key_map = directory->key_map; + uint8_t *data = malloc(KEY_MAP_SIZE); + if (data == NULL) { + return EEPROM_ERROR_ALLOCATION; + } + + eeprom_status_t res = m24c32_read(device, KEY_MAP_BEGIN, data, KEY_MAP_SIZE); + if (res != EEPROM_OK) { + free(data); + return res; + } + + for (int i = 0; i < KEY_MAP_COUNT; i++) { + uint8_t *entry = data + (i * KEY_MAP_STRUCT_SIZE); + + // key[4] + memcpy(key_map[i].key, entry, 4); + + // ids[4] + for (int j = 0; j < 4; j++) { + key_map[i].ids[j] = + (uint16_t)entry[4 + j * 2] | ((uint16_t)entry[4 + j * 2 + 1] << 8); + } + } + free(data); + return EEPROM_OK; } -eeprom_status_t get_data(eeprom_directory_t *directory, - const uint16_t *ids, uint8_t **out, - uint16_t *out_size) -{ - uint8_t id_count = get_id_count(ids); - *out_size = BLOCK_SIZE * id_count; - - // Free existing buffer if provided - if (*out) { - free(*out); - *out = NULL; - } - - // Allocate new buffer - *out = malloc(*out_size); - if (*out == NULL) { - return EEPROM_ERROR_ALLOCATION; - } - - for (int i = 0; i < id_count; i++) { - uint16_t id = ids[i]; - if (!is_allocated(directory, id)) { - free(*out); - *out = NULL; - return EEPROM_ERROR_NOT_FOUND; - } - - uint16_t addr = get_addr_for_data(id); - uint8_t *data_ptr = *out + BLOCK_SIZE * i; - eeprom_status_t res; - - res = m24c32_read(directory->device, addr, data_ptr, - BLOCK_SIZE); - if (res != EEPROM_OK) { - free(*out); - *out = NULL; - return res; - } - } - return EEPROM_OK; +eeprom_status_t get_data(eeprom_directory_t *directory, const uint16_t *ids, + uint8_t **out, uint16_t *out_size) { + uint8_t id_count = get_id_count(ids); + *out_size = BLOCK_SIZE * id_count; + + // Free existing buffer if provided + if (*out) { + free(*out); + *out = NULL; + } + + // Allocate new buffer + *out = malloc(*out_size); + if (*out == NULL) { + return EEPROM_ERROR_ALLOCATION; + } + + for (int i = 0; i < id_count; i++) { + uint16_t id = ids[i]; + if (!is_allocated(directory, id)) { + free(*out); + *out = NULL; + return EEPROM_ERROR_NOT_FOUND; + } + + uint16_t addr = get_addr_for_data(id); + uint8_t *data_ptr = *out + BLOCK_SIZE * i; + eeprom_status_t res; + + res = m24c32_read(directory->device, addr, data_ptr, BLOCK_SIZE); + if (res != EEPROM_OK) { + free(*out); + *out = NULL; + return res; + } + } + return EEPROM_OK; } -eeprom_status_t put_data(eeprom_directory_t *directory, - const uint16_t *ids, uint8_t *value, - uint16_t value_size) -{ - uint8_t id_count = get_id_count(ids); - uint8_t *block_buffer = malloc(BLOCK_SIZE); - if (block_buffer == NULL) { - return EEPROM_ERROR_ALLOCATION; - } - - for (int i = 0; i < id_count; i++) { - uint16_t id = ids[i]; - uint16_t addr = get_addr_for_data(id); - - // Calculate how many bytes to copy for this block - uint16_t offset = i * BLOCK_SIZE; - uint16_t bytes_to_copy = BLOCK_SIZE; - if (offset + BLOCK_SIZE > value_size) { - bytes_to_copy = value_size - offset; - } - - // Clear the block buffer - memset(block_buffer, 0, BLOCK_SIZE); - - // Copy the actual data - if (bytes_to_copy > 0) { - memcpy(block_buffer, value + offset, bytes_to_copy); - } - - // Write the entire block (BLOCK_SIZE bytes) to EEPROM - eeprom_status_t res = m24c32_write(directory->device, addr, - block_buffer, BLOCK_SIZE); - if (res != EEPROM_OK) { - free(block_buffer); - return res; - } - } - - free(block_buffer); - return EEPROM_OK; +eeprom_status_t put_data(eeprom_directory_t *directory, const uint16_t *ids, + uint8_t *value, uint16_t value_size) { + uint8_t id_count = get_id_count(ids); + uint8_t *block_buffer = malloc(BLOCK_SIZE); + if (block_buffer == NULL) { + return EEPROM_ERROR_ALLOCATION; + } + + for (int i = 0; i < id_count; i++) { + uint16_t id = ids[i]; + uint16_t addr = get_addr_for_data(id); + + // Calculate how many bytes to copy for this block + uint16_t offset = i * BLOCK_SIZE; + uint16_t bytes_to_copy = BLOCK_SIZE; + if (offset + BLOCK_SIZE > value_size) { + bytes_to_copy = value_size - offset; + } + + // Clear the block buffer + memset(block_buffer, 0, BLOCK_SIZE); + + // Copy the actual data + if (bytes_to_copy > 0) { + memcpy(block_buffer, value + offset, bytes_to_copy); + } + + // Write the entire block (BLOCK_SIZE bytes) to EEPROM + eeprom_status_t res = + m24c32_write(directory->device, addr, block_buffer, BLOCK_SIZE); + if (res != EEPROM_OK) { + free(block_buffer); + return res; + } + } + + free(block_buffer); + return EEPROM_OK; } -eeprom_status_t delete_data(eeprom_directory_t *directory, uint16_t *ids) -{ - uint8_t id_count = get_id_count(ids); +eeprom_status_t delete_data(eeprom_directory_t *directory, uint16_t *ids) { + uint8_t id_count = get_id_count(ids); - free_block(directory, ids, id_count); - return EEPROM_OK; + free_block(directory, ids, id_count); + return EEPROM_OK; } From 78ddf1cfc2916a345aa98abefcee5a13bee3a2f9 Mon Sep 17 00:00:00 2001 From: sogo Date: Sat, 3 Jan 2026 10:05:20 -0500 Subject: [PATCH 7/7] format by clang-format --- middleware/include/eeprom_directory.h | 10 +- middleware/include/eeprom_directory_struct.h | 13 +- middleware/include/eeprom_status.h | 19 +- middleware/include/eeprom_storage.h | 4 +- middleware/src/eeprom_alloc.c | 139 +++++---- middleware/src/eeprom_directory.c | 311 ++++++++++--------- middleware/src/eeprom_storage.c | 243 ++++++++------- 7 files changed, 382 insertions(+), 357 deletions(-) diff --git a/middleware/include/eeprom_directory.h b/middleware/include/eeprom_directory.h index 61914426..f81f545c 100644 --- a/middleware/include/eeprom_directory.h +++ b/middleware/include/eeprom_directory.h @@ -66,8 +66,8 @@ eeprom_status_t directory_init(m24c32_t *device, eeprom_directory_t *directory); * @retval EEPROM_ERROR_ALLOCATION If memory allocation fails. */ eeprom_status_t get_directory_value(eeprom_directory_t *directory, - const uint8_t *key, uint8_t **out, - uint16_t *out_size); + const uint8_t *key, uint8_t **out, + uint16_t *out_size); /** * @brief Store a value in the directory with the specified key. @@ -91,8 +91,8 @@ eeprom_status_t get_directory_value(eeprom_directory_t *directory, * @retval EEPROM_ERROR_ALLOCATION If block allocation fails. */ eeprom_status_t set_directory_value(eeprom_directory_t *directory, - const uint8_t *key, uint8_t *value, - const uint16_t value_size); + const uint8_t *key, uint8_t *value, + const uint16_t value_size); /** * @brief Delete a value from the directory by key. @@ -110,6 +110,6 @@ eeprom_status_t set_directory_value(eeprom_directory_t *directory, * @retval EEPROM_ERROR_NOT_FOUND If the key does not exist in the directory. */ eeprom_status_t delete_directory_value(eeprom_directory_t *directory, - const uint8_t *key); + const uint8_t *key); #endif // EEPROM_DIRECTORY_H \ No newline at end of file diff --git a/middleware/include/eeprom_directory_struct.h b/middleware/include/eeprom_directory_struct.h index 37fe633a..2120360f 100644 --- a/middleware/include/eeprom_directory_struct.h +++ b/middleware/include/eeprom_directory_struct.h @@ -89,9 +89,8 @@ * to a BLOCK_SIZE-byte data block in the EEPROM data space. */ typedef struct { - uint8_t key[4]; /** 4-byte key (not null-terminated). */ - uint16_t - ids[4]; /** Array of up to 4 block IDs (BLOCK_COUNT indicates end). */ + uint8_t key[4]; /** 4-byte key (not null-terminated). */ + uint16_t ids[4]; /** Array of up to 4 block IDs (BLOCK_COUNT indicates end). */ } directory_key_map_t; /** @@ -101,11 +100,11 @@ typedef struct { * including the device interface, allocation table, and key map. */ typedef struct { - m24c32_t *device; /** Pointer to the M24C32 device interface. */ - uint8_t alloc_table[ALLOC_TABLE_SIZE]; /** Bit-vector allocation table (one + m24c32_t *device; /** Pointer to the M24C32 device interface. */ + uint8_t alloc_table[ALLOC_TABLE_SIZE]; /** Bit-vector allocation table (one bit per block). */ - directory_key_map_t - key_map[KEY_MAP_COUNT]; /** Array of key-value mappings. */ + directory_key_map_t + key_map[KEY_MAP_COUNT]; /** Array of key-value mappings. */ } eeprom_directory_t; #endif \ No newline at end of file diff --git a/middleware/include/eeprom_status.h b/middleware/include/eeprom_status.h index e9dad29b..8e396e85 100644 --- a/middleware/include/eeprom_status.h +++ b/middleware/include/eeprom_status.h @@ -11,16 +11,15 @@ #define EEPROM_STATUS typedef enum { - EEPROM_OK = 0, - EEPROM_ERROR = -1, - EEPROM_ERROR_NOT_FOUND = -2, - EEPROM_ERROR_OUT_OF_BOUNDS = -3, - EEPROM_ERROR_ALIGNMENT = -4, - EEPROM_ERROR_NULL_POINTER = -5, - EEPROM_ERROR_ALLOCATION = -6, - EEPROM_ERROR_COMMS = -7, - EEPROM_ERROR_TOO_BIG = -8 - + EEPROM_OK = 0, + EEPROM_ERROR = -1, + EEPROM_ERROR_NOT_FOUND = -2, + EEPROM_ERROR_OUT_OF_BOUNDS = -3, + EEPROM_ERROR_ALIGNMENT = -4, + EEPROM_ERROR_NULL_POINTER = -5, + EEPROM_ERROR_ALLOCATION = -6, + EEPROM_ERROR_COMMS = -7, + EEPROM_ERROR_TOO_BIG = -8 } eeprom_status_t; #endif \ No newline at end of file diff --git a/middleware/include/eeprom_storage.h b/middleware/include/eeprom_storage.h index c54537cb..4a8bb513 100644 --- a/middleware/include/eeprom_storage.h +++ b/middleware/include/eeprom_storage.h @@ -54,7 +54,7 @@ eeprom_status_t init_storage(eeprom_directory_t *directory); * @retval EEPROM_ERROR If EEPROM read operation fails. */ eeprom_status_t get_data(eeprom_directory_t *directory, const uint16_t *ids, - uint8_t **out, uint16_t *out_size); + uint8_t **out, uint16_t *out_size); /** * @brief Store data in EEPROM using block IDs. @@ -75,7 +75,7 @@ eeprom_status_t get_data(eeprom_directory_t *directory, const uint16_t *ids, * @retval EEPROM_ERROR If EEPROM write operation fails. */ eeprom_status_t put_data(eeprom_directory_t *directory, const uint16_t *ids, - uint8_t *value, uint16_t value_size); + uint8_t *value, uint16_t value_size); /** * @brief Delete data blocks from EEPROM. diff --git a/middleware/src/eeprom_alloc.c b/middleware/src/eeprom_alloc.c index 2804aa6c..4aa8b2c5 100644 --- a/middleware/src/eeprom_alloc.c +++ b/middleware/src/eeprom_alloc.c @@ -1,88 +1,97 @@ #include "eeprom_alloc.h" -#define byte_index(n) ((n) / 8) -#define bit_index(n) ((n) % 8) +#define byte_index(n) ((n) / 8) +#define bit_index(n) ((n) % 8) #define nth_bit_mask(n) (1 << (n)) -static int get_alloc_table(uint8_t *table, uint16_t id) { - return (table[byte_index(id)] >> bit_index(id)) & 1; +static int get_alloc_table(uint8_t *table, uint16_t id) +{ + return (table[byte_index(id)] >> bit_index(id)) & 1; } -static void put_alloc_table(uint8_t *table, uint16_t id, uint8_t val) { - uint8_t bit_mask = nth_bit_mask(bit_index(id)); +static void put_alloc_table(uint8_t *table, uint16_t id, uint8_t val) +{ + uint8_t bit_mask = nth_bit_mask(bit_index(id)); - if (val) { - table[byte_index(id)] |= bit_mask; - } else { - bit_mask = ~bit_mask; - table[byte_index(id)] &= bit_mask; - } + if (val) { + table[byte_index(id)] |= bit_mask; + } else { + bit_mask = ~bit_mask; + table[byte_index(id)] &= bit_mask; + } } static eeprom_status_t update_eeprom_alloc_table(eeprom_directory_t *directory, - uint16_t id) { - uint16_t data_index = byte_index(id); - m24c32_t *device = directory->device; - uint16_t addr = ALLOC_TABLE_BEGIN + data_index; - uint8_t *data = directory->alloc_table + data_index; - - return m24c32_write(device, addr, data, 1); + uint16_t id) +{ + uint16_t data_index = byte_index(id); + m24c32_t *device = directory->device; + uint16_t addr = ALLOC_TABLE_BEGIN + data_index; + uint8_t *data = directory->alloc_table + data_index; + + return m24c32_write(device, addr, data, 1); } -eeprom_status_t init_alloc_table(eeprom_directory_t *directory) { - m24c32_t *device = directory->device; +eeprom_status_t init_alloc_table(eeprom_directory_t *directory) +{ + m24c32_t *device = directory->device; - return m24c32_read(device, ALLOC_TABLE_BEGIN, directory->alloc_table, - ALLOC_TABLE_SIZE); + return m24c32_read(device, ALLOC_TABLE_BEGIN, directory->alloc_table, + ALLOC_TABLE_SIZE); } -void print_alloc_table(eeprom_directory_t *directory) { - uint8_t *alloc_table = directory->alloc_table; - for (int id = 0; id < BLOCK_COUNT; id++) { - putchar(get_alloc_table(alloc_table, id) ? '1' : '0'); - - if ((id + 1) % 64 == 0) { - putchar('\n'); - } else if ((id + 1) % 8 == 0) { - putchar(' '); - } - } - putchar('\n'); +void print_alloc_table(eeprom_directory_t *directory) +{ + uint8_t *alloc_table = directory->alloc_table; + for (int id = 0; id < BLOCK_COUNT; id++) { + putchar(get_alloc_table(alloc_table, id) ? '1' : '0'); + + if ((id + 1) % 64 == 0) { + putchar('\n'); + } else if ((id + 1) % 8 == 0) { + putchar(' '); + } + } + putchar('\n'); } -uint16_t alloc_block(eeprom_directory_t *directory) { - uint8_t *alloc_table = directory->alloc_table; - - for (uint16_t id = 0; id < BLOCK_COUNT; id++) { - if (get_alloc_table(alloc_table, id) == 0) { - put_alloc_table(alloc_table, id, 1); - eeprom_status_t ret = update_eeprom_alloc_table(directory, id); - if (ret != EEPROM_OK) { - printf("ERROR: failed to update eeprom alloc table.\n"); - put_alloc_table(alloc_table, id, 0); - return BLOCK_COUNT; - } - return id; - } - } - return BLOCK_COUNT; +uint16_t alloc_block(eeprom_directory_t *directory) +{ + uint8_t *alloc_table = directory->alloc_table; + + for (uint16_t id = 0; id < BLOCK_COUNT; id++) { + if (get_alloc_table(alloc_table, id) == 0) { + put_alloc_table(alloc_table, id, 1); + eeprom_status_t ret = + update_eeprom_alloc_table(directory, id); + if (ret != EEPROM_OK) { + printf("ERROR: failed to update eeprom alloc table.\n"); + put_alloc_table(alloc_table, id, 0); + return BLOCK_COUNT; + } + return id; + } + } + return BLOCK_COUNT; } -void free_block(eeprom_directory_t *directory, uint16_t *ids, uint8_t size) { - uint8_t *alloc_table = directory->alloc_table; - - for (int i = 0; i < size; i++) { - uint16_t id = ids[i]; - put_alloc_table(alloc_table, id, 0); - eeprom_status_t ret = update_eeprom_alloc_table(directory, id); - if (ret != EEPROM_OK) { - printf("ERROR: failed to update eeprom allo table.\n"); - } - } +void free_block(eeprom_directory_t *directory, uint16_t *ids, uint8_t size) +{ + uint8_t *alloc_table = directory->alloc_table; + + for (int i = 0; i < size; i++) { + uint16_t id = ids[i]; + put_alloc_table(alloc_table, id, 0); + eeprom_status_t ret = update_eeprom_alloc_table(directory, id); + if (ret != EEPROM_OK) { + printf("ERROR: failed to update eeprom allo table.\n"); + } + } } -int is_allocated(eeprom_directory_t *directory, uint16_t id) { - uint8_t *alloc_table = directory->alloc_table; +int is_allocated(eeprom_directory_t *directory, uint16_t id) +{ + uint8_t *alloc_table = directory->alloc_table; - return get_alloc_table(alloc_table, id); + return get_alloc_table(alloc_table, id); } diff --git a/middleware/src/eeprom_directory.c b/middleware/src/eeprom_directory.c index b2c02acd..87ca270f 100644 --- a/middleware/src/eeprom_directory.c +++ b/middleware/src/eeprom_directory.c @@ -1,171 +1,180 @@ #include "eeprom_directory.h" -static uint16_t *get_ids(eeprom_directory_t *directory, const uint8_t *key) { - directory_key_map_t *key_map = directory->key_map; - - for (int i = 0; i < KEY_MAP_COUNT; i++) { - // Keys are fixed 4-byte arrays, not null-terminated strings - if (memcmp(key_map[i].key, key, 4) == 0) { - return key_map[i].ids; - } - } - return NULL; +static uint16_t *get_ids(eeprom_directory_t *directory, const uint8_t *key) +{ + directory_key_map_t *key_map = directory->key_map; + + for (int i = 0; i < KEY_MAP_COUNT; i++) { + // Keys are fixed 4-byte arrays, not null-terminated strings + if (memcmp(key_map[i].key, key, 4) == 0) { + return key_map[i].ids; + } + } + return NULL; } static eeprom_status_t set_key(eeprom_directory_t *directory, - const uint8_t *key, uint16_t *ids) { - m24c32_t *device = directory->device; - directory_key_map_t *key_map = directory->key_map; - - for (int i = 0; i < KEY_MAP_COUNT; i++) { - if ((char)key_map[i].key[0] == '\0') { - memcpy(key_map[i].key, key, 4); - memcpy(key_map[i].ids, ids, 8); - - uint16_t addr = KEY_MAP_BEGIN + i * KEY_MAP_STRUCT_SIZE; - return m24c32_write(device, addr, (uint8_t *)&key_map[i], - KEY_MAP_STRUCT_SIZE); - } - } - return EEPROM_ERROR_ALLOCATION; + const uint8_t *key, uint16_t *ids) +{ + m24c32_t *device = directory->device; + directory_key_map_t *key_map = directory->key_map; + + for (int i = 0; i < KEY_MAP_COUNT; i++) { + if ((char)key_map[i].key[0] == '\0') { + memcpy(key_map[i].key, key, 4); + memcpy(key_map[i].ids, ids, 8); + + uint16_t addr = KEY_MAP_BEGIN + i * KEY_MAP_STRUCT_SIZE; + return m24c32_write(device, addr, + (uint8_t *)&key_map[i], + KEY_MAP_STRUCT_SIZE); + } + } + return EEPROM_ERROR_ALLOCATION; } static eeprom_status_t delete_key(eeprom_directory_t *directory, - const uint8_t *key) { - m24c32_t *device = directory->device; - directory_key_map_t *key_map = directory->key_map; - - for (int i = 0; i < KEY_MAP_COUNT; i++) { - // Keys are fixed 4-byte arrays, not null-terminated strings - if (memcmp(key_map[i].key, key, 4) == 0) { - memset(&key_map[i], 0, KEY_MAP_STRUCT_SIZE); - - uint16_t addr = KEY_MAP_BEGIN + i * KEY_MAP_STRUCT_SIZE; - return m24c32_write(device, addr, (uint8_t *)&key_map[i], - KEY_MAP_STRUCT_SIZE); - } - } - return EEPROM_ERROR_NOT_FOUND; + const uint8_t *key) +{ + m24c32_t *device = directory->device; + directory_key_map_t *key_map = directory->key_map; + + for (int i = 0; i < KEY_MAP_COUNT; i++) { + // Keys are fixed 4-byte arrays, not null-terminated strings + if (memcmp(key_map[i].key, key, 4) == 0) { + memset(&key_map[i], 0, KEY_MAP_STRUCT_SIZE); + + uint16_t addr = KEY_MAP_BEGIN + i * KEY_MAP_STRUCT_SIZE; + return m24c32_write(device, addr, + (uint8_t *)&key_map[i], + KEY_MAP_STRUCT_SIZE); + } + } + return EEPROM_ERROR_NOT_FOUND; } -eeprom_status_t directory_init(m24c32_t *device, - eeprom_directory_t *directory) { - if (directory == NULL || device == NULL) { - return EEPROM_ERROR_NULL_POINTER; - } - - directory->device = device; - eeprom_status_t res; - res = init_alloc_table(directory); - if (res != EEPROM_OK) { - return res; - } - res = init_storage(directory); - if (res != EEPROM_OK) { - return res; - } - return EEPROM_OK; +eeprom_status_t directory_init(m24c32_t *device, eeprom_directory_t *directory) +{ + if (directory == NULL || device == NULL) { + return EEPROM_ERROR_NULL_POINTER; + } + + directory->device = device; + eeprom_status_t res; + res = init_alloc_table(directory); + if (res != EEPROM_OK) { + return res; + } + res = init_storage(directory); + if (res != EEPROM_OK) { + return res; + } + return EEPROM_OK; } eeprom_status_t get_directory_value(eeprom_directory_t *directory, - const uint8_t *key, uint8_t **out, - uint16_t *out_size) { - if (directory == NULL || key == NULL || out == NULL || out_size == NULL) { - return EEPROM_ERROR_NULL_POINTER; - } - - uint16_t *ids = get_ids(directory, key); - if (ids == NULL) { - return EEPROM_ERROR_NOT_FOUND; - } - - return get_data(directory, ids, out, out_size); + const uint8_t *key, uint8_t **out, + uint16_t *out_size) +{ + if (directory == NULL || key == NULL || out == NULL || + out_size == NULL) { + return EEPROM_ERROR_NULL_POINTER; + } + + uint16_t *ids = get_ids(directory, key); + if (ids == NULL) { + return EEPROM_ERROR_NOT_FOUND; + } + + return get_data(directory, ids, out, out_size); } eeprom_status_t set_directory_value(eeprom_directory_t *directory, - const uint8_t *key, uint8_t *value, - const uint16_t value_size) { - if (directory == NULL || value == NULL) { - return EEPROM_ERROR_NULL_POINTER; - } - if (value_size <= 0) { - return EEPROM_ERROR; - } - - uint16_t *existing_ids = get_ids(directory, key); - - // If key already exists, delete it first - if (existing_ids != NULL) { - eeprom_status_t res = delete_directory_value(directory, key); - if (res != EEPROM_OK) { - return res; - } - } - - // Allocate new blocks for the value - int block_count = (value_size - 1) / BLOCK_SIZE + 1; - if (block_count > 4) { - return EEPROM_ERROR_TOO_BIG; - } - - uint16_t *ids = malloc(sizeof(uint16_t) * 4); - if (ids == NULL) { - return EEPROM_ERROR_ALLOCATION; - } - - for (int block_idx = 0; block_idx < block_count; block_idx++) { - uint16_t id = alloc_block(directory); - if (id == BLOCK_COUNT) { - // Free already allocated blocks on failure - for (int j = 0; j < block_idx; j++) { - free_block(directory, &ids[j], 1); - } - free(ids); - return EEPROM_ERROR_ALLOCATION; - } - ids[block_idx] = id; - } - for (int block_idx = block_count; block_idx < 4; block_idx++) { - ids[block_idx] = BLOCK_COUNT; - } - - eeprom_status_t res; - res = set_key(directory, key, ids); - if (res != EEPROM_OK) { - // Free allocated blocks on failure - free_block(directory, ids, block_count); - free(ids); - return res; - } - - res = put_data(directory, ids, value, value_size); - if (res != EEPROM_OK) { - // Free allocated blocks and remove key on failure - free_block(directory, ids, block_count); - delete_key(directory, key); - free(ids); - return res; - } - - free(ids); - return EEPROM_OK; + const uint8_t *key, uint8_t *value, + const uint16_t value_size) +{ + if (directory == NULL || value == NULL) { + return EEPROM_ERROR_NULL_POINTER; + } + if (value_size <= 0) { + return EEPROM_ERROR; + } + + uint16_t *existing_ids = get_ids(directory, key); + + // If key already exists, delete it first + if (existing_ids != NULL) { + eeprom_status_t res = delete_directory_value(directory, key); + if (res != EEPROM_OK) { + return res; + } + } + + // Allocate new blocks for the value + int block_count = (value_size - 1) / BLOCK_SIZE + 1; + if (block_count > 4) { + return EEPROM_ERROR_TOO_BIG; + } + + uint16_t *ids = malloc(sizeof(uint16_t) * 4); + if (ids == NULL) { + return EEPROM_ERROR_ALLOCATION; + } + + for (int block_idx = 0; block_idx < block_count; block_idx++) { + uint16_t id = alloc_block(directory); + if (id == BLOCK_COUNT) { + // Free already allocated blocks on failure + for (int j = 0; j < block_idx; j++) { + free_block(directory, &ids[j], 1); + } + free(ids); + return EEPROM_ERROR_ALLOCATION; + } + ids[block_idx] = id; + } + for (int block_idx = block_count; block_idx < 4; block_idx++) { + ids[block_idx] = BLOCK_COUNT; + } + + eeprom_status_t res; + res = set_key(directory, key, ids); + if (res != EEPROM_OK) { + // Free allocated blocks on failure + free_block(directory, ids, block_count); + free(ids); + return res; + } + + res = put_data(directory, ids, value, value_size); + if (res != EEPROM_OK) { + // Free allocated blocks and remove key on failure + free_block(directory, ids, block_count); + delete_key(directory, key); + free(ids); + return res; + } + + free(ids); + return EEPROM_OK; } eeprom_status_t delete_directory_value(eeprom_directory_t *directory, - const uint8_t *key) { - if (directory == NULL || key == NULL) { - return EEPROM_ERROR_NULL_POINTER; - } - - uint16_t *ids = get_ids(directory, key); - if (ids == NULL) { - return EEPROM_ERROR_NOT_FOUND; - } - - eeprom_status_t res; - res = delete_data(directory, ids); - if (res != EEPROM_OK) { - return res; - } - return delete_key(directory, key); + const uint8_t *key) +{ + if (directory == NULL || key == NULL) { + return EEPROM_ERROR_NULL_POINTER; + } + + uint16_t *ids = get_ids(directory, key); + if (ids == NULL) { + return EEPROM_ERROR_NOT_FOUND; + } + + eeprom_status_t res; + res = delete_data(directory, ids); + if (res != EEPROM_OK) { + return res; + } + return delete_key(directory, key); } diff --git a/middleware/src/eeprom_storage.c b/middleware/src/eeprom_storage.c index cfd70ba8..bc56ce87 100644 --- a/middleware/src/eeprom_storage.c +++ b/middleware/src/eeprom_storage.c @@ -1,134 +1,143 @@ #include "eeprom_storage.h" #include -static uint8_t get_id_count(const uint16_t *ids) { - uint8_t count = 0; - - for (int i = 0; i < 4; i++) { - if (ids[i] >= BLOCK_COUNT) { - break; - } - count++; - } - return count; +static uint8_t get_id_count(const uint16_t *ids) +{ + uint8_t count = 0; + + for (int i = 0; i < 4; i++) { + if (ids[i] >= BLOCK_COUNT) { + break; + } + count++; + } + return count; } -static uint16_t get_addr_for_data(const uint16_t id) { - return DATA_SPACE_BEGIN + id * BLOCK_SIZE; +static uint16_t get_addr_for_data(const uint16_t id) +{ + return DATA_SPACE_BEGIN + id * BLOCK_SIZE; } -eeprom_status_t init_storage(eeprom_directory_t *directory) { - m24c32_t *device = directory->device; - directory_key_map_t *key_map = directory->key_map; - uint8_t *data = malloc(KEY_MAP_SIZE); - if (data == NULL) { - return EEPROM_ERROR_ALLOCATION; - } - - eeprom_status_t res = m24c32_read(device, KEY_MAP_BEGIN, data, KEY_MAP_SIZE); - if (res != EEPROM_OK) { - free(data); - return res; - } - - for (int i = 0; i < KEY_MAP_COUNT; i++) { - uint8_t *entry = data + (i * KEY_MAP_STRUCT_SIZE); - - // key[4] - memcpy(key_map[i].key, entry, 4); - - // ids[4] - for (int j = 0; j < 4; j++) { - key_map[i].ids[j] = - (uint16_t)entry[4 + j * 2] | ((uint16_t)entry[4 + j * 2 + 1] << 8); - } - } - free(data); - return EEPROM_OK; +eeprom_status_t init_storage(eeprom_directory_t *directory) +{ + m24c32_t *device = directory->device; + directory_key_map_t *key_map = directory->key_map; + uint8_t *data = malloc(KEY_MAP_SIZE); + if (data == NULL) { + return EEPROM_ERROR_ALLOCATION; + } + + eeprom_status_t res = + m24c32_read(device, KEY_MAP_BEGIN, data, KEY_MAP_SIZE); + if (res != EEPROM_OK) { + free(data); + return res; + } + + for (int i = 0; i < KEY_MAP_COUNT; i++) { + uint8_t *entry = data + (i * KEY_MAP_STRUCT_SIZE); + + // key[4] + memcpy(key_map[i].key, entry, 4); + + // ids[4] + for (int j = 0; j < 4; j++) { + key_map[i].ids[j] = + (uint16_t)entry[4 + j * 2] | + ((uint16_t)entry[4 + j * 2 + 1] << 8); + } + } + free(data); + return EEPROM_OK; } eeprom_status_t get_data(eeprom_directory_t *directory, const uint16_t *ids, - uint8_t **out, uint16_t *out_size) { - uint8_t id_count = get_id_count(ids); - *out_size = BLOCK_SIZE * id_count; - - // Free existing buffer if provided - if (*out) { - free(*out); - *out = NULL; - } - - // Allocate new buffer - *out = malloc(*out_size); - if (*out == NULL) { - return EEPROM_ERROR_ALLOCATION; - } - - for (int i = 0; i < id_count; i++) { - uint16_t id = ids[i]; - if (!is_allocated(directory, id)) { - free(*out); - *out = NULL; - return EEPROM_ERROR_NOT_FOUND; - } - - uint16_t addr = get_addr_for_data(id); - uint8_t *data_ptr = *out + BLOCK_SIZE * i; - eeprom_status_t res; - - res = m24c32_read(directory->device, addr, data_ptr, BLOCK_SIZE); - if (res != EEPROM_OK) { - free(*out); - *out = NULL; - return res; - } - } - return EEPROM_OK; + uint8_t **out, uint16_t *out_size) +{ + uint8_t id_count = get_id_count(ids); + *out_size = BLOCK_SIZE * id_count; + + // Free existing buffer if provided + if (*out) { + free(*out); + *out = NULL; + } + + // Allocate new buffer + *out = malloc(*out_size); + if (*out == NULL) { + return EEPROM_ERROR_ALLOCATION; + } + + for (int i = 0; i < id_count; i++) { + uint16_t id = ids[i]; + if (!is_allocated(directory, id)) { + free(*out); + *out = NULL; + return EEPROM_ERROR_NOT_FOUND; + } + + uint16_t addr = get_addr_for_data(id); + uint8_t *data_ptr = *out + BLOCK_SIZE * i; + eeprom_status_t res; + + res = m24c32_read(directory->device, addr, data_ptr, + BLOCK_SIZE); + if (res != EEPROM_OK) { + free(*out); + *out = NULL; + return res; + } + } + return EEPROM_OK; } eeprom_status_t put_data(eeprom_directory_t *directory, const uint16_t *ids, - uint8_t *value, uint16_t value_size) { - uint8_t id_count = get_id_count(ids); - uint8_t *block_buffer = malloc(BLOCK_SIZE); - if (block_buffer == NULL) { - return EEPROM_ERROR_ALLOCATION; - } - - for (int i = 0; i < id_count; i++) { - uint16_t id = ids[i]; - uint16_t addr = get_addr_for_data(id); - - // Calculate how many bytes to copy for this block - uint16_t offset = i * BLOCK_SIZE; - uint16_t bytes_to_copy = BLOCK_SIZE; - if (offset + BLOCK_SIZE > value_size) { - bytes_to_copy = value_size - offset; - } - - // Clear the block buffer - memset(block_buffer, 0, BLOCK_SIZE); - - // Copy the actual data - if (bytes_to_copy > 0) { - memcpy(block_buffer, value + offset, bytes_to_copy); - } - - // Write the entire block (BLOCK_SIZE bytes) to EEPROM - eeprom_status_t res = - m24c32_write(directory->device, addr, block_buffer, BLOCK_SIZE); - if (res != EEPROM_OK) { - free(block_buffer); - return res; - } - } - - free(block_buffer); - return EEPROM_OK; + uint8_t *value, uint16_t value_size) +{ + uint8_t id_count = get_id_count(ids); + uint8_t *block_buffer = malloc(BLOCK_SIZE); + if (block_buffer == NULL) { + return EEPROM_ERROR_ALLOCATION; + } + + for (int i = 0; i < id_count; i++) { + uint16_t id = ids[i]; + uint16_t addr = get_addr_for_data(id); + + // Calculate how many bytes to copy for this block + uint16_t offset = i * BLOCK_SIZE; + uint16_t bytes_to_copy = BLOCK_SIZE; + if (offset + BLOCK_SIZE > value_size) { + bytes_to_copy = value_size - offset; + } + + // Clear the block buffer + memset(block_buffer, 0, BLOCK_SIZE); + + // Copy the actual data + if (bytes_to_copy > 0) { + memcpy(block_buffer, value + offset, bytes_to_copy); + } + + // Write the entire block (BLOCK_SIZE bytes) to EEPROM + eeprom_status_t res = m24c32_write(directory->device, addr, + block_buffer, BLOCK_SIZE); + if (res != EEPROM_OK) { + free(block_buffer); + return res; + } + } + + free(block_buffer); + return EEPROM_OK; } -eeprom_status_t delete_data(eeprom_directory_t *directory, uint16_t *ids) { - uint8_t id_count = get_id_count(ids); +eeprom_status_t delete_data(eeprom_directory_t *directory, uint16_t *ids) +{ + uint8_t id_count = get_id_count(ids); - free_block(directory, ids, id_count); - return EEPROM_OK; + free_block(directory, ids, id_count); + return EEPROM_OK; }