From d1b5c5e995cdbb4003f7cb42ab1282d47a64ad86 Mon Sep 17 00:00:00 2001 From: David Saada Date: Sun, 5 Aug 2018 19:29:22 +0300 Subject: [PATCH] Change driver initialization behavior: - Remove configuration file (base and size taken from driver). - Add initializtion variables (is initialized and rinit ref count). - Add destructor. --- FlashIAPBlockDevice.cpp | 69 +++++++++++++++++++++++++++++++++++++---- FlashIAPBlockDevice.h | 25 ++++++--------- README.md | 18 ++--------- mbed_lib.json | 19 ------------ 4 files changed, 74 insertions(+), 57 deletions(-) delete mode 100644 mbed_lib.json diff --git a/FlashIAPBlockDevice.cpp b/FlashIAPBlockDevice.cpp index 51fb3f4321..a79f57f482 100644 --- a/FlashIAPBlockDevice.cpp +++ b/FlashIAPBlockDevice.cpp @@ -17,6 +17,7 @@ #ifdef DEVICE_FLASH #include "FlashIAPBlockDevice.h" +#include "mbed_critical.h" #include "mbed.h" @@ -35,23 +36,67 @@ #define DEBUG_PRINTF(...) #endif -FlashIAPBlockDevice::FlashIAPBlockDevice(uint32_t address, uint32_t size) - : _flash(), _base(address), _size(size) +FlashIAPBlockDevice::FlashIAPBlockDevice() + : _flash(), _base(0), _size(0), _is_initialized(false), _init_ref_count(0) { DEBUG_PRINTF("FlashIAPBlockDevice: %" PRIX32 " %" PRIX32 "\r\n", address, size); } +FlashIAPBlockDevice::FlashIAPBlockDevice(uint32_t address, uint32_t) + : _flash(), _base(0), _size(0), _is_initialized(false), _init_ref_count(0) +{ + +} + +FlashIAPBlockDevice::~FlashIAPBlockDevice() +{ + deinit(); +} + int FlashIAPBlockDevice::init() { DEBUG_PRINTF("init\r\n"); - return _flash.init(); + if (!_is_initialized) { + _init_ref_count = 0; + } + + uint32_t val = core_util_atomic_incr_u32(&_init_ref_count, 1); + + if (val != 1) { + return BD_ERROR_OK; + } + + int ret = _flash.init(); + + if (ret) { + return ret; + } + + _base = _flash.get_flash_start(); + _size = _flash.get_flash_size(); + + _is_initialized = true; + return ret; } int FlashIAPBlockDevice::deinit() { DEBUG_PRINTF("deinit\r\n"); + if (!_is_initialized) { + _init_ref_count = 0; + return 0; + } + + uint32_t val = core_util_atomic_decr_u32(&_init_ref_count, 1); + + if (val) { + return 0; + } + + _is_initialized = false; + return _flash.deinit(); } @@ -65,7 +110,7 @@ int FlashIAPBlockDevice::read(void *buffer, int result = BD_ERROR_DEVICE_ERROR; /* Check that the address and size are properly aligned and fit. */ - if (is_valid_read(virtual_address, size)) { + if (_is_initialized && is_valid_read(virtual_address, size)) { /* Convert virtual address to the physical address for the device. */ bd_addr_t physical_address = _base + virtual_address; @@ -89,7 +134,7 @@ int FlashIAPBlockDevice::program(const void *buffer, int result = BD_ERROR_DEVICE_ERROR; /* Check that the address and size are properly aligned and fit. */ - if (is_valid_program(virtual_address, size)) { + if (_is_initialized && is_valid_program(virtual_address, size)) { /* Convert virtual address to the physical address for the device. */ bd_addr_t physical_address = _base + virtual_address; @@ -114,7 +159,7 @@ int FlashIAPBlockDevice::erase(bd_addr_t virtual_address, int result = BD_ERROR_DEVICE_ERROR; /* Check that the address and size are properly aligned and fit. */ - if (is_valid_erase(virtual_address, size)) { + if (_is_initialized && is_valid_erase(virtual_address, size)) { /* Convert virtual address to the physical address for the device. */ bd_addr_t physical_address = _base + virtual_address; @@ -135,6 +180,10 @@ bd_size_t FlashIAPBlockDevice::get_read_size() const bd_size_t FlashIAPBlockDevice::get_program_size() const { + if (!_is_initialized) { + return 0; + } + uint32_t page_size = _flash.get_page_size(); DEBUG_PRINTF("get_program_size: %" PRIX32 "\r\n", page_size); @@ -144,6 +193,10 @@ bd_size_t FlashIAPBlockDevice::get_program_size() const bd_size_t FlashIAPBlockDevice::get_erase_size() const { + if (!_is_initialized) { + return 0; + } + uint32_t erase_size = _flash.get_sector_size(_base); DEBUG_PRINTF("get_erase_size: %" PRIX32 "\r\n", erase_size); @@ -153,6 +206,10 @@ bd_size_t FlashIAPBlockDevice::get_erase_size() const bd_size_t FlashIAPBlockDevice::get_erase_size(bd_addr_t addr) const { + if (!_is_initialized) { + return 0; + } + uint32_t erase_size = _flash.get_sector_size(_base + addr); DEBUG_PRINTF("get_erase_size: %" PRIX32 "\r\n", erase_size); diff --git a/FlashIAPBlockDevice.h b/FlashIAPBlockDevice.h index 39ede5f592..54c1a8a486 100644 --- a/FlashIAPBlockDevice.h +++ b/FlashIAPBlockDevice.h @@ -22,14 +22,6 @@ #include "BlockDevice.h" #include -#ifndef MBED_CONF_FLASHIAP_BLOCK_DEVICE_BASE_ADDRESS -#error flashiap-block-device.base-address not set -#endif - -#ifndef MBED_CONF_FLASHIAP_BLOCK_DEVICE_SIZE -#error flashiap-block-device.size not set -#endif - /** BlockDevice using the FlashIAP API * * @code @@ -39,14 +31,13 @@ */ class FlashIAPBlockDevice : public BlockDevice { public: - /** Creates a FlashIAPBlockDevice, starting at the given address and - * with a certain size. - * - * @param address Starting address for the BlockDevice - * @param size Maximum size allocated to this BlockDevice - */ - FlashIAPBlockDevice(uint32_t address = MBED_CONF_FLASHIAP_BLOCK_DEVICE_BASE_ADDRESS, - uint32_t size = MBED_CONF_FLASHIAP_BLOCK_DEVICE_SIZE); + /** Creates a FlashIAPBlockDevice **/ + FlashIAPBlockDevice(); + + MBED_DEPRECATED("Please use default constructor instead") + FlashIAPBlockDevice(uint32_t address, uint32_t size = 0); + + virtual ~FlashIAPBlockDevice(); /** Initialize a block device * @@ -129,6 +120,8 @@ private: FlashIAP _flash; bd_addr_t _base; bd_size_t _size; + bool _is_initialized; + uint32_t _init_ref_count; }; #endif /* DEVICE_FLASH */ diff --git a/README.md b/README.md index 998f1ebbe8..54165e0550 100644 --- a/README.md +++ b/README.md @@ -6,27 +6,13 @@ This driver is **EXPERIMENTAL** and improper usage could kill your board's flash This driver should only be used on platforms where the FlashIAP implementation is using external flash or in conjunction with a filesystem with wear leveling, that can operate on a page size granularity. Additional concerns: -- The BlockDevice API assumes a uniform erase size so the underlying flash must also have uniform sectors. - The FlashIAP may freeze code execution for a long period of time while writing to flash. Not even high-priority irqs will be allowed to run, which may interrupt background processes. ## Configuration - -The driver must be configured with the starting address for the internal flash area reserved for the block device and it's size in bytes. In the application's `mbed_app.json`, add the following lines: - -```json -{ - "target_overrides": { - "K64F": { - "flashiap-block-device.base-address": "", - "flashiap-block-device.size": "" - } - } -} -``` - +None. ## Tested on -* Realtek RTL8195AM +* K82F * K64F diff --git a/mbed_lib.json b/mbed_lib.json deleted file mode 100644 index 49b4cdb7b9..0000000000 --- a/mbed_lib.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "flashiap-block-device", - "config": { - "base-address": { - "help": "Base address for the block device on the external flash.", - "value": "0xFFFFFFFF" - }, - "size": { - "help": "Memory allocated for block device.", - "value": "0" - } - }, - "target_overrides": { - "REALTEK_RTL8195AM": { - "base-address": "0x1C0000", - "size": "0x40000" - } - } -}