add configuration options to allow SRAM2 to be used for heap, or not at all, and to zero-init it on OS start, or not at all.

This commit is contained in:
ziggurat29 2016-04-26 10:12:13 -05:00
parent 1218ee5f51
commit 31e7f6fd00
3 changed files with 69 additions and 52 deletions

View File

@ -69,6 +69,34 @@ config STM32L4_FLASH_1024KB
endchoice # Embedded FLASH size
comment "SRAM2 Options"
config STM32L4_SRAM2_HEAP
bool "SRAM2 is used for heap"
default n
select STM32L4_SRAM2_INIT
---help---
The STM32L4 SRAM2 region has special properties (power, protection, parity)
which may be used by the application for special purposes. But if these
special properties are not needed, it may be instead added to the heap for
use by malloc().
NOTE: you must also select an appropriate number of memory regions in the
'Memory Management' section.
config STM32L4_SRAM2_INIT
bool "SRAM2 is initialized to zero"
default n
---help---
The STM32L4 SRAM2 region has parity checking. However, when the system
powers on, the memory is in an unknown state, and reads from uninitialized
memory can trigger parity faults from the random data. This can be
avoided by first writing to all locations to force the parity into a valid
state.
However, if the SRAM2 is being used for it's battery-backed capability,
this may be undesireable (because it will destroy the contents). In that
case, the board should handle the initialization itself at the appropriate
time.
menu "STM32L4 Peripheral Support"
# These "hidden" settings determine is a peripheral option is available for the

View File

@ -62,13 +62,13 @@
****************************************************************************/
/* Internal SRAM is available in all members of the STM32L4 family. The
* following definitions must be provided to specify the size and
* location of internal(system) SRAM:
* location of internal (system) SRAM1 and SRAM2:
*
* SRAM1_END 0x20018000
* SRAM2_START 0x10000000
* SRAM2_END 0x10008000
*
* In addition to internal SRAM, SRAM may also be available through the FSMC.
* In addition to internal SRAM, memory may also be available through the FSMC.
* In order to use FSMC SRAM, the following additional things need to be
* present in the NuttX configuration file:
*
@ -80,15 +80,14 @@
* CONFIG_HEAP2_SIZE : The size of the SRAM in the FSMC
* address space
* CONFIG_MM_REGIONS : Must be set to a large enough value to
* include the FSMC SRAM (as determined by
* the rules provided below)
* include the additional regions.
*/
#ifndef CONFIG_STM32L4_FSMC
# undef CONFIG_STM32L4_FSMC_SRAM
#endif
/* MSTM32L4x6xx have 128Kib in two banks, both accessible to DMA:
/* STM32L4x6xx have 128Kib in two banks, both accessible to DMA:
*
* 1) 96KiB of System SRAM beginning at address 0x2000:0000 - 0x2001:8000
* 2) 32KiB of System SRAM beginning at address 0x1000:0000 - 0x1000:8000
@ -105,55 +104,21 @@
#define SRAM2_START 0x10000000
#define SRAM2_END 0x10008000
/* Allocations according to the number of memory regions:
*
* 1 region available:
* - map it to SRAM1
* - warn that SRAM2 is not available for heap
* - if FMC is enabled, warn that it is not available for heap
*
* 2 regions available: map them to SRAM1 and SRAM2
* - map region 1 to SRAM1
* - map region 2 to SRAM2
* - if FMC is enabled, warn that it is not available for heap
*
* 3 or more regions
*
* - map them to SRAM1, SRAM2, FMC
*/
#if CONFIG_MM_REGIONS < 1
# warning heap is not usable
#elif CONFIG_MM_REGIONS < 2
# warning SRAM2 (32k) is NOT available for heap, only SRAM1 (96k) : not enough MM regions
# undef SRAM2_START
# undef SRAM2_END
# if defined(CONFIG_STM32L4_FSMC_SRAM)
# warning FMC SRAM is NOT available for heap : not enough MM regions (1)
# undef CONFIG_STM32L4_FSMC_SRAM
#if defined(STM32L4_SRAM2_HEAP) && defined(CONFIG_STM32L4_FSMC_SRAM_HEAP)
# if CONFIG_MM_REGIONS < 3
# error you need at least 3 memory manager regions to support SRAM2 and FSMC
# endif
#elif CONFIG_MM_REGIONS < 3
# if defined(CONFIG_STM32L4_FSMC_SRAM)
# warning FMC SRAM is NOT available for heap : not enough MM regions (2)
# undef CONFIG_STM32L4_FSMC_SRAM
# endif
#elif CONFIG_MM_REGIONS > 3
/*Everything can be mapped but some entries wont be used -> warn and correct*/
# warning "CONFIG_MM_REGIONS > 3 but I don't know what some of the region(s) are"
# undef CONFIG_MM_REGIONS
# define CONFIG_MM_REGIONS 3
#else
/*Everything can be mapped*/
#endif
#if defined(STM32L4_SRAM2_HEAP) || defined(CONFIG_STM32L4_FSMC_SRAM_HEAP)
# if CONFIG_MM_REGIONS < 2
# error you need at least 2 memory manager regions to support SRAM2 or FSMC
# endif
#endif
#if CONFIG_MM_REGIONS < 1
# warning you have no heap; malloc() will fail. are you sure?
#endif
/* If FSMC SRAM is going to be used as heap, then verify that the starting
* address and size of the external SRAM region has been provided in the
@ -338,6 +303,8 @@ void up_allocate_kheap(FAR void **heap_start, size_t *heap_size)
void up_addregion(void)
{
#ifdef CONFIG_STM32L4_SRAM2_HEAP
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)
/* Allow user-mode access to the SRAM2 heap */
@ -354,7 +321,9 @@ void up_addregion(void)
kumm_addregion((FAR void *)SRAM2_START, SRAM2_END-SRAM2_START);
#ifdef CONFIG_STM32L4_FSMC_SRAM
#endif
#ifdef CONFIG_STM32L4_FSMC_SRAM_HEAP
#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MM_KERNEL_HEAP)
/* Allow user-mode access to the FSMC SRAM user heap memory */

View File

@ -79,6 +79,8 @@
* 0x2001:7fff - End of internal SRAM and end of heap
*/
#define SRAM2_START 0x10000000
#define SRAM2_END 0x10008000
#define IDLE_STACK ((uintptr_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE-4)
#define HEAP_BASE ((uintptr_t)&_ebss+CONFIG_IDLETHREAD_STACKSIZE)
@ -287,6 +289,24 @@ void __start(void)
__asm__ volatile ("sub r10, sp, %0" : : "r" (CONFIG_IDLETHREAD_STACKSIZE - 64) : );
#endif
#ifdef CONFIG_STM32L4_SRAM2_INIT
/* The SRAM2 region is parity checked, but upon power up, it will be in
* a random state and probably invalid with respect to parity, potentially
* generating faults if accessed. If elected, we will write zeros to the
* memory, forcing the parity to be set to a valid state.
* NOTE: this is optional because this may be inappropriate, especially
* if the memory is being used for it's battery backed purpose. In that
* case, the first-time initialization needs to be performed by the board
* under application-specific circumstances. On the other hand, if we're
* using this memory for, say, additional heap space, then this is handy.
*/
for (dest = (uint32_t *)SRAM2_START; dest < (uint32_t *)SRAM2_END; )
{
*dest++ = 0;
}
#endif
/* Configure the UART so that we can get debug output as soon as possible */
stm32l4_clockconfig();