diff --git a/UNITTESTS/stubs/EmulatedSD.cpp b/UNITTESTS/stubs/EmulatedSD.cpp new file mode 100644 index 0000000000..40337271aa --- /dev/null +++ b/UNITTESTS/stubs/EmulatedSD.cpp @@ -0,0 +1,103 @@ +#include "EmulatedSD.h" +#include + +class EmulatedSD_Private { +public: + ~EmulatedSD_Private() { + if (fs) { + fclose(fs); + } + } + const char *path; + FILE *fs; + bd_size_t size; +}; + +EmulatedSD::EmulatedSD(const char *path) +{ + _p = new EmulatedSD_Private; + _p->path = path; +} + +EmulatedSD::~EmulatedSD() +{ + delete _p; +} + +int EmulatedSD::init() +{ + _p->fs = fopen(_p->path, "r+"); + if (!_p->fs) { + perror("fdopen():"); + return -1; + } + if (fseek(_p->fs, 0, SEEK_END)) { + perror("fseek()"); + fclose(_p->fs); + _p->fs = nullptr; + return -1; + } + _p->size = ftell(_p->fs); + rewind(_p->fs); + return 0; +} + +int EmulatedSD::deinit() +{ + fclose(_p->fs); + _p->fs = nullptr; +} + +int EmulatedSD::read(void *buffer, bd_addr_t addr, bd_size_t size) +{ + if (!_p->fs) { + return -1; + } + if (fseek(_p->fs, addr, SEEK_SET)) { + perror("fseek()"); + return -1; + } + size_t r = fread(buffer, size, 1, _p->fs); + if (r < 1) { + perror("fread()"); + return -1; + } + return 0; +} + +int EmulatedSD::program(const void *buffer, bd_addr_t addr, bd_size_t size) +{ + if (!_p->fs) { + return -1; + } + if (fseek(_p->fs, addr, SEEK_SET)) { + perror("fseek()"); + return -1; + } + size_t r = fwrite(buffer, size, 1, _p->fs); + if (r < 1) { + perror("fread()"); + return -1; + } + return 0; +} + +bd_size_t EmulatedSD::get_read_size() const +{ + return 512; +} +bd_size_t EmulatedSD::get_program_size() const +{ + return 512; +} +bd_size_t EmulatedSD::size() const +{ + if (!_p->fs) { + return -1; + } + return _p->size; +} +const char *EmulatedSD::get_type() const +{ + return "SD"; +} diff --git a/UNITTESTS/stubs/EmulatedSD.h b/UNITTESTS/stubs/EmulatedSD.h new file mode 100644 index 0000000000..2393ac186e --- /dev/null +++ b/UNITTESTS/stubs/EmulatedSD.h @@ -0,0 +1,77 @@ +#ifndef EMULATEDSD_H +#define EMULATEDSD_H + +#include "features/storage/blockdevice/BlockDevice.h" + +class EmulatedSD_Private; + +class EmulatedSD : public mbed::BlockDevice { +public: + EmulatedSD(const char *path); + ~EmulatedSD(); + + /** Initialize a block device + * + * @return 0 on success or a negative error code on failure + */ + virtual int init(); + + /** Deinitialize a block device + * + * @return 0 on success or a negative error code on failure + */ + virtual int deinit(); + + /** Read blocks from a block device + * + * If a failure occurs, it is not possible to determine how many bytes succeeded + * + * @param buffer Buffer to write blocks to + * @param addr Address of block to begin reading from + * @param size Size to read in bytes, must be a multiple of the read block size + * @return 0 on success or a negative error code on failure + */ + virtual int read(void *buffer, bd_addr_t addr, bd_size_t size); + + /** Program blocks to a block device + * + * The blocks must have been erased prior to being programmed + * + * If a failure occurs, it is not possible to determine how many bytes succeeded + * + * @param buffer Buffer of data to write to blocks + * @param addr Address of block to begin writing to + * @param size Size to write in bytes, must be a multiple of the program block size + * @return 0 on success or a negative error code on failure + */ + virtual int program(const void *buffer, bd_addr_t addr, bd_size_t size); + + /** Get the size of a readable block + * + * @return Size of a readable block in bytes + */ + virtual bd_size_t get_read_size() const; + + /** Get the size of a programmable block + * + * @return Size of a programmable block in bytes + * @note Must be a multiple of the read size + */ + virtual bd_size_t get_program_size() const; + + /** Get the total size of the underlying device + * + * @return Size of the underlying device in bytes + */ + virtual bd_size_t size() const; + + /** Get the BlockDevice class type. + * + * @return A string represent the BlockDevice class type. + */ + virtual const char *get_type() const; +private: + EmulatedSD_Private *_p; +}; + +#endif // EMULATEDSD_H