stmhal: Add config option for storage to use second flash segment.

When enabled this allows the internal storage to be split over 2
contiguous regions of flash (two segments), and so the storage can be
increased.

This option is disabled by default, giving original behaviour.
This commit is contained in:
Damien George 2015-06-27 23:27:23 +01:00
parent fa1cdb09fc
commit 0807139c1d
1 changed files with 45 additions and 18 deletions

View File

@ -37,24 +37,36 @@
#if defined(STM32F405xx) || defined(STM32F407xx) #if defined(STM32F405xx) || defined(STM32F407xx)
#define CACHE_MEM_START_ADDR (0x10000000) // CCM data RAM, 64k #define CACHE_MEM_START_ADDR (0x10000000) // CCM data RAM, 64k
#define FLASH_PART1_START_BLOCK (0x100)
#define FLASH_PART1_NUM_BLOCKS (224) // 16k+16k+16k+64k=112k
#define FLASH_MEM_START_ADDR (0x08004000) // sector 1, 16k
#define FLASH_SECTOR_SIZE_MAX (0x10000) // 64k max, size of CCM #define FLASH_SECTOR_SIZE_MAX (0x10000) // 64k max, size of CCM
#define FLASH_MEM_SEG1_START_ADDR (0x08004000) // sector 1
#define FLASH_MEM_SEG1_NUM_BLOCKS (224) // sectors 1,2,3,4: 16k+16k+16k+64k=112k
// enable this to get an extra 64k of storage (uses the last sector of the flash)
#if 0
#define FLASH_MEM_SEG2_START_ADDR (0x080e0000) // sector 11
#define FLASH_MEM_SEG2_NUM_BLOCKS (128) // sector 11: 128k
#endif
#elif defined(STM32F401xE) || defined(STM32F411xE) #elif defined(STM32F401xE) || defined(STM32F411xE)
STATIC byte flash_cache_mem[0x4000] __attribute__((aligned(4))); // 16k STATIC byte flash_cache_mem[0x4000] __attribute__((aligned(4))); // 16k
#define CACHE_MEM_START_ADDR (&flash_cache_mem[0]) #define CACHE_MEM_START_ADDR (&flash_cache_mem[0])
#define FLASH_PART1_START_BLOCK (0x100)
#define FLASH_PART1_NUM_BLOCKS (128) // 16k+16k+16k+16k(of64k)=64k
#define FLASH_MEM_START_ADDR (0x08004000) // sector 1, 16k
#define FLASH_SECTOR_SIZE_MAX (0x4000) // 16k max due to size of cache buffer #define FLASH_SECTOR_SIZE_MAX (0x4000) // 16k max due to size of cache buffer
#define FLASH_MEM_SEG1_START_ADDR (0x08004000) // sector 1
#define FLASH_MEM_SEG1_NUM_BLOCKS (128) // sectors 1,2,3,4: 16k+16k+16k+16k(of 64k)=64k
#else #else
#error "no storage support for this MCU" #error "no storage support for this MCU"
#endif #endif
#if !defined(FLASH_MEM_SEG2_START_ADDR)
#define FLASH_MEM_SEG2_START_ADDR (0) // no second segment
#define FLASH_MEM_SEG2_NUM_BLOCKS (0) // no second segment
#endif
#define FLASH_PART1_START_BLOCK (0x100)
#define FLASH_PART1_NUM_BLOCKS (FLASH_MEM_SEG1_NUM_BLOCKS + FLASH_MEM_SEG2_NUM_BLOCKS)
#define FLASH_FLAG_DIRTY (1) #define FLASH_FLAG_DIRTY (1)
#define FLASH_FLAG_FORCE_WRITE (2) #define FLASH_FLAG_FORCE_WRITE (2)
#define FLASH_FLAG_ERASED (4) #define FLASH_FLAG_ERASED (4)
@ -212,6 +224,21 @@ static void build_partition(uint8_t *buf, int boot, int type, uint32_t start_blo
buf[15] = num_blocks >> 24; buf[15] = num_blocks >> 24;
} }
static uint32_t convert_block_to_flash_addr(uint32_t block) {
if (FLASH_PART1_START_BLOCK <= block && block < FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS) {
// a block in partition 1
block -= FLASH_PART1_START_BLOCK;
if (block < FLASH_MEM_SEG1_NUM_BLOCKS) {
return FLASH_MEM_SEG1_START_ADDR + block * FLASH_BLOCK_SIZE;
} else if (block < FLASH_MEM_SEG1_NUM_BLOCKS + FLASH_MEM_SEG2_NUM_BLOCKS) {
return FLASH_MEM_SEG2_START_ADDR + (block - FLASH_MEM_SEG1_NUM_BLOCKS) * FLASH_BLOCK_SIZE;
}
// can add more flash segments here if needed, following above pattern
}
// bad block
return -1;
}
bool storage_read_block(uint8_t *dest, uint32_t block) { bool storage_read_block(uint8_t *dest, uint32_t block) {
//printf("RD %u\n", block); //printf("RD %u\n", block);
if (block == 0) { if (block == 0) {
@ -231,16 +258,16 @@ bool storage_read_block(uint8_t *dest, uint32_t block) {
return true; return true;
} else if (FLASH_PART1_START_BLOCK <= block && block < FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS) { } else {
// non-MBR block, get data from flash memory, possibly via cache // non-MBR block, get data from flash memory, possibly via cache
uint32_t flash_addr = FLASH_MEM_START_ADDR + (block - FLASH_PART1_START_BLOCK) * FLASH_BLOCK_SIZE; uint32_t flash_addr = convert_block_to_flash_addr(block);
if (flash_addr == -1) {
// bad block number
return false;
}
uint8_t *src = flash_cache_get_addr_for_read(flash_addr); uint8_t *src = flash_cache_get_addr_for_read(flash_addr);
memcpy(dest, src, FLASH_BLOCK_SIZE); memcpy(dest, src, FLASH_BLOCK_SIZE);
return true; return true;
} else {
// bad block number
return false;
} }
} }
@ -250,15 +277,15 @@ bool storage_write_block(const uint8_t *src, uint32_t block) {
// can't write MBR, but pretend we did // can't write MBR, but pretend we did
return true; return true;
} else if (FLASH_PART1_START_BLOCK <= block && block < FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS) { } else {
// non-MBR block, copy to cache // non-MBR block, copy to cache
uint32_t flash_addr = FLASH_MEM_START_ADDR + (block - FLASH_PART1_START_BLOCK) * FLASH_BLOCK_SIZE; uint32_t flash_addr = convert_block_to_flash_addr(block);
if (flash_addr == -1) {
// bad block number
return false;
}
uint8_t *dest = flash_cache_get_addr_for_write(flash_addr); uint8_t *dest = flash_cache_get_addr_for_write(flash_addr);
memcpy(dest, src, FLASH_BLOCK_SIZE); memcpy(dest, src, FLASH_BLOCK_SIZE);
return true; return true;
} else {
// bad block number
return false;
} }
} }