void esp_sj_uart_dispatcher(void *arg) { int uart_no = (int) arg; struct esp_sj_uart_state *us = &sj_us[uart_no]; cs_rbuf_t *txb = esp_uart_tx_buf(uart_no); us->dispatch_pending = 0; esp_uart_dispatch_rx_top(uart_no); uint16_t tx_used_before = txb->used; /* ignore unused because of CS_DISABLE_JS below */ (void) tx_used_before; esp_uart_dispatch_tx_top(uart_no); #ifndef CS_DISABLE_JS cs_rbuf_t *rxb = esp_uart_rx_buf(uart_no); if (us->v7 != NULL) { /* Detect the edge of TX buffer becoming empty. */ if (tx_used_before > 0 && txb->used == 0) { v7_val_t txcb = v7_get(us->v7, us->obj, "_txcb", 5); if (v7_is_callable(us->v7, txcb)) { sj_invoke_cb(us->v7, txcb, us->obj, V7_UNDEFINED); } } if (rxb->used > 0) { /* Check for JS recv handler. */ v7_val_t rxcb = esp_sj_uart_get_recv_handler(uart_no); if (v7_is_callable(us->v7, rxcb)) { if (!us->recv_pending) { us->recv_pending = 1; sj_invoke_cb(us->v7, rxcb, us->obj, V7_UNDEFINED); /* Note: Callback has not run yet, it has been scheduled. */ } } else if (us->prompt) { uint8_t *cp; while (rxb != NULL && cs_rbuf_get(rxb, 1, &cp) == 1) { char c = (char) *cp; cs_rbuf_consume(rxb, 1); sj_prompt_process_char(c); /* UART could've been re-initialized by the command from prompt. */ rxb = esp_uart_rx_buf(uart_no); } } } } #endif esp_uart_dispatch_bottom(uart_no); }
/* * SmartJS initialization, called as an SDK timer callback (`os_timer_...()`). */ void sjs_init(void *dummy) { /* * In order to see debug output (at least errors) during boot we have to * initialize debug in this point. But default we put debug to UART0 with * level=LL_ERROR, then configuration is loaded this settings are overridden */ { struct esp_uart_config *u0cfg = esp_sj_uart_default_config(0); #if ESP_DEBUG_UART == 0 u0cfg->baud_rate = ESP_DEBUG_UART_BAUD_RATE; #endif esp_uart_init(u0cfg); struct esp_uart_config *u1cfg = esp_sj_uart_default_config(1); /* UART1 has no RX pin, no point in allocating a buffer. */ u1cfg->rx_buf_size = 0; #if ESP_DEBUG_UART == 1 u1cfg->baud_rate = ESP_DEBUG_UART_BAUD_RATE; #endif esp_uart_init(u1cfg); fs_set_stdout_uart(0); fs_set_stderr_uart(ESP_DEBUG_UART); setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); cs_log_set_level(LL_DEBUG); os_install_putc1(dbg_putc); system_set_os_print(1); #ifdef ESP_ENABLE_HEAP_LOG uart_initialized = 1; #endif } init_v7(&dummy); /* disable GC during further initialization */ v7_set_gc_enabled(v7, 0); esp_sj_uart_init(v7); #ifndef V7_NO_FS #ifndef DISABLE_OTA fs_init(get_fs_addr(get_current_rom()), get_fs_size(get_current_rom())); finish_update(); #else fs_init(FS_ADDR, FS_SIZE); #endif #endif sj_common_api_setup(v7); sj_common_init(v7); sj_init_sys(v7); mongoose_init(); /* NOTE(lsm): must be done after mongoose_init(). */ if (!init_device(v7)) { LOG(LL_ERROR, ("init_device failed")); abort(); } esp_print_reset_info(); #ifndef DISABLE_OTA init_updater(v7); #endif LOG(LL_INFO, ("Sys init done, SDK %s", system_get_sdk_version())); if (!sj_app_init(v7)) { LOG(LL_ERROR, ("App init failed")); abort(); } LOG(LL_INFO, ("App init done")); /* SJS initialized, enable GC back, and trigger it */ v7_set_gc_enabled(v7, 1); v7_gc(v7, 1); #ifndef V7_NO_FS run_init_script(); #endif /* Install prompt if enabled in the config and user's app has not installed * a custom RX handler. */ if (get_cfg()->debug.enable_prompt && v7_is_undefined(esp_sj_uart_get_recv_handler(0))) { sj_prompt_init(v7); esp_sj_uart_set_prompt(0); } #ifdef ESP_UMM_ENABLE /* * We want to use our own heap functions instead of the ones provided by the * SDK. * * We have marked `pvPortMalloc` and friends weak, so that we can override * them with our own implementations, but to actually make it work, we have * to reference any function from the file with our implementation, so that * linker will not garbage-collect the whole compilation unit. * * So, we have a call to the no-op `esp_umm_init()` here. */ esp_umm_init(); #endif }