Skip to content
Permalink
bcafcf8fc3
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
252 lines (215 sloc) 7.21 KB
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* Development of the code in this file was sponsored by Microbric Pty Ltd
*
* The MIT License (MIT)
*
* Copyright (c) 2016 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <sys/time.h>
#include <time.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_task.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_psram.h"
#include "py/stackctrl.h"
#include "py/nlr.h"
#include "py/compile.h"
#include "py/runtime.h"
#include "py/persistentcode.h"
#include "py/repl.h"
#include "py/gc.h"
#include "py/mphal.h"
#include "shared/readline/readline.h"
#include "shared/runtime/pyexec.h"
#include "shared/timeutils/timeutils.h"
#include "mbedtls/platform_time.h"
#include "uart.h"
#include "usb.h"
#include "usb_serial_jtag.h"
#include "modmachine.h"
#include "modnetwork.h"
#if MICROPY_BLUETOOTH_NIMBLE
#include "extmod/modbluetooth.h"
#endif
#if MICROPY_PY_ESPNOW
#include "modespnow.h"
#endif
// MicroPython runs as a task under FreeRTOS
#define MP_TASK_PRIORITY (ESP_TASK_PRIO_MIN + 1)
// Set the margin for detecting stack overflow, depending on the CPU architecture.
#if CONFIG_IDF_TARGET_ESP32C3
#define MP_TASK_STACK_LIMIT_MARGIN (2048)
#else
#define MP_TASK_STACK_LIMIT_MARGIN (1024)
#endif
int vprintf_null(const char *format, va_list ap) {
// do nothing: this is used as a log target during raw repl mode
return 0;
}
time_t platform_mbedtls_time(time_t *timer) {
// mbedtls_time requires time in seconds from EPOCH 1970
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + TIMEUTILS_SECONDS_1970_TO_2000;
}
void mp_task(void *pvParameter) {
volatile uint32_t sp = (uint32_t)esp_cpu_get_sp();
#if MICROPY_PY_THREAD
mp_thread_init(pxTaskGetStackStart(NULL), MICROPY_TASK_STACK_SIZE / sizeof(uintptr_t));
#endif
#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
usb_serial_jtag_init();
#elif CONFIG_USB_OTG_SUPPORTED
usb_init();
#endif
#if MICROPY_HW_ENABLE_UART_REPL
uart_stdout_init();
#endif
machine_init();
// Configure time function, for mbedtls certificate time validation.
mbedtls_platform_set_time(platform_mbedtls_time);
esp_err_t err = esp_event_loop_create_default();
if (err != ESP_OK) {
ESP_LOGE("esp_init", "can't create event loop: 0x%x\n", err);
}
void *mp_task_heap = MP_PLAT_ALLOC_HEAP(MICROPY_GC_INITIAL_HEAP_SIZE);
if (mp_task_heap == NULL) {
printf("mp_task_heap allocation failed!\n");
esp_restart();
}
soft_reset:
// initialise the stack pointer for the main thread
mp_stack_set_top((void *)sp);
mp_stack_set_limit(MICROPY_TASK_STACK_SIZE - MP_TASK_STACK_LIMIT_MARGIN);
gc_init(mp_task_heap, mp_task_heap + MICROPY_GC_INITIAL_HEAP_SIZE);
mp_init();
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib));
readline_init0();
MP_STATE_PORT(native_code_pointers) = MP_OBJ_NULL;
// initialise peripherals
machine_pins_init();
#if MICROPY_PY_MACHINE_I2S
machine_i2s_init0();
#endif
// run boot-up scripts
pyexec_frozen_module("_boot.py", false);
int ret = pyexec_file_if_exists("boot.py");
if (ret & PYEXEC_FORCED_EXIT) {
goto soft_reset_exit;
}
if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL && ret != 0) {
int ret = pyexec_file_if_exists("main.py");
if (ret & PYEXEC_FORCED_EXIT) {
goto soft_reset_exit;
}
}
for (;;) {
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
vprintf_like_t vprintf_log = esp_log_set_vprintf(vprintf_null);
if (pyexec_raw_repl() != 0) {
break;
}
esp_log_set_vprintf(vprintf_log);
} else {
if (pyexec_friendly_repl() != 0) {
break;
}
}
}
soft_reset_exit:
#if MICROPY_BLUETOOTH_NIMBLE
mp_bluetooth_deinit();
#endif
#if MICROPY_PY_ESPNOW
espnow_deinit(mp_const_none);
MP_STATE_PORT(espnow_singleton) = NULL;
#endif
machine_timer_deinit_all();
#if MICROPY_PY_THREAD
mp_thread_deinit();
#endif
// Free any native code pointers that point to iRAM.
if (MP_STATE_PORT(native_code_pointers) != MP_OBJ_NULL) {
size_t len;
mp_obj_t *items;
mp_obj_list_get(MP_STATE_PORT(native_code_pointers), &len, &items);
for (size_t i = 0; i < len; ++i) {
heap_caps_free(MP_OBJ_TO_PTR(items[i]));
}
}
gc_sweep_all();
mp_hal_stdout_tx_str("MPY: soft reboot\r\n");
// deinitialise peripherals
machine_pwm_deinit_all();
// TODO: machine_rmt_deinit_all();
machine_pins_deinit();
machine_deinit();
#if MICROPY_PY_SOCKET_EVENTS
socket_events_deinit();
#endif
mp_deinit();
fflush(stdout);
goto soft_reset;
}
void boardctrl_startup(void) {
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
nvs_flash_erase();
nvs_flash_init();
}
}
void app_main(void) {
// Hook for a board to run code at start up.
// This defaults to initialising NVS.
MICROPY_BOARD_STARTUP();
// Create and transfer control to the MicroPython task.
xTaskCreatePinnedToCore(mp_task, "mp_task", MICROPY_TASK_STACK_SIZE / sizeof(StackType_t), NULL, MP_TASK_PRIORITY, &mp_main_task_handle, MP_TASK_COREID);
}
void nlr_jump_fail(void *val) {
printf("NLR jump failed, val=%p\n", val);
esp_restart();
}
void *esp_native_code_commit(void *buf, size_t len, void *reloc) {
len = (len + 3) & ~3;
uint32_t *p = heap_caps_malloc(len, MALLOC_CAP_EXEC);
if (p == NULL) {
m_malloc_fail(len);
}
if (MP_STATE_PORT(native_code_pointers) == MP_OBJ_NULL) {
MP_STATE_PORT(native_code_pointers) = mp_obj_new_list(0, NULL);
}
mp_obj_list_append(MP_STATE_PORT(native_code_pointers), MP_OBJ_TO_PTR(p));
if (reloc) {
mp_native_relocate(reloc, buf, (uintptr_t)p);
}
memcpy(p, buf, len);
return p;
}
MP_REGISTER_ROOT_POINTER(mp_obj_t native_code_pointers);