Skip to content

Commit 843fab8

Browse files
authored
Revise Partition in-memory storage mechanism (#2564)
This PR makes some changes to the way partition tables are constructed internally. The changes are intended to make the system more intuitive, flexible, and to pave the way for external disk (SD card) storage interfaces. **Use linked list to store partition tables** Currently the partition table is allocated using a fixed array of `Partition::Info` structures. This means any additional information would cause all partition entries to increase in size. This has been changed to a linked list so that future extensions can be accommodated. It also avoids having a fixed limit on the partition table size. **Replace `CustomDevice::createPartition` methods with `partitions().add()`** 'create' was a poor naming choice as it doesn't write anything to storage, just updates the partition table. These methods have been removed in favour of operating on the `partitions()` property directly. The default `Device::partitions()` is read-only (const) but it is overridden in custom devices to support writes, etc. **Add `Partition::FullType` for better type/subtype handling** Partition types consist of a `type` and `subtype` component, however standard subtypes can be referred to using just the subtype as these are defined using strong enums from which the type can be inferred. When explicitly providing both a type and subtype, this must now be provided as a `FullType` structure, e.g. `{`Storage::Partition::Type::Data`, 100}`. This simplifies the API and removes any ambiguity between overloaded method parameters.
1 parent e5eccdb commit 843fab8

File tree

20 files changed

+180
-171
lines changed

20 files changed

+180
-171
lines changed

Sming/Components/IFS

Sming/Components/Storage/src/CustomDevice.cpp

Lines changed: 0 additions & 42 deletions
This file was deleted.

Sming/Components/Storage/src/Iterator.cpp

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,39 +18,23 @@ Iterator::Iterator(Partition::Type type, uint8_t subtype) : mSearch{nullptr, typ
1818
next();
1919
}
2020

21-
bool Iterator::next()
21+
void Iterator::next()
2222
{
2323
while(mDevice != nullptr) {
24-
while(uint8_t(++mPos) < mDevice->partitions().count()) {
25-
auto entry = mDevice->partitions()[mPos];
26-
27-
if(mSearch.type != Partition::Type::any && mSearch.type != entry.type()) {
28-
continue;
29-
}
30-
31-
if(mSearch.subType != Partition::SubType::any && mSearch.subType != entry.subType()) {
32-
continue;
24+
mInfo = mInfo ? mInfo->getNext() : mDevice->partitions().mEntries.head();
25+
if(mInfo == nullptr) {
26+
if(mSearch.device != nullptr) {
27+
break;
3328
}
34-
35-
return true;
29+
mDevice = mDevice->getNext();
30+
mInfo = nullptr;
31+
continue;
3632
}
3733

38-
if(mSearch.device != nullptr) {
34+
if(mInfo->match(mSearch.type, mSearch.subType)) {
3935
break;
4036
}
41-
42-
mDevice = mDevice->getNext();
43-
mPos = beforeStart;
4437
}
45-
46-
mDevice = nullptr;
47-
mPos = afterEnd;
48-
return false;
49-
}
50-
51-
Partition Iterator::operator*() const
52-
{
53-
return mDevice ? mDevice->partitions()[mPos] : Partition{};
5438
}
5539

5640
} // namespace Storage

Sming/Components/Storage/src/Partition.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ String toLongString(Partition::Type type, uint8_t subType)
123123

124124
namespace Storage
125125
{
126+
Partition::FullType::operator String() const
127+
{
128+
return toString(type, subtype);
129+
}
130+
126131
String Partition::typeString() const
127132
{
128133
return toString(type(), subType());

Sming/Components/Storage/src/PartitionTable.cpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,14 @@ namespace Storage
1616
{
1717
void PartitionTable::load(const esp_partition_info_t* entry, unsigned count)
1818
{
19-
if(count == 0) {
20-
mEntries.reset();
21-
mCount = count;
22-
return;
23-
}
24-
25-
mCount = count;
26-
mEntries.reset(new Partition::Info[count]);
19+
mEntries.clear();
2720
for(unsigned i = 0; i < count; ++i) {
2821
auto& e = entry[i];
2922
// name may not be zero-terminated
3023
char name[Partition::nameSize + 1];
3124
memcpy(name, e.name, Partition::nameSize);
3225
name[Partition::nameSize] = '\0';
33-
mEntries.get()[i] = Partition::Info{name, e.type, e.subtype, e.offset, e.size, e.flags};
26+
add(name, {e.type, e.subtype}, e.offset, e.size, e.flags);
3427
}
3528
}
3629

Sming/Components/Storage/src/ProgMem.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ bool ProgMem::read(uint32_t address, void* dst, size_t size)
2121
return readCount == size;
2222
}
2323

24-
Partition ProgMem::createPartition(const String& name, const void* flashPtr, size_t size, Partition::Type type,
25-
uint8_t subtype)
24+
Partition ProgMem::ProgMemPartitionTable::add(const String& name, const void* flashPtr, size_t size,
25+
Partition::FullType type)
2626
{
2727
auto addr = flashmem_get_address(flashPtr);
2828
if(addr == 0) {
2929
return Partition{};
3030
}
3131

32-
return createPartition(name, type, subtype, addr, size, Partition::Flag::readOnly);
32+
return CustomPartitionTable::add(name, type, addr, size, Partition::Flag::readOnly);
3333
}
3434

3535
} // namespace Storage

Sming/Components/Storage/src/SysMem.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,8 @@
99
****/
1010

1111
#include "include/Storage/SysMem.h"
12-
#include <esp_spi_flash.h>
1312

1413
namespace Storage
1514
{
1615
SysMem sysMem;
17-
18-
Partition SysMem::createPartition(const String& name, const FSTR::ObjectBase& fstr, Partition::Type type,
19-
uint8_t subtype)
20-
{
21-
return createPartition(name, type, subtype, reinterpret_cast<uint32_t>(fstr.data()), fstr.size(),
22-
Partition::Flag::readOnly);
23-
}
24-
2516
} // namespace Storage

Sming/Components/Storage/src/include/Storage/CustomDevice.h

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,23 @@ namespace Storage
1010
{
1111
/**
1212
* @brief Class to support dynamic partitions
13-
*
14-
* Call `createPartition` to add partitions up to a maximum of 16 entries.
1513
*/
1614
class CustomDevice : public Device
1715
{
1816
public:
19-
Partition createPartition(const Partition::Info& info);
20-
21-
Partition createPartition(const String& name, Partition::Type type, uint8_t subtype, uint32_t offset, size_t size,
22-
Partition::Flags flags = 0)
17+
class CustomPartitionTable : public PartitionTable
2318
{
24-
return createPartition(Partition::Info{name, type, subtype, offset, size, flags});
25-
}
19+
public:
20+
using PartitionTable::add;
21+
using PartitionTable::clear;
22+
};
2623

27-
template <typename SubType>
28-
Partition createPartition(const String& name, SubType subtype, uint32_t offset, size_t size,
29-
Partition::Flags flags = 0)
24+
/**
25+
* @brief Provide read/write access to in-memory partition table
26+
*/
27+
CustomPartitionTable& partitions()
3028
{
31-
return createPartition(name, Partition::Type(SubType::partitionType), uint8_t(subtype), offset, size, flags);
29+
return static_cast<CustomPartitionTable&>(mPartitions);
3230
}
3331
};
3432

Sming/Components/Storage/src/include/Storage/Device.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ class Device : public LinkedObjectTemplate<Device>
5656
return getName() == name;
5757
}
5858

59+
/**
60+
* @brief Provide read-only access to partition table
61+
*/
5962
const PartitionTable& partitions() const
6063
{
6164
return mPartitions;

Sming/Components/Storage/src/include/Storage/Iterator.h

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class Iterator : public std::iterator<std::forward_iterator_tag, Partition>
3232

3333
explicit operator bool() const
3434
{
35-
return (mDevice != nullptr) && (mPos > beforeStart) && (mPos < afterEnd);
35+
return mDevice && mInfo;
3636
}
3737

3838
Iterator operator++(int)
@@ -50,15 +50,18 @@ class Iterator : public std::iterator<std::forward_iterator_tag, Partition>
5050

5151
bool operator==(const Iterator& other) const
5252
{
53-
return (mDevice == other.mDevice) && (mPos == other.mPos);
53+
return mInfo == other.mInfo;
5454
}
5555

5656
bool operator!=(const Iterator& other) const
5757
{
5858
return !operator==(other);
5959
}
6060

61-
Partition operator*() const;
61+
Partition operator*() const
62+
{
63+
return mDevice && mInfo ? Partition(*mDevice, *mInfo) : Partition{};
64+
}
6265

6366
Iterator begin()
6467
{
@@ -71,15 +74,11 @@ class Iterator : public std::iterator<std::forward_iterator_tag, Partition>
7174
}
7275

7376
private:
74-
static constexpr int8_t beforeStart{-1};
75-
static constexpr int8_t afterEnd{0x7f};
76-
77-
Iterator() : mPos(afterEnd)
77+
Iterator()
7878
{
7979
}
8080

81-
bool seek(uint8_t pos);
82-
bool next();
81+
void next();
8382

8483
struct Search {
8584
Device* device;
@@ -88,7 +87,7 @@ class Iterator : public std::iterator<std::forward_iterator_tag, Partition>
8887
};
8988
Search mSearch{};
9089
Device* mDevice{nullptr};
91-
int8_t mPos{beforeStart};
90+
const Partition::Info* mInfo{nullptr};
9291
};
9392

9493
} // namespace Storage

0 commit comments

Comments
 (0)