You can define a device with various partitions like this:
Code: Select all
static struct smtd_partition snorparts[] = {
{
.name = "config"
.offset = 0,
.size = 1024,
},
{
.name = "histograms"
.offset = 1024,
.size = 1024,
},
{
.name = "diags"
.offset = 2048,
.size = 1024,
},
};
static struct smtd_info snor1 = {
.name = "sda",
.drv = (BaseFlash *)&SNORDriver,
.erase_range = NULL,
.partitions = &snorparts,
.npart = sizeof(snorparts)/sizeof(snorparts[0]),
};
And you can have multiple devices with partitions - just define another struct smtd_info for each.
Register the struct smtd_info with the system like so:
Code: Select all
smtd_device_register(&snor1);
smtd_device_register(&snor2);
smtd_device_register(&internal_flash);
smtd_device_register(&fram);
etc ...
The application can get a context (or call it a handle) to a specific partition by just giving a path "<device>/<partition>".
The context stores a current file position as well. So you can use typical read/write/fseek/ftell like APIs. The offsets/position/sector_index of the partition are relative to the start of the partition. That's really the bulk of what this layer is doing - constraining and address translation between the partition base address and the actual memory location in the device itself.
Code: Select all
smtd_ctx_t * fp = smtd_get_ctx("sda/histograms");
flash_offset_t cur_pos = smtd_ftell(fp);
smtd_fseek(fp, cur_pos + 100, SMTD_SEEK_CUR);
smtd_write(fp, buf, sizeof(buf));
If anyone's gonna use this - it needs to be updated to use the acquire_exclusive/release_exclusive BaseFlash APIs (it's just a few lines). When I get around to it, I'll update this post.