arch/xtensa/esp32: Allow internal drivers and tasks' stack to be

allocated in an internal heap.

Signed-off-by: Abdelatif Guettouche <abdelatif.guettouche@espressif.com>
This commit is contained in:
Abdelatif Guettouche 2020-09-17 14:22:30 +01:00 committed by Alan Carvalho de Assis
parent bcf3381d06
commit a1318926b4
8 changed files with 185 additions and 4 deletions

View file

@ -94,6 +94,16 @@ config XTENSA_CP_INITSET
is provided by CONFIG_XTENSA_CP_INITSET. Each bit corresponds to one
coprocessor with the same bit layout as for the CPENABLE register.
config XTENSA_USE_SEPERATE_IMEM
bool "Use a seperate heap for internal memory"
default n
config XTENSA_IMEM_REGION_SIZE
hex "DRAM region size for internal use"
depends on XTENSA_USE_SEPERATE_IMEM
range 0x2000 0x28000
default 0x28000
source arch/xtensa/src/lx6/Kconfig
if ARCH_CHIP_ESP32
source arch/xtensa/src/esp32/Kconfig

View file

@ -91,6 +91,14 @@ extern "C"
#define EXTERN extern
#endif
#ifdef CONFIG_XTENSA_USE_SEPERATE_IMEM
void up_imm_initialize(void);
FAR void *up_imm_malloc(size_t size);
void up_imm_free(FAR void *mem);
FAR void *up_imm_memalign(size_t alignment, size_t size);
bool up_imm_heapmember(FAR void *mem);
#endif
#undef EXTERN
#ifdef __cplusplus
}

View file

@ -73,6 +73,18 @@
#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK)
#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
#ifdef CONFIG_XTENSA_USE_SEPERATE_IMEM
# define UMM_MALLOC(s) up_imm_malloc(s)
# define UMM_MEMALIGN(a,s) up_imm_memalign(a,s)
# define UMM_FREE(p) up_imm_free(p)
# define UMM_HEAPMEMEBER(p) up_imm_heapmember(p)
#else
# define UMM_MALLOC(s) kumm_malloc(s)
# define UMM_MEMALIGN(a,s) kumm_memalign(a,s)
# define UMM_FREE(p) kumm_free(p)
# define UMM_HEAPMEMEBER(p) umm_heapmember(p)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -183,7 +195,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
/* Use the user-space allocator if this is a task or pthread */
tcb->stack_alloc_ptr =
(uint32_t *)kumm_memalign(TLS_STACK_ALIGN, stack_size);
(uint32_t *)UMM_MEMALIGN(TLS_STACK_ALIGN, stack_size);
}
#else /* CONFIG_TLS_ALIGNED */
@ -199,7 +211,7 @@ int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype)
{
/* Use the user-space allocator if this is a task or pthread */
tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size);
tcb->stack_alloc_ptr = (uint32_t *)UMM_MALLOC(stack_size);
}
#endif /* CONFIG_TLS_ALIGNED */

View file

@ -108,6 +108,12 @@ void up_initialize(void)
xtensa_pminitialize();
#endif
/* Initialize the internal heap */
#ifdef CONFIG_XTENSA_USE_SEPERATE_IMEM
up_imm_initialize();
#endif
#ifdef CONFIG_ARCH_DMA
/* Initialize the DMA subsystem if the weak function xtensa_dma_initialize
* has been brought into the build
@ -208,5 +214,6 @@ void up_initialize(void)
/* Initialize USB -- device and/or host */
up_usbinitialize();
board_autoled_on(LED_IRQSENABLED);
}

View file

@ -47,6 +47,22 @@
#include "xtensa.h"
/****************************************************************************
* Pre-processor Macros
****************************************************************************/
#ifdef CONFIG_XTENSA_USE_SEPERATE_IMEM
# define UMM_MALLOC(s) up_imm_malloc(s)
# define UMM_MEMALIGN(a,s) up_imm_memalign(a,s)
# define UMM_FREE(p) up_imm_free(p)
# define UMM_HEAPMEMEBER(p) up_imm_heapmember(p)
#else
# define UMM_MALLOC(s) kumm_malloc(s)
# define UMM_MEMALIGN(a,s) kumm_memalign(a,s)
# define UMM_FREE(p) kumm_free(p)
# define UMM_HEAPMEMEBER(p) umm_heapmember(p)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -103,9 +119,9 @@ void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype)
{
/* Use the user-space allocator if this is a task or pthread */
if (umm_heapmember(dtcb->stack_alloc_ptr))
if (UMM_HEAPMEMEBER(dtcb->stack_alloc_ptr))
{
kumm_free(dtcb->stack_alloc_ptr);
UMM_FREE(dtcb->stack_alloc_ptr);
}
}

View file

@ -99,6 +99,10 @@ endif
CHIP_CSRCS += esp32_rtc.c
ifeq ($(CONFIG_XTENSA_USE_SEPERATE_IMEM),y)
CHIP_CSRCS += esp32_imm.c
endif
ifeq ($(CONFIG_ESP32_I2C),y)
CHIP_CSRCS += esp32_i2c.c
endif

View file

@ -77,8 +77,13 @@
void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
{
board_autoled_on(LED_HEAPALLOCATE);
#ifdef CONFIG_XTENSA_USE_SEPERATE_IMEM
*heap_start = (FAR void *)&_sheap + CONFIG_XTENSA_IMEM_REGION_SIZE;
*heap_size = (size_t)((uintptr_t)&_eheap - (uintptr_t)*heap_start);
#else
*heap_start = (FAR void *)&_sheap;
*heap_size = (size_t)((uintptr_t)&_eheap - (uintptr_t)&_sheap);
#endif
}
/****************************************************************************

View file

@ -0,0 +1,119 @@
/****************************************************************************
* arch/xtensa/src/esp32/esp32_imm.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/arch.h>
#include <nuttx/mm/mm.h>
#include "xtensa.h"
#if CONFIG_XTENSA_USE_SEPERATE_IMEM
/****************************************************************************
* Private Data
****************************************************************************/
struct mm_heap_s g_iheap;
/****************************************************************************
* Name: up_imm_initialize
*
* Description:
* Initialize the internal heap.
*
****************************************************************************/
void up_imm_initialize(void)
{
void *start;
size_t size;
start = (FAR void *)&_sheap;
size = CONFIG_XTENSA_IMEM_REGION_SIZE;
mm_initialize(&g_iheap, start, size);
}
/****************************************************************************
* Name: up_imm_malloc
*
* Description:
* Allocate memory from the internal heap.
*
****************************************************************************/
FAR void *up_imm_malloc(size_t size)
{
return mm_malloc(&g_iheap, size);
}
/****************************************************************************
* Name: up_imm_free
*
* Description:
* Free memory from the internal heap.
*
****************************************************************************/
void up_imm_free(FAR void *mem)
{
mm_free(&g_iheap, mem);
}
/****************************************************************************
* Name: up_imm_memalign
*
* Description:
* memalign requests more than enough space from malloc, finds a region
* within that chunk that meets the alignment request and then frees any
* leading or trailing space.
*
* The alignment argument must be a power of two (not checked). 8-byte
* alignment is guaranteed by normal malloc calls.
*
****************************************************************************/
FAR void *up_imm_memalign(size_t alignment, size_t size)
{
return mm_memalign(&g_iheap, alignment, size);
}
/****************************************************************************
* Name: up_imm_heapmember
*
* Description:
* Check if an address lies in the internal heap.
*
* Parameters:
* mem - The address to check
*
* Return Value:
* true if the address is a member of the internal heap. false if not
*
****************************************************************************/
bool up_imm_heapmember(FAR void *mem)
{
return mm_heapmember(&g_iheap, mem);
}
#endif /* CONFIG_XTENSA_USE_SEPERATE_IMEM */