Merge pull request #3 from ARMmbed/david_init_changes

Change driver initialization behavior:
pull/7774/head
Christopher Haster 2018-08-25 12:17:49 -05:00 committed by GitHub
commit 8f1ac821f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 74 additions and 57 deletions

View File

@ -17,6 +17,7 @@
#ifdef DEVICE_FLASH #ifdef DEVICE_FLASH
#include "FlashIAPBlockDevice.h" #include "FlashIAPBlockDevice.h"
#include "mbed_critical.h"
#include "mbed.h" #include "mbed.h"
@ -35,23 +36,67 @@
#define DEBUG_PRINTF(...) #define DEBUG_PRINTF(...)
#endif #endif
FlashIAPBlockDevice::FlashIAPBlockDevice(uint32_t address, uint32_t size) FlashIAPBlockDevice::FlashIAPBlockDevice()
: _flash(), _base(address), _size(size) : _flash(), _base(0), _size(0), _is_initialized(false), _init_ref_count(0)
{ {
DEBUG_PRINTF("FlashIAPBlockDevice: %" PRIX32 " %" PRIX32 "\r\n", address, size); 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() int FlashIAPBlockDevice::init()
{ {
DEBUG_PRINTF("init\r\n"); 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() int FlashIAPBlockDevice::deinit()
{ {
DEBUG_PRINTF("deinit\r\n"); 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(); return _flash.deinit();
} }
@ -65,7 +110,7 @@ int FlashIAPBlockDevice::read(void *buffer,
int result = BD_ERROR_DEVICE_ERROR; int result = BD_ERROR_DEVICE_ERROR;
/* Check that the address and size are properly aligned and fit. */ /* 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. */ /* Convert virtual address to the physical address for the device. */
bd_addr_t physical_address = _base + virtual_address; bd_addr_t physical_address = _base + virtual_address;
@ -89,7 +134,7 @@ int FlashIAPBlockDevice::program(const void *buffer,
int result = BD_ERROR_DEVICE_ERROR; int result = BD_ERROR_DEVICE_ERROR;
/* Check that the address and size are properly aligned and fit. */ /* 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. */ /* Convert virtual address to the physical address for the device. */
bd_addr_t physical_address = _base + virtual_address; 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; int result = BD_ERROR_DEVICE_ERROR;
/* Check that the address and size are properly aligned and fit. */ /* 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. */ /* Convert virtual address to the physical address for the device. */
bd_addr_t physical_address = _base + virtual_address; 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 bd_size_t FlashIAPBlockDevice::get_program_size() const
{ {
if (!_is_initialized) {
return 0;
}
uint32_t page_size = _flash.get_page_size(); uint32_t page_size = _flash.get_page_size();
DEBUG_PRINTF("get_program_size: %" PRIX32 "\r\n", 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 bd_size_t FlashIAPBlockDevice::get_erase_size() const
{ {
if (!_is_initialized) {
return 0;
}
uint32_t erase_size = _flash.get_sector_size(_base); uint32_t erase_size = _flash.get_sector_size(_base);
DEBUG_PRINTF("get_erase_size: %" PRIX32 "\r\n", erase_size); 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 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); uint32_t erase_size = _flash.get_sector_size(_base + addr);
DEBUG_PRINTF("get_erase_size: %" PRIX32 "\r\n", erase_size); DEBUG_PRINTF("get_erase_size: %" PRIX32 "\r\n", erase_size);

View File

@ -22,14 +22,6 @@
#include "BlockDevice.h" #include "BlockDevice.h"
#include <mbed.h> #include <mbed.h>
#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 /** BlockDevice using the FlashIAP API
* *
* @code * @code
@ -39,14 +31,13 @@
*/ */
class FlashIAPBlockDevice : public BlockDevice { class FlashIAPBlockDevice : public BlockDevice {
public: public:
/** Creates a FlashIAPBlockDevice, starting at the given address and /** Creates a FlashIAPBlockDevice **/
* with a certain size. FlashIAPBlockDevice();
*
* @param address Starting address for the BlockDevice MBED_DEPRECATED("Please use default constructor instead")
* @param size Maximum size allocated to this BlockDevice FlashIAPBlockDevice(uint32_t address, uint32_t size = 0);
*/
FlashIAPBlockDevice(uint32_t address = MBED_CONF_FLASHIAP_BLOCK_DEVICE_BASE_ADDRESS, virtual ~FlashIAPBlockDevice();
uint32_t size = MBED_CONF_FLASHIAP_BLOCK_DEVICE_SIZE);
/** Initialize a block device /** Initialize a block device
* *
@ -129,6 +120,8 @@ private:
FlashIAP _flash; FlashIAP _flash;
bd_addr_t _base; bd_addr_t _base;
bd_size_t _size; bd_size_t _size;
bool _is_initialized;
uint32_t _init_ref_count;
}; };
#endif /* DEVICE_FLASH */ #endif /* DEVICE_FLASH */

View File

@ -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. 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: 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. - 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 ## Configuration
None.
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": "<internal flash address where the block device starts>",
"flashiap-block-device.size": "<number of bytes allocated to the internal flash block device>"
}
}
}
```
## Tested on ## Tested on
* Realtek RTL8195AM * K82F
* K64F * K64F

View File

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