mirror of https://github.com/ARMmbed/mbed-os.git
Add get_type method to block devices.
parent
a8fa6ec38b
commit
1d71fb1c9f
|
@ -527,6 +527,11 @@ bd_size_t DataFlashBlockDevice::size() const
|
|||
return device_size;
|
||||
}
|
||||
|
||||
const char * DataFlashBlockDevice::get_type()
|
||||
{
|
||||
return "DATAFLASH";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function for reading a specific register.
|
||||
* @details Used for reading either the Status Register or Manufacture and ID Register.
|
||||
|
|
|
@ -153,6 +153,12 @@ public:
|
|||
*/
|
||||
virtual mbed::bd_size_t size() const;
|
||||
|
||||
/** Get the BlockDevice class type.
|
||||
*
|
||||
* @return A string represent the BlockDevice class type.
|
||||
*/
|
||||
virtual const char * get_type();
|
||||
|
||||
private:
|
||||
// Master side hardware
|
||||
mbed::SPI _spi;
|
||||
|
|
|
@ -248,4 +248,9 @@ bd_size_t FlashIAPBlockDevice::size() const
|
|||
return _size;
|
||||
}
|
||||
|
||||
const char * FlashIAPBlockDevice::get_type()
|
||||
{
|
||||
return "FLASHIAP";
|
||||
}
|
||||
|
||||
#endif /* DEVICE_FLASH */
|
||||
|
|
|
@ -121,6 +121,12 @@ public:
|
|||
*/
|
||||
virtual mbed::bd_size_t size() const;
|
||||
|
||||
/** Get the BlockDevice class type.
|
||||
*
|
||||
* @return A string represent the BlockDevice class type.
|
||||
*/
|
||||
virtual const char * get_type();
|
||||
|
||||
private:
|
||||
// Device configuration
|
||||
mbed::FlashIAP _flash;
|
||||
|
|
|
@ -477,6 +477,11 @@ bd_size_t QSPIFBlockDevice::get_erase_size() const
|
|||
return _min_common_erase_size;
|
||||
}
|
||||
|
||||
const char * QSPIFBlockDevice::get_type()
|
||||
{
|
||||
return "QSPIF";
|
||||
}
|
||||
|
||||
// Find minimal erase size supported by the region to which the address belongs to
|
||||
bd_size_t QSPIFBlockDevice::get_erase_size(bd_addr_t addr)
|
||||
{
|
||||
|
|
|
@ -211,6 +211,12 @@ public:
|
|||
*/
|
||||
virtual mbed::bd_size_t size() const;
|
||||
|
||||
/** Get the BlockDevice class type.
|
||||
*
|
||||
* @return A string represent the BlockDevice class type.
|
||||
*/
|
||||
virtual const char * get_type();
|
||||
|
||||
private:
|
||||
// Internal functions
|
||||
|
||||
|
@ -307,8 +313,6 @@ private:
|
|||
int _utils_iterate_next_largest_erase_type(uint8_t &bitfield, int size, int offset, int boundry);
|
||||
|
||||
private:
|
||||
// Internal Members
|
||||
|
||||
// QSPI Driver Object
|
||||
mbed::QSPI _qspi;
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ enum ops {
|
|||
#define SPIF_WEL 0x2
|
||||
#define SPIF_WIP 0x1
|
||||
|
||||
|
||||
SPIFReducedBlockDevice::SPIFReducedBlockDevice(
|
||||
PinName mosi, PinName miso, PinName sclk, PinName cs, int freq)
|
||||
: _spi(mosi, miso, sclk), _cs(cs), _size(0)
|
||||
|
@ -344,3 +343,9 @@ bd_size_t SPIFReducedBlockDevice::size() const
|
|||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
const char * SPIFReducedBlockDevice::get_type()
|
||||
{
|
||||
return "SPIFR";
|
||||
}
|
||||
|
||||
|
|
|
@ -155,6 +155,12 @@ public:
|
|||
*/
|
||||
virtual mbed::bd_size_t size() const;
|
||||
|
||||
/** Get the BlockDevice class type.
|
||||
*
|
||||
* @return A string represent the BlockDevice class type.
|
||||
*/
|
||||
virtual const char * get_type();
|
||||
|
||||
private:
|
||||
// Master side hardware
|
||||
mbed::SPI _spi;
|
||||
|
|
|
@ -632,6 +632,11 @@ bd_size_t SDBlockDevice::size() const
|
|||
return _block_size * _sectors;
|
||||
}
|
||||
|
||||
const char * SDBlockDevice::get_type()
|
||||
{
|
||||
return "SD";
|
||||
}
|
||||
|
||||
void SDBlockDevice::debug(bool dbg)
|
||||
{
|
||||
_dbg = dbg;
|
||||
|
|
|
@ -116,6 +116,11 @@ public:
|
|||
*/
|
||||
virtual int frequency(uint64_t freq);
|
||||
|
||||
/** Get the BlockDevice class type.
|
||||
*
|
||||
* @return A string represent the BlockDevice class type.
|
||||
*/
|
||||
virtual const char * get_type();
|
||||
|
||||
private:
|
||||
/* Commands : Listed below are commands supported
|
||||
|
|
|
@ -472,6 +472,11 @@ int SPIFBlockDevice::get_erase_value() const
|
|||
return 0xFF;
|
||||
}
|
||||
|
||||
const char * SPIFBlockDevice::get_type()
|
||||
{
|
||||
return "SPIF";
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
/*********** SPI Driver API Functions **************/
|
||||
/***************************************************/
|
||||
|
|
|
@ -189,6 +189,12 @@ public:
|
|||
*/
|
||||
virtual mbed::bd_size_t size() const;
|
||||
|
||||
/** Get the BlockDevice class type.
|
||||
*
|
||||
* @return A string represent the BlockDevice class type.
|
||||
*/
|
||||
virtual const char * get_type();
|
||||
|
||||
private:
|
||||
|
||||
// Internal functions
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
# Get type method addon to block devices class
|
||||
|
||||
### Revision history
|
||||
| Revision | Date | Authors | Mbed OS version | Comments |
|
||||
|---------- |-----------------|-------------------------------------------------------------|------------------------|------------------|
|
||||
| 1.0 | 04/12/2018 | Yossi Levy ([@yossi2le](https://github.com/yossi2le/)) | 5.11+ | Initial revision |
|
||||
|
||||
## Introduction
|
||||
|
||||
Most storage solutions use block devices, whether it is Filesystems, KVStore or any other solution
|
||||
most of them will have some BlockDevice class underneath. However, sometimes a storage type or an application needs to know the physical
|
||||
BlockDevice type in order to work smoothly or the BlockDevice type in order to decide what is
|
||||
the best storage configuration to use.
|
||||
To address this an add-on method of getting type is proposed for BlockDevice interface class.
|
||||
|
||||
## The Motivation
|
||||
|
||||
Below there is a list of some examples to explain the motivation and the need for the adding of get_type to BlockDevice interface.
|
||||
|
||||
examples:
|
||||
- TDBStore needs to know if there are flash characteristics for the block device and if there aren<65>t it should use
|
||||
FlashSimBlockDevice to simulate a flash BlockDevice.
|
||||
- TDBStore should not co-exists with NVStore, but this is true only if TDBStore is running on internal memory. Therefore if TDBStore running on
|
||||
internal memory and NVStore is also there an error should be raised.
|
||||
- When creating a file system you would prefer working with FAT on top of SD while LITTLEFS on top of any flash block device.
|
||||
Those preference in favor of better performance.
|
||||
|
||||
To summarize the above, it may be very useful when using block device to know the type of the instance and especially, but not only,
|
||||
when using get_default_instace. Sometimes applications and tests would like to behave differently depending on the instance that has been created
|
||||
or provided to them.
|
||||
|
||||
In fact it might be worth to consider adding the get_type to any interface with get_default_instance at mbed-os.
|
||||
|
||||
## Dive into details
|
||||
we should add the following method to BlockDevice interface class.
|
||||
|
||||
```virtual const char * get_type() = 0;```
|
||||
|
||||
then every physical BlockDevice class which implements the interface should also implement this method and return a string
|
||||
representing its type. Furthermore, a nonphysical BlockDevice like SlicingBlockDevice should return the underlying physical
|
||||
BlockDevice type.
|
||||
|
||||
### Physical BlockDevice:
|
||||
```
|
||||
const char * HeapBlockDevice::get_type()
|
||||
{
|
||||
return "HEAP";
|
||||
}
|
||||
```
|
||||
|
||||
### Logical BlockDevice:
|
||||
```
|
||||
const char * SlicingBlockDevice::get_type()
|
||||
{
|
||||
if (_bd != NULL) {
|
||||
return _bd->get_type();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
```
|
||||
|
||||
The below table describes physical BlockDevice and its tyep names
|
||||
|
||||
|
||||
| BlockDevice class | String description |
|
||||
|-----------------------------|--------------------|
|
||||
| HeapBlockDevice | "HEAP" |
|
||||
| SPIFBlockDevice | "SPIF" |
|
||||
| SPIFReducedBlockDevice | "SPIFR" |
|
||||
| QSPIFBlockDevice | "QSPIF" |
|
||||
| SDBlockDevice | "SD" |
|
||||
| FlashIAPBlockDevice | "FLASHIAP" |
|
||||
| DataFlashBlockDevice | "DATAFLASH" |
|
|
@ -466,6 +466,30 @@ void test_program_read_small_data_sizes()
|
|||
delete block_device;
|
||||
}
|
||||
|
||||
void test_get_type_functionality()
|
||||
{
|
||||
BlockDevice *block_device = BlockDevice::get_default_instance();
|
||||
if (block_device == NULL) {
|
||||
TEST_SKIP_MESSAGE("No block device component is defined for this target");
|
||||
return;
|
||||
}
|
||||
const char * bd_type = block_device->get_type();
|
||||
TEST_ASSERT_NOT_EQUAL(0, bd_type);
|
||||
|
||||
#if COMPONENT_QSPIF
|
||||
TEST_ASSERT_EQUAL(0, strcmp(bd_type, "QSPIF"));
|
||||
#elif COMPONENT_SPIF
|
||||
TEST_ASSERT_EQUAL(0, strcmp(bd_type, "SPIF"));
|
||||
#elif COMPONENT_DATAFLASH
|
||||
TEST_ASSERT_EQUAL(0, strcmp(bd_type, "DATAFLASH"));
|
||||
#elif COMPONENT_SD
|
||||
TEST_ASSERT_EQUAL(0, strcmp(bd_type, "SD"));
|
||||
#elif COMPONET_FLASHIAP
|
||||
TEST_ASSERT_EQUAL(0, strcmp(bd_type, "FLASHIAP"));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason)
|
||||
{
|
||||
greentea_case_failure_abort_handler(source, reason);
|
||||
|
@ -484,7 +508,8 @@ Case cases[] = {
|
|||
Case("Testing multi threads erase program read", test_multi_threads, greentea_failure_handler),
|
||||
Case("Testing contiguous erase, write and read", test_contiguous_erase_write_read, greentea_failure_handler),
|
||||
Case("Testing BlockDevice::get_erase_value()", test_get_erase_value, greentea_failure_handler),
|
||||
Case("Testing program read small data sizes", test_program_read_small_data_sizes, greentea_failure_handler)
|
||||
Case("Testing program read small data sizes", test_program_read_small_data_sizes, greentea_failure_handler),
|
||||
Case("Testing get type functionality", test_get_type_functionality, greentea_failure_handler)
|
||||
};
|
||||
|
||||
Specification specification(test_setup, cases);
|
||||
|
|
|
@ -154,6 +154,19 @@ end:
|
|||
|
||||
}
|
||||
|
||||
void test_get_type_functionality()
|
||||
{
|
||||
uint8_t *dummy = new (std::nothrow) uint8_t[TEST_BLOCK_DEVICE_SIZE];
|
||||
TEST_SKIP_UNLESS_MESSAGE(dummy, "Not enough memory for test");
|
||||
delete[] dummy;
|
||||
|
||||
HeapBlockDevice bd(TEST_BLOCK_DEVICE_SIZE, TEST_BLOCK_SIZE);
|
||||
|
||||
const char * bd_type = bd.get_type();
|
||||
TEST_ASSERT_NOT_EQUAL(0, bd_type);
|
||||
TEST_ASSERT_EQUAL(0, strcmp(bd_type, "HEAP"));
|
||||
}
|
||||
|
||||
|
||||
// Test setup
|
||||
utest::v1::status_t test_setup(const size_t number_of_cases)
|
||||
|
@ -164,6 +177,7 @@ utest::v1::status_t test_setup(const size_t number_of_cases)
|
|||
|
||||
Case cases[] = {
|
||||
Case("Testing read write random blocks", test_read_write),
|
||||
Case("Testing get type functionality", test_get_type_functionality)
|
||||
};
|
||||
|
||||
Specification specification(test_setup, cases);
|
||||
|
|
|
@ -233,6 +233,12 @@ public:
|
|||
(addr + size) % get_erase_size(addr + size - 1) == 0 &&
|
||||
addr + size <= this->size());
|
||||
}
|
||||
|
||||
/** Get the BlockDevice class type.
|
||||
*
|
||||
* @return A string represent the BlockDevice class type.
|
||||
*/
|
||||
virtual const char * get_type() = 0;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -330,4 +330,13 @@ bd_size_t BufferedBlockDevice::size() const
|
|||
return _bd_size;
|
||||
}
|
||||
|
||||
const char * BufferedBlockDevice::get_type()
|
||||
{
|
||||
if (_bd != NULL) {
|
||||
return _bd->get_type();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -152,6 +152,12 @@ public:
|
|||
*/
|
||||
virtual bd_size_t size() const;
|
||||
|
||||
/** Get the BlockDevice class type.
|
||||
*
|
||||
* @return A string represent the BlockDevice class type.
|
||||
*/
|
||||
virtual const char * get_type();
|
||||
|
||||
protected:
|
||||
BlockDevice *_bd;
|
||||
bd_size_t _bd_program_size;
|
||||
|
|
|
@ -283,4 +283,9 @@ bd_size_t ChainingBlockDevice::size() const
|
|||
return _size;
|
||||
}
|
||||
|
||||
const char * ChainingBlockDevice::get_type()
|
||||
{
|
||||
return "CHAINING";
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -172,6 +172,12 @@ public:
|
|||
*/
|
||||
virtual bd_size_t size() const;
|
||||
|
||||
/** Get the BlockDevice class type.
|
||||
*
|
||||
* @return A string represent the BlockDevice class type.
|
||||
*/
|
||||
virtual const char * get_type();
|
||||
|
||||
protected:
|
||||
BlockDevice **_bds;
|
||||
size_t _bd_count;
|
||||
|
|
|
@ -194,4 +194,14 @@ bd_size_t ExhaustibleBlockDevice::size() const
|
|||
return _bd->size();
|
||||
}
|
||||
|
||||
const char * ExhaustibleBlockDevice::get_type()
|
||||
{
|
||||
if (_bd != NULL) {
|
||||
return _bd->get_type();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
|
|
|
@ -154,6 +154,12 @@ public:
|
|||
*/
|
||||
virtual bd_size_t size() const;
|
||||
|
||||
/** Get the BlockDevice class type.
|
||||
*
|
||||
* @return A string represent the BlockDevice class type.
|
||||
*/
|
||||
virtual const char * get_type();
|
||||
|
||||
private:
|
||||
BlockDevice *_bd;
|
||||
uint32_t *_erase_array;
|
||||
|
|
|
@ -212,4 +212,14 @@ int FlashSimBlockDevice::get_erase_value() const
|
|||
return _erase_value;
|
||||
}
|
||||
|
||||
const char * FlashSimBlockDevice::get_type()
|
||||
{
|
||||
if (_bd != NULL) {
|
||||
return _bd->get_type();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
|
|
|
@ -136,6 +136,12 @@ public:
|
|||
*/
|
||||
virtual bd_size_t size() const;
|
||||
|
||||
/** Get the BlockDevice class type.
|
||||
*
|
||||
* @return A string represent the BlockDevice class type.
|
||||
*/
|
||||
virtual const char * get_type();
|
||||
|
||||
private:
|
||||
uint8_t _erase_value;
|
||||
bd_size_t _blank_buf_size;
|
||||
|
|
|
@ -183,4 +183,10 @@ int HeapBlockDevice::erase(bd_addr_t addr, bd_size_t size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
const char * HeapBlockDevice::get_type()
|
||||
{
|
||||
return "HEAP";
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
|
|
|
@ -150,6 +150,12 @@ public:
|
|||
*/
|
||||
virtual bd_size_t size() const;
|
||||
|
||||
/** Get the BlockDevice class type.
|
||||
*
|
||||
* @return A string represent the BlockDevice class type.
|
||||
*/
|
||||
virtual const char * get_type();
|
||||
|
||||
private:
|
||||
bd_size_t _read_size;
|
||||
bd_size_t _program_size;
|
||||
|
|
|
@ -423,4 +423,14 @@ int MBRBlockDevice::get_partition_number() const
|
|||
return _part;
|
||||
}
|
||||
|
||||
const char * MBRBlockDevice::get_type()
|
||||
{
|
||||
if (_bd != NULL) {
|
||||
return _bd->get_type();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
|
|
|
@ -249,6 +249,12 @@ public:
|
|||
*/
|
||||
virtual int get_partition_number() const;
|
||||
|
||||
/** Get the BlockDevice class type.
|
||||
*
|
||||
* @return A string represent the BlockDevice class type.
|
||||
*/
|
||||
virtual const char * get_type();
|
||||
|
||||
protected:
|
||||
BlockDevice *_bd;
|
||||
bd_size_t _offset;
|
||||
|
|
|
@ -111,4 +111,14 @@ bd_size_t ObservingBlockDevice::size() const
|
|||
return _bd->size();
|
||||
}
|
||||
|
||||
const char * ObservingBlockDevice::get_type()
|
||||
{
|
||||
if (_bd != NULL) {
|
||||
return _bd->get_type();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
|
|
|
@ -140,6 +140,12 @@ public:
|
|||
*/
|
||||
virtual bd_size_t size() const;
|
||||
|
||||
/** Get the BlockDevice class type.
|
||||
*
|
||||
* @return A string represent the BlockDevice class type.
|
||||
*/
|
||||
virtual const char * get_type();
|
||||
|
||||
private:
|
||||
BlockDevice *_bd;
|
||||
mbed::Callback<void(BlockDevice *)> _change;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "ProfilingBlockDevice.h"
|
||||
#include "stddef.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
@ -120,4 +121,14 @@ bd_size_t ProfilingBlockDevice::get_erase_count() const
|
|||
return _erase_count;
|
||||
}
|
||||
|
||||
const char * ProfilingBlockDevice::get_type()
|
||||
{
|
||||
if (_bd != NULL) {
|
||||
return _bd->get_type();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
|
|
|
@ -179,6 +179,12 @@ public:
|
|||
*/
|
||||
bd_size_t get_erase_count() const;
|
||||
|
||||
/** Get the BlockDevice class type.
|
||||
*
|
||||
* @return A string represent the BlockDevice class type.
|
||||
*/
|
||||
virtual const char * get_type();
|
||||
|
||||
private:
|
||||
BlockDevice *_bd;
|
||||
bd_size_t _read_count;
|
||||
|
|
|
@ -101,6 +101,17 @@ bd_size_t ReadOnlyBlockDevice::size() const
|
|||
return _bd->size();
|
||||
}
|
||||
|
||||
const char * ReadOnlyBlockDevice::get_type()
|
||||
{
|
||||
if (_bd != NULL) {
|
||||
return _bd->get_type();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
/** @}*/
|
||||
|
||||
|
||||
|
|
|
@ -133,6 +133,12 @@ public:
|
|||
*/
|
||||
virtual bd_size_t size() const;
|
||||
|
||||
/** Get the BlockDevice class type.
|
||||
*
|
||||
* @return A string represent the BlockDevice class type.
|
||||
*/
|
||||
virtual const char * get_type();
|
||||
|
||||
private:
|
||||
BlockDevice *_bd;
|
||||
};
|
||||
|
|
|
@ -16,9 +16,11 @@
|
|||
|
||||
#include "SlicingBlockDevice.h"
|
||||
#include "platform/mbed_assert.h"
|
||||
#include "stddef.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
||||
SlicingBlockDevice::SlicingBlockDevice(BlockDevice *bd, bd_addr_t start, bd_addr_t stop)
|
||||
: _bd(bd)
|
||||
, _start_from_end(false), _start(start)
|
||||
|
@ -119,4 +121,14 @@ bd_size_t SlicingBlockDevice::size() const
|
|||
return _stop - _start;
|
||||
}
|
||||
|
||||
const char * SlicingBlockDevice::get_type()
|
||||
{
|
||||
if (_bd != NULL) {
|
||||
return _bd->get_type();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
|
|
|
@ -163,6 +163,12 @@ public:
|
|||
*/
|
||||
virtual bd_size_t size() const;
|
||||
|
||||
/** Get the BlockDevice class type.
|
||||
*
|
||||
* @return A string represent the BlockDevice class type.
|
||||
*/
|
||||
virtual const char * get_type();
|
||||
|
||||
protected:
|
||||
BlockDevice *_bd;
|
||||
bool _start_from_end;
|
||||
|
|
Loading…
Reference in New Issue