mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #3 from ARMmbed/david_init_changes
Change driver initialization behavior:pull/7774/head
commit
8f1ac821f1
|
@ -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);
|
||||
|
|
|
@ -22,14 +22,6 @@
|
|||
#include "BlockDevice.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
|
||||
*
|
||||
* @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 */
|
||||
|
|
18
README.md
18
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": "<internal flash address where the block device starts>",
|
||||
"flashiap-block-device.size": "<number of bytes allocated to the internal flash block device>"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
None.
|
||||
|
||||
## Tested on
|
||||
|
||||
* Realtek RTL8195AM
|
||||
* K82F
|
||||
* K64F
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue