Skip to content

drivers: KV flash storage - #1067

Draft
tact1m4n3 wants to merge 5 commits into
mainfrom
storage-driver
Draft

tact1m4n3 wants to merge 5 commits into
mainfrom
storage-driver

Conversation

@tact1m4n3

Copy link
Copy Markdown
Collaborator

Generic flash storage driver inspired by the rust crate sequential-storage. I needed a persistent storage lib for a project of mine and this is my attempt at writing one. I tried to make it as resilient as possible, like an interrupted store operation shouldn't mess anything up. There are still some TODOs left, but I'd love some feedback on it. I wrote a tiny rp2xxx demo example if anyone wants to try it out.

@tact1m4n3
tact1m4n3 marked this pull request as draft October 3, 2026 18:50
pub const Flash = struct {
// TODO: We must also wait for flash dma transfers to finish in addition to
// critical sections
// TODO: Maybe instead of asserts we should return errors?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so, unless we're going down we shouldn't make a hal that makes it hard to make a resilient system

Comment thread port/raspberrypi/rp2xxx/src/hal/drivers.zig
});
rp2xxx.uart.init_logger(uart);

const flash_storage_start: u32 = 256 * 1024;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we take this from the target? We don't want someone to build an example and accidentally wipe something important.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wdym?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is generic across all rp2xxx. is 256k as the start going to be safe? What about different boards/variants?

This is probably totally fine, but I was basically asking whether we can use a field in board or something to put this value so e.g. a board with some bootloader won't have the bootloader accidentally wiped running this example.

It is probably not worth worrying about at this point.

var current_offset: u32 = flash_storage_start;
while (current_offset < flash_storage_end) : (current_offset += flash.SECTOR_SIZE) {
std.log.info("Erasing sector at offset {x}", .{current_offset});
flash.range_erase(current_offset, flash.SECTOR_SIZE);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this function handle whatever looping it needs to do to wipe everything in the requested range?

Comment thread drivers/src/root.zig Outdated
Comment thread drivers/src/storage.zig Outdated

/// A generic storage implementation that can be used with any flash device.
/// Items are stored sequentially in sectors (inspired by the rust crate
/// sequential storage). It should be resilient to power loss and flash

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you link the crate?

Comment thread drivers/src/storage.zig Outdated
Comment thread drivers/src/kv_store.zig
Comment thread drivers/src/storage.zig Outdated
try testing.expectEqual(@as(?u32, null), try s.fetch(3, u32));
}

test "overwrite frees the old item" {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

frees or reuses?

Comment thread drivers/src/kv_store.zig
if (i > 1000) return error.NeverRanOutOfMemory;
}
}
};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I imagine you plan on writing tests which utilize the tripwires?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to implement some fuzzing, but unfortunatelly the zig compiler crashed when trying to run the fuzz test 😄

@tact1m4n3 tact1m4n3 Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

apparently now fuzzing works but I have no idea how to use it, I wrote a basic test but I am not sure I am generating the values the right way. There are no docs at the moment :)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean like power_loss_tripwire which you support and check for but never use in your tests.

@mattnite

mattnite commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

In addition to this PR, could you write a couple issues to implement this driver for architectures unlike the rp2xxx? I want to try to catch any leaky abstractions by having you think through some systems like AVR or MSP430, but I don't want to make you implement a patch for hardware you may not have.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants