Skip to content

Commit d154fa3

Browse files
committed
re-implement eeprom directory
1 parent 8772f98 commit d154fa3

File tree

10 files changed

+729
-214
lines changed

10 files changed

+729
-214
lines changed

middleware/include/eeprom_alloc.h

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/**
2+
* @file eeprom_alloc.h
3+
* @author Sogo Nishihara (sogonishi@gmail.com)
4+
* @brief EEPROM Block Allocation Management
5+
* @version 0.1
6+
* @date 2026-01-02
7+
*
8+
* This file provides functions for managing data block allocation in the EEPROM.
9+
* It maintains a bit-vector allocation table to track which blocks are in use.
10+
*
11+
*/
12+
13+
#ifndef EEPROM_ALLOC_H
14+
#define EEPROM_ALLOC_H
15+
16+
#include <stdio.h>
17+
18+
#include "eeprom_directory_struct.h"
19+
20+
/**
21+
* @brief Initialize allocation table by loading it from EEPROM memory.
22+
*
23+
* This function reads the allocation table from EEPROM and populates the directory's
24+
* alloc_table structure in memory.
25+
*
26+
* @param directory Pointer to the initialized directory structure.
27+
*
28+
* @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure.
29+
*
30+
* @retval EEPROM_ERROR If EEPROM read operation fails.
31+
*/
32+
eeprom_status_t init_alloc_table(eeprom_directory_t *directory);
33+
34+
/**
35+
* @brief Print the allocation table in a human-readable format.
36+
*
37+
* This function prints the allocation table showing which blocks are allocated (1)
38+
* and which are free (0). The output is formatted with 8 bits per group and
39+
* 64 bits per line.
40+
*
41+
* @param directory Pointer to the initialized directory structure.
42+
*/
43+
void print_alloc_table(eeprom_directory_t *directory);
44+
45+
/**
46+
* @brief Allocate a single block from the EEPROM.
47+
*
48+
* This function finds the first free block in the allocation table, marks it as
49+
* allocated in both local memory and EEPROM, and returns its ID.
50+
*
51+
* @param directory Pointer to the initialized directory structure.
52+
*
53+
* @return uint16_t Returns the allocated block ID on success, or BLOCK_COUNT if allocation fails.
54+
*
55+
* @retval BLOCK_COUNT If no free blocks are available or EEPROM update fails.
56+
*/
57+
uint16_t alloc_block(eeprom_directory_t *directory);
58+
59+
/**
60+
* @brief Free one or more blocks in the EEPROM.
61+
*
62+
* This function marks the specified blocks as free in both local memory and EEPROM.
63+
* If a block is already freed, this function does nothing for that block.
64+
*
65+
* @param directory Pointer to the initialized directory structure.
66+
* @param ids Array of block IDs to free.
67+
* @param size Number of block IDs in the array.
68+
*/
69+
void free_block(eeprom_directory_t *directory, uint16_t *ids, uint8_t size);
70+
71+
/**
72+
* @brief Check if a block is allocated.
73+
*
74+
* This function checks the allocation table to determine if a specific block is
75+
* currently allocated or free.
76+
*
77+
* @param directory Pointer to the initialized directory structure.
78+
* @param id Block ID to check.
79+
*
80+
* @return int Returns 1 if the block is allocated, 0 if it is free.
81+
*/
82+
int is_allocated(eeprom_directory_t *directory, uint16_t id);
83+
84+
#endif
Lines changed: 91 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,118 @@
11
/**
22
* @file eeprom_directory.h
3-
* @brief EEPROM Directory Management
3+
* @author Sogo Nishihara (sogonishi@gmail.com)
4+
* @brief EEPROM Directory Management API
45
*
5-
* This file provides functions to initialize and manage an EEPROM directory with partitions.
6-
* Functions return `eeprom_status_t` error codes, which are defined in `eeprom_status.h`.
6+
* This file defines the public API for a simple key-value directory
7+
* stored on EEPROM device.
78
*
8-
*/
9+
* The directory provides block-based persistent storage, managing
10+
* allocation, lookup, insertion, and deletion of values associated
11+
* with fixed-size (4-byte) keys.
12+
*
13+
* All functions return eeprom_status_t error codes defined in
14+
* eeprom_status.h. */
915

1016
#ifndef EEPROM_DIRECTORY_H
1117
#define EEPROM_DIRECTORY_H
1218

13-
#include "eeprom_status.h"
14-
#include <stddef.h>
15-
#include <stdint.h>
16-
17-
struct partition_cfg {
18-
const char *id; /* The ID of the partition */
19-
uint16_t size; /* The size of the partition in bytes */
20-
uint16_t address;
21-
uint16_t head_address;
22-
};
19+
#include <stdlib.h>
20+
#include <stdio.h>
21+
#include <string.h>
2322

24-
typedef struct {
25-
struct partition_cfg *partitions;
26-
size_t num_partitions;
27-
} eeprom_directory_t;
23+
#include "m24c32.h"
24+
#include "eeprom_status.h"
25+
#include "eeprom_directory_struct.h"
26+
#include "eeprom_alloc.h"
27+
#include "eeprom_storage.h"
2828

2929
/**
30-
* @brief Initializes an EEPROM directory with partition IDs and sizes.
30+
* @brief Initialize the EEPROM directory structure.
3131
*
32-
* This function sets up partition configurations within the EEPROM memory.
33-
* The total allocated address space is calculated based on the provided partitions.
34-
*
35-
* @param directory Pointer to the EEPROM directory structure.
36-
* @param partitions Array of partition configurations, including IDs and sizes.
37-
* @param num_partitions Number of partitions to create.
38-
* @return eeprom_status_t Returns EEPROM_OK on success or an error code on failure.
32+
* This function initializes the directory structure with the provided device interface,
33+
* loads the allocation table and key map from EEPROM memory.
34+
*
35+
* @param device Pointer to the M24C32 device interface structure.
36+
* @param directory Pointer to the directory structure to initialize. Must be allocated by caller.
37+
*
38+
* @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure.
39+
*
40+
* @retval EEPROM_ERROR_NULL_POINTER If device or directory is NULL.
41+
* @retval EEPROM_ERROR If initialization of alloc table or storage fails.
3942
*/
40-
eeprom_status_t directory_init(eeprom_directory_t *directory,
41-
const struct partition_cfg partitions[],
42-
size_t num_partitions);
43+
eeprom_status_t directory_init(
44+
m24c32_t *device,
45+
eeprom_directory_t *directory
46+
);
4347

4448
/**
45-
* @brief Get the address of the beginning of a partition.
46-
*
47-
* This function searches for a partition by its name and returns its starting address.
49+
* @brief Retrieve a value from the directory by key.
50+
*
51+
* This function looks up a key in the directory and retrieves the associated data.
52+
* The output buffer is allocated by this function and must be freed by the caller.
4853
*
49-
* @param directory Pointer to the EEPROM directory structure.
50-
* @param key Name of the partition.
51-
* @param address Pointer to store the retrieved base address.
52-
* @return eeprom_status_t Returns EEPROM_OK on success or an error code if the partition is not found.
54+
* @param directory Pointer to the initialized directory structure.
55+
* @param key Pointer to a 4-byte key (not null-terminated).
56+
* @param out Pointer to a pointer that will receive the allocated output buffer.
57+
* The caller is responsible for freeing this buffer.
58+
* @param out_size Pointer to store the size of the output data in bytes.
59+
*
60+
* @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure.
61+
*
62+
* @retval EEPROM_ERROR_NULL_POINTER If directory, key, out, or out_size is NULL.
63+
* @retval EEPROM_ERROR_NOT_FOUND If the key does not exist in the directory.
64+
* @retval EEPROM_ERROR_ALLOCATION If memory allocation fails.
5365
*/
54-
eeprom_status_t eeprom_get_base_address(const eeprom_directory_t *directory,
55-
const char *key, uint16_t *address);
66+
eeprom_status_t get_directory_value(
67+
eeprom_directory_t *directory,
68+
const uint8_t *key,
69+
uint8_t **out,
70+
uint16_t *out_size
71+
);
5672

5773
/**
58-
* @brief Get the current read/write head of a partition.
59-
*
60-
* This function provides the address of the next location available for writing within the partition.
74+
* @brief Store a value in the directory with the specified key.
75+
*
76+
* This function stores data in the directory. If the key already exists, the old value
77+
* is deleted first. The data is stored in blocks of BLOCK_SIZE bytes, with remaining
78+
* bytes padded with zeros.
79+
*
80+
* @param directory Pointer to the initialized directory structure.
81+
* @param key Pointer to a 4-byte key (not null-terminated).
82+
* @param value Pointer to the data to store.
83+
* @param value_size Size of the data in bytes (maximum 16 bytes, i.e., 4 blocks).
6184
*
62-
* @param directory Pointer to EEPROM directory struct.
63-
* @param key Name of the partition.
64-
* @param address Pointer to store the retrieved head address.
65-
* @return eeprom_status_t Returns EEPROM_OK on success or an error code if the partition is not found.
85+
* @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure.
86+
*
87+
* @retval EEPROM_ERROR_NULL_POINTER If directory or value is NULL.
88+
* @retval EEPROM_ERROR If value_size is 0.
89+
* @retval EEPROM_ERROR_TOO_BIG If value_size exceeds 16 bytes (4 blocks).
90+
* @retval EEPROM_ERROR_ALLOCATION If block allocation fails.
6691
*/
67-
eeprom_status_t eeprom_get_head_address(const eeprom_directory_t *directory,
68-
const char *key, uint16_t *address);
92+
eeprom_status_t set_directory_value(
93+
eeprom_directory_t *directory,
94+
const uint8_t *key,
95+
uint8_t *value,
96+
const uint16_t value_size
97+
);
6998

7099
/**
71-
* @brief Get the size of a partition
72-
*
73-
* This function returns the allocated size of a specific partition in bytes.
100+
* @brief Delete a value from the directory by key.
101+
*
102+
* This function removes a key-value pair from the directory and frees the associated
103+
* blocks. The blocks are marked as available for reuse.
104+
*
105+
* @param directory Pointer to the initialized directory structure.
106+
* @param key Pointer to a 4-byte key (not null-terminated).
107+
*
108+
* @return eeprom_status_t Returns EEPROM_OK on success, or an error code on failure.
74109
*
75-
* @param directory Pointer to EEPROM directory struct.
76-
* @param key Name of a partition.
77-
* @param size Pointer to store the partition size.
78-
* @return eeprom_status_t Returns EEPROM_OK on success or an error code if the partition is not found.
110+
* @retval EEPROM_ERROR_NULL_POINTER If directory or key is NULL.
111+
* @retval EEPROM_ERROR_NOT_FOUND If the key does not exist in the directory.
79112
*/
80-
eeprom_status_t eeprom_get_size(const eeprom_directory_t *directory,
81-
const char *key, uint16_t *size);
113+
eeprom_status_t delete_directory_value(
114+
eeprom_directory_t *directory,
115+
const uint8_t *key
116+
);
82117

83118
#endif // EEPROM_DIRECTORY_H
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/**
2+
* @file eeprom_directory_struct.h
3+
* @author Sogo Nishihara (sogonishi@gmail.com)
4+
* @brief EEPROM Directory Data Structures and Constants
5+
* @version 0.1
6+
* @date 2026-01-02
7+
*
8+
* This file defines the data structures and constants used for the EEPROM directory system.
9+
* It includes memory layout definitions, block allocation parameters, and structure definitions.
10+
*
11+
* EEPROM Memory Layout (Total: 4096 bytes)
12+
*
13+
* Address
14+
* 0x0000
15+
* +--------------------------------------------------+
16+
* | Allocation Table |
17+
* | - Bit map (1 bit per data block) |
18+
* | - Size : ALLOC_TABLE_SIZE bytes |
19+
* | - Blocks : BLOCK_COUNT |
20+
* +--------------------------------------------------+
21+
* | Key Map Table |
22+
* | - Array of directory_key_map_t |
23+
* | - Entry size : KEY_MAP_STRUCT_SIZE bytes |
24+
* | - Entry count: KEY_MAP_COUNT |
25+
* | - Total size : KEY_MAP_SIZE bytes |
26+
* +--------------------------------------------------+
27+
* | Data Space |
28+
* | - Data blocks |
29+
* | - Block size : BLOCK_SIZE bytes |
30+
* | - Block count: BLOCK_COUNT |
31+
* | |
32+
* | +------------------+ |
33+
* | | Block 0 | |
34+
* | +------------------+ |
35+
* | | Block 1 | |
36+
* | +------------------+ |
37+
* | | ... | |
38+
* | +------------------+ |
39+
* | | Block N | |
40+
* | +------------------+ |
41+
* +--------------------------------------------------+
42+
* 0x0FFF
43+
*/
44+
45+
#ifndef EEPROM_DIRECTORY_STRUCT
46+
#define EEPROM_DIRECTORY_STRUCT
47+
48+
/** @brief Size of a single key-map entry structure in bytes (4-byte key + 8-byte IDs array). */
49+
#define KEY_MAP_STRUCT_SIZE 12
50+
51+
/** @brief Maximum number of key-value pairs that can be stored in the directory. */
52+
#define KEY_MAP_COUNT 128
53+
54+
/** @brief Size of a data block in bytes. */
55+
#define BLOCK_SIZE 4
56+
57+
/** @brief Total number of data blocks available in the EEPROM. */
58+
#define BLOCK_COUNT 512
59+
60+
/** @brief Starting address of the allocation table in EEPROM. */
61+
#define ALLOC_TABLE_BEGIN 0
62+
63+
/** @brief Size of the allocation table in bytes (one bit per block). */
64+
#define ALLOC_TABLE_SIZE (BLOCK_COUNT / 8)
65+
66+
/** @brief Starting address of the key-map table in EEPROM. */
67+
#define KEY_MAP_BEGIN (ALLOC_TABLE_BEGIN + ALLOC_TABLE_SIZE)
68+
69+
/** @brief Total size of the key-map table in bytes. */
70+
#define KEY_MAP_SIZE (KEY_MAP_STRUCT_SIZE * KEY_MAP_COUNT)
71+
72+
/** @brief Starting address of the data space in EEPROM. */
73+
#define DATA_SPACE_BEGIN (KEY_MAP_BEGIN + KEY_MAP_SIZE)
74+
75+
/** @brief Total size of the EEPROM in bytes. */
76+
#define EEPROM_SIZE 4096
77+
78+
#include <stdint.h>
79+
80+
#include "m24c32.h"
81+
82+
/**
83+
* @brief Key-value mapping structure.
84+
*
85+
* This structure maps a 4-byte key to up to 4 block IDs. Each block ID points to
86+
* a BLOCK_SIZE-byte data block in the EEPROM data space.
87+
*/
88+
typedef struct {
89+
uint8_t key[4]; /** 4-byte key (not null-terminated). */
90+
uint16_t ids[4]; /** Array of up to 4 block IDs (BLOCK_COUNT indicates end). */
91+
} directory_key_map_t;
92+
93+
/**
94+
* @brief Main EEPROM directory structure.
95+
*
96+
* This structure contains all the state information for the EEPROM directory,
97+
* including the device interface, allocation table, and key map.
98+
*/
99+
typedef struct {
100+
m24c32_t *device; /** Pointer to the M24C32 device interface. */
101+
uint8_t alloc_table[ALLOC_TABLE_SIZE]; /** Bit-vector allocation table (one bit per block). */
102+
directory_key_map_t key_map[KEY_MAP_COUNT]; /** Array of key-value mappings. */
103+
} eeprom_directory_t;
104+
105+
#endif

middleware/include/eeprom_status.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ typedef enum {
1919
EEPROM_ERROR_NULL_POINTER = -5,
2020
EEPROM_ERROR_ALLOCATION = -6,
2121
EEPROM_ERROR_COMMS = -7,
22+
EEPROM_ERROR_TOO_BIG = -8
2223

2324
} eeprom_status_t;
2425

0 commit comments

Comments
 (0)