2014-12-22 12:35:05 +01:00
/******************************************************************************
* Copyright 2013 - 2014 Espressif Systems ( Wuxi )
*
* FileName : user_main . c
*
* Description : entry file of user application
*
* Modification history :
* 2014 / 1 / 1 , v1 .0 create this file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "lua.h"
# include "platform.h"
# include "c_string.h"
# include "c_stdlib.h"
# include "c_stdio.h"
2015-04-02 18:51:02 +02:00
# include "flash_fs.h"
2014-12-22 12:35:05 +01:00
# include "user_interface.h"
2015-06-22 10:43:01 +02:00
# include "user_exceptions.h"
2015-06-25 07:32:21 +02:00
# include "user_modules.h"
2014-12-22 12:35:05 +01:00
# include "ets_sys.h"
# include "driver/uart.h"
# include "mem.h"
2015-06-25 07:32:21 +02:00
# ifdef LUA_USE_MODULES_RTCTIME
# include "rtc/rtctime.h"
# endif
2014-12-22 12:35:05 +01:00
# define SIG_LUA 0
2015-10-08 04:33:15 +02:00
# define SIG_UARTINPUT 1
2014-12-22 12:35:05 +01:00
# define TASK_QUEUE_LEN 4
2015-11-12 02:57:07 +01:00
static os_event_t * taskQueue ;
/* Important: no_init_data CAN NOT be left as zero initialised, as that
* initialisation will happen after user_start_trampoline , but before
* the user_init , thus clobbering our state !
*/
static uint8_t no_init_data = 0xff ;
2014-12-22 12:35:05 +01:00
2015-06-23 07:38:52 +02:00
/* 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 .
*/
2015-07-06 05:45:35 +02:00
void TEXT_SECTION_ATTR user_start_trampoline ( void )
2015-06-23 07:38:52 +02:00
{
__real__xtos_set_exception_handler (
EXCCAUSE_LOAD_STORE_ERROR , load_non_32_wide_handler ) ;
2015-06-25 07:32:21 +02:00
# ifdef LUA_USE_MODULES_RTCTIME
// Note: Keep this as close to call_user_start() as possible, since it
// is where the cpu clock actually gets bumped to 80MHz.
2015-07-06 05:45:35 +02:00
rtctime_early_startup ( ) ;
2015-06-25 07:32:21 +02:00
# endif
2015-11-12 02:57:07 +01:00
/* Minimal early detection of missing esp_init_data.
* If it is missing , the SDK will write its own and thus we ' d end up
* using that unless the flash size field is incorrect . This then leads
* to different esp_init_data being used depending on whether the user
* flashed with the right flash size or not ( and the better option would
* be to flash with an * incorrect * flash size , counter - intuitively ) .
* To avoid that mess , we read out the flash size and do a test for
* esp_init_data based on that size . If it ' s missing , flag for later .
* If the flash size was incorrect , we ' ll end up fixing it all up
* anyway , so this ends up solving the conundrum . Only remaining issue
* is lack of spare code bytes in iram , so this is deliberately quite
* terse and not as readable as one might like .
*/
SPIFlashInfo sfi ;
SPIRead ( 0 , & sfi , sizeof ( sfi ) ) ; // Cache read not enabled yet, safe to use
if ( sfi . size < 2 ) // Compensate for out-of-order 4mbit vs 2mbit values
sfi . size ^ = 1 ;
uint32_t flash_end_addr = ( 256 * 1024 ) < < sfi . size ;
uint32_t init_data_hdr = 0xffffffff ;
SPIRead ( flash_end_addr - 4 * SPI_FLASH_SEC_SIZE , & init_data_hdr , sizeof ( init_data_hdr ) ) ;
no_init_data = ( init_data_hdr = = 0xffffffff ) ;
2015-06-23 07:38:52 +02:00
call_user_start ( ) ;
}
2015-10-28 06:14:07 +01:00
/* To avoid accidentally losing the fix for the TCP port randomization
* during an LWIP upgrade , we ' ve implemented most it outside the LWIP
* source itself . This enables us to test for the presence of the fix
* / at link time / and error out if it ' s been lost .
* The fix itself consists of putting the function - static ' port ' variable
* into its own section , and get the linker to provide an alias for it .
* From there we can then manually randomize it at boot .
*/
static inline void tcp_random_port_init ( void )
{
extern uint16_t _tcp_new_port_port ; // provided by the linker script
_tcp_new_port_port + = xthal_get_ccount ( ) % 4096 ;
}
2014-12-22 12:35:05 +01:00
void task_lua ( os_event_t * e ) {
char * lua_argv [ ] = { ( char * ) " lua " , ( char * ) " -i " , NULL } ;
NODE_DBG ( " Task task_lua started. \n " ) ;
switch ( e - > sig ) {
case SIG_LUA :
NODE_DBG ( " SIG_LUA received. \n " ) ;
lua_main ( 2 , lua_argv ) ;
break ;
2015-10-08 04:33:15 +02:00
case SIG_UARTINPUT :
2015-10-08 05:14:51 +02:00
lua_handle_input ( false ) ;
break ;
case LUA_PROCESS_LINE_SIG :
lua_handle_input ( true ) ;
2015-10-08 04:33:15 +02:00
break ;
2014-12-22 12:35:05 +01:00
default :
break ;
}
}
void task_init ( void ) {
taskQueue = ( os_event_t * ) os_malloc ( sizeof ( os_event_t ) * TASK_QUEUE_LEN ) ;
system_os_task ( task_lua , USER_TASK_PRIO_0 , taskQueue , TASK_QUEUE_LEN ) ;
}
// extern void test_spiffs();
// extern int test_romfs();
2014-12-30 19:47:44 +01:00
// extern uint16_t flash_get_sec_num();
2015-01-23 06:25:54 +01:00
void nodemcu_init ( void )
2014-12-22 12:35:05 +01:00
{
NODE_ERR ( " \n " ) ;
2015-10-30 04:25:02 +01:00
// Initialize platform first for lua modules.
2014-12-22 12:35:05 +01:00
if ( platform_init ( ) ! = PLATFORM_OK )
{
// This should never happen
NODE_DBG ( " Can not init platform for modules. \n " ) ;
return ;
}
2015-03-15 22:40:43 +01:00
# if defined(FLASH_SAFE_API)
if ( flash_safe_get_size_byte ( ) ! = flash_rom_get_size_byte ( ) ) {
NODE_ERR ( " Self adjust flash size. \n " ) ;
// Fit hardware real flash size.
flash_rom_set_size_byte ( flash_safe_get_size_byte ( ) ) ;
2015-11-12 02:57:07 +01:00
// Write out init data at real location.
no_init_data = true ;
2015-04-02 18:51:02 +02:00
if ( ! fs_format ( ) )
{
NODE_ERR ( " \n i*** ERROR ***: unable to format. FS might be compromised. \n " ) ;
NODE_ERR ( " It is advised to re-flash the NodeMCU image. \n " ) ;
}
else {
NODE_ERR ( " format done. \n " ) ;
}
fs_unmount ( ) ; // mounted by format.
2015-03-15 22:40:43 +01:00
}
# endif // defined(FLASH_SAFE_API)
2015-11-12 02:57:07 +01:00
if ( no_init_data )
{
2015-01-05 16:57:07 +01:00
NODE_ERR ( " Restore init data. \n " ) ;
2015-01-23 06:25:54 +01:00
// Flash init data at FLASHSIZE - 0x04000 Byte.
2015-01-05 16:57:07 +01:00
flash_init_data_default ( ) ;
2015-01-23 06:25:54 +01:00
// Flash blank data at FLASHSIZE - 0x02000 Byte.
2015-10-30 04:25:02 +01:00
flash_init_data_blank ( ) ;
2015-11-12 02:57:07 +01:00
// Reboot to make the new data come into effect
system_restart ( ) ;
2015-01-05 16:57:07 +01:00
}
2014-12-22 12:35:05 +01:00
# if defined( BUILD_WOFS )
romfs_init ( ) ;
// if( !wofs_format() )
// {
// NODE_ERR( "\ni*** ERROR ***: unable to erase the flash. WOFS might be compromised.\n" );
// NODE_ERR( "It is advised to re-flash the NodeWifi image.\n" );
// }
// else
// NODE_ERR( "format done.\n" );
// test_romfs();
# elif defined ( BUILD_SPIFFS )
2015-04-02 18:51:02 +02:00
fs_mount ( ) ;
2014-12-22 12:35:05 +01:00
// test_spiffs();
# endif
// endpoint_setup();
// char* lua_argv[] = { (char *)"lua", (char *)"-e", (char *)"print(collectgarbage'count');ttt={};for i=1,100 do table.insert(ttt,i*2 -1);print(i);end for k, v in pairs(ttt) do print('<'..k..' '..v..'>') end print(collectgarbage'count');", NULL };
// lua_main( 3, lua_argv );
// char* lua_argv[] = { (char *)"lua", (char *)"-i", NULL };
// lua_main( 2, lua_argv );
// char* lua_argv[] = { (char *)"lua", (char *)"-e", (char *)"pwm.setup(0,100,50) pwm.start(0) pwm.stop(0)", NULL };
// lua_main( 3, lua_argv );
2014-12-30 19:47:44 +01:00
// NODE_DBG("Flash sec num: 0x%x\n", flash_get_sec_num());
2015-10-28 06:14:07 +01:00
tcp_random_port_init ( ) ;
2014-12-22 12:35:05 +01:00
task_init ( ) ;
2015-10-08 05:14:51 +02:00
system_os_post ( LUA_TASK_PRIO , SIG_LUA , ' s ' ) ;
2014-12-22 12:35:05 +01:00
}
2015-01-23 06:25:54 +01:00
/******************************************************************************
* FunctionName : user_init
* Description : entry of user application , init user function here
* Parameters : none
* Returns : none
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void user_init ( void )
{
2015-07-06 05:45:35 +02:00
# ifdef LUA_USE_MODULES_RTCTIME
rtctime_late_startup ( ) ;
# endif
2015-01-23 06:25:54 +01:00
// NODE_DBG("SDK version:%s\n", system_get_sdk_version());
// system_print_meminfo();
// os_printf("Heap size::%d.\n",system_get_free_heap_size());
// os_delay_us(50*1000); // delay 50ms before init uart
2015-10-30 04:25:02 +01:00
UartBautRate br = BIT_RATE_DEFAULT ;
2015-10-08 04:33:15 +02:00
uart_init ( br , br , USER_TASK_PRIO_0 , SIG_UARTINPUT ) ;
2015-10-30 04:25:02 +01:00
2015-01-23 06:25:54 +01:00
# ifndef NODE_DEBUG
system_set_os_print ( 0 ) ;
# endif
2015-10-08 05:14:51 +02:00
2015-01-23 06:25:54 +01:00
system_init_done_cb ( nodemcu_init ) ;
}