Partition.h
Go to the documentation of this file.
1 /****
2  * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
3  * Created 2015 by Skurydin Alexey
4  * http://github.com/SmingHub/Sming
5  * All files of the Sming Core are provided under the LGPL v3 license.
6  *
7  * Partition.h - C++ wrapper for universal partition table support
8  *
9  * Original license for IDF code:
10  *
11  * Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
12  *
13  * Licensed under the Apache License, Version 2.0 (the "License");
14  * you may not use this file except in compliance with the License.
15  * You may obtain a copy of the License at
16  *
17  * http://www.apache.org/licenses/LICENSE-2.0
18  *
19  * Unless required by applicable law or agreed to in writing, software
20  * distributed under the License is distributed on an "AS IS" BASIS,
21  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  * See the License for the specific language governing permissions and
23  * limitations under the License.
24  *
25  *
26  ****/
27 #pragma once
28 
29 #include <Printable.h>
30 #include <Data/BitSet.h>
31 #include <Data/CString.h>
32 #include <Data/LinkedObjectList.h>
33 #include <cassert>
34 #include "Types.h"
35 
36 #define PARTITION_APP_SUBTYPE_MAP(XX) \
37  XX(factory, 0x00, "Factory application") \
38  XX(ota0, 0x10, "OTA #0") \
39  XX(ota1, 0x11, "OTA #1") \
40  XX(ota2, 0x12, "OTA #2") \
41  XX(ota3, 0x13, "OTA #3") \
42  XX(ota4, 0x14, "OTA #4") \
43  XX(ota5, 0x15, "OTA #5") \
44  XX(ota6, 0x16, "OTA #6") \
45  XX(ota7, 0x17, "OTA #7") \
46  XX(ota8, 0x18, "OTA #8") \
47  XX(ota9, 0x19, "OTA #9") \
48  XX(ota10, 0x1a, "OTA #10") \
49  XX(ota11, 0x1b, "OTA #11") \
50  XX(ota12, 0x1c, "OTA #12") \
51  XX(ota13, 0x1d, "OTA #13") \
52  XX(ota14, 0x1e, "OTA #14") \
53  XX(ota15, 0x1f, "OTA #15") \
54  XX(test, 0x20, "Test application")
55 
56 #define PARTITION_DATA_SUBTYPE_MAP(XX) \
57  XX(ota, 0x00, "OTA selection") \
58  XX(phy, 0x01, "PHY init data") \
59  XX(nvs, 0x02, "NVS") \
60  XX(coreDump, 0x03, "Core Dump data") \
61  XX(nvsKeys, 0x04, "NVS key information") \
62  XX(eFuseEm, 0x05, "eFuse emulation") \
63  XX(sysParam, 0x40, "System Parameters") \
64  XX(rfCal, 0x41, "RF Calibration") \
65  XX(espHttpd, 0x80, "ESPHTTPD") \
66  XX(fat, 0x81, "FAT") \
67  XX(spiffs, 0x82, "SPIFFS") \
68  XX(fwfs, 0xF1, "FWFS") \
69  XX(littlefs, 0xF2, "LittleFS")
70 
71 namespace Storage
72 {
73 class Device;
74 class PartitionTable;
76 
77 namespace Disk
78 {
79 class DiskPart;
80 }
81 
85 class Partition
86 {
87 public:
88  enum class Type : uint8_t {
89  app = 0x00,
90  data = 0x01,
91  storage = 0x02,
92  userMin = 0x40,
93  userMax = 0xFE,
94  invalid = 0xff,
95  any = 0xff,
96  };
97 
98  struct SubType {
99  static constexpr uint8_t any{0xff};
100  static constexpr uint8_t invalid{0xff};
101 
105  enum class App : uint8_t {
106  partitionType = uint8_t(Type::app),
107 #define XX(type, value, desc) type = value,
109 #undef XX
110  ota_min = ota0,
111  ota_max = ota15,
112  any = 0xff
113  };
114 
118  enum class Data : uint8_t {
119  partitionType = uint8_t(Type::data),
120 #define XX(subtype, value, desc) subtype = value,
122 #undef XX
123  any = 0xff
124  };
125  };
126 
127  enum class Flag {
128  encrypted = 0,
129  readOnly = 31,
130  };
131 
132  static constexpr size_t nameSize{16};
133  using Name = char[nameSize];
135 
139  struct FullType {
141  uint8_t subtype;
142 
143  constexpr FullType() : type(Type::invalid), subtype(SubType::invalid)
144  {
145  }
146 
147  constexpr FullType(Type type, uint8_t subtype) : type(type), subtype(subtype)
148  {
149  }
150 
151  explicit operator bool() const
152  {
153  return type != Type::invalid && subtype != uint8_t(SubType::invalid);
154  }
155 
156  template <typename T> constexpr FullType(T subType) : FullType(Type(T::partitionType), uint8_t(subType))
157  {
158  }
159 
160  bool operator==(const FullType& other) const
161  {
162  return type == other.type && subtype == other.subtype;
163  }
164 
165  bool operator!=(const FullType& other) const
166  {
167  return !operator==(other);
168  }
169 
170  constexpr uint16_t value() const
171  {
172  return uint8_t(type) << 8 | subtype;
173  }
174 
175  operator String() const;
176  };
177 
181  struct Info : public LinkedObjectTemplate<Info>, public Printable {
183 
190 
192  {
193  }
194 
197  {
198  }
199 
201  {
202  return {type, subtype};
203  }
204 
205  bool match(Type type, uint8_t subType) const
206  {
207  return (type == Type::any || type == this->type) && (subType == SubType::any || subType == this->subtype);
208  }
209 
210  virtual const Disk::DiskPart* diskpart() const
211  {
212  return nullptr;
213  }
214 
215  size_t printTo(Print& p) const override;
216  };
217 
219  {
220  }
221 
222  Partition(const Partition& other) : mDevice(other.mDevice), mPart(other.mPart)
223  {
224  }
225 
226  Partition(Partition&& other) = default;
227 
228  Partition(Device& device, const Info& info) : mDevice(&device), mPart(&info)
229  {
230  }
231 
233  {
234  }
235 
236  Partition& operator=(const Partition& other) = default;
237  Partition& operator=(Partition&& other) = default;
238 
251  bool verify(Type type, uint8_t subtype) const;
252 
254  bool verify(uint8_t type, uint8_t subtype) const
255  {
256  return verify(Type(type), subtype);
257  }
258 
260  template <typename T> bool verify(T subType) const
261  {
262  return verify(Type(T::partitionType), uint8_t(subType));
263  }
264 
270  static inline SubType::App apptypeOta(uint8_t i)
271  {
272  auto subtype = SubType::App(uint8_t(SubType::App::ota_min) + i);
273  assert(subtype >= SubType::App::ota_min && subtype <= SubType::App::ota_max);
274  return subtype;
275  }
276 
277  explicit operator bool() const
278  {
279  return mDevice != nullptr && mPart != nullptr;
280  }
281 
289  bool read(storage_size_t offset, void* dst, size_t size);
290 
291  template <typename T>
292  typename std::enable_if<std::is_pod<T>::value, bool>::type read(storage_size_t offset, T& value)
293  {
294  return read(offset, &value, sizeof(value));
295  }
296 
305  bool write(storage_size_t offset, const void* src, size_t size);
306 
315 
320  {
322  }
323 
327  uint8_t subType() const
328  {
329  return mPart ? mPart->subtype : SubType::invalid;
330  }
331 
336  {
337  return mPart ? mPart->fullType() : FullType{};
338  }
339 
345  {
346  return (mPart && mPart->type != Partition::Type::storage) ? mPart->offset : 0;
347  }
348 
354  {
355  return mPart ? (mPart->offset + mPart->size - 1) : 0;
356  }
357 
363  {
364  return mPart ? mPart->size : 0;
365  }
366 
370  String name() const
371  {
372  return mPart ? mPart->name.c_str() : nullptr;
373  }
374 
378  Flags flags() const
379  {
380  return mPart ? mPart->flags : 0;
381  }
382 
386  bool isEncrypted() const
387  {
388  return flags()[Flag::encrypted];
389  }
390 
394  bool isReadOnly() const
395  {
396  return mPart ? mPart->flags[Flag::readOnly] : true;
397  }
398 
415 
421 
425  bool contains(storage_size_t addr) const
426  {
427  return mPart ? (addr >= mPart->offset && addr <= lastAddress()) : false;
428  }
429 
430  bool operator==(const Partition& other) const
431  {
432  return mDevice == other.mDevice && mPart == other.mPart;
433  }
434 
435  bool operator==(const char* name) const
436  {
437  return mPart ? mPart->name.equals(name) : false;
438  }
439 
440  bool operator==(const String& name) const
441  {
442  return mPart ? mPart->name.equals(name) : false;
443  }
444 
445  template <typename T> bool operator!=(const T& other) const
446  {
447  return !operator==(other);
448  }
449 
453  size_t getBlockSize() const;
454 
459  uint16_t getSectorSize() const;
460 
465  {
466  return size() / getSectorSize();
467  }
468 
473  bool sync();
474 
478  const Disk::DiskPart* diskpart() const
479  {
480  return mPart ? mPart->diskpart() : nullptr;
481  }
482 
483  size_t printTo(Print& p) const;
484 
485 protected:
486  Device* mDevice{nullptr};
487  const Info* mPart{nullptr};
488 
489 private:
490  bool allowRead();
491  bool allowWrite();
492 };
493 
494 } // namespace Storage
495 
496 String toString(Storage::Partition::Type type, uint8_t subType);
498 
499 template <typename E> typename std::enable_if<bool(E::partitionType), String>::type toString(E subType)
500 {
501  return toString(Storage::Partition::Type(E::partitionType), uint8_t(subType));
502 }
503 
504 template <typename E> typename std::enable_if<bool(E::partitionType), String>::type toLongString(E subType)
505 {
506  return toLongString(Storage::Partition::Type(E::partitionType), uint8_t(subType));
507 }
uint32_t storage_size_t
Definition: Components/Storage/src/include/Storage/Types.h:19
#define PARTITION_APP_SUBTYPE_MAP(XX)
Definition: Partition.h:36
#define PARTITION_DATA_SUBTYPE_MAP(XX)
Definition: Partition.h:56
String toLongString(Storage::Partition::Type type, uint8_t subType)
String toString(Storage::Partition::Type type, uint8_t subType)
Class to manage a NUL-terminated C-style string When storing persistent strings in RAM the regular St...
Definition: CString.h:27
const char * c_str() const
Definition: CString.h:100
bool equals(const CString &other) const
Definition: CString.h:105
Base class template for linked items with type casting.
Definition: LinkedObject.h:62
Provides formatted output to stream.
Definition: Print.h:37
Definition: Printable.h:43
Represents a storage device (e.g. flash memory)
Definition: Components/Storage/src/include/Storage/Device.h:34
Represents a flash partition.
Definition: Partition.h:86
bool getDeviceAddress(storage_size_t &address, storage_size_t size) const
Get corresponding storage device address for a given partition offset.
bool verify(uint8_t type, uint8_t subtype) const
Weak 'type' value.
Definition: Partition.h:254
std::enable_if< std::is_pod< T >::value, bool >::type read(storage_size_t offset, T &value)
Definition: Partition.h:292
Partition::Type type() const
Obtain partition type.
Definition: Partition.h:319
storage_size_t getSectorCount() const
Obtain total number of sectors in this partition.
Definition: Partition.h:464
uint8_t subType() const
Obtain partition sub-type.
Definition: Partition.h:327
FullType fullType() const
Obtain both type and subtype.
Definition: Partition.h:335
const Info * mPart
Definition: Partition.h:487
bool isReadOnly() const
Check state of partition readOnly flag.
Definition: Partition.h:394
String typeString() const
Flags flags() const
Get partition flags.
Definition: Partition.h:378
storage_size_t size() const
Obtain partition size.
Definition: Partition.h:362
char[nameSize] Name
Definition: Partition.h:133
Partition(Partition &&other)=default
Partition()
Definition: Partition.h:218
bool verify(Type type, uint8_t subtype) const
Strong C++ type value.
static SubType::App apptypeOta(uint8_t i)
Convenience function to get SubType value for the i-th OTA partition.
Definition: Partition.h:270
uint16_t getSectorSize() const
Get sector size for block-addressable devices.
bool operator==(const Partition &other) const
Definition: Partition.h:430
const Disk::DiskPart * diskpart() const
If this is a disk partition, return pointer to the additional information.
Definition: Partition.h:478
bool operator!=(const T &other) const
Definition: Partition.h:445
bool write(storage_size_t offset, const void *src, size_t size)
Write data to the partition.
bool erase_range(storage_size_t offset, storage_size_t size)
Erase part of the partition.
Partition(const Partition &other)
Definition: Partition.h:222
bool isEncrypted() const
Check state of partition encrypted flag.
Definition: Partition.h:386
Type
Definition: Partition.h:88
Flag
Definition: Partition.h:127
@ readOnly
Write/erase prohibited.
Partition & operator=(Partition &&other)=default
storage_size_t address() const
Obtain partition starting address.
Definition: Partition.h:344
storage_size_t lastAddress() const
Obtain address of last byte in this this partition.
Definition: Partition.h:353
bool operator==(const String &name) const
Definition: Partition.h:440
bool sync()
Flush any pending writes to the physical media.
static constexpr size_t nameSize
Definition: Partition.h:132
Partition(Device &device, const Info &info)
Definition: Partition.h:228
bool read(storage_size_t offset, void *dst, size_t size)
Read data from the partition.
Device * mDevice
Definition: Partition.h:486
String longTypeString() const
~Partition()
Definition: Partition.h:232
bool contains(storage_size_t addr) const
Determine if given address contained within this partition.
Definition: Partition.h:425
size_t getBlockSize() const
Obtain smallest allocation unit for erase operations.
bool verify(T subType) const
Derive type from subtype, expressed as strong C++ enum.
Definition: Partition.h:260
String getDeviceName() const
Get name of storage device for this partition.
String name() const
Get partition name.
Definition: Partition.h:370
bool operator==(const char *name) const
Definition: Partition.h:435
Partition & operator=(const Partition &other)=default
size_t printTo(Print &p) const
The String class.
Definition: WString.h:137
Definition: FileDevice.h:26
Adds information specific to MBR/GPT disk partitions.
Definition: PartInfo.h:85
Express both partition type and subtype together.
Definition: Partition.h:139
constexpr FullType(T subType)
Definition: Partition.h:156
uint8_t subtype
Definition: Partition.h:141
constexpr FullType(Type type, uint8_t subtype)
Definition: Partition.h:147
Type type
Definition: Partition.h:140
constexpr FullType()
Definition: Partition.h:143
bool operator==(const FullType &other) const
Definition: Partition.h:160
bool operator!=(const FullType &other) const
Definition: Partition.h:165
constexpr uint16_t value() const
Definition: Partition.h:170
Partition information.
Definition: Partition.h:181
CString name
Definition: Partition.h:184
size_t printTo(Print &p) const override
Info()
Definition: Partition.h:191
bool match(Type type, uint8_t subType) const
Definition: Partition.h:205
storage_size_t offset
Definition: Partition.h:185
virtual const Disk::DiskPart * diskpart() const
Definition: Partition.h:210
storage_size_t size
Definition: Partition.h:186
FullType fullType() const
Definition: Partition.h:200
Info(const String &name, FullType fullType, storage_size_t offset, storage_size_t size, Flags flags=0)
Definition: Partition.h:195
Type type
Definition: Partition.h:187
uint8_t subtype
Definition: Partition.h:188
Flags flags
Definition: Partition.h:189
Definition: Partition.h:98
App
Application partition type.
Definition: Partition.h:105
Data
Data partition type.
Definition: Partition.h:118
static constexpr uint8_t any
Definition: Partition.h:99
static constexpr uint8_t invalid
Definition: Partition.h:100
Internal structure describing the binary layout of a partition table entry.
Definition: partition.h:16