@ -699,6 +699,99 @@ STATIC mp_obj_t esp_esf_free_bufs(mp_obj_t idx_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1 ( esp_esf_free_bufs_obj , esp_esf_free_bufs ) ;
# if MICROPY_EMIT_XTENSA
// We provide here a way of committing executable data to a region from
// which it can be executed by the CPU. There are 2 such writable regions:
// - iram1, which may have some space left at the end of it
// - memory-mapped flash rom
//
// By default the iram1 region (the space at the end of it) is used. The
// user can select iram1 or a section of flash by calling the
// esp.set_native_code_location() function; see below. If flash is selected
// then it is erased as needed.
# define IRAM1_END (0x40108000)
# define FLASH_START (0x40200000)
# define FLASH_END (0x40300000)
# define FLASH_SEC_SIZE (4096)
# define ESP_NATIVE_CODE_IRAM1 (0)
# define ESP_NATIVE_CODE_FLASH (1)
extern uint32_t _lit4_end ;
STATIC uint32_t esp_native_code_location ;
STATIC uint32_t esp_native_code_start ;
STATIC uint32_t esp_native_code_end ;
STATIC uint32_t esp_native_code_cur ;
STATIC uint32_t esp_native_code_erased ;
void esp_native_code_init ( void ) {
esp_native_code_location = ESP_NATIVE_CODE_IRAM1 ;
esp_native_code_start = ( uint32_t ) & _lit4_end ;
esp_native_code_end = IRAM1_END ;
esp_native_code_cur = esp_native_code_start ;
esp_native_code_erased = 0 ;
}
void * esp_native_code_commit ( void * buf , size_t len ) {
//printf("COMMIT(buf=%p, len=%u, start=%08x, cur=%08x, end=%08x, erased=%08x)\n", buf, len, esp_native_code_start, esp_native_code_cur, esp_native_code_end, esp_native_code_erased);
len = ( len + 3 ) & ~ 3 ;
if ( esp_native_code_cur + len > esp_native_code_end ) {
nlr_raise ( mp_obj_new_exception_msg_varg ( & mp_type_MemoryError ,
" memory allocation failed, allocating %u bytes for native code " , ( uint ) len ) ) ;
}
void * dest ;
if ( esp_native_code_location = = ESP_NATIVE_CODE_IRAM1 ) {
dest = ( void * ) esp_native_code_cur ;
memcpy ( dest , buf , len ) ;
} else {
SpiFlashOpResult res ;
while ( esp_native_code_erased < esp_native_code_cur + len ) {
res = spi_flash_erase_sector ( esp_native_code_erased / FLASH_SEC_SIZE ) ;
if ( res ! = SPI_FLASH_RESULT_OK ) {
break ;
}
esp_native_code_erased + = FLASH_SEC_SIZE ;
}
if ( res = = SPI_FLASH_RESULT_OK ) {
res = spi_flash_write ( esp_native_code_cur , buf , len ) ;
}
if ( res ! = SPI_FLASH_RESULT_OK ) {
mp_raise_OSError ( res = = SPI_FLASH_RESULT_TIMEOUT ? MP_ETIMEDOUT : MP_EIO ) ;
}
dest = ( void * ) ( FLASH_START + esp_native_code_cur ) ;
}
esp_native_code_cur + = len ;
return dest ;
}
STATIC mp_obj_t esp_set_native_code_location ( mp_obj_t start_in , mp_obj_t len_in ) {
if ( start_in = = mp_const_none & & len_in = = mp_const_none ) {
// use end of iram1 region
esp_native_code_init ( ) ;
} else {
// use flash; input params are byte offsets from start of flash
esp_native_code_location = ESP_NATIVE_CODE_FLASH ;
esp_native_code_start = mp_obj_get_int ( start_in ) ;
esp_native_code_end = esp_native_code_start + mp_obj_get_int ( len_in ) ;
esp_native_code_cur = esp_native_code_start ;
esp_native_code_erased = esp_native_code_start ;
// memory-mapped flash is limited in extents to 1MByte
if ( esp_native_code_end > FLASH_END - FLASH_START ) {
mp_raise_ValueError ( " flash location must be below 1MByte " ) ;
}
}
return mp_const_none ;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2 ( esp_set_native_code_location_obj , esp_set_native_code_location ) ;
# endif
STATIC const mp_map_elem_t esp_module_globals_table [ ] = {
{ MP_OBJ_NEW_QSTR ( MP_QSTR___name__ ) , MP_OBJ_NEW_QSTR ( MP_QSTR_esp ) } ,
@ -729,6 +822,9 @@ STATIC const mp_map_elem_t esp_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR ( MP_QSTR_malloc ) , ( mp_obj_t ) & esp_malloc_obj } ,
{ MP_OBJ_NEW_QSTR ( MP_QSTR_free ) , ( mp_obj_t ) & esp_free_obj } ,
{ MP_OBJ_NEW_QSTR ( MP_QSTR_esf_free_bufs ) , ( mp_obj_t ) & esp_esf_free_bufs_obj } ,
# if MICROPY_EMIT_XTENSA
{ MP_OBJ_NEW_QSTR ( MP_QSTR_set_native_code_location ) , ( mp_obj_t ) & esp_set_native_code_location_obj } ,
# endif
# if MODESP_INCLUDE_CONSTANTS
{ MP_OBJ_NEW_QSTR ( MP_QSTR_SLEEP_NONE ) ,