Move constants to ROM. Frees up 16k+ of RAM.

Accessing 8bit and 16bit constants from ROM rather than RAM comes with a
performance cost, as these loads go through the load/store exception
vector. Any performance critical constants can be forced back into RAM
as RAM_CONST_ATTR.

The entry point has changed from call_user_start() to user_start_trampoline()
in order for the exception handler to be installed early enough.
This commit is contained in:
Johny Mattsson 2015-06-23 15:38:52 +10:00
parent 0c924e56c6
commit b0f9788a6d
6 changed files with 52 additions and 9 deletions

View File

@ -99,7 +99,7 @@ LINKFLAGS_eagle.app.v6 = \
-nostdlib \
-T$(LD_FILE) \
-Wl,--no-check-sections \
-u call_user_start \
-Wl,--wrap=_xtos_set_exception_handler \
-Wl,-static \
-Wl,--start-group \
-lc \

View File

@ -95,3 +95,18 @@ die:
ef->a_reg[regno] = val; /* carry out the load */
ef->epc += 3; /* resume at following instruction */
}
/**
* The SDK's user_main function installs a debugging handler regardless
* of whether there's a proper handler installed for EXCCAUSE_LOAD_STORE_ERROR,
* which of course breaks everything if we allow that to go through. As such,
* we use the linker to wrap that call and stop the SDK from shooting itself in
* its proverbial foot.
*/
exception_handler_fn
__wrap__xtos_set_exception_handler (uint32_t cause, exception_handler_fn fn)
{
if (cause != EXCCAUSE_LOAD_STORE_ERROR)
__real__xtos_set_exception_handler (cause, fn);
}

View File

@ -26,6 +26,21 @@
#define TASK_QUEUE_LEN 4
os_event_t *taskQueue;
/* Note: the trampoline *must* be explicitly put into the .text segment, since
* by the time it is invoked the irom has not yet been mapped. This naturally
* also goes for anything the trampoline itself calls.
*/
void user_start_trampoline (void) TEXT_SECTION_ATTR;
void user_start_trampoline (void)
{
__real__xtos_set_exception_handler (
EXCCAUSE_LOAD_STORE_ERROR, load_non_32_wide_handler);
call_user_start ();
}
void task_lua(os_event_t *e){
char* lua_argv[] = { (char *)"lua", (char *)"-i", NULL };
NODE_DBG("Task task_lua started.\n");
@ -126,9 +141,6 @@ void nodemcu_init(void)
*******************************************************************************/
void user_init(void)
{
_xtos_set_exception_handler (
EXCCAUSE_LOAD_STORE_ERROR, load_non_32_wide_handler);
// NODE_DBG("SDK version:%s\n", system_get_sdk_version());
// system_print_meminfo();
// os_printf("Heap size::%d.\n",system_get_free_heap_size());

View File

@ -85,6 +85,7 @@ typedef enum {
#endif /* ICACHE_FLASH */
#define TEXT_SECTION_ATTR __attribute__((section(".text")))
#define RAM_CONST_ATTR __attribute__((section(".text")))
#ifndef __cplusplus
typedef unsigned char bool;

View File

@ -19,7 +19,7 @@ PHDRS
/* Default entry point: */
ENTRY(call_user_start)
ENTRY(user_start_trampoline)
PROVIDE(_memmap_vecbase_reset = 0x40000000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00000110;
@ -75,6 +75,10 @@ SECTIONS
/* put font and progmem data into irom0 */
*(.u8g_progmem.*)
/* Trade some performance for lots of ram. At the time of writing the
* available Lua heap went from 18248 to 34704. */
*(.rodata*)
_irom0_text_end = ABSOLUTE(.);
_flash_used_end = ABSOLUTE(.);
} >irom0_0_seg :irom0_0_phdr
@ -124,10 +128,7 @@ SECTIONS
.rodata : ALIGN(4)
{
_rodata_start = ABSOLUTE(.);
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
*(.rodata1)
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
*(.xt_except_table)
*(.gcc_except_table)

View File

@ -360,6 +360,20 @@ class ELFFile:
self._fetch_symbols()
return self.symbols[sym]
def get_entry_point(self):
tool_readelf = "xtensa-lx106-elf-readelf"
if os.getenv('XTENSA_CORE')=='lx106':
tool_objcopy = "xt-readelf"
try:
proc = subprocess.Popen([tool_readelf, "-h", self.name], stdout=subprocess.PIPE)
except OSError:
print "Error calling "+tool_nm+", do you have Xtensa toolchain in PATH?"
sys.exit(1)
for l in proc.stdout:
fields = l.strip().split()
if fields[0] == "Entry":
return int(fields[3], 0);
def load_section(self, section):
tool_objcopy = "xtensa-lx106-elf-objcopy"
if os.getenv('XTENSA_CORE')=='lx106':
@ -586,7 +600,7 @@ if __name__ == '__main__':
args.output = args.input + '-'
e = ELFFile(args.input)
image = ESPFirmwareImage()
image.entrypoint = e.get_symbol_addr("call_user_start")
image.entrypoint = e.get_entry_point()
for section, start in ((".text", "_text_start"), (".data", "_data_start"), (".rodata", "_rodata_start")):
data = e.load_section(section)
image.add_segment(e.get_symbol_addr(start), data)