From 26cbc91373cdfff43317da01e102617ed5885655 Mon Sep 17 00:00:00 2001 From: danicampora Date: Mon, 2 Mar 2015 14:11:02 +0100 Subject: [PATCH] cc3200: Place functions only used while booting in a special section. Such functions are never used after MicroPython has started, and they remain in RAM wasting space. Now they are placed in a special section named "boot" which sits just before the heap, allowing us to extend the effective heap area up to the new boot section. Right now, this gives us back ~1K, but in the future, more functions might end up in there as well. --- .../Source/portable/GCC/ARM_CM3/port.c | 5 ++ cc3200/FreeRTOS/Source/tasks.c | 8 ++- cc3200/application.lds | 11 +++ cc3200/hal/cc3200_hal.c | 3 +- cc3200/hal/startup_gcc.c | 1 + cc3200/main.c | 2 +- cc3200/mods/pybrtc.c | 1 + cc3200/mods/pybsd.c | 1 + cc3200/mptask.c | 72 ++++++++++--------- cc3200/simplelink/oslib/osi_freertos.c | 3 + cc3200/util/gccollect.h | 2 + 11 files changed, 71 insertions(+), 38 deletions(-) diff --git a/cc3200/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c b/cc3200/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c index b287f7df99..8c94d7d795 100644 --- a/cc3200/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c +++ b/cc3200/FreeRTOS/Source/portable/GCC/ARM_CM3/port.c @@ -202,6 +202,7 @@ static void prvTaskExitError( void ); /* * See header file for description. */ +__attribute__ ((section (".boot"))) StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) { /* Simulate the stack frame as it would be created by a context switch @@ -220,6 +221,7 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px } /*-----------------------------------------------------------*/ +__attribute__ ((section (".boot"))) static void prvTaskExitError( void ) { /* A function that implements a task must not exit or attempt to return to @@ -254,6 +256,7 @@ void vPortSVCHandler( void ) } /*-----------------------------------------------------------*/ +__attribute__ ((section (".boot"))) static void prvPortStartFirstTask( void ) { __asm volatile( @@ -274,6 +277,7 @@ static void prvPortStartFirstTask( void ) /* * See header file for description. */ +__attribute__ ((section (".boot"))) BaseType_t xPortStartScheduler( void ) { /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. @@ -643,6 +647,7 @@ void xPortSysTickHandler( void ) * Setup the systick timer to generate the tick interrupts at the required * frequency. */ +__attribute__ ((section (".boot"))) __attribute__(( weak )) void vPortSetupTimerInterrupt( void ) { /* Calculate the constants required to configure the tick interrupt. */ diff --git a/cc3200/FreeRTOS/Source/tasks.c b/cc3200/FreeRTOS/Source/tasks.c index 11bbc251c1..ea3ff3c571 100644 --- a/cc3200/FreeRTOS/Source/tasks.c +++ b/cc3200/FreeRTOS/Source/tasks.c @@ -515,6 +515,7 @@ static void prvResetNextTaskUnblockTime( void ); /*-----------------------------------------------------------*/ +__attribute__ ((section (".boot"))) BaseType_t xTaskGenericCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask, StackType_t * const puxStackBuffer, const MemoryRegion_t * const xRegions ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ { BaseType_t xReturn; @@ -1454,6 +1455,7 @@ TCB_t * pxNewTCB; #endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */ /*-----------------------------------------------------------*/ +__attribute__ ((section (".boot"))) void vTaskStartScheduler( void ) { BaseType_t xReturn; @@ -2700,7 +2702,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) } #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ - +__attribute__ ((section (".boot"))) static void prvInitialiseTCBVariables( TCB_t * const pxTCB, const char * const pcName, UBaseType_t uxPriority, const MemoryRegion_t * const xRegions, const uint16_t usStackDepth ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ { UBaseType_t x; @@ -2809,7 +2811,7 @@ UBaseType_t x; #endif /* portUSING_MPU_WRAPPERS */ /*-----------------------------------------------------------*/ - +__attribute__ ((section (".boot"))) static void prvInitialiseTaskLists( void ) { UBaseType_t uxPriority; @@ -2912,7 +2914,7 @@ static void prvAddCurrentTaskToDelayedList( const TickType_t xTimeToWake ) } } /*-----------------------------------------------------------*/ - +__attribute__ ((section (".boot"))) static TCB_t *prvAllocateTCBAndStack( const uint16_t usStackDepth, StackType_t * const puxStackBuffer ) { TCB_t *pxNewTCB; diff --git a/cc3200/application.lds b/cc3200/application.lds index 147941f4cf..162988da99 100644 --- a/cc3200/application.lds +++ b/cc3200/application.lds @@ -89,6 +89,17 @@ SECTIONS . = ALIGN(8); _ebss = .; } > SRAM + + /* place here functions that are only called during boot up, */ + /* that way, we can re-use this area for the micropython heap */ + .boot : + { + . = ALIGN(8); + _boot = .; + *(.boot*) + . = ALIGN(8); + _eboot = .; + } > SRAM /* allocate the micropython heap */ .heap : diff --git a/cc3200/hal/cc3200_hal.c b/cc3200/hal/cc3200_hal.c index e1ae0eafcb..3860641161 100644 --- a/cc3200/hal/cc3200_hal.c +++ b/cc3200/hal/cc3200_hal.c @@ -78,7 +78,8 @@ extern void (* const g_pfnVectors[256])(void); /****************************************************************************** DEFINE PUBLIC FUNCTIONS ******************************************************************************/ - + +__attribute__ ((section (".boot"))) void HAL_SystemInit (void) { MAP_IntVTableBaseSet((unsigned long)&g_pfnVectors[0]); diff --git a/cc3200/hal/startup_gcc.c b/cc3200/hal/startup_gcc.c index ecae05bdc5..2d364f87d1 100644 --- a/cc3200/hal/startup_gcc.c +++ b/cc3200/hal/startup_gcc.c @@ -60,6 +60,7 @@ extern uint32_t __init_data; // Forward declaration of the default fault handlers. // //***************************************************************************** +__attribute__ ((section (".boot"))) void ResetISR(void); #ifdef DEBUG static void NmiSR(void) __attribute__( ( naked ) ); diff --git a/cc3200/main.c b/cc3200/main.c index d65fc240fc..e38fd37286 100644 --- a/cc3200/main.c +++ b/cc3200/main.c @@ -59,6 +59,7 @@ OsiTaskHandle mpTaskHandle; DEFINE PUBLIC FUNCTIONS ******************************************************************************/ +__attribute__ ((section (".boot"))) int main (void) { // Initialize the clocks and the interrupt system @@ -82,7 +83,6 @@ int main (void) { for ( ; ; ); } - void stoupper (char *str) { while (str && *str != '\0') { *str = (char)toupper((int)(*str)); diff --git a/cc3200/mods/pybrtc.c b/cc3200/mods/pybrtc.c index 5d6c2a7ca1..1844a6d7f3 100644 --- a/cc3200/mods/pybrtc.c +++ b/cc3200/mods/pybrtc.c @@ -51,6 +51,7 @@ /// rtc.datetime((2014, 5, 1, 4, 13, 0, 0, 0)) /// print(rtc.datetime()) +__attribute__ ((section (".boot"))) void pybrtc_init(void) { // if RTC was previously set leave it alone if (MAP_PRCMSysResetCauseGet() == PRCM_POWER_ON) { diff --git a/cc3200/mods/pybsd.c b/cc3200/mods/pybsd.c index 4ae8772503..6d326ded51 100644 --- a/cc3200/mods/pybsd.c +++ b/cc3200/mods/pybsd.c @@ -79,6 +79,7 @@ STATIC mp_obj_t pybsd_enable (mp_obj_t self_in); /****************************************************************************** DECLARE PUBLIC FUNCTIONS ******************************************************************************/ +__attribute__ ((section (".boot"))) void pybsd_init0 (void) { // allocate memory for the sd file system ASSERT ((pybsd_obj.fatfs = mem_Malloc(sizeof(FATFS))) != NULL); diff --git a/cc3200/mptask.c b/cc3200/mptask.c index f90a64e8c0..53468f79c9 100644 --- a/cc3200/mptask.c +++ b/cc3200/mptask.c @@ -69,9 +69,10 @@ /****************************************************************************** DECLARE PRIVATE FUNCTIONS ******************************************************************************/ -STATIC void main_init_sflash_filesystem (void); -STATIC void main_enter_ap_mode (void); -STATIC void main_create_main_py (void); +STATIC void mptask_pre_init (void); +STATIC void mptask_init_sflash_filesystem (void); +STATIC void mptask_enter_ap_mode (void); +STATIC void mptask_create_main_py (void); /****************************************************************************** DECLARE PUBLIC DATA @@ -100,39 +101,18 @@ void TASK_Micropython (void *pvParameters) { bool safeboot; FRESULT res; -#if MICROPY_HW_ENABLE_RTC - pybrtc_init(); -#endif - #ifdef DEBUG safeboot = false; #else safeboot = mperror_safe_boot_requested(); #endif - // Create the simple link spawn task - ASSERT (OSI_OK == VStartSimpleLinkSpawnTask(SIMPLELINK_SPAWN_TASK_PRIORITY)); - - // Allocate memory for the flash file system - ASSERT ((sflash_fatfs = mem_Malloc(sizeof(FATFS))) != NULL); -#if MICROPY_HW_HAS_SDCARD - pybsd_init0(); -#endif - -#ifdef DEBUG - ASSERT (OSI_OK == osi_TaskCreate(TASK_Servers, - (const signed char *)"Servers", - SERVERS_STACK_SIZE, NULL, SERVERS_PRIORITY, &svTaskHandle)); -#else - ASSERT (OSI_OK == osi_TaskCreate(TASK_Servers, - (const signed char *)"Servers", - SERVERS_STACK_SIZE, NULL, SERVERS_PRIORITY, NULL)); -#endif + mptask_pre_init (); soft_reset: // GC init - gc_init(&_heap, &_eheap); + gc_init(&_boot, &_eheap); // Micro Python init mp_init(); @@ -167,13 +147,13 @@ soft_reset: mperror_enable_heartbeat(); - main_enter_ap_mode(); + mptask_enter_ap_mode(); // enable telnet and ftp servers servers_enable(); // initialize the serial flash file system - main_init_sflash_filesystem(); + mptask_init_sflash_filesystem(); // append the SFLASH paths to the system path mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_SFLASH)); @@ -268,8 +248,34 @@ soft_reset_exit: /****************************************************************************** DEFINE PRIVATE FUNCTIONS ******************************************************************************/ +__attribute__ ((section (".boot"))) +STATIC void mptask_pre_init (void) { +#if MICROPY_HW_ENABLE_RTC + pybrtc_init(); +#endif -STATIC void main_init_sflash_filesystem (void) { + // Create the simple link spawn task + ASSERT (OSI_OK == VStartSimpleLinkSpawnTask(SIMPLELINK_SPAWN_TASK_PRIORITY)); + + // Allocate memory for the flash file system + ASSERT ((sflash_fatfs = mem_Malloc(sizeof(FATFS))) != NULL); + +#if MICROPY_HW_HAS_SDCARD + pybsd_init0(); +#endif + +#ifdef DEBUG + ASSERT (OSI_OK == osi_TaskCreate(TASK_Servers, + (const signed char *)"Servers", + SERVERS_STACK_SIZE, NULL, SERVERS_PRIORITY, &svTaskHandle)); +#else + ASSERT (OSI_OK == osi_TaskCreate(TASK_Servers, + (const signed char *)"Servers", + SERVERS_STACK_SIZE, NULL, SERVERS_PRIORITY, NULL)); +#endif +} + +STATIC void mptask_init_sflash_filesystem (void) { // Initialise the local flash filesystem. // Create it if needed, and mount in on /sflash. // try to mount the flash @@ -283,13 +289,13 @@ STATIC void main_init_sflash_filesystem (void) { __fatal_error("could not create /SFLASH file system"); } // create empty main.py - main_create_main_py(); + mptask_create_main_py(); } else if (res == FR_OK) { // mount sucessful FILINFO fno; if (FR_OK != f_stat("/SFLASH/MAIN.PY", &fno)) { // create empty main.py - main_create_main_py(); + mptask_create_main_py(); } } else { __fatal_error("could not create /SFLASH file system"); @@ -321,14 +327,14 @@ STATIC void main_init_sflash_filesystem (void) { } } -STATIC void main_enter_ap_mode (void) { +STATIC void mptask_enter_ap_mode (void) { // Enable simplelink in low power mode wlan_sl_enable (ROLE_AP, SERVERS_DEF_AP_SSID, strlen(SERVERS_DEF_AP_SSID), SERVERS_DEF_AP_SECURITY, SERVERS_DEF_AP_KEY, strlen(SERVERS_DEF_AP_KEY), SERVERS_DEF_AP_CHANNEL); wlan_set_pm_policy (SL_NORMAL_POLICY); } -STATIC void main_create_main_py (void) { +STATIC void mptask_create_main_py (void) { // create empty main.py FIL fp; f_open(&fp, "/SFLASH/MAIN.PY", FA_WRITE | FA_CREATE_ALWAYS); diff --git a/cc3200/simplelink/oslib/osi_freertos.c b/cc3200/simplelink/oslib/osi_freertos.c index 8ed75a1302..2f00ab2689 100644 --- a/cc3200/simplelink/oslib/osi_freertos.c +++ b/cc3200/simplelink/oslib/osi_freertos.c @@ -275,6 +275,7 @@ OsiReturnVal_e osi_LockObjCreate(OsiLockObj_t* pLockObj) \note \warning */ +__attribute__ ((section (".boot"))) OsiReturnVal_e osi_TaskCreate(P_OSI_TASK_ENTRY pEntry,const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned long uxPriority,OsiTaskHandle* pTaskHandle) @@ -449,6 +450,7 @@ void vSimpleLinkSpawnTask(void *pvParameters) \note \warning */ +__attribute__ ((section (".boot"))) OsiReturnVal_e VStartSimpleLinkSpawnTask(unsigned portBASE_TYPE uxPriority) { xSimpleLinkSpawnQueue = xQueueCreate( slQUEUE_SIZE, sizeof( tSimpleLinkSpawnMsg ) ); @@ -666,6 +668,7 @@ void osi_ExitCritical(void) \note \warning */ +__attribute__ ((section (".boot"))) void osi_start() { vTaskStartScheduler(); diff --git a/cc3200/util/gccollect.h b/cc3200/util/gccollect.h index 8e4c8896bf..b8b6502cb2 100644 --- a/cc3200/util/gccollect.h +++ b/cc3200/util/gccollect.h @@ -30,6 +30,8 @@ extern uint32_t _etext; extern uint32_t _sidata; extern uint32_t _data; extern uint32_t _edata; +extern uint32_t _boot; +extern uint32_t _eboot; extern uint32_t _bss; extern uint32_t _ebss; extern uint32_t _heap;