Add get_type method to block devices.

pull/9135/head
Yossi Levy 2018-11-27 18:44:30 +02:00
parent a8fa6ec38b
commit 1d71fb1c9f
36 changed files with 340 additions and 4 deletions

View File

@ -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.

View File

@ -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;

View File

@ -248,4 +248,9 @@ bd_size_t FlashIAPBlockDevice::size() const
return _size;
}
const char * FlashIAPBlockDevice::get_type()
{
return "FLASHIAP";
}
#endif /* DEVICE_FLASH */

View File

@ -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;

View File

@ -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)
{

View File

@ -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;

View File

@ -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";
}

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -472,6 +472,11 @@ int SPIFBlockDevice::get_erase_value() const
return 0xFF;
}
const char * SPIFBlockDevice::get_type()
{
return "SPIF";
}
/***************************************************/
/*********** SPI Driver API Functions **************/
/***************************************************/

View File

@ -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

View File

@ -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" |

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -283,4 +283,9 @@ bd_size_t ChainingBlockDevice::size() const
return _size;
}
const char * ChainingBlockDevice::get_type()
{
return "CHAINING";
}
} // namespace mbed

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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
/** @}*/

View File

@ -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;
};

View File

@ -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

View File

@ -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;