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(Device& device, const Info& info) : mDevice(&device), mPart(&info)
227  {
228  }
229 
242  bool verify(Type type, uint8_t subtype) const;
243 
245  bool verify(uint8_t type, uint8_t subtype) const
246  {
247  return verify(Type(type), subtype);
248  }
249 
251  template <typename T> bool verify(T subType) const
252  {
253  return verify(Type(T::partitionType), uint8_t(subType));
254  }
255 
261  static inline SubType::App apptypeOta(uint8_t i)
262  {
263  auto subtype = SubType::App(uint8_t(SubType::App::ota_min) + i);
264  assert(subtype >= SubType::App::ota_min && subtype <= SubType::App::ota_max);
265  return subtype;
266  }
267 
268  explicit operator bool() const
269  {
270  return mDevice != nullptr && mPart != nullptr;
271  }
272 
280  bool read(storage_size_t offset, void* dst, size_t size);
281 
282  template <typename T>
283  typename std::enable_if<std::is_pod<T>::value, bool>::type read(storage_size_t offset, T& value)
284  {
285  return read(offset, &value, sizeof(value));
286  }
287 
296  bool write(storage_size_t offset, const void* src, size_t size);
297 
306 
311  {
313  }
314 
318  uint8_t subType() const
319  {
320  return mPart ? mPart->subtype : SubType::invalid;
321  }
322 
327  {
328  return mPart ? mPart->fullType() : FullType{};
329  }
330 
336  {
337  return (mPart && mPart->type != Partition::Type::storage) ? mPart->offset : 0;
338  }
339 
345  {
346  return mPart ? (mPart->offset + mPart->size - 1) : 0;
347  }
348 
354  {
355  return mPart ? mPart->size : 0;
356  }
357 
361  String name() const
362  {
363  return mPart ? mPart->name.c_str() : nullptr;
364  }
365 
369  Flags flags() const
370  {
371  return mPart ? mPart->flags : 0;
372  }
373 
377  bool isEncrypted() const
378  {
379  return flags()[Flag::encrypted];
380  }
381 
385  bool isReadOnly() const
386  {
387  return mPart ? mPart->flags[Flag::readOnly] : true;
388  }
389 
406 
412 
416  bool contains(storage_size_t addr) const
417  {
418  return mPart ? (addr >= mPart->offset && addr <= lastAddress()) : false;
419  }
420 
421  bool operator==(const Partition& other) const
422  {
423  return mDevice == other.mDevice && mPart == other.mPart;
424  }
425 
426  bool operator==(const char* name) const
427  {
428  return mPart ? mPart->name.equals(name) : false;
429  }
430 
431  bool operator==(const String& name) const
432  {
433  return mPart ? mPart->name.equals(name) : false;
434  }
435 
436  template <typename T> bool operator!=(const T& other) const
437  {
438  return !operator==(other);
439  }
440 
444  size_t getBlockSize() const;
445 
450  uint16_t getSectorSize() const;
451 
456  {
457  return size() / getSectorSize();
458  }
459 
464  bool sync();
465 
469  const Disk::DiskPart* diskpart() const
470  {
471  return mPart ? mPart->diskpart() : nullptr;
472  }
473 
474  size_t printTo(Print& p) const;
475 
476 protected:
477  Device* mDevice{nullptr};
478  const Info* mPart{nullptr};
479 
480 private:
481  bool allowRead();
482  bool allowWrite();
483 };
484 
485 } // namespace Storage
486 
487 String toString(Storage::Partition::Type type, uint8_t subType);
489 
490 template <typename E> typename std::enable_if<bool(E::partitionType), String>::type toString(E subType)
491 {
492  return toString(Storage::Partition::Type(E::partitionType), uint8_t(subType));
493 }
494 
495 template <typename E> typename std::enable_if<bool(E::partitionType), String>::type toLongString(E subType)
496 {
497  return toLongString(Storage::Partition::Type(E::partitionType), uint8_t(subType));
498 }
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:94
bool equals(const CString &other) const
Definition: CString.h:99
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:245
std::enable_if< std::is_pod< T >::value, bool >::type read(storage_size_t offset, T &value)
Definition: Partition.h:283
Partition::Type type() const
Obtain partition type.
Definition: Partition.h:310
storage_size_t getSectorCount() const
Obtain total number of sectors in this partition.
Definition: Partition.h:455
uint8_t subType() const
Obtain partition sub-type.
Definition: Partition.h:318
FullType fullType() const
Obtain both type and subtype.
Definition: Partition.h:326
const Info * mPart
Definition: Partition.h:478
bool isReadOnly() const
Check state of partition readOnly flag.
Definition: Partition.h:385
String typeString() const
Flags flags() const
Get partition flags.
Definition: Partition.h:369
storage_size_t size() const
Obtain partition size.
Definition: Partition.h:353
char[nameSize] Name
Definition: Partition.h:133
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:261
uint16_t getSectorSize() const
Get sector size for block-addressable devices.
bool operator==(const Partition &other) const
Definition: Partition.h:421
const Disk::DiskPart * diskpart() const
If this is a disk partition, return pointer to the additional information.
Definition: Partition.h:469
bool operator!=(const T &other) const
Definition: Partition.h:436
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:377
Type
Definition: Partition.h:88
Flag
Definition: Partition.h:127
@ readOnly
Write/erase prohibited.
storage_size_t address() const
Obtain partition starting address.
Definition: Partition.h:335
storage_size_t lastAddress() const
Obtain address of last byte in this this partition.
Definition: Partition.h:344
bool operator==(const String &name) const
Definition: Partition.h:431
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:226
bool read(storage_size_t offset, void *dst, size_t size)
Read data from the partition.
Device * mDevice
Definition: Partition.h:477
String longTypeString() const
bool contains(storage_size_t addr) const
Determine if given address contained within this partition.
Definition: Partition.h:416
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:251
String getDeviceName() const
Get name of storage device for this partition.
String name() const
Get partition name.
Definition: Partition.h:361
bool operator==(const char *name) const
Definition: Partition.h:426
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