Skip to content

Commit

Permalink
Malloc support for allocating to DRAM and/or IRAM.
Browse files Browse the repository at this point in the history
  • Loading branch information
ourairquality committed Apr 3, 2018
1 parent 1b4a859 commit 1e6f584
Show file tree
Hide file tree
Showing 18 changed files with 111 additions and 54 deletions.
12 changes: 2 additions & 10 deletions FreeRTOS/Source/portable/esp8266/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,8 @@ portBASE_TYPE xPortStartScheduler( void )
return pdTRUE;
}

/* Determine free heap size via libc sbrk function & mallinfo
/* Determine free heap size via mallinfo
sbrk gives total size in totally unallocated memory,
mallinfo.fordblks gives free space inside area dedicated to heap.
mallinfo is possibly non-portable, although glibc & newlib both support
Expand All @@ -183,14 +182,7 @@ portBASE_TYPE xPortStartScheduler( void )
size_t xPortGetFreeHeapSize( void )
{
struct mallinfo mi = mallinfo();
uint32_t brk_val = (uint32_t) sbrk(0);

intptr_t sp = (intptr_t)xPortSupervisorStackPointer;
if (sp == 0) {
/* scheduler not started */
SP(sp);
}
return sp - brk_val + mi.fordblks;
return mi.fordblks;
}

void vPortEndScheduler( void )
Expand Down
18 changes: 17 additions & 1 deletion FreeRTOS/Source/tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,11 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
/* Allocate space for the stack used by the task being created.
The base of the stack memory stored in the TCB so the task can
be deleted later if required. */

/* Allocate the stack in dram, not iram. */
uint32_t malloc_mask = set_malloc_regions(MALLOC_MASK_DRAM);
pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
set_malloc_regions(malloc_mask);

if( pxNewTCB->pxStack == NULL )
{
Expand All @@ -769,7 +773,10 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
StackType_t *pxStack;

/* Allocate space for the stack used by the task being created. */
/* Allocate the stack in dram, not iram. */
uint32_t malloc_mask = set_malloc_regions(MALLOC_MASK_DRAM);
pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
set_malloc_regions(malloc_mask);

if( pxStack != NULL )
{
Expand Down Expand Up @@ -990,7 +997,16 @@ UBaseType_t x;
{
/* Initialise this task's Newlib reent structure. */
_REENT_INIT_PTR( ( &( pxNewTCB->xNewLib_reent ) ) );
}

if (strcmp(pcName, "ppTask") == 0 ||
strcmp(pcName, "rtc_timer_task") == 0 ||
strcmp(pcName, "Tmr Svc") == 0) {
pxNewTCB->xNewLib_reent.malloc_region_mask = MALLOC_MASK_DRAM;
} else {
pxNewTCB->xNewLib_reent.malloc_region_mask = MALLOC_MASK_PREFER_DRAM;
//pxNewTCB->xNewLib_reent.malloc_region_mask = MALLOC_MASK_PREFER_IRAM;
}
}
#endif

#if( INCLUDE_xTaskAbortDelay == 1 )
Expand Down
29 changes: 29 additions & 0 deletions core/app_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ static void IRAM default_putc(char c) {
void init_newlib_locks(void);
extern uint8_t sdk_wDevCtrl[];
void nano_malloc_insert_chunk(void *start, size_t size);
extern uint8_t _heap_start[];
extern uint8_t _text_end[];
extern uint8_t enable_low_icache;

// .text+0x258
void IRAM sdk_user_start(void) {
Expand Down Expand Up @@ -202,8 +205,13 @@ void IRAM sdk_user_start(void) {
cksum_value = buf32[5 + boot_slot];
ic_flash_addr = (flash_sectors - 3 + boot_slot) * sdk_flashchip.sector_size;
sdk_SPIRead(ic_flash_addr, buf32, sizeof(struct sdk_g_ic_saved_st));

#ifdef ESP8266_ENABLE_LOW_ICACHE
enable_low_icache = ESP8266_ENABLE_LOW_ICACHE;
#endif
Cache_Read_Enable(0, 0, 1);
zero_bss();

sdk_os_install_putc1(default_putc);

/* HACK Reclaim a region of unused bss from wdev.o. This would not be
Expand All @@ -212,6 +220,26 @@ void IRAM sdk_user_start(void) {
* it is in very useful dram. */
nano_malloc_insert_chunk((void *)(sdk_wDevCtrl + 0x2190), 8000);

/* Use all the used DRAM is for the dynamic heap. */
nano_malloc_insert_chunk(_heap_start, 0x3FFFC000 - (uintptr_t)_heap_start);

/* Add unused IRAM to the malloc free list. */
if (enable_low_icache) {
/* The memory region 0x40108000 to 0x4010C000 is used for icache so can
* not be used, but there might still be some unused IRAM */
nano_malloc_insert_chunk(_text_end, 0x40108000 - (uintptr_t)_text_end);
} else {
/* The memory region 0x40108000 to 0x4010C000 is not used as part of the
* instruction cache and is usable as extra IRAM. */
nano_malloc_insert_chunk(_text_end, 0x4010C000 - (uintptr_t)_text_end);
}

/* The preferred memory region to start allocate the early data. If the app
* has ample memory the use the DRAM, other if the app is running low on
* DRAM then it might help the allocated to the IRAM when possible. */
set_malloc_regions(MALLOC_MASK_PREFER_DRAM);
//set_malloc_regions(MALLOC_MASK_PREFER_IRAM);

init_newlib_locks();

if (cksum_magic == 0xffffffff) {
Expand Down Expand Up @@ -361,6 +389,7 @@ void sdk_user_init_task(void *params) {
/* The start up stack is not used after scheduling has started, so all of
* the top area of RAM which was stack can be used for the dynamic heap. */
xPortSupervisorStackPointer = (void *)0x40000000;
nano_malloc_insert_chunk((void *)0x3FFFC000, 0x4000);

sdk_ets_timer_init();
printf("\nESP-Open-SDK ver: %s compiled @ %s %s\n", OS_VERSION_STR, __DATE__, __TIME__);
Expand Down
5 changes: 5 additions & 0 deletions core/include/common_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,5 +117,10 @@
#define IROM __attribute__((section(".irom0.literal"))) const
#endif

uint32_t set_malloc_regions(uint32_t mask);
#define MALLOC_MASK_PREFER_IRAM 0xfffdfffc
#define MALLOC_MASK_PREFER_DRAM 0
#define MALLOC_MASK_DRAM 0xfffffffe
#define MALLOC_MASK_IRAM 0xfffffffd

#endif
45 changes: 18 additions & 27 deletions core/newlib_syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,39 +34,30 @@
#error Too many lwip sockets for the FD_SETSIZE.
#endif

extern void *xPortSupervisorStackPointer;
void *_sbrk_r (struct _reent *r, ptrdiff_t incr)
{
r->_errno = ENOMEM;
return (caddr_t)-1;
}

IRAM void *_sbrk_r (struct _reent *r, ptrdiff_t incr)
/* If there is a restriction on the dram usage then skip this chunk if in dram,
* and if there is a restriction on the iram usage then skip this chunk if in
* iram */
IRAM int _malloc_region_masked(void *r, unsigned int mask)
{
extern char _heap_start; /* linker script defined */
static char * heap_end;
char * prev_heap_end;

if (heap_end == NULL)
heap_end = &_heap_start;
prev_heap_end = heap_end;

intptr_t sp = (intptr_t)xPortSupervisorStackPointer;
if(sp == 0) /* scheduler not started */
SP(sp);

if ((intptr_t)heap_end + incr >= sp)
{
r->_errno = ENOMEM;
return (caddr_t)-1;
if ( ((mask & 1) && (uint32_t)r < 0x40000000) ||
((mask & 2) && (uint32_t)r >= 0x40100000) ) {
return 1;
}

heap_end += incr;

return (caddr_t) prev_heap_end;
return 0;
}


/* Insert a disjoint region into the nano malloc pool. Create a malloc chunk,
* filling the size as newlib nano malloc expects, and then free it. */
void nano_malloc_insert_chunk(void *start, size_t size) {
*(uint32_t *)start = size;
free(start + sizeof(size_t));
uint32_t set_malloc_regions(uint32_t mask)
{
uint32_t malloc_mask = _REENT->malloc_region_mask;
_REENT->malloc_region_mask = mask;
return malloc_mask;
}

/* syscall implementation for stdio write to UART */
Expand Down
19 changes: 18 additions & 1 deletion extras/wificfg/wificfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,11 @@ static const char *http_wificfg_content[] = {
#include "content/wificfg/index.html"
};

extern unsigned nano_malloc_region_total_0;
extern unsigned nano_malloc_region_free_0;
extern unsigned nano_malloc_region_total_1;
extern unsigned nano_malloc_region_free_1;

static int handle_wificfg_index(int s, wificfg_method method,
uint32_t content_length,
wificfg_content_type content_type,
Expand Down Expand Up @@ -632,7 +637,19 @@ static int handle_wificfg_index(int s, wificfg_method method,
xTaskGetTickCount() * portTICK_PERIOD_MS / 1000);
if (wificfg_write_string_chunk(s, buf, buf, len) < 0) return -1;

snprintf(buf, len, "<dt>Free heap</dt><dd>%u bytes</dd>", (int)xPortGetFreeHeapSize());
snprintf(buf, len, "<dt>Free dram heap</dt><dd>%u of %u bytes</dd>",
nano_malloc_region_free_0, nano_malloc_region_total_0);
if (wificfg_write_string_chunk(s, buf, buf, len) < 0) return -1;

set_malloc_regions(MALLOC_MASK_IRAM);
snprintf(buf, len, "<dt>Free iram heap</dt><dd>%u of %u bytes</dd>",
nano_malloc_region_free_1, nano_malloc_region_total_1);
if (wificfg_write_string_chunk(s, buf, buf, len) < 0) return -1;

set_malloc_regions(MALLOC_MASK_PREFER_DRAM);
snprintf(buf, len, "<dt>Free heap</dt><dd>%u of %u bytes</dd>",
nano_malloc_region_free_0 + nano_malloc_region_free_1,
nano_malloc_region_total_0 + nano_malloc_region_total_1);
if (wificfg_write_string_chunk(s, buf, buf, len) < 0) return -1;

snprintf(buf, len, "<dt>Flash ID</dt><dd>0x%08x</dd>", sdk_spi_flash_get_id());
Expand Down
2 changes: 1 addition & 1 deletion libc/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Newlib from git://sourceware.org/git/newlib-cygwin.git with xtensa & locking patches see https://github.com/ourairquality/newlib and built from commit 984b749fb223daab954060c04720933290584f00
Newlib from git://sourceware.org/git/newlib-cygwin.git with xtensa & locking patches see https://github.com/ourairquality/newlib and built from commit e06f70041061344a62c2e5b8f0a602a902e72306

The build commands were:

Expand Down
4 changes: 2 additions & 2 deletions libc/xtensa-lx106-elf/include/pthread.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ int pthread_attr_getschedparam (const pthread_attr_t *__attr,
int pthread_getschedparam (pthread_t __pthread, int *__policy,
struct sched_param *__param);
int pthread_setschedparam (pthread_t __pthread, int __policy,
struct sched_param *__param);
const struct sched_param *__param);

/* Set Scheduling Priority of a Thread */
int pthread_setschedprio (pthread_t thread, int prio);
Expand Down Expand Up @@ -190,7 +190,7 @@ int pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *__attr,

int pthread_mutex_setprioceiling (pthread_mutex_t *__mutex,
int __prioceiling, int *__old_ceiling);
int pthread_mutex_getprioceiling (pthread_mutex_t *__mutex,
int pthread_mutex_getprioceiling (const pthread_mutex_t *__restrict __mutex,
int *__prioceiling);

#endif /* _POSIX_THREAD_PRIO_PROTECT */
Expand Down
7 changes: 3 additions & 4 deletions libc/xtensa-lx106-elf/include/stdlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,7 @@ void qsort (void *__base, size_t __nmemb, size_t __size, __compar_fn_t _compar);
int rand (void);
void * realloc (void *__r, size_t __size) _NOTHROW;
#if __BSD_VISIBLE
void *reallocarray(void *, size_t, size_t) __result_use_check __alloc_size(2)
__alloc_size(3);
void *reallocarray(void *, size_t, size_t) __result_use_check __alloc_size((2,3));
void * reallocf (void *__r, size_t __size);
#endif
#if __BSD_VISIBLE || __XSI_VISIBLE >= 4
Expand Down Expand Up @@ -329,8 +328,8 @@ extern long double strtold (const char *__restrict, char **__restrict);
* If we're in a mode greater than C99, expose C11 functions.
*/
#if __ISO_C_VISIBLE >= 2011
void * aligned_alloc(size_t, size_t) __malloc_like __alloc_align(1)
__alloc_size(2);
void * aligned_alloc(size_t, size_t) __malloc_like __alloc_align((1))
__alloc_size((2));
int at_quick_exit(void (*)(void));
_Noreturn void
quick_exit(int);
Expand Down
3 changes: 3 additions & 0 deletions libc/xtensa-lx106-elf/include/sys/_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,10 @@ typedef _CLOCK_T_ __clock_t;
#endif
typedef _TIME_T_ __time_t;

#ifndef __machine_clockid_t_defined
#define _CLOCKID_T_ unsigned long
#endif

typedef _CLOCKID_T_ __clockid_t;

#define _TIMER_T_ unsigned long
Expand Down
4 changes: 2 additions & 2 deletions libc/xtensa-lx106-elf/include/sys/cdefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,12 +258,12 @@
#define __section(x) __attribute__((__section__(x)))
#endif
#if __GNUC_PREREQ__(4, 3) || __has_attribute(__alloc_size__)
#define __alloc_size(x) __attribute__((__alloc_size__(x)))
#define __alloc_size(x) __attribute__((__alloc_size__ x))
#else
#define __alloc_size(x)
#endif
#if __GNUC_PREREQ__(4, 9) || __has_attribute(__alloc_align__)
#define __alloc_align(x) __attribute__((__alloc_align__(x)))
#define __alloc_align(x) __attribute__((__alloc_align__ x))
#else
#define __alloc_align(x)
#endif
Expand Down
13 changes: 8 additions & 5 deletions libc/xtensa-lx106-elf/include/sys/reent.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,9 @@ extern void __sinit (struct _reent *);
__sinit (ptr); \
} \
while (0)
#else
#else /* _REENT_SMALL && !_REENT_GLOBAL_STDIO_STREAMS */
# define _REENT_SMALL_CHECK_INIT(ptr) /* nothing */
#endif
#endif /* _REENT_SMALL && !_REENT_GLOBAL_STDIO_STREAMS */

struct __sFILE {
unsigned char *_p; /* current position in (some) buffer */
Expand Down Expand Up @@ -416,6 +416,8 @@ struct _reent
__FILE *__sf; /* file descriptors */
struct _misc_reent *_misc; /* strtok, multibyte states */
char *_signal_buf; /* strsignal */

unsigned int malloc_region_mask;
};

#ifdef _REENT_GLOBAL_STDIO_STREAMS
Expand Down Expand Up @@ -453,7 +455,7 @@ extern __FILE __sf[3];
(var)->_stderr = &__sf[2]; \
}

#else
#else /* _REENT_GLOBAL_STDIO_STREAMS */

extern const struct __sFILE_fake __sf_fake_stdin;
extern const struct __sFILE_fake __sf_fake_stdout;
Expand Down Expand Up @@ -482,7 +484,8 @@ extern const struct __sFILE_fake __sf_fake_stderr;
{_NULL, 0, _NULL}, \
_NULL, \
_NULL, \
_NULL \
_NULL, \
0 \
}

#define _REENT_INIT_PTR_ZEROED(var) \
Expand All @@ -491,7 +494,7 @@ extern const struct __sFILE_fake __sf_fake_stderr;
(var)->_stderr = (__FILE *)&__sf_fake_stderr; \
}

#endif
#endif /* _REENT_GLOBAL_STDIO_STREAMS */

/* Only add assert() calls if we are specified to debug. */
#ifdef _REENT_CHECK_DEBUG
Expand Down
Binary file modified libc/xtensa-lx106-elf/lib/crt0.o
Binary file not shown.
Binary file modified libc/xtensa-lx106-elf/lib/libc.a
Binary file not shown.
Binary file modified libc/xtensa-lx106-elf/lib/libg.a
Binary file not shown.
Binary file modified libc/xtensa-lx106-elf/lib/libm.a
Binary file not shown.
2 changes: 2 additions & 0 deletions lwip/esp_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,9 @@ size_t ooseq_bytes_limit(struct tcp_pcb *pcb)
ooseq_blen += p->tot_len;
}

uint32_t malloc_mask = set_malloc_regions(MALLOC_MASK_DRAM);
size_t free = xPortGetFreeHeapSize();
set_malloc_regions(malloc_mask);
ssize_t target = ((ssize_t)free - 8000) + ooseq_blen;

if (target < 0) {
Expand Down
2 changes: 1 addition & 1 deletion lwip/lwip
Submodule lwip updated 44 files
+2 −0 doc/doxygen/lwip.Doxyfile
+8 −3 src/Filelists.mk
+3 −1 src/api/tcpip.c
+20 −35 src/apps/altcp_tls/altcp_tls_mbedtls.c
+5 −7 src/apps/altcp_tls/altcp_tls_mbedtls_structs.h
+579 −0 src/apps/http/altcp_proxyconnect.c
+43 −30 src/apps/http/http_client.c
+2 −1 src/apps/http/makefsdata/makefsdata.c
+65 −2 src/core/altcp.c
+81 −0 src/core/altcp_alloc.c
+11 −0 src/core/altcp_tcp.c
+3 −0 src/core/init.c
+1 −1 src/core/ipv4/dhcp.c
+0 −1 src/core/ipv4/etharp.c
+1 −1 src/core/ipv4/igmp.c
+770 −8 src/core/ipv6/dhcp6.c
+1 −3 src/core/ipv6/icmp6.c
+7 −0 src/core/ipv6/nd6.c
+2 −0 src/core/pbuf.c
+2 −0 src/core/tcp.c
+5 −2 src/core/tcp_out.c
+4 −0 src/core/timeouts.c
+17 −0 src/include/lwip/altcp.h
+2 −0 src/include/lwip/altcp_tcp.h
+7 −0 src/include/lwip/altcp_tls.h
+71 −0 src/include/lwip/apps/altcp_proxyconnect.h
+22 −8 src/include/lwip/apps/http_client.h
+1 −1 src/include/lwip/apps/tftp_opts.h
+47 −9 src/include/lwip/dhcp6.h
+10 −0 src/include/lwip/netif.h
+85 −2 src/include/lwip/opt.h
+11 −9 src/include/lwip/prot/dhcp6.h
+113 −0 src/include/netif/ieee802154.h
+3 −1 src/include/netif/lowpan6.h
+69 −0 src/include/netif/lowpan6_ble.h
+87 −0 src/include/netif/lowpan6_ble_opts.h
+5 −1 src/include/netif/lowpan6_opts.h
+77 −0 src/include/netif/zepif.h
+4 −5 src/netif/FILES
+0 −337 src/netif/ethernetif.c
+314 −134 src/netif/lowpan6.c
+993 −0 src/netif/lowpan6_ble.c
+5 −0 src/netif/slipif.c
+270 −0 src/netif/zepif.c

0 comments on commit 1e6f584

Please sign in to comment.