atmel-samd: Switch to MICROPY_PORT_ROOT_POINTERS for the flash cache.

This commit is contained in:
Scott Shawcroft 2016-11-29 14:29:33 -08:00
parent 05c14dfe78
commit 2d9a0c76c5
14 changed files with 33 additions and 50 deletions

View File

@ -11,4 +11,4 @@
#define AUTORESET_DELAY_MS 500
#define FLASH_INCLUDE "internal_flash.h"
#include "internal_flash.h"

View File

@ -19,4 +19,4 @@
#define AUTORESET_DELAY_MS 500
#define FLASH_INCLUDE "spi_flash.h"
#include "spi_flash.h"

View File

@ -8,4 +8,4 @@
#define AUTORESET_DELAY_MS 500
#define FLASH_INCLUDE "internal_flash.h"
#include "internal_flash.h"

View File

@ -8,4 +8,4 @@
#define AUTORESET_DELAY_MS 500
#define FLASH_INCLUDE "internal_flash.h"
#include "internal_flash.h"

View File

@ -20,4 +20,4 @@
#define AUTORESET_DELAY_MS 500
#define FLASH_INCLUDE "spi_flash.h"
#include "spi_flash.h"

View File

@ -7,4 +7,4 @@
#define AUTORESET_DELAY_MS 500
#define FLASH_INCLUDE "internal_flash.h"
#include "internal_flash.h"

View File

@ -34,4 +34,4 @@
#define AUTORESET_DELAY_MS 500
#define FLASH_INCLUDE "spi_flash.h"
#include "spi_flash.h"

View File

@ -7,4 +7,4 @@
#define AUTORESET_DELAY_MS 500
#define FLASH_INCLUDE "internal_flash.h"
#include "internal_flash.h"

View File

@ -242,8 +242,6 @@ mp_uint_t internal_flash_write_blocks(const uint8_t *src, uint32_t block_num, ui
return 0; // success
}
void mark_flash_cache_for_gc(void) {}
/******************************************************************************/
// MicroPython bindings
//

View File

@ -30,6 +30,8 @@
#include "mpconfigport.h"
#define FLASH_ROOT_POINTERS (0)
#define INTERNAL_FLASH_BLOCK_SIZE (512)
#define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms
@ -47,8 +49,6 @@ bool internal_flash_write_block(const uint8_t *src, uint32_t block);
mp_uint_t internal_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks);
mp_uint_t internal_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks);
void mark_flash_cache_for_gc(void);
extern const struct _mp_obj_type_t internal_flash_type;
struct _fs_user_mount_t;

View File

@ -25,7 +25,6 @@
#include "mpconfigboard.h"
#include "neopixel_status.h"
#include "tick.h"
#include FLASH_INCLUDE
fs_user_mount_t fs_user_mount_flash;
@ -341,7 +340,6 @@ void gc_collect(void) {
// This naively collects all object references from an approximate stack
// range.
gc_collect_root(&dummy, ((mp_uint_t)stack_top - (mp_uint_t)&dummy) / sizeof(mp_uint_t));
mark_flash_cache_for_gc();
gc_collect_end();
gc_dump_info();
}

View File

@ -158,5 +158,6 @@ extern const struct _mp_obj_module_t uheap_module;
const char *readline_hist[8]; \
vstr_t *repl_line; \
mp_obj_t mp_kbd_exception; \
FLASH_ROOT_POINTERS \
#endif // __INCLUDED_MPCONFIGPORT_H

View File

@ -71,9 +71,6 @@ static uint32_t current_sector;
// cache.
static uint32_t dirty_mask;
// We use this when we can allocate the whole cache in RAM.
static uint8_t** ram_cache;
// Address of the scratch flash sector.
#define SCRATCH_SECTOR (flash_size - sector_size)
@ -239,7 +236,7 @@ void spi_flash_init(void) {
current_sector = NO_SECTOR_LOADED;
dirty_mask = 0;
ram_cache = NULL;
MP_STATE_VM(flash_ram_cache) = NULL;
spi_flash_is_initialised = true;
}
@ -291,8 +288,8 @@ static bool flush_scratch_flash(void) {
static bool allocate_ram_cache(void) {
uint8_t blocks_per_sector = sector_size / FLASH_BLOCK_SIZE;
uint8_t pages_per_block = FLASH_BLOCK_SIZE / page_size;
ram_cache = gc_alloc(blocks_per_sector * pages_per_block * sizeof(uint32_t), false);
if (ram_cache == NULL) {
MP_STATE_VM(flash_ram_cache) = gc_alloc(blocks_per_sector * pages_per_block * sizeof(uint32_t), false);
if (MP_STATE_VM(flash_ram_cache) == NULL) {
return false;
}
// Declare i and j outside the loops in case we fail to allocate everything
@ -307,7 +304,7 @@ static bool allocate_ram_cache(void) {
success = false;
break;
}
ram_cache[i * pages_per_block + j] = page_cache;
MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j] = page_cache;
}
if (!success) {
break;
@ -320,12 +317,12 @@ static bool allocate_ram_cache(void) {
i++;
for (; i > 0; i--) {
for (; j > 0; j--) {
gc_free(ram_cache[(i - 1) * pages_per_block + (j - 1)]);
gc_free(MP_STATE_VM(flash_ram_cache)[(i - 1) * pages_per_block + (j - 1)]);
}
j = pages_per_block;
}
gc_free(ram_cache);
ram_cache = NULL;
gc_free(MP_STATE_VM(flash_ram_cache));
MP_STATE_VM(flash_ram_cache) = NULL;
}
return success;
}
@ -343,7 +340,7 @@ static bool flush_ram_cache(bool keep_cache) {
for (uint8_t j = 0; j < pages_per_block; j++) {
copy_to_ram_ok = read_flash(
current_sector + (i * pages_per_block + j) * page_size,
ram_cache[i * pages_per_block + j],
MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j],
page_size);
if (!copy_to_ram_ok) {
break;
@ -364,17 +361,17 @@ static bool flush_ram_cache(bool keep_cache) {
for (uint8_t i = 0; i < sector_size / FLASH_BLOCK_SIZE; i++) {
for (uint8_t j = 0; j < pages_per_block; j++) {
write_flash(current_sector + (i * pages_per_block + j) * page_size,
ram_cache[i * pages_per_block + j],
MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j],
page_size);
if (!keep_cache) {
gc_free(ram_cache[i * pages_per_block + j]);
gc_free(MP_STATE_VM(flash_ram_cache)[i * pages_per_block + j]);
}
}
}
// We're done with the cache for now so give it back.
if (!keep_cache) {
gc_free(ram_cache);
ram_cache = NULL;
gc_free(MP_STATE_VM(flash_ram_cache));
MP_STATE_VM(flash_ram_cache) = NULL;
}
return true;
}
@ -391,7 +388,7 @@ static void spi_flash_flush_keep_cache(bool keep_cache) {
temp_status_color(0x8f, 0x00, 0x00);
#endif
// If we've cached to the flash itself flush from there.
if (ram_cache == NULL) {
if (MP_STATE_VM(flash_ram_cache) == NULL) {
flush_scratch_flash();
} else {
flush_ram_cache(keep_cache);
@ -494,11 +491,11 @@ bool spi_flash_read_block(uint8_t *dest, uint32_t block) {
uint8_t mask = 1 << (block_index);
// We're reading from the currently cached sector.
if (current_sector == this_sector && (mask & dirty_mask) > 0) {
if (ram_cache != NULL) {
if (MP_STATE_VM(flash_ram_cache) != NULL) {
uint8_t pages_per_block = FLASH_BLOCK_SIZE / page_size;
for (int i = 0; i < pages_per_block; i++) {
memcpy(dest + i * page_size,
ram_cache[block_index * pages_per_block + i],
MP_STATE_VM(flash_ram_cache)[block_index * pages_per_block + i],
page_size);
}
return true;
@ -534,7 +531,7 @@ bool spi_flash_write_block(const uint8_t *data, uint32_t block) {
if (current_sector != NO_SECTOR_LOADED) {
spi_flash_flush_keep_cache(true);
}
if (ram_cache == NULL && !allocate_ram_cache()) {
if (MP_STATE_VM(flash_ram_cache) == NULL && !allocate_ram_cache()) {
erase_sector(SCRATCH_SECTOR);
wait_for_flash_ready();
}
@ -543,10 +540,10 @@ bool spi_flash_write_block(const uint8_t *data, uint32_t block) {
}
dirty_mask |= mask;
// Copy the block to the appropriate cache.
if (ram_cache != NULL) {
if (MP_STATE_VM(flash_ram_cache) != NULL) {
uint8_t pages_per_block = FLASH_BLOCK_SIZE / page_size;
for (int i = 0; i < pages_per_block; i++) {
memcpy(ram_cache[block_index * pages_per_block + i],
memcpy(MP_STATE_VM(flash_ram_cache)[block_index * pages_per_block + i],
data + i * page_size,
page_size);
}
@ -576,19 +573,6 @@ mp_uint_t spi_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_
return 0; // success
}
void mark_flash_cache_for_gc(void) {
if (current_sector != NO_SECTOR_LOADED && ram_cache != NULL) {
gc_mark_block(ram_cache);
uint8_t blocks_per_sector = sector_size / FLASH_BLOCK_SIZE;
uint8_t pages_per_block = FLASH_BLOCK_SIZE / page_size;
for (uint8_t i = 0; i < blocks_per_sector; i++) {
for (uint8_t j = 0; j < pages_per_block; j++) {
gc_mark_block(ram_cache[i * pages_per_block + j]);
}
}
}
}
/******************************************************************************/
// MicroPython bindings
//

View File

@ -30,6 +30,10 @@
#include "mpconfigport.h"
// We use this when we can allocate the whole cache in RAM.
#define FLASH_ROOT_POINTERS \
uint8_t** flash_ram_cache; \
// Erase sector size.
#define SPI_FLASH_SECTOR_SIZE (0x1000 - 100)
@ -48,8 +52,6 @@ bool spi_flash_write_block(const uint8_t *src, uint32_t block);
mp_uint_t spi_flash_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks);
mp_uint_t spi_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks);
void mark_flash_cache_for_gc(void);
extern const struct _mp_obj_type_t spi_flash_type;
struct _fs_user_mount_t;