-
Notifications
You must be signed in to change notification settings - Fork 39
[driver] Block device #328
[driver] Block device #328
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice interface and implementation. The drivers need to inherit the interface though for doxygen to understand this relationship.
} | ||
|
||
struct FilenameA { | ||
static constexpr const char* name = "testA.bin"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to commit the examples/linux/block_device/mirror/testA.bin
and testB.bin
files below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, because otherwise the test*.bin
files have to be created manually by the user (or CI) before running the example.
The is no nice way to create the files from C++.
Idea: Create the file in the SConstruct:
# path to the xpcc root directory
xpccpath = '../../../..'
# create empty `test.bin~` file (if it does not exist)
open('test.bin~', 'a').close()
# execute the common SConstruct file
exec(compile(open(xpccpath + '/scons/SConstruct', "rb").read(), xpccpath + '/scons/SConstruct', 'exec'))
(Filename changed to test.bin~
so that it is ignored by gitignore.)
(Edit: filename test.bin~
)
* @author Raphael Lehmann | ||
* @ingroup storage | ||
*/ | ||
#ifdef __DOXYGEN__ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be inside the class? And the drivers then inherit from this class.
* @return True on success | ||
*/ | ||
xpcc::ResumableResult<bool> | ||
read(uint8_t *buffer, uint32_t address, size_t size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a using address_t = uint32_t;
to use here and then specialize this for implementations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
/** | ||
* \brief Block device using heap (RAM) | ||
* | ||
* Usually not persistant, but at least useful for testing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is useful for battery backed SRAM, some stm32 have up to 4kB of this stuff. Very nice!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this use-case BdHeap
is now extended to optionally use externally supplied memory instead of allocation memory. See here.
#ifndef XPCC_BLOCK_DEVICE_FILE_HPP | ||
#define XPCC_BLOCK_DEVICE_FILE_HPP | ||
|
||
#include <xpcc/processing/resumable.hpp> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and all other drivers should include <xpcc/architecture/interface/block_device.hpp>
and inherit from it.
#ifndef XPCC_BLOCK_DEVICE_SPIFLASH_HPP | ||
#error "Don't include this file directly, use 'block_device_spiflash.hpp' instead!" | ||
#endif | ||
#include "block_device_spiflash.hpp" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope.
#ifndef XPCC_BLOCK_DEVICE_MIRROR_HPP | ||
#error "Don't include this file directly, use 'block_device_mirror.hpp' instead!" | ||
#endif | ||
#include "block_device_mirror.hpp" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? This includes don't hurt and make QtCreators syntax highlighting and auto-completion work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, ok, that's a good enough reason.
#ifndef XPCC_BLOCK_DEVICE_FILE_HPP | ||
#error "Don't include this file directly, use 'block_device_file.hpp' instead!" | ||
#endif | ||
#include "block_device_file.hpp" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See below.
|
||
/** Writes data to one or more blocks after erasing them | ||
* | ||
* The blocks are erased proir to being programmed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pior
|
||
/** Writes data to one or more blocks after erasing them | ||
* | ||
* The blocks are erased proir to being programmed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prior
Oh, and Travis is broken, just ignore it. |
fa13256
to
106f443
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
* \ingroup driver_storage | ||
* \author Raphael Lehmann | ||
*/ | ||
template <typename Spi, typename Cs, size_t flashSize> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On AVR size_t is a 16 bit unsigned int. This wouldn't allow you to use a flash larger than 65535 bytes. You could take a plain uint32_t or something like using flash_size_t = ...
and define it to uint32_t on microcontrollers and size_t on hosted to also support 4GB+ files. The same applies for the size_t function parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wouldn't allow you to use a flash larger than 65535 bytes.
No. You are just unable to write, read or delete >64k memory at once. address
is a uint32_t
, so you can write/read to/from a <=4GBit flash chip in <=64kBit blocks.
For write and read operations you would need a >64k buffer in your AVRs RAM, but erasing a complete 64MBit flash chip at once on AVR is more realistic. Hmmm...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I missed that this size_t
is the template parameter and not an read/write/erase function argument.
I'll change the flashSize
type to uint32_t
here.
#undef XPCC_LOG_LEVEL | ||
#define XPCC_LOG_LEVEL xpcc::log::INFO | ||
|
||
void printMemoryContent(uint8_t* address, std::size_t size) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const uint8_t*
#undef XPCC_LOG_LEVEL | ||
#define XPCC_LOG_LEVEL xpcc::log::INFO | ||
|
||
void printMemoryContent(uint8_t* address, std::size_t size) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const uint8_t*
* Most persistent storage devices require `program()`, `erase()` | ||
* and sometimes `read()` operations to be executed on fixed sized blocks. | ||
*/ | ||
static constexpr std::size_t BlockSizeRead = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason for mixing std::size_t and plain size_t? It is guaranteed to be the same type anyway (since C++11).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. I'll change all size_t
to std::size_t
.
(std::size_t
has 385 vs size_t
has only 184 occurrences in xpcc.)
* | ||
* @return BlockDeviceA | ||
*/ | ||
inline BlockDeviceA getBlockDeviceA() {return blockDeviceA;}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning a copy is probably not what you intended. I suppose you meant BlockDeviceA&. Probably being able to copy an spi flash driver object is a bad idea. Maybe deleting the copy constructor and copy assignment operator would prevent bugs like that.
* | ||
* @return BlockDeviceB | ||
*/ | ||
inline BlockDeviceB getBlockDeviceB() {return blockDeviceB;}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BlockDeviceB&
106f443
to
e1e8af3
Compare
This PR adds a block device interface to xpcc, inspired by mbeds block device interface.
Drivers to store data in a SPI SST flash
xpcc::BdSpiFlash
, to store data in a file (on hosted)xpcc::BdFile
and to store data in RAM (for testing purposes)xpcc::BdHeap
are included.Additionally
xpcc::BdMirror
is a virtual block device that behaves like RAID1 devices.For every driver a test is included.
The flash chip driver has been tested on a Nucleo-F429ZI board.