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
|
#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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
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.
|
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
|
||||||
|
|
|
@ -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