diff options
Diffstat (limited to 'esp8266')
32 files changed, 505 insertions, 1575 deletions
diff --git a/esp8266/Makefile b/esp8266/Makefile index 90392cd49..c1ec3ca93 100644 --- a/esp8266/Makefile +++ b/esp8266/Makefile @@ -35,9 +35,6 @@ ESP_SDK = $(shell $(CC) -print-sysroot)/usr INC += -I. INC += -I.. INC += -I../stmhal -INC += -I../lib/mp-readline -INC += -I../lib/netutils -INC += -I../lib/timeutils INC += -I$(BUILD) INC += -I$(ESP_SDK)/include @@ -51,7 +48,7 @@ CFLAGS_XTENSA = -fsingle-precision-constant -Wdouble-promotion \ -Wl,-EL -mlongcalls -mtext-section-literals -mforce-l32 \ -DLWIP_OPEN_SRC -CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -ansi -std=gnu99 -nostdlib -DUART_OS=$(UART_OS) \ +CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -std=gnu99 -nostdlib -DUART_OS=$(UART_OS) \ $(CFLAGS_XTENSA) $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA) LDSCRIPT = esp8266.ld @@ -158,7 +155,7 @@ LIB_SRC_C = $(addprefix lib/,\ libc/string0.c \ libm/math.c \ libm/fmodf.c \ - libm/roundf.c \ + libm/nearbyintf.c \ libm/ef_sqrt.c \ libm/kf_rem_pio2.c \ libm/kf_sin.c \ @@ -174,21 +171,19 @@ LIB_SRC_C = $(addprefix lib/,\ libm/asinfacosf.c \ libm/atanf.c \ libm/atan2f.c \ - mp-readline/builtin_input.c \ mp-readline/readline.c \ netutils/netutils.c \ timeutils/timeutils.c \ utils/buffer_helper.c \ utils/context_manager_helpers.c \ utils/pyexec.c \ - utils/pyhelp.c \ utils/interrupt_char.c \ ) ifeq ($(MICROPY_FATFS), 1) LIB_SRC_C += \ - lib/fatfs/ff.c \ - lib/fatfs/option/ccsbcs.c + lib/oofatfs/ff.c \ + lib/oofatfs/option/unicode.c endif DRIVERS_SRC_C = $(addprefix drivers/,\ @@ -293,7 +288,11 @@ axtls: $(BUILD)/libaxtls.a $(BUILD)/libaxtls.a: cd ../lib/axtls; cp config/upyconfig config/.config - cd ../lib/axtls; make oldconfig -B - cd ../lib/axtls; make clean - cd ../lib/axtls; make all CC="$(Q)$(CC)" LD="$(Q)$(LD)" AR="$(Q)$(AR)" CFLAGS_EXTRA="$(CFLAGS_XTENSA) -Dabort=abort_ -DRT_MAX_PLAIN_LENGTH=1024 -DRT_EXTRA=3072" + cd ../lib/axtls; $(MAKE) oldconfig -B + cd ../lib/axtls; $(MAKE) clean + cd ../lib/axtls; $(MAKE) all CC="$(CC)" LD="$(LD)" AR="$(AR)" CFLAGS_EXTRA="$(CFLAGS_XTENSA) -Dabort=abort_ -DRT_MAX_PLAIN_LENGTH=1024 -DRT_EXTRA=3072" cp ../lib/axtls/_stage/libaxtls.a $@ + +clean-modules: + git clean -f -d modules + rm -f build/frozen*.c diff --git a/esp8266/README.md b/esp8266/README.md index 54591fcc1..d717d26fe 100644 --- a/esp8266/README.md +++ b/esp8266/README.md @@ -79,6 +79,16 @@ $ make PORT=/dev/ttyUSB0 FLASH_MODE=qio FLASH_SIZE=32m deploy The image produced is `build/firmware-combined.bin`, to be flashed at 0x00000. +__512KB FlashROM version__ + +The normal build described above requires modules with at least 1MB of FlashROM +onboard. There's a special configuration for 512KB modules, which can be +built with `make 512k`. This configuration is highly limited, lacks filesystem +support, WebREPL, and has many other features disabled. It's mostly suitable +for advanced users who are interested to fine-tune options to achieve a required +setup. If you are an end user, please consider using a module with at least 1MB +of FlashROM. + First start ----------- @@ -90,7 +100,7 @@ programming). __WiFi__ -Initally, the device configures itself as a WiFi access point (AP). +Initially, the device configures itself as a WiFi access point (AP). - ESSID: MicroPython-xxxxxx (x’s are replaced with part of the MAC address). - Password: micropythoN (note the upper-case N). - IP address of the board: 192.168.4.1. @@ -110,7 +120,7 @@ http://docs.micropython.org/en/latest/esp8266/esp8266/tutorial/intro.html Troubleshooting --------------- -While the port is still in alpha, it's known to be generally stable. If you +While the port is in beta, it's known to be generally stable. If you experience strange bootloops, crashes, lockups, here's a list to check against: - You didn't erase flash before programming MicroPython firmware. diff --git a/esp8266/esp8266.ld b/esp8266/esp8266.ld index 3af32c994..deeb82b45 100644 --- a/esp8266/esp8266.ld +++ b/esp8266/esp8266.ld @@ -5,304 +5,8 @@ MEMORY dport0_0_seg : org = 0x3ff00000, len = 0x10 dram0_0_seg : org = 0x3ffe8000, len = 0x14000 iram1_0_seg : org = 0x40100000, len = 0x8000 - irom0_0_seg : org = 0x40209000, len = 0x87000 + irom0_0_seg : org = 0x40209000, len = 0x8f000 } -/* define the top of RAM */ -_heap_end = ORIGIN(dram0_0_seg) + LENGTH(dram0_0_seg); - -PHDRS -{ - dport0_0_phdr PT_LOAD; - dram0_0_phdr PT_LOAD; - dram0_0_bss_phdr PT_LOAD; - iram1_0_phdr PT_LOAD; - irom0_0_phdr PT_LOAD; -} - -ENTRY(firmware_start) -EXTERN(_DebugExceptionVector) -EXTERN(_DoubleExceptionVector) -EXTERN(_KernelExceptionVector) -EXTERN(_NMIExceptionVector) -EXTERN(_UserExceptionVector) - -PROVIDE(_memmap_vecbase_reset = 0x40000000); - -/* Various memory-map dependent cache attribute settings: */ -_memmap_cacheattr_wb_base = 0x00000110; -_memmap_cacheattr_wt_base = 0x00000110; -_memmap_cacheattr_bp_base = 0x00000220; -_memmap_cacheattr_unused_mask = 0xFFFFF00F; -_memmap_cacheattr_wb_trapnull = 0x2222211F; -_memmap_cacheattr_wba_trapnull = 0x2222211F; -_memmap_cacheattr_wbna_trapnull = 0x2222211F; -_memmap_cacheattr_wt_trapnull = 0x2222211F; -_memmap_cacheattr_bp_trapnull = 0x2222222F; -_memmap_cacheattr_wb_strict = 0xFFFFF11F; -_memmap_cacheattr_wt_strict = 0xFFFFF11F; -_memmap_cacheattr_bp_strict = 0xFFFFF22F; -_memmap_cacheattr_wb_allvalid = 0x22222112; -_memmap_cacheattr_wt_allvalid = 0x22222112; -_memmap_cacheattr_bp_allvalid = 0x22222222; -PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull); - -SECTIONS -{ - - .dport0.rodata : ALIGN(4) - { - _dport0_rodata_start = ABSOLUTE(.); - *(.dport0.rodata) - *(.dport.rodata) - _dport0_rodata_end = ABSOLUTE(.); - } >dport0_0_seg :dport0_0_phdr - - .dport0.literal : ALIGN(4) - { - _dport0_literal_start = ABSOLUTE(.); - *(.dport0.literal) - *(.dport.literal) - _dport0_literal_end = ABSOLUTE(.); - } >dport0_0_seg :dport0_0_phdr - - .dport0.data : ALIGN(4) - { - _dport0_data_start = ABSOLUTE(.); - *(.dport0.data) - *(.dport.data) - _dport0_data_end = ABSOLUTE(.); - } >dport0_0_seg :dport0_0_phdr - - .irom0.text : ALIGN(4) - { - _irom0_text_start = ABSOLUTE(.); - *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text) - - /* we put some specific text in this section */ - *common-hal/*.o*(.literal* .text*) - *shared-bindings/*.o*(.literal* .text*) - *shared-module/*.o*(.literal* .text*) - - *py/argcheck.o*(.literal* .text*) - *py/asm*.o*(.literal* .text*) - *py/bc.o*(.literal* .text*) - *py/binary.o*(.literal* .text*) - *py/builtin*.o*(.literal* .text*) - *py/compile.o*(.literal* .text*) - *py/emit*.o*(.literal* .text*) - *py/persistentcode*.o*(.literal* .text*) - *py/formatfloat.o*(.literal* .text*) - *py/frozenmod.o*(.literal* .text*) - *py/gc.o*(.literal* .text*) - *py/reader*.o*(.literal* .text*) - *py/lexer*.o*(.literal* .text*) - *py/malloc*.o*(.literal* .text*) - *py/map*.o*(.literal* .text*) - *py/mod*.o*(.literal* .text*) - *py/mpprint.o*(.literal* .text*) - *py/mpstate.o*(.literal* .text*) - *py/mpz.o*(.literal* .text*) - *py/native*.o*(.literal* .text*) - *py/nlr*.o*(.literal* .text*) - *py/obj*.o*(.literal* .text*) - *py/opmethods.o*(.literal* .text*) - *py/parse*.o*(.literal* .text*) - *py/qstr.o*(.literal* .text*) - *py/repl.o*(.literal* .text*) - *py/runtime.o*(.literal* .text*) - *py/scope.o*(.literal* .text*) - *py/sequence.o*(.literal* .text*) - *py/showbc.o*(.literal* .text*) - *py/smallint.o*(.literal* .text*) - *py/stackctrl.o*(.literal* .text*) - *py/stream.o*(.literal* .text*) - *py/unicode.o*(.literal* .text*) - *py/vm.o*(.literal* .text*) - *py/vstr.o*(.literal* .text*) - *py/warning.o*(.literal* .text*) - - *extmod/*.o*(.literal* .text*) - - *lib/fatfs/*.o*(.literal*, .text*) - */libaxtls.a:(.literal*, .text*) - *lib/berkeley-db-1.xx/*.o(.literal*, .text*) - *lib/libm/*.o*(.literal*, .text*) - *lib/mp-readline/*.o(.literal*, .text*) - *lib/netutils/*.o*(.literal*, .text*) - *lib/timeutils/*.o*(.literal*, .text*) - *lib/utils/*.o*(.literal*, .text*) - - *stmhal/pybstdio.o(.literal*, .text*) - - build/main.o(.literal* .text*) - *gccollect.o(.literal* .text*) - *gchelper.o(.literal* .text*) - *help.o(.literal* .text*) - *lexerstr32.o(.literal* .text*) - *utils.o(.literal* .text*) - *modpyb.o(.literal*, .text*) - *machine_pin.o(.literal*, .text*) - *machine_pwm.o(.literal*, .text*) - *machine_rtc.o(.literal*, .text*) - *machine_adc.o(.literal*, .text*) - *machine_uart.o(.literal*, .text*) - *modpybi2c.o(.literal*, .text*) - *modmachine.o(.literal*, .text*) - *machine_wdt.o(.literal*, .text*) - *machine_spi.o(.literal*, .text*) - *machine_hspi.o(.literal*, .text*) - *hspi.o(.literal*, .text*) - *modesp.o(.literal* .text*) - *modnetwork.o(.literal* .text*) - *moduos.o(.literal* .text*) - *modutime.o(.literal* .text*) - *modlwip.o(.literal* .text*) - *modsocket.o(.literal* .text*) - *modonewire.o(.literal* .text*) - - /* we put as much rodata as possible in this section */ - /* note that only rodata accessed as a machine word is allowed here */ - *py/qstr.o(.rodata.const_pool) - *.o(.rodata.mp_type_*) /* catches type: mp_obj_type_t */ - *.o(.rodata.*_locals_dict*) /* catches types: mp_obj_dict_t, mp_map_elem_t */ - *.o(.rodata.mp_module_*) /* catches types: mp_obj_module_t, mp_obj_dict_t, mp_map_elem_t */ - */frozen.o(.rodata.mp_frozen_sizes) /* frozen modules */ - */frozen.o(.rodata.mp_frozen_content) /* frozen modules */ - - /* for -mforce-l32 */ - build/*.o(.rodata*) - - _irom0_text_end = ABSOLUTE(.); - } >irom0_0_seg :irom0_0_phdr - - .text : ALIGN(4) - { - _stext = .; - _text_start = ABSOLUTE(.); - *(.UserEnter.text) - . = ALIGN(16); - *(.DebugExceptionVector.text) - . = ALIGN(16); - *(.NMIExceptionVector.text) - . = ALIGN(16); - *(.KernelExceptionVector.text) - LONG(0) - LONG(0) - LONG(0) - LONG(0) - . = ALIGN(16); - *(.UserExceptionVector.text) - LONG(0) - LONG(0) - LONG(0) - LONG(0) - . = ALIGN(16); - *(.DoubleExceptionVector.text) - LONG(0) - LONG(0) - LONG(0) - LONG(0) - . = ALIGN (16); - *(.entry.text) - *(.init.literal) - *(.init) - *(.literal .text .literal.* .text.* .iram0.literal .iram0.text .iram0.text.*.literal .iram0.text.*) - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.fini.literal) - *(.fini) - *(.gnu.version) - _text_end = ABSOLUTE(.); - _etext = .; - } >iram1_0_seg :iram1_0_phdr - - .lit4 : ALIGN(4) - { - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - } >iram1_0_seg :iram1_0_phdr - - .data : ALIGN(4) - { - _data_start = ABSOLUTE(.); - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.sdata2) - *(.sdata2.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - _data_end = ABSOLUTE(.); - } >dram0_0_seg :dram0_0_phdr - - .rodata : ALIGN(4) - { - _rodata_start = ABSOLUTE(.); - *(.sdk.version) - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - *(.rodata1) - __XT_EXCEPTION_TABLE__ = ABSOLUTE(.); - *(.xt_except_table) - *(.gcc_except_table) - *(.gnu.linkonce.e.*) - *(.gnu.version_r) - *(.eh_frame) - /* C++ constructor and destructor tables, properly ordered: */ - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - /* C++ exception handlers table: */ - __XT_EXCEPTION_DESCS__ = ABSOLUTE(.); - *(.xt_except_desc) - *(.gnu.linkonce.h.*) - __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); - *(.xt_except_desc_end) - *(.dynamic) - *(.gnu.version_d) - . = ALIGN(4); /* this table MUST be 4-byte aligned */ - _bss_table_start = ABSOLUTE(.); - LONG(_bss_start) - LONG(_bss_end) - _bss_table_end = ABSOLUTE(.); - _rodata_end = ABSOLUTE(.); - } >dram0_0_seg :dram0_0_phdr - - .bss ALIGN(8) (NOLOAD) : ALIGN(4) - { - . = ALIGN (8); - _bss_start = ABSOLUTE(.); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _bss_end = ABSOLUTE(.); - _heap_start = ABSOLUTE(.); - } >dram0_0_seg :dram0_0_bss_phdr -} - -/* get ROM code address */ -INCLUDE "eagle.rom.addr.v6.ld" +/* define common sections and symbols */ +INCLUDE esp8266_common.ld diff --git a/esp8266/esp8266_512k.ld b/esp8266/esp8266_512k.ld index 2bffcab80..0ae663db1 100644 --- a/esp8266/esp8266_512k.ld +++ b/esp8266/esp8266_512k.ld @@ -8,298 +8,5 @@ MEMORY irom0_0_seg : org = 0x40209000, len = 0x72000 } -/* define the top of RAM */ -_heap_end = ORIGIN(dram0_0_seg) + LENGTH(dram0_0_seg); - -PHDRS -{ - dport0_0_phdr PT_LOAD; - dram0_0_phdr PT_LOAD; - dram0_0_bss_phdr PT_LOAD; - iram1_0_phdr PT_LOAD; - irom0_0_phdr PT_LOAD; -} - -ENTRY(firmware_start) -EXTERN(_DebugExceptionVector) -EXTERN(_DoubleExceptionVector) -EXTERN(_KernelExceptionVector) -EXTERN(_NMIExceptionVector) -EXTERN(_UserExceptionVector) - -PROVIDE(_memmap_vecbase_reset = 0x40000000); - -/* Various memory-map dependent cache attribute settings: */ -_memmap_cacheattr_wb_base = 0x00000110; -_memmap_cacheattr_wt_base = 0x00000110; -_memmap_cacheattr_bp_base = 0x00000220; -_memmap_cacheattr_unused_mask = 0xFFFFF00F; -_memmap_cacheattr_wb_trapnull = 0x2222211F; -_memmap_cacheattr_wba_trapnull = 0x2222211F; -_memmap_cacheattr_wbna_trapnull = 0x2222211F; -_memmap_cacheattr_wt_trapnull = 0x2222211F; -_memmap_cacheattr_bp_trapnull = 0x2222222F; -_memmap_cacheattr_wb_strict = 0xFFFFF11F; -_memmap_cacheattr_wt_strict = 0xFFFFF11F; -_memmap_cacheattr_bp_strict = 0xFFFFF22F; -_memmap_cacheattr_wb_allvalid = 0x22222112; -_memmap_cacheattr_wt_allvalid = 0x22222112; -_memmap_cacheattr_bp_allvalid = 0x22222222; -PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull); - -SECTIONS -{ - - .dport0.rodata : ALIGN(4) - { - _dport0_rodata_start = ABSOLUTE(.); - *(.dport0.rodata) - *(.dport.rodata) - _dport0_rodata_end = ABSOLUTE(.); - } >dport0_0_seg :dport0_0_phdr - - .dport0.literal : ALIGN(4) - { - _dport0_literal_start = ABSOLUTE(.); - *(.dport0.literal) - *(.dport.literal) - _dport0_literal_end = ABSOLUTE(.); - } >dport0_0_seg :dport0_0_phdr - - .dport0.data : ALIGN(4) - { - _dport0_data_start = ABSOLUTE(.); - *(.dport0.data) - *(.dport.data) - _dport0_data_end = ABSOLUTE(.); - } >dport0_0_seg :dport0_0_phdr - - .irom0.text : ALIGN(4) - { - _irom0_text_start = ABSOLUTE(.); - *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text) - - /* we put some specific text in this section */ - - *py/argcheck.o*(.literal* .text*) - *py/asm*.o*(.literal* .text*) - *py/bc.o*(.literal* .text*) - *py/binary.o*(.literal* .text*) - *py/builtin*.o*(.literal* .text*) - *py/compile.o*(.literal* .text*) - *py/emit*.o*(.literal* .text*) - *py/persistentcode*.o*(.literal* .text*) - *py/formatfloat.o*(.literal* .text*) - *py/frozenmod.o*(.literal* .text*) - *py/gc.o*(.literal* .text*) - *py/reader*.o*(.literal* .text*) - *py/lexer*.o*(.literal* .text*) - *py/malloc*.o*(.literal* .text*) - *py/map*.o*(.literal* .text*) - *py/mod*.o*(.literal* .text*) - *py/mpprint.o*(.literal* .text*) - *py/mpstate.o*(.literal* .text*) - *py/mpz.o*(.literal* .text*) - *py/native*.o*(.literal* .text*) - *py/nlr*.o*(.literal* .text*) - *py/obj*.o*(.literal* .text*) - *py/opmethods.o*(.literal* .text*) - *py/parse*.o*(.literal* .text*) - *py/qstr.o*(.literal* .text*) - *py/repl.o*(.literal* .text*) - *py/runtime.o*(.literal* .text*) - *py/scope.o*(.literal* .text*) - *py/sequence.o*(.literal* .text*) - *py/showbc.o*(.literal* .text*) - *py/smallint.o*(.literal* .text*) - *py/stackctrl.o*(.literal* .text*) - *py/stream.o*(.literal* .text*) - *py/unicode.o*(.literal* .text*) - *py/vm.o*(.literal* .text*) - *py/vstr.o*(.literal* .text*) - *py/warning.o*(.literal* .text*) - - *extmod/*.o*(.literal* .text*) - - *lib/fatfs/*.o*(.literal*, .text*) - */libaxtls.a:(.literal*, .text*) - *lib/berkeley-db-1.xx/*.o(.literal*, .text*) - *lib/libm/*.o*(.literal*, .text*) - *lib/mp-readline/*.o(.literal*, .text*) - *lib/netutils/*.o*(.literal*, .text*) - *lib/timeutils/*.o*(.literal*, .text*) - *lib/utils/*.o*(.literal*, .text*) - - *stmhal/pybstdio.o(.literal*, .text*) - - build/main.o(.literal* .text*) - *gccollect.o(.literal* .text*) - *gchelper.o(.literal* .text*) - *help.o(.literal* .text*) - *lexerstr32.o(.literal* .text*) - *utils.o(.literal* .text*) - *modpyb.o(.literal*, .text*) - *machine_pin.o(.literal*, .text*) - *machine_pwm.o(.literal*, .text*) - *machine_rtc.o(.literal*, .text*) - *machine_adc.o(.literal*, .text*) - *machine_uart.o(.literal*, .text*) - *modpybi2c.o(.literal*, .text*) - *modmachine.o(.literal*, .text*) - *machine_wdt.o(.literal*, .text*) - *machine_spi.o(.literal*, .text*) - *machine_hspi.o(.literal*, .text*) - *hspi.o(.literal*, .text*) - *modesp.o(.literal* .text*) - *modnetwork.o(.literal* .text*) - *moduos.o(.literal* .text*) - *modutime.o(.literal* .text*) - *modlwip.o(.literal* .text*) - *modsocket.o(.literal* .text*) - *modonewire.o(.literal* .text*) - - /* we put as much rodata as possible in this section */ - /* note that only rodata accessed as a machine word is allowed here */ - *py/qstr.o(.rodata.const_pool) - *.o(.rodata.mp_type_*) /* catches type: mp_obj_type_t */ - *.o(.rodata.*_locals_dict*) /* catches types: mp_obj_dict_t, mp_map_elem_t */ - *.o(.rodata.mp_module_*) /* catches types: mp_obj_module_t, mp_obj_dict_t, mp_map_elem_t */ - */frozen.o(.rodata.mp_frozen_sizes) /* frozen modules */ - */frozen.o(.rodata.mp_frozen_content) /* frozen modules */ - - /* for -mforce-l32 */ - build/*.o(.rodata*) - - _irom0_text_end = ABSOLUTE(.); - } >irom0_0_seg :irom0_0_phdr - - .text : ALIGN(4) - { - _stext = .; - _text_start = ABSOLUTE(.); - *(.UserEnter.text) - . = ALIGN(16); - *(.DebugExceptionVector.text) - . = ALIGN(16); - *(.NMIExceptionVector.text) - . = ALIGN(16); - *(.KernelExceptionVector.text) - LONG(0) - LONG(0) - LONG(0) - LONG(0) - . = ALIGN(16); - *(.UserExceptionVector.text) - LONG(0) - LONG(0) - LONG(0) - LONG(0) - . = ALIGN(16); - *(.DoubleExceptionVector.text) - LONG(0) - LONG(0) - LONG(0) - LONG(0) - . = ALIGN (16); - *(.entry.text) - *(.init.literal) - *(.init) - *(.literal .text .literal.* .text.* .iram0.literal .iram0.text .iram0.text.*.literal .iram0.text.*) - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.fini.literal) - *(.fini) - *(.gnu.version) - _text_end = ABSOLUTE(.); - _etext = .; - } >iram1_0_seg :iram1_0_phdr - - .lit4 : ALIGN(4) - { - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - } >iram1_0_seg :iram1_0_phdr - - .data : ALIGN(4) - { - _data_start = ABSOLUTE(.); - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.sdata2) - *(.sdata2.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - _data_end = ABSOLUTE(.); - } >dram0_0_seg :dram0_0_phdr - - .rodata : ALIGN(4) - { - _rodata_start = ABSOLUTE(.); - *(.sdk.version) - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - *(.rodata1) - __XT_EXCEPTION_TABLE__ = ABSOLUTE(.); - *(.xt_except_table) - *(.gcc_except_table) - *(.gnu.linkonce.e.*) - *(.gnu.version_r) - *(.eh_frame) - /* C++ constructor and destructor tables, properly ordered: */ - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - /* C++ exception handlers table: */ - __XT_EXCEPTION_DESCS__ = ABSOLUTE(.); - *(.xt_except_desc) - *(.gnu.linkonce.h.*) - __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); - *(.xt_except_desc_end) - *(.dynamic) - *(.gnu.version_d) - . = ALIGN(4); /* this table MUST be 4-byte aligned */ - _bss_table_start = ABSOLUTE(.); - LONG(_bss_start) - LONG(_bss_end) - _bss_table_end = ABSOLUTE(.); - _rodata_end = ABSOLUTE(.); - } >dram0_0_seg :dram0_0_phdr - - .bss ALIGN(8) (NOLOAD) : ALIGN(4) - { - . = ALIGN (8); - _bss_start = ABSOLUTE(.); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _bss_end = ABSOLUTE(.); - _heap_start = ABSOLUTE(.); - } >dram0_0_seg :dram0_0_bss_phdr -} - -/* get ROM code address */ -INCLUDE "eagle.rom.addr.v6.ld" +/* define common sections and symbols */ +INCLUDE esp8266_common.ld diff --git a/esp8266/esp8266_common.ld b/esp8266/esp8266_common.ld new file mode 100644 index 000000000..43cb5d0d5 --- /dev/null +++ b/esp8266/esp8266_common.ld @@ -0,0 +1,304 @@ +/* GNU linker script for ESP8266, common sections and symbols */ + +/* define the top of RAM */ +_heap_end = ORIGIN(dram0_0_seg) + LENGTH(dram0_0_seg); + +PHDRS +{ + dport0_0_phdr PT_LOAD; + dram0_0_phdr PT_LOAD; + dram0_0_bss_phdr PT_LOAD; + iram1_0_phdr PT_LOAD; + irom0_0_phdr PT_LOAD; +} + +ENTRY(firmware_start) +EXTERN(_DebugExceptionVector) +EXTERN(_DoubleExceptionVector) +EXTERN(_KernelExceptionVector) +EXTERN(_NMIExceptionVector) +EXTERN(_UserExceptionVector) + +_firmware_size = ORIGIN(irom0_0_seg) + LENGTH(irom0_0_seg) - 0x40200000; + +PROVIDE(_memmap_vecbase_reset = 0x40000000); + +/* Various memory-map dependent cache attribute settings: */ +_memmap_cacheattr_wb_base = 0x00000110; +_memmap_cacheattr_wt_base = 0x00000110; +_memmap_cacheattr_bp_base = 0x00000220; +_memmap_cacheattr_unused_mask = 0xFFFFF00F; +_memmap_cacheattr_wb_trapnull = 0x2222211F; +_memmap_cacheattr_wba_trapnull = 0x2222211F; +_memmap_cacheattr_wbna_trapnull = 0x2222211F; +_memmap_cacheattr_wt_trapnull = 0x2222211F; +_memmap_cacheattr_bp_trapnull = 0x2222222F; +_memmap_cacheattr_wb_strict = 0xFFFFF11F; +_memmap_cacheattr_wt_strict = 0xFFFFF11F; +_memmap_cacheattr_bp_strict = 0xFFFFF22F; +_memmap_cacheattr_wb_allvalid = 0x22222112; +_memmap_cacheattr_wt_allvalid = 0x22222112; +_memmap_cacheattr_bp_allvalid = 0x22222222; +PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull); + +SECTIONS +{ + + .dport0.rodata : ALIGN(4) + { + _dport0_rodata_start = ABSOLUTE(.); + *(.dport0.rodata) + *(.dport.rodata) + _dport0_rodata_end = ABSOLUTE(.); + } >dport0_0_seg :dport0_0_phdr + + .dport0.literal : ALIGN(4) + { + _dport0_literal_start = ABSOLUTE(.); + *(.dport0.literal) + *(.dport.literal) + _dport0_literal_end = ABSOLUTE(.); + } >dport0_0_seg :dport0_0_phdr + + .dport0.data : ALIGN(4) + { + _dport0_data_start = ABSOLUTE(.); + *(.dport0.data) + *(.dport.data) + _dport0_data_end = ABSOLUTE(.); + } >dport0_0_seg :dport0_0_phdr + + .irom0.text : ALIGN(4) + { + _irom0_text_start = ABSOLUTE(.); + *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text) + + /* we put some specific text in this section */ + + *common-hal/*.o*(.literal* .text*) + *shared-bindings/*.o*(.literal* .text*) + *shared-module/*.o*(.literal* .text*) + + *py/argcheck.o*(.literal* .text*) + *py/asm*.o*(.literal* .text*) + *py/bc.o*(.literal* .text*) + *py/binary.o*(.literal* .text*) + *py/builtin*.o*(.literal* .text*) + *py/compile.o*(.literal* .text*) + *py/emit*.o*(.literal* .text*) + *py/persistentcode*.o*(.literal* .text*) + *py/formatfloat.o*(.literal* .text*) + *py/frozenmod.o*(.literal* .text*) + *py/gc.o*(.literal* .text*) + *py/reader*.o*(.literal* .text*) + *py/lexer*.o*(.literal* .text*) + *py/malloc*.o*(.literal* .text*) + *py/map*.o*(.literal* .text*) + *py/mod*.o*(.literal* .text*) + *py/mpprint.o*(.literal* .text*) + *py/mpstate.o*(.literal* .text*) + *py/mpz.o*(.literal* .text*) + *py/native*.o*(.literal* .text*) + *py/nlr*.o*(.literal* .text*) + *py/obj*.o*(.literal* .text*) + *py/opmethods.o*(.literal* .text*) + *py/parse*.o*(.literal* .text*) + *py/qstr.o*(.literal* .text*) + *py/repl.o*(.literal* .text*) + *py/runtime.o*(.literal* .text*) + *py/scheduler.o*(.literal* .text*) + *py/scope.o*(.literal* .text*) + *py/sequence.o*(.literal* .text*) + *py/showbc.o*(.literal* .text*) + *py/smallint.o*(.literal* .text*) + *py/stackctrl.o*(.literal* .text*) + *py/stream.o*(.literal* .text*) + *py/unicode.o*(.literal* .text*) + *py/vm.o*(.literal* .text*) + *py/vstr.o*(.literal* .text*) + *py/warning.o*(.literal* .text*) + + *extmod/*.o*(.literal* .text*) + + *lib/oofatfs/*.o*(.literal*, .text*) + */libaxtls.a:(.literal*, .text*) + *lib/berkeley-db-1.xx/*.o(.literal*, .text*) + *lib/libm/*.o*(.literal*, .text*) + *lib/mp-readline/*.o(.literal*, .text*) + *lib/netutils/*.o*(.literal*, .text*) + *lib/timeutils/*.o*(.literal*, .text*) + *lib/utils/*.o*(.literal*, .text*) + + *stmhal/pybstdio.o(.literal*, .text*) + + build/main.o(.literal* .text*) + *gccollect.o(.literal* .text*) + *gchelper.o(.literal* .text*) + *help.o(.literal* .text*) + *lexerstr32.o(.literal* .text*) + *utils.o(.literal* .text*) + *modpyb.o(.literal*, .text*) + *machine_pin.o(.literal*, .text*) + *machine_pwm.o(.literal*, .text*) + *machine_rtc.o(.literal*, .text*) + *machine_adc.o(.literal*, .text*) + *machine_uart.o(.literal*, .text*) + *modpybi2c.o(.literal*, .text*) + *modmachine.o(.literal*, .text*) + *machine_wdt.o(.literal*, .text*) + *machine_spi.o(.literal*, .text*) + *machine_hspi.o(.literal*, .text*) + *hspi.o(.literal*, .text*) + *modesp.o(.literal* .text*) + *modnetwork.o(.literal* .text*) + *moduos.o(.literal* .text*) + *modutime.o(.literal* .text*) + *modlwip.o(.literal* .text*) + *modsocket.o(.literal* .text*) + *modonewire.o(.literal* .text*) + + /* we put as much rodata as possible in this section */ + /* note that only rodata accessed as a machine word is allowed here */ + *py/qstr.o(.rodata.const_pool) + *.o(.rodata.mp_type_*) /* catches type: mp_obj_type_t */ + *.o(.rodata.*_locals_dict*) /* catches types: mp_obj_dict_t, mp_map_elem_t */ + *.o(.rodata.mp_module_*) /* catches types: mp_obj_module_t, mp_obj_dict_t, mp_map_elem_t */ + */frozen.o(.rodata.mp_frozen_sizes) /* frozen modules */ + */frozen.o(.rodata.mp_frozen_content) /* frozen modules */ + + /* for -mforce-l32 */ + build/*.o(.rodata*) + + _irom0_text_end = ABSOLUTE(.); + } >irom0_0_seg :irom0_0_phdr + + .text : ALIGN(4) + { + _stext = .; + _text_start = ABSOLUTE(.); + *(.UserEnter.text) + . = ALIGN(16); + *(.DebugExceptionVector.text) + . = ALIGN(16); + *(.NMIExceptionVector.text) + . = ALIGN(16); + *(.KernelExceptionVector.text) + LONG(0) + LONG(0) + LONG(0) + LONG(0) + . = ALIGN(16); + *(.UserExceptionVector.text) + LONG(0) + LONG(0) + LONG(0) + LONG(0) + . = ALIGN(16); + *(.DoubleExceptionVector.text) + LONG(0) + LONG(0) + LONG(0) + LONG(0) + . = ALIGN (16); + *(.entry.text) + *(.init.literal) + *(.init) + *(.literal .text .literal.* .text.* .iram0.literal .iram0.text .iram0.text.*.literal .iram0.text.*) + *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.fini.literal) + *(.fini) + *(.gnu.version) + _text_end = ABSOLUTE(.); + _etext = .; + } >iram1_0_seg :iram1_0_phdr + + .lit4 : ALIGN(4) + { + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + } >iram1_0_seg :iram1_0_phdr + + .data : ALIGN(4) + { + _data_start = ABSOLUTE(.); + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.data1) + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + *(.jcr) + _data_end = ABSOLUTE(.); + } >dram0_0_seg :dram0_0_phdr + + .rodata : ALIGN(4) + { + _rodata_start = ABSOLUTE(.); + *(.sdk.version) + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE__ = ABSOLUTE(.); + *(.xt_except_table) + *(.gcc_except_table) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + *(.eh_frame) + /* C++ constructor and destructor tables, properly ordered: */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + /* C++ exception handlers table: */ + __XT_EXCEPTION_DESCS__ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + . = ALIGN(4); /* this table MUST be 4-byte aligned */ + _bss_table_start = ABSOLUTE(.); + LONG(_bss_start) + LONG(_bss_end) + _bss_table_end = ABSOLUTE(.); + _rodata_end = ABSOLUTE(.); + } >dram0_0_seg :dram0_0_phdr + + .bss ALIGN(8) (NOLOAD) : ALIGN(4) + { + . = ALIGN (8); + _bss_start = ABSOLUTE(.); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + _bss_end = ABSOLUTE(.); + _heap_start = ABSOLUTE(.); + } >dram0_0_seg :dram0_0_bss_phdr +} + +/* get ROM code address */ +INCLUDE "eagle.rom.addr.v6.ld" diff --git a/esp8266/esp8266_ota.ld b/esp8266/esp8266_ota.ld index aceeb25a5..604480a0a 100644 --- a/esp8266/esp8266_ota.ld +++ b/esp8266/esp8266_ota.ld @@ -6,301 +6,8 @@ MEMORY dram0_0_seg : org = 0x3ffe8000, len = 0x14000 iram1_0_seg : org = 0x40100000, len = 0x8000 /* 0x3c000 is size of bootloader, 0x9000 is size of packed RAM segments */ - irom0_0_seg : org = 0x40200000 + 0x3c000 + 0x9000, len = 0x87000 + irom0_0_seg : org = 0x40200000 + 0x3c000 + 0x9000, len = 0x8f000 } -/* define the top of RAM */ -_heap_end = ORIGIN(dram0_0_seg) + LENGTH(dram0_0_seg); - -PHDRS -{ - dport0_0_phdr PT_LOAD; - dram0_0_phdr PT_LOAD; - dram0_0_bss_phdr PT_LOAD; - iram1_0_phdr PT_LOAD; - irom0_0_phdr PT_LOAD; -} - -ENTRY(firmware_start) -EXTERN(_DebugExceptionVector) -EXTERN(_DoubleExceptionVector) -EXTERN(_KernelExceptionVector) -EXTERN(_NMIExceptionVector) -EXTERN(_UserExceptionVector) - -PROVIDE(_memmap_vecbase_reset = 0x40000000); - -/* Various memory-map dependent cache attribute settings: */ -_memmap_cacheattr_wb_base = 0x00000110; -_memmap_cacheattr_wt_base = 0x00000110; -_memmap_cacheattr_bp_base = 0x00000220; -_memmap_cacheattr_unused_mask = 0xFFFFF00F; -_memmap_cacheattr_wb_trapnull = 0x2222211F; -_memmap_cacheattr_wba_trapnull = 0x2222211F; -_memmap_cacheattr_wbna_trapnull = 0x2222211F; -_memmap_cacheattr_wt_trapnull = 0x2222211F; -_memmap_cacheattr_bp_trapnull = 0x2222222F; -_memmap_cacheattr_wb_strict = 0xFFFFF11F; -_memmap_cacheattr_wt_strict = 0xFFFFF11F; -_memmap_cacheattr_bp_strict = 0xFFFFF22F; -_memmap_cacheattr_wb_allvalid = 0x22222112; -_memmap_cacheattr_wt_allvalid = 0x22222112; -_memmap_cacheattr_bp_allvalid = 0x22222222; -PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull); - -SECTIONS -{ - - .dport0.rodata : ALIGN(4) - { - _dport0_rodata_start = ABSOLUTE(.); - *(.dport0.rodata) - *(.dport.rodata) - _dport0_rodata_end = ABSOLUTE(.); - } >dport0_0_seg :dport0_0_phdr - - .dport0.literal : ALIGN(4) - { - _dport0_literal_start = ABSOLUTE(.); - *(.dport0.literal) - *(.dport.literal) - _dport0_literal_end = ABSOLUTE(.); - } >dport0_0_seg :dport0_0_phdr - - .dport0.data : ALIGN(4) - { - _dport0_data_start = ABSOLUTE(.); - *(.dport0.data) - *(.dport.data) - _dport0_data_end = ABSOLUTE(.); - } >dport0_0_seg :dport0_0_phdr - - .irom0.text : ALIGN(4) - { - _irom0_text_start = ABSOLUTE(.); - *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text) - - /* we put some specific text in this section */ - - *py/argcheck.o*(.literal* .text*) - *py/asm*.o*(.literal* .text*) - *py/bc.o*(.literal* .text*) - *py/binary.o*(.literal* .text*) - *py/builtin*.o*(.literal* .text*) - *py/compile.o*(.literal* .text*) - *py/emit*.o*(.literal* .text*) - *py/persistentcode*.o*(.literal* .text*) - *py/formatfloat.o*(.literal* .text*) - *py/frozenmod.o*(.literal* .text*) - *py/gc.o*(.literal* .text*) - *py/reader*.o*(.literal* .text*) - *py/lexer*.o*(.literal* .text*) - *py/malloc*.o*(.literal* .text*) - *py/map*.o*(.literal* .text*) - *py/mod*.o*(.literal* .text*) - *py/mpprint.o*(.literal* .text*) - *py/mpstate.o*(.literal* .text*) - *py/mpz.o*(.literal* .text*) - *py/native*.o*(.literal* .text*) - *py/nlr*.o*(.literal* .text*) - *py/obj*.o*(.literal* .text*) - *py/opmethods.o*(.literal* .text*) - *py/parse*.o*(.literal* .text*) - *py/qstr.o*(.literal* .text*) - *py/repl.o*(.literal* .text*) - *py/runtime.o*(.literal* .text*) - *py/scope.o*(.literal* .text*) - *py/sequence.o*(.literal* .text*) - *py/showbc.o*(.literal* .text*) - *py/smallint.o*(.literal* .text*) - *py/stackctrl.o*(.literal* .text*) - *py/stream.o*(.literal* .text*) - *py/unicode.o*(.literal* .text*) - *py/vm.o*(.literal* .text*) - *py/vstr.o*(.literal* .text*) - *py/warning.o*(.literal* .text*) - - *extmod/*.o*(.literal* .text*) - - *lib/fatfs/*.o*(.literal*, .text*) - */libaxtls.a:(.literal*, .text*) - *lib/berkeley-db-1.xx/*.o(.literal*, .text*) - *lib/libm/*.o*(.literal*, .text*) - *lib/mp-readline/*.o(.literal*, .text*) - *lib/netutils/*.o*(.literal*, .text*) - *lib/timeutils/*.o*(.literal*, .text*) - *lib/utils/*.o*(.literal*, .text*) - - *stmhal/pybstdio.o(.literal*, .text*) - - build/main.o(.literal* .text*) - *gccollect.o(.literal* .text*) - *gchelper.o(.literal* .text*) - *help.o(.literal* .text*) - *lexerstr32.o(.literal* .text*) - *utils.o(.literal* .text*) - *modpyb.o(.literal*, .text*) - *machine_pin.o(.literal*, .text*) - *machine_pwm.o(.literal*, .text*) - *machine_rtc.o(.literal*, .text*) - *machine_adc.o(.literal*, .text*) - *machine_uart.o(.literal*, .text*) - *modpybi2c.o(.literal*, .text*) - *modmachine.o(.literal*, .text*) - *machine_wdt.o(.literal*, .text*) - *machine_spi.o(.literal*, .text*) - *machine_hspi.o(.literal*, .text*) - *hspi.o(.literal*, .text*) - *modesp.o(.literal* .text*) - *modnetwork.o(.literal* .text*) - *moduos.o(.literal* .text*) - *modutime.o(.literal* .text*) - *modlwip.o(.literal* .text*) - *modsocket.o(.literal* .text*) - *modonewire.o(.literal* .text*) - - /* we put as much rodata as possible in this section */ - /* note that only rodata accessed as a machine word is allowed here */ - *py/qstr.o(.rodata.const_pool) - *.o(.rodata.mp_type_*) /* catches type: mp_obj_type_t */ - *.o(.rodata.*_locals_dict*) /* catches types: mp_obj_dict_t, mp_map_elem_t */ - *.o(.rodata.mp_module_*) /* catches types: mp_obj_module_t, mp_obj_dict_t, mp_map_elem_t */ - */frozen.o(.rodata.mp_frozen_sizes) /* frozen modules */ - */frozen.o(.rodata.mp_frozen_content) /* frozen modules */ - - /* for -mforce-l32 */ - build/*.o(.rodata*) - - _irom0_text_end = ABSOLUTE(.); - } >irom0_0_seg :irom0_0_phdr - - .text : ALIGN(4) - { - _stext = .; - _text_start = ABSOLUTE(.); - *(.UserEnter.text) - . = ALIGN(16); - *(.DebugExceptionVector.text) - . = ALIGN(16); - *(.NMIExceptionVector.text) - . = ALIGN(16); - *(.KernelExceptionVector.text) - LONG(0) - LONG(0) - LONG(0) - LONG(0) - . = ALIGN(16); - *(.UserExceptionVector.text) - LONG(0) - LONG(0) - LONG(0) - LONG(0) - . = ALIGN(16); - *(.DoubleExceptionVector.text) - LONG(0) - LONG(0) - LONG(0) - LONG(0) - . = ALIGN (16); - *(.entry.text) - *(.init.literal) - *(.init) - *(.literal .text .literal.* .text.* .iram0.literal .iram0.text .iram0.text.*.literal .iram0.text.*) - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.fini.literal) - *(.fini) - *(.gnu.version) - _text_end = ABSOLUTE(.); - _etext = .; - } >iram1_0_seg :iram1_0_phdr - - .lit4 : ALIGN(4) - { - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - } >iram1_0_seg :iram1_0_phdr - - .data : ALIGN(4) - { - _data_start = ABSOLUTE(.); - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.sdata2) - *(.sdata2.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - _data_end = ABSOLUTE(.); - } >dram0_0_seg :dram0_0_phdr - - .rodata : ALIGN(4) - { - _rodata_start = ABSOLUTE(.); - *(.sdk.version) - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - *(.rodata1) - __XT_EXCEPTION_TABLE__ = ABSOLUTE(.); - *(.xt_except_table) - *(.gcc_except_table) - *(.gnu.linkonce.e.*) - *(.gnu.version_r) - *(.eh_frame) - /* C++ constructor and destructor tables, properly ordered: */ - KEEP (*crtbegin.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - KEEP (*crtbegin.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - /* C++ exception handlers table: */ - __XT_EXCEPTION_DESCS__ = ABSOLUTE(.); - *(.xt_except_desc) - *(.gnu.linkonce.h.*) - __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); - *(.xt_except_desc_end) - *(.dynamic) - *(.gnu.version_d) - . = ALIGN(4); /* this table MUST be 4-byte aligned */ - _bss_table_start = ABSOLUTE(.); - LONG(_bss_start) - LONG(_bss_end) - _bss_table_end = ABSOLUTE(.); - _rodata_end = ABSOLUTE(.); - } >dram0_0_seg :dram0_0_phdr - - .bss ALIGN(8) (NOLOAD) : ALIGN(4) - { - . = ALIGN (8); - _bss_start = ABSOLUTE(.); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _bss_end = ABSOLUTE(.); - _heap_start = ABSOLUTE(.); - } >dram0_0_seg :dram0_0_bss_phdr -} - -/* get ROM code address */ -INCLUDE "eagle.rom.addr.v6.ld" +/* define common sections and symbols */ +INCLUDE esp8266_common.ld diff --git a/esp8266/esp_mphal.c b/esp8266/esp_mphal.c index 5db4f1968..88e11844a 100644 --- a/esp8266/esp_mphal.c +++ b/esp8266/esp_mphal.c @@ -33,6 +33,7 @@ #include "ets_alt_task.h" #include "py/obj.h" #include "py/mpstate.h" +#include "py/runtime.h" #include "extmod/misc.h" #include "lib/utils/pyexec.h" @@ -130,11 +131,7 @@ void mp_hal_delay_ms(uint32_t delay) { void ets_event_poll(void) { ets_loop_iter(); - if (MP_STATE_VM(mp_pending_exception) != NULL) { - mp_obj_t obj = MP_STATE_VM(mp_pending_exception); - MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL; - nlr_raise(obj); - } + mp_handle_pending(); } void __assert_func(const char *file, int line, const char *func, const char *expr) { diff --git a/esp8266/espuart.c b/esp8266/espuart.c index ee893f4ec..dc4d1e611 100644 --- a/esp8266/espuart.c +++ b/esp8266/espuart.c @@ -200,6 +200,21 @@ bool uart_rx_wait(uint32_t timeout_us) { } } +int uart_rx_any(uint8 uart) { + if (input_buf.iget != input_buf.iput) { + return true; // have at least 1 char ready for reading + } + return false; +} + +int uart_tx_any_room(uint8 uart) { + uint32_t fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S); + if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) >= 126) { + return false; + } + return true; +} + // Returns char from the input buffer, else -1 if buffer is empty. int uart_rx_char(void) { return ringbuf_get(&input_buf); diff --git a/esp8266/espuart.h b/esp8266/espuart.h index 2b97683ff..f6850c42d 100644 --- a/esp8266/espuart.h +++ b/esp8266/espuart.h @@ -99,5 +99,8 @@ void uart_tx_one_char(uint8 uart, uint8 TxChar); void uart_flush(uint8 uart); void uart_os_config(int uart); void uart_setup(uint8 uart); +// check status of rx/tx +int uart_rx_any(uint8 uart); +int uart_tx_any_room(uint8 uart); #endif // _INCLUDED_UART_H_ diff --git a/esp8266/ets_alt_task.c b/esp8266/ets_alt_task.c index 6434f2366..ff7dba186 100644 --- a/esp8266/ets_alt_task.c +++ b/esp8266/ets_alt_task.c @@ -120,11 +120,13 @@ bool ets_loop_iter(void) { } // handle overflow of system microsecond counter + ets_intr_lock(); uint32_t system_time_cur = system_get_time(); if (system_time_cur < system_time_prev) { system_time_high_word += 1; // record overflow of low 32-bits } system_time_prev = system_time_cur; + ets_intr_unlock(); //static unsigned cnt; bool progress = false; diff --git a/esp8266/fatfs_port.c b/esp8266/fatfs_port.c index 9c84f04e4..02384f605 100644 --- a/esp8266/fatfs_port.c +++ b/esp8266/fatfs_port.c @@ -25,8 +25,8 @@ */ #include "py/obj.h" -#include "lib/fatfs/ff.h" -#include "timeutils.h" +#include "lib/timeutils/timeutils.h" +#include "lib/oofatfs/ff.h" #include "modmachine.h" DWORD get_fattime(void) { diff --git a/esp8266/help.c b/esp8266/help.c index 5370ee71e..2035cdd6c 100644 --- a/esp8266/help.c +++ b/esp8266/help.c @@ -24,11 +24,9 @@ * THE SOFTWARE. */ -#include <stdio.h> +#include "py/builtin.h" -#include "lib/utils/pyhelp.h" - -STATIC const char *help_text = +const char *esp_help_text = "Welcome to MicroPython!\n" "\n" "For online docs please visit http://docs.micropython.org/en/latest/esp8266/ .\n" @@ -54,17 +52,3 @@ STATIC const char *help_text = "\n" "For further help on a specific object, type help(obj)\n" ; - -STATIC mp_obj_t builtin_help(uint n_args, const mp_obj_t *args) { - if (n_args == 0) { - // print a general help message - printf("%s", help_text); - - } else { - // try to print something sensible about the given object - pyhelp_print_obj(args[0]); - } - - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_help_obj, 0, 1, builtin_help); diff --git a/esp8266/lexerstr32.c b/esp8266/lexerstr32.c index 3fc62399e..6fb84bb74 100644 --- a/esp8266/lexerstr32.c +++ b/esp8266/lexerstr32.c @@ -58,10 +58,7 @@ STATIC void str32_buf_free(void *sb_in) { } mp_lexer_t *mp_lexer_new_from_str32(qstr src_name, const char *str, mp_uint_t len, mp_uint_t free_len) { - mp_lexer_str32_buf_t *sb = m_new_obj_maybe(mp_lexer_str32_buf_t); - if (sb == NULL) { - return NULL; - } + mp_lexer_str32_buf_t *sb = m_new_obj(mp_lexer_str32_buf_t); sb->byte_off = (uint32_t)str & 3; sb->src_cur = (uint32_t*)(str - sb->byte_off); sb->val = *sb->src_cur++ >> sb->byte_off * 8; diff --git a/esp8266/machine_pin.c b/esp8266/machine_pin.c index e10b2cfb7..385551578 100644 --- a/esp8266/machine_pin.c +++ b/esp8266/machine_pin.c @@ -37,6 +37,7 @@ #include "py/runtime.h" #include "py/gc.h" #include "py/mphal.h" +#include "extmod/virtpin.h" #include "modmachine.h" #define GET_TRIGGER(phys_port) \ @@ -86,11 +87,15 @@ STATIC uint8_t pin_mode[16 + 1]; // forward declaration STATIC const pin_irq_obj_t pin_irq_obj[16]; +// whether the irq is hard or soft +STATIC bool pin_irq_is_hard[16]; + void pin_init0(void) { ETS_GPIO_INTR_DISABLE(); ETS_GPIO_INTR_ATTACH(pin_intr_handler_iram, NULL); // disable all interrupts memset(&MP_STATE_PORT(pin_irq_handler)[0], 0, 16 * sizeof(mp_obj_t)); + memset(pin_irq_is_hard, 0, sizeof(pin_irq_is_hard)); for (int p = 0; p < 16; ++p) { GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << p); SET_TRIGGER(p, 0); @@ -99,17 +104,23 @@ void pin_init0(void) { } void pin_intr_handler(uint32_t status) { + mp_sched_lock(); gc_lock(); status &= 0xffff; for (int p = 0; status; ++p, status >>= 1) { if (status & 1) { mp_obj_t handler = MP_STATE_PORT(pin_irq_handler)[p]; if (handler != MP_OBJ_NULL) { - mp_call_function_1_protected(handler, MP_OBJ_FROM_PTR(&pyb_pin_obj[p])); + if (pin_irq_is_hard[p]) { + mp_call_function_1_protected(handler, MP_OBJ_FROM_PTR(&pyb_pin_obj[p])); + } else { + mp_sched_schedule(handler, MP_OBJ_FROM_PTR(&pyb_pin_obj[p])); + } } } } gc_unlock(); + mp_sched_unlock(); } pyb_pin_obj_t *mp_obj_get_pin_obj(mp_obj_t pin_in) { @@ -276,7 +287,7 @@ STATIC mp_obj_t pyb_pin_obj_init_helper(pyb_pin_obj_t *self, mp_uint_t n_args, c } // constructor(id, ...) -STATIC mp_obj_t pyb_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { +mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); // get the wanted pin object @@ -325,28 +336,27 @@ STATIC mp_obj_t pyb_pin_value(mp_uint_t n_args, const mp_obj_t *args) { } STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_pin_value_obj, 1, 2, pyb_pin_value); -// pin.low() -STATIC mp_obj_t pyb_pin_low(mp_obj_t self_in) { +STATIC mp_obj_t pyb_pin_off(mp_obj_t self_in) { pyb_pin_obj_t *self = self_in; pin_set(self->phys_port, 0); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_pin_low_obj, pyb_pin_low); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_pin_off_obj, pyb_pin_off); -// pin.high() -STATIC mp_obj_t pyb_pin_high(mp_obj_t self_in) { +STATIC mp_obj_t pyb_pin_on(mp_obj_t self_in) { pyb_pin_obj_t *self = self_in; pin_set(self->phys_port, 1); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_pin_high_obj, pyb_pin_high); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_pin_on_obj, pyb_pin_on); -// pin.irq(*, trigger, handler=None) +// pin.irq(handler=None, trigger=IRQ_FALLING|IRQ_RISING, hard=False) STATIC mp_obj_t pyb_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_trigger, ARG_handler }; + enum { ARG_handler, ARG_trigger, ARG_hard }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_trigger, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_handler, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_handler, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_trigger, MP_ARG_INT, {.u_int = GPIO_PIN_INTR_POSEDGE | GPIO_PIN_INTR_NEGEDGE} }, + { MP_QSTR_hard, MP_ARG_BOOL, {.u_bool = false} }, }; pyb_pin_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -356,15 +366,18 @@ STATIC mp_obj_t pyb_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "pin does not have IRQ capabilities")); } - if (args[ARG_trigger].u_int != 0) { + if (n_args > 1 || kw_args->used != 0) { // configure irq mp_obj_t handler = args[ARG_handler].u_obj; + uint32_t trigger = args[ARG_trigger].u_int; if (handler == mp_const_none) { handler = MP_OBJ_NULL; + trigger = 0; } ETS_GPIO_INTR_DISABLE(); MP_STATE_PORT(pin_irq_handler)[self->phys_port] = handler; - SET_TRIGGER(self->phys_port, args[ARG_trigger].u_int); + pin_irq_is_hard[self->phys_port] = args[ARG_hard].u_bool; + SET_TRIGGER(self->phys_port, trigger); GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << self->phys_port); ETS_GPIO_INTR_ENABLE(); } @@ -374,12 +387,29 @@ STATIC mp_obj_t pyb_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_pin_irq_obj, 1, pyb_pin_irq); +STATIC mp_uint_t pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode); +STATIC mp_uint_t pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { + (void)errcode; + pyb_pin_obj_t *self = self_in; + + switch (request) { + case MP_PIN_READ: { + return pin_get(self->phys_port); + } + case MP_PIN_WRITE: { + pin_set(self->phys_port, arg); + return 0; + } + } + return -1; +} + STATIC const mp_map_elem_t pyb_pin_locals_dict_table[] = { // instance methods { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_pin_init_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&pyb_pin_value_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_low), (mp_obj_t)&pyb_pin_low_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_high), (mp_obj_t)&pyb_pin_high_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_off), (mp_obj_t)&pyb_pin_off_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_on), (mp_obj_t)&pyb_pin_on_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_irq), (mp_obj_t)&pyb_pin_irq_obj }, // class constants @@ -396,12 +426,17 @@ STATIC const mp_map_elem_t pyb_pin_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(pyb_pin_locals_dict, pyb_pin_locals_dict_table); +STATIC const mp_pin_p_t pin_pin_p = { + .ioctl = pin_ioctl, +}; + const mp_obj_type_t pyb_pin_type = { { &mp_type_type }, .name = MP_QSTR_Pin, .print = pyb_pin_print, - .make_new = pyb_pin_make_new, + .make_new = mp_pin_make_new, .call = pyb_pin_call, + .protocol = &pin_pin_p, .locals_dict = (mp_obj_t)&pyb_pin_locals_dict, }; diff --git a/esp8266/machine_rtc.c b/esp8266/machine_rtc.c index 8c1fe0779..b17bcb261 100644 --- a/esp8266/machine_rtc.c +++ b/esp8266/machine_rtc.c @@ -30,7 +30,7 @@ #include "py/nlr.h" #include "py/obj.h" #include "py/runtime.h" -#include "timeutils.h" +#include "lib/timeutils/timeutils.h" #include "user_interface.h" #include "modmachine.h" @@ -93,7 +93,7 @@ void pyb_rtc_set_us_since_2000(uint64_t nowus) { int64_t delta = nowus - (((uint64_t)rtc_last_ticks * cal) >> 12); // As the calibration value jitters quite a bit, to make the - // clock at least somewhat practially usable, we need to store it + // clock at least somewhat practically usable, we need to store it system_rtc_mem_write(MEM_CAL_ADDR, &cal, sizeof(cal)); system_rtc_mem_write(MEM_DELTA_ADDR, &delta, sizeof(delta)); }; diff --git a/esp8266/machine_uart.c b/esp8266/machine_uart.c index 0ae9c6e6c..aa7e91b01 100644 --- a/esp8266/machine_uart.c +++ b/esp8266/machine_uart.c @@ -193,9 +193,16 @@ STATIC mp_obj_t pyb_uart_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_ } MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_init_obj, 1, pyb_uart_init); +STATIC mp_obj_t pyb_uart_any(mp_obj_t self_in) { + pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(uart_rx_any(self->uart_id)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_any_obj, pyb_uart_any); + STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_uart_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&pyb_uart_any_obj) }, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, @@ -255,8 +262,22 @@ STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t } STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { - *errcode = MP_EINVAL; - return MP_STREAM_ERROR; + pyb_uart_obj_t *self = self_in; + mp_uint_t ret; + if (request == MP_STREAM_POLL) { + mp_uint_t flags = arg; + ret = 0; + if ((flags & MP_STREAM_POLL_RD) && uart_rx_any(self->uart_id)) { + ret |= MP_STREAM_POLL_RD; + } + if ((flags & MP_STREAM_POLL_WR) && uart_tx_any_room(self->uart_id)) { + ret |= MP_STREAM_POLL_WR; + } + } else { + *errcode = MP_EINVAL; + ret = MP_STREAM_ERROR; + } + return ret; } STATIC const mp_stream_p_t uart_stream_p = { @@ -271,7 +292,7 @@ const mp_obj_type_t pyb_uart_type = { .name = MP_QSTR_UART, .print = pyb_uart_print, .make_new = pyb_uart_make_new, - .getiter = mp_identity, + .getiter = mp_identity_getiter, .iternext = mp_stream_unbuffered_iter, .protocol = &uart_stream_p, .locals_dict = (mp_obj_dict_t*)&pyb_uart_locals_dict, diff --git a/esp8266/main.c b/esp8266/main.c index 9ac728e38..15a7f05cc 100644 --- a/esp8266/main.c +++ b/esp8266/main.c @@ -32,9 +32,10 @@ #include "py/runtime0.h" #include "py/runtime.h" #include "py/stackctrl.h" +#include "py/mperrno.h" #include "py/mphal.h" #include "py/gc.h" -#include "lib/fatfs/ff.h" +#include "lib/oofatfs/ff.h" #include "lib/mp-readline/readline.h" #include "lib/utils/pyexec.h" #include "gccollect.h" @@ -45,13 +46,8 @@ STATIC char heap[36 * 1024]; bool maybe_run(const char* filename, pyexec_result_t* exec_result) { - FILINFO fno; -#if _USE_LFN - fno.lfname = NULL; - fno.lfsize = 0; -#endif - FRESULT res = f_stat(filename, &fno); - if (res != FR_OK || fno.fattrib & AM_DIR) { + mp_import_stat_t stat = mp_import_stat(filename); + if (stat != MP_IMPORT_STAT_FILE) { return false; } mp_hal_stdout_tx_str(filename); @@ -151,34 +147,23 @@ void user_init(void) { system_init_done_cb(init_done); } -mp_import_stat_t fat_vfs_import_stat(const char *path); - -#if !MICROPY_VFS_FAT +#if !MICROPY_VFS mp_lexer_t *mp_lexer_new_from_file(const char *filename) { - return NULL; + mp_raise_OSError(MP_ENOENT); } -#endif mp_import_stat_t mp_import_stat(const char *path) { - #if MICROPY_VFS_FAT - return fat_vfs_import_stat(path); - #else (void)path; return MP_IMPORT_STAT_NO_EXIST; - #endif } -mp_obj_t vfs_proxy_call(qstr method_name, mp_uint_t n_args, const mp_obj_t *args); mp_obj_t mp_builtin_open(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) { - #if MICROPY_VFS_FAT - // TODO: Handle kwargs! - return vfs_proxy_call(MP_QSTR_open, n_args, args); - #else return mp_const_none; - #endif } MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open); +#endif + void MP_FASTCODE(nlr_jump_fail)(void *val) { printf("NLR jump failed\n"); for (;;) { diff --git a/esp8266/modesp.c b/esp8266/modesp.c index 77f8d1332..efd484878 100644 --- a/esp8266/modesp.c +++ b/esp8266/modesp.c @@ -25,492 +25,19 @@ */ #include <stdio.h> -#include <string.h> -#include <stdbool.h> -#include "py/nlr.h" -#include "py/obj.h" #include "py/gc.h" #include "py/runtime.h" #include "py/mperrno.h" #include "py/mphal.h" #include "drivers/dht/dht.h" -#include "netutils.h" -#include "queue.h" -#include "ets_sys.h" #include "espuart.h" #include "user_interface.h" -#include "espconn.h" -#include "spi_flash.h" #include "mem.h" #include "espneopixel.h" #include "espapa102.h" #include "modmachine.h" -#define MODESP_ESPCONN (0) - -#if MODESP_ESPCONN -STATIC const mp_obj_type_t esp_socket_type; - -typedef struct _esp_socket_obj_t { - mp_obj_base_t base; - struct espconn *espconn; - - mp_obj_t cb_connect; - mp_obj_t cb_recv; - mp_obj_t cb_sent; - mp_obj_t cb_disconnect; - - uint8_t *recvbuf; - mp_uint_t recvbuf_len; - - bool fromserver; - - mp_obj_list_t *connlist; -} esp_socket_obj_t; - -// Due to the onconnect callback not being able to recognize the parent esp_socket, -// we can have only one esp_socket listening at a time -// This should be solvable by some PIC hacking -STATIC esp_socket_obj_t *esp_socket_listening; - -STATIC mp_obj_t esp_socket_make_new_base() { - esp_socket_obj_t *s = m_new_obj_with_finaliser(esp_socket_obj_t); - s->recvbuf = NULL; - s->base.type = (mp_obj_t)&esp_socket_type; - s->cb_connect = mp_const_none; - s->cb_recv = mp_const_none; - s->cb_disconnect = mp_const_none; - s->cb_sent = mp_const_none; - s->fromserver = false; - s->connlist = NULL; - return s; -} - -// constructor esp_socket(family=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP, fileno=None) -// Arguments ignored as we do not support UDP (yet) -STATIC mp_obj_t esp_socket_make_new(const mp_obj_type_t *type_in, mp_uint_t n_args, - mp_uint_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 4, false); - - esp_socket_obj_t *s = esp_socket_make_new_base(); - s->espconn = m_new_obj(struct espconn); - - s->espconn->reverse = s; - // TODO: UDP Support - s->espconn->type = ESPCONN_TCP; - s->espconn->state = ESPCONN_NONE; - - s->espconn->proto.tcp = m_new_obj(esp_tcp); - - return s; -} - -// method socket.close() -STATIC mp_obj_t esp_socket_close(mp_obj_t self_in) { - esp_socket_obj_t *s = self_in; - - if (esp_socket_listening == s) { - esp_socket_listening = NULL; - } - - if (s->espconn->state != ESPCONN_NONE && s->espconn->state != ESPCONN_CLOSE) { - espconn_disconnect(s->espconn); - } - - if (s->connlist != NULL) { - mp_obj_list_set_len(s->connlist, 0); - } - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_socket_close_obj, esp_socket_close); - -// method socket.__del__() -STATIC mp_obj_t esp_socket___del__(mp_obj_t self_in) { - esp_socket_obj_t *s = self_in; - - esp_socket_close(self_in); - - if (s->fromserver) { - espconn_delete(s->espconn); - } - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_socket___del___obj, esp_socket___del__); - -// method socket.bind(address) -STATIC mp_obj_t esp_socket_bind(mp_obj_t self_in, mp_obj_t addr_in) { - esp_socket_obj_t *s = self_in; - - mp_uint_t port = netutils_parse_inet_addr(addr_in, - s->espconn->proto.tcp->remote_ip, NETUTILS_BIG); - s->espconn->proto.tcp->local_port = port; - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_bind_obj, esp_socket_bind); - -STATIC void esp_socket_recv_callback(void *arg, char *pdata, unsigned short len) { - struct espconn *conn = arg; - esp_socket_obj_t *s = conn->reverse; - - if (s->cb_recv != mp_const_none) { - call_function_2_protected(s->cb_recv, s, mp_obj_new_bytes((byte *)pdata, len)); - } else { - if (s->recvbuf == NULL) { - s->recvbuf = m_new(uint8_t, len); - s->recvbuf_len = len; - if (s->recvbuf != NULL) { - memcpy(s->recvbuf, pdata, len); - } - } else { - s->recvbuf = m_renew(uint8_t, s->recvbuf, s->recvbuf_len, s->recvbuf_len + len); - if (s->recvbuf != NULL) { - memcpy(&s->recvbuf[s->recvbuf_len], pdata, len); - s->recvbuf_len += len; - } - } - if (s->recvbuf == NULL) { - esp_socket_close(s); - return; - } - } -} - -STATIC void esp_socket_sent_callback(void *arg) { - struct espconn *conn = arg; - esp_socket_obj_t *s = conn->reverse; - - if (s->cb_sent != mp_const_none) { - call_function_1_protected(s->cb_sent, s); - } -} - -STATIC void esp_socket_disconnect_callback(void *arg) { - struct espconn *conn = arg; - esp_socket_obj_t *s = conn->reverse; - - if (s->cb_disconnect != mp_const_none) { - call_function_1_protected(s->cb_disconnect, s); - } - - esp_socket_close(s); -} - -STATIC void esp_socket_connect_callback_server(void *arg) { - struct espconn *conn = arg; - - esp_socket_obj_t *s = esp_socket_make_new_base(); - s->espconn = conn; - s->fromserver = true; - conn->reverse = s; - - espconn_regist_recvcb(conn, esp_socket_recv_callback); - espconn_regist_sentcb(conn, esp_socket_sent_callback); - espconn_regist_disconcb(conn, esp_socket_disconnect_callback); - espconn_regist_time(conn, 15, 0); - - if (esp_socket_listening->cb_connect != mp_const_none) { - call_function_1_protected(esp_socket_listening->cb_connect, s); - } else { - mp_obj_list_append(esp_socket_listening->connlist, s); - } -} - -STATIC void esp_socket_connect_callback_client(void *arg) { - struct espconn *conn = arg; - esp_socket_obj_t *s = conn->reverse; - - if (s->cb_connect != mp_const_none) { - call_function_1_protected(s->cb_connect, s); - } -} - -// method socket.listen(backlog) -STATIC mp_obj_t esp_socket_listen(mp_obj_t self_in, mp_obj_t backlog) { - esp_socket_obj_t *s = self_in; - - if (esp_socket_listening != NULL) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, - "only one espconn can listen at a time")); - } - - esp_socket_listening = s; - - s->connlist = mp_obj_new_list(0, NULL); - - espconn_regist_connectcb(s->espconn, esp_socket_connect_callback_server); - espconn_accept(s->espconn); - espconn_regist_time(s->espconn, 1500, 0); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_listen_obj, esp_socket_listen); - -// method socket.accept() -STATIC mp_obj_t esp_socket_accept(mp_obj_t self_in) { - esp_socket_obj_t *s = self_in; - - if (s->connlist == NULL) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, - "not listening")); - } - - do { - mp_uint_t len; - mp_obj_t *items; - - mp_obj_list_get(s->connlist, &len, &items); - if (len == 0) { - break; - } - - esp_socket_obj_t *rs = items[0]; - mp_obj_list_remove(s->connlist, rs); - if (rs->espconn->state != ESPCONN_CLOSE) { - return rs; - } - } while (true); - - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, - "no connection in queue")); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_socket_accept_obj, esp_socket_accept); - -// method socket.connect(address) -STATIC mp_obj_t esp_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { - esp_socket_obj_t *s = self_in; - - if (s->espconn == NULL || s->espconn->state != ESPCONN_NONE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, - "transport endpoint is already connected or closed")); - } - - espconn_regist_connectcb(s->espconn, esp_socket_connect_callback_client); - espconn_regist_recvcb(s->espconn, esp_socket_recv_callback); - espconn_regist_sentcb(s->espconn, esp_socket_sent_callback); - espconn_regist_disconcb(s->espconn, esp_socket_disconnect_callback); - - s->espconn->proto.tcp->remote_port = - netutils_parse_inet_addr(addr_in, s->espconn->proto.tcp->remote_ip, - NETUTILS_BIG); - espconn_connect(s->espconn); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_connect_obj, esp_socket_connect); - -// method socket.send(bytes) -STATIC mp_obj_t esp_socket_send(mp_obj_t self_in, mp_obj_t buf_in) { - esp_socket_obj_t *s = self_in; - - if (s->espconn->state == ESPCONN_NONE || s->espconn->state == ESPCONN_CLOSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, - "not connected")); - } - - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); - - espconn_sent(s->espconn, bufinfo.buf, bufinfo.len); - - return mp_obj_new_int(bufinfo.len); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_send_obj, esp_socket_send); - -// method socket.recv(bufsize) -STATIC mp_obj_t esp_socket_recv(mp_obj_t self_in, mp_obj_t len_in) { - esp_socket_obj_t *s = self_in; - - if (s->recvbuf == NULL) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, - "no data available")); - } - - mp_uint_t mxl = mp_obj_get_int(len_in); - if (mxl >= s->recvbuf_len) { - mp_obj_t trt = mp_obj_new_bytes(s->recvbuf, s->recvbuf_len); - m_del(uint8_t, s->recvbuf, s->recvbuf_len); - s->recvbuf = NULL; - return trt; - } else { - mp_obj_t trt = mp_obj_new_bytes(s->recvbuf, mxl); - memmove(s->recvbuf, &s->recvbuf[mxl], s->recvbuf_len - mxl); - s->recvbuf = m_renew(uint8_t, s->recvbuf, s->recvbuf_len, s->recvbuf_len - mxl); - s->recvbuf_len -= mxl; - return trt; - } -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_recv_obj, esp_socket_recv); - -// method socket.sendto(bytes, address) -STATIC mp_obj_t esp_socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "UDP not supported")); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(esp_socket_sendto_obj, esp_socket_sendto); - -// method socket.recvfrom(bufsize) -STATIC mp_obj_t esp_socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "UDP not supported")); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_recvfrom_obj, esp_socket_recvfrom); - -// method socket.getpeername() -STATIC mp_obj_t esp_socket_getpeername(mp_obj_t self_in) { - esp_socket_obj_t *s = self_in; - - if (s->espconn->state == ESPCONN_NONE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, - "not connected")); - } - - mp_obj_t tuple[2] = { - netutils_format_ipv4_addr(s->espconn->proto.tcp->remote_ip, NETUTILS_BIG), - mp_obj_new_int(s->espconn->proto.tcp->remote_port), - }; - - return mp_obj_new_tuple(2, tuple); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_socket_getpeername_obj, esp_socket_getpeername); - -STATIC mp_obj_t esp_socket_onconnect(mp_obj_t self_in, mp_obj_t lambda_in) { - esp_socket_obj_t *s = self_in; - s->cb_connect = lambda_in; - - if (s->connlist != NULL) { - do { - mp_uint_t len; - mp_obj_t *items; - - mp_obj_list_get(s->connlist, &len, &items); - if (len == 0) { - break; - } - - esp_socket_obj_t *rs = items[0]; - mp_obj_list_remove(s->connlist, rs); - if (s->espconn->state != ESPCONN_CLOSE) { - call_function_1_protected(s->cb_connect, rs); - } - } while (true); - } - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_onconnect_obj, esp_socket_onconnect); - -STATIC mp_obj_t esp_socket_onrecv(mp_obj_t self_in, mp_obj_t lambda_in) { - esp_socket_obj_t *s = self_in; - s->cb_recv = lambda_in; - if (s->recvbuf != NULL) { - call_function_2_protected(s->cb_recv, s, - mp_obj_new_bytes((byte *)s->recvbuf, s->recvbuf_len)); - s->recvbuf = NULL; - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_onrecv_obj, esp_socket_onrecv); - -STATIC mp_obj_t esp_socket_onsent(mp_obj_t self_in, mp_obj_t lambda_in) { - esp_socket_obj_t *s = self_in; - s->cb_sent = lambda_in; - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_onsent_obj, esp_socket_onsent); - -STATIC mp_obj_t esp_socket_ondisconnect(mp_obj_t self_in, mp_obj_t lambda_in) { - esp_socket_obj_t *s = self_in; - s->cb_disconnect = lambda_in; - - if (s->espconn->state == ESPCONN_CLOSE) { - call_function_1_protected(s->cb_disconnect, s); - } - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_socket_ondisconnect_obj, esp_socket_ondisconnect); - -typedef struct _esp_getaddrinfo_cb_struct_t { - mp_obj_t lambda; - mp_uint_t port; -} esp_getaddrinfo_cb_struct_t; - -STATIC esp_getaddrinfo_cb_struct_t esp_getaddrinfo_cb_struct; - -STATIC void esp_getaddrinfo_cb(const char *name, ip_addr_t *ipaddr, void *arg) { - mp_obj_t namestr = mp_obj_new_str(name, strlen(name), true); - if (ipaddr != NULL) { - uint8_t ip[4]; - ip[0] = (ipaddr->addr >> 24) & 0xff; - ip[1] = (ipaddr->addr >> 16) & 0xff; - ip[2] = (ipaddr->addr >> 8) & 0xff; - ip[3] = (ipaddr->addr >> 0) & 0xff; - - mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL); - - tuple->items[0] = MP_OBJ_NEW_SMALL_INT(0); - tuple->items[1] = MP_OBJ_NEW_SMALL_INT(0); - tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0); - tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_); - tuple->items[4] = netutils_format_inet_addr(ip, - esp_getaddrinfo_cb_struct.port, NETUTILS_LITTLE); - call_function_2_protected(esp_getaddrinfo_cb_struct.lambda, namestr, tuple); - } else { - call_function_2_protected(esp_getaddrinfo_cb_struct.lambda, namestr, mp_const_none); - } -} - -STATIC mp_obj_t esp_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in, - mp_obj_t lambda_in) { - mp_uint_t hlen; - const char *host = mp_obj_str_get_data(host_in, &hlen); - ip_addr_t ipaddr; - - esp_getaddrinfo_cb_struct.lambda = lambda_in; - esp_getaddrinfo_cb_struct.port = mp_obj_get_int(port_in); - - err_t ret = espconn_gethostbyname(NULL, host, &ipaddr, - esp_getaddrinfo_cb); - - if (ret == ESPCONN_OK) { - esp_getaddrinfo_cb(host, &ipaddr, NULL); - } - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(esp_getaddrinfo_obj, esp_getaddrinfo); - -STATIC const mp_map_elem_t esp_socket_locals_dict_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&esp_socket___del___obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&esp_socket_close_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_bind), (mp_obj_t)&esp_socket_bind_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_listen), (mp_obj_t)&esp_socket_listen_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_accept), (mp_obj_t)&esp_socket_accept_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_connect), (mp_obj_t)&esp_socket_connect_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&esp_socket_send_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&esp_socket_recv_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_sendto), (mp_obj_t)&esp_socket_sendto_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_recvfrom), (mp_obj_t)&esp_socket_recvfrom_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_getpeername), (mp_obj_t)&esp_socket_getpeername_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_onconnect), (mp_obj_t)&esp_socket_onconnect_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_onrecv), (mp_obj_t)&esp_socket_onrecv_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_onsent), (mp_obj_t)&esp_socket_onsent_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ondisconnect), (mp_obj_t)&esp_socket_ondisconnect_obj }, -}; -STATIC MP_DEFINE_CONST_DICT(esp_socket_locals_dict, esp_socket_locals_dict_table); - -STATIC const mp_obj_type_t esp_socket_type = { - { &mp_type_type }, - .name = MP_QSTR_socket, - .make_new = esp_socket_make_new, - .locals_dict = (mp_obj_t)&esp_socket_locals_dict, -}; -#endif - #define MODESP_INCLUDE_CONSTANTS (1) void error_check(bool status, const char *msg) { @@ -632,12 +159,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_flash_size_obj, esp_flash_size); // we assume there's a yaota8266 bootloader. #define IS_OTA_FIRMWARE() ((*(uint32_t*)0x40200000 & 0xff00) == 0x100) +extern byte _firmware_size[]; + STATIC mp_obj_t esp_flash_user_start(void) { - if (IS_OTA_FIRMWARE()) { - return MP_OBJ_NEW_SMALL_INT(0x3c000 + 0x90000); - } else { - return MP_OBJ_NEW_SMALL_INT(0x90000); - } + return MP_OBJ_NEW_SMALL_INT((uint32_t)_firmware_size); } STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_flash_user_start_obj, esp_flash_user_start); @@ -837,10 +362,6 @@ STATIC const mp_map_elem_t esp_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_flash_erase), (mp_obj_t)&esp_flash_erase_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_flash_size), (mp_obj_t)&esp_flash_size_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_flash_user_start), (mp_obj_t)&esp_flash_user_start_obj }, - #if MODESP_ESPCONN - { MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&esp_socket_type }, - { MP_OBJ_NEW_QSTR(MP_QSTR_getaddrinfo), (mp_obj_t)&esp_getaddrinfo_obj }, - #endif #if MICROPY_ESP8266_NEOPIXEL { MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write), (mp_obj_t)&esp_neopixel_write_obj }, #endif diff --git a/esp8266/modmachine.c b/esp8266/modmachine.c index a5073d96c..c26c63396 100644 --- a/esp8266/modmachine.c +++ b/esp8266/modmachine.c @@ -31,6 +31,7 @@ #include "py/obj.h" #include "py/runtime.h" #include "extmod/machine_mem.h" +#include "extmod/machine_signal.h" #include "extmod/machine_pulse.h" #include "extmod/machine_i2c.h" #include "modmachine.h" @@ -156,7 +157,7 @@ STATIC mp_obj_t esp_timer_make_new(const mp_obj_type_t *type, size_t n_args, siz STATIC void esp_timer_cb(void *arg) { esp_timer_obj_t *self = arg; - mp_call_function_1_protected(self->callback, self); + mp_sched_schedule(self->callback, self); } STATIC mp_obj_t esp_timer_init_helper(esp_timer_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { @@ -251,6 +252,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&esp_timer_type) }, { MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&esp_wdt_type) }, { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&pyb_pin_type) }, + { MP_ROM_QSTR(MP_QSTR_Signal), MP_ROM_PTR(&machine_signal_type) }, { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&pyb_pwm_type) }, { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pyb_adc_type) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&pyb_uart_type) }, diff --git a/esp8266/modnetwork.c b/esp8266/modnetwork.c index 1d8a02bc9..eb9d75e28 100644 --- a/esp8266/modnetwork.c +++ b/esp8266/modnetwork.c @@ -32,7 +32,7 @@ #include "py/objlist.h" #include "py/runtime.h" #include "py/mphal.h" -#include "netutils.h" +#include "lib/netutils/netutils.h" #include "queue.h" #include "user_interface.h" #include "espconn.h" @@ -97,18 +97,18 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_active_obj, 1, 2, esp_active); STATIC mp_obj_t esp_connect(mp_uint_t n_args, const mp_obj_t *args) { require_if(args[0], STATION_IF); struct station_config config = {{0}}; - mp_uint_t len; + size_t len; const char *p; if (n_args > 1) { p = mp_obj_str_get_data(args[1], &len); + len = MIN(len, sizeof(config.ssid)); memcpy(config.ssid, p, len); if (n_args > 2) { p = mp_obj_str_get_data(args[2], &len); - } else { - p = ""; + len = MIN(len, sizeof(config.password)); + memcpy(config.password, p, len); } - memcpy(config.password, p, len); error_check(wifi_station_set_config(&config), "Cannot set STA config"); } @@ -311,7 +311,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs } case QS(MP_QSTR_essid): { req_if = SOFTAP_IF; - mp_uint_t len; + size_t len; const char *s = mp_obj_str_get_data(kwargs->table[i].value, &len); len = MIN(len, sizeof(cfg.ap.ssid)); memcpy(cfg.ap.ssid, s, len); @@ -330,7 +330,7 @@ STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs } case QS(MP_QSTR_password): { req_if = SOFTAP_IF; - mp_uint_t len; + size_t len; const char *s = mp_obj_str_get_data(kwargs->table[i].value, &len); len = MIN(len, sizeof(cfg.ap.password) - 1); memcpy(cfg.ap.password, s, len); diff --git a/esp8266/modules/_boot.py b/esp8266/modules/_boot.py index c200b3d3f..81eb20dd6 100644 --- a/esp8266/modules/_boot.py +++ b/esp8266/modules/_boot.py @@ -5,9 +5,9 @@ from flashbdev import bdev try: if bdev: - vfs = uos.VfsFat(bdev, "") + uos.mount(bdev, '/') except OSError: import inisetup - vfs = inisetup.setup() + inisetup.setup() gc.collect() diff --git a/esp8266/scripts/apa102.py b/esp8266/modules/apa102.py index 41b7c0485..41b7c0485 100644 --- a/esp8266/scripts/apa102.py +++ b/esp8266/modules/apa102.py diff --git a/esp8266/scripts/dht.py b/esp8266/modules/dht.py index 9a69e7e07..9a69e7e07 100644 --- a/esp8266/scripts/dht.py +++ b/esp8266/modules/dht.py diff --git a/esp8266/modules/flashbdev.py b/esp8266/modules/flashbdev.py index 8f8df0b64..40ba655c6 100644 --- a/esp8266/modules/flashbdev.py +++ b/esp8266/modules/flashbdev.py @@ -3,7 +3,7 @@ import esp class FlashBdev: SEC_SIZE = 4096 - RESERVED_SECS = 0 + RESERVED_SECS = 1 START_SEC = esp.flash_user_start() // SEC_SIZE + RESERVED_SECS NUM_BLK = 0x6b - RESERVED_SECS diff --git a/esp8266/scripts/inisetup.py b/esp8266/modules/inisetup.py index 3930089db..af78dfad5 100644 --- a/esp8266/scripts/inisetup.py +++ b/esp8266/modules/inisetup.py @@ -37,8 +37,9 @@ def setup(): print("Performing initial setup") wifi() uos.VfsFat.mkfs(bdev) - vfs = uos.VfsFat(bdev, "") - with open("/boot.py", "w") as f: + vfs = uos.VfsFat(bdev) + uos.mount(vfs, '/') + with open("boot.py", "w") as f: f.write("""\ # This file is executed on every boot (including wake-boot from deepsleep) #import esp diff --git a/esp8266/scripts/neopixel.py b/esp8266/modules/neopixel.py index b13424d7d..b13424d7d 100644 --- a/esp8266/scripts/neopixel.py +++ b/esp8266/modules/neopixel.py diff --git a/esp8266/scripts/ntptime.py b/esp8266/modules/ntptime.py index a97e08e60..a97e08e60 100644 --- a/esp8266/scripts/ntptime.py +++ b/esp8266/modules/ntptime.py diff --git a/esp8266/scripts/port_diag.py b/esp8266/modules/port_diag.py index ef8800355..ef8800355 100644 --- a/esp8266/scripts/port_diag.py +++ b/esp8266/modules/port_diag.py diff --git a/esp8266/moduos.c b/esp8266/moduos.c index e9c4c3e8c..807d2e18a 100644 --- a/esp8266/moduos.c +++ b/esp8266/moduos.c @@ -26,20 +26,15 @@ #include <string.h> -#include "py/mpconfig.h" -#include "py/nlr.h" -#include "py/obj.h" #include "py/objtuple.h" #include "py/objstr.h" -#include "py/runtime.h" -#include "py/mperrno.h" #include "extmod/misc.h" +#include "extmod/vfs.h" +#include "extmod/vfs_fat.h" #include "genhdr/mpversion.h" #include "esp_mphal.h" #include "user_interface.h" -extern const mp_obj_type_t mp_fat_vfs_type; - STATIC const qstr os_uname_info_fields[] = { MP_QSTR_sysname, MP_QSTR_nodename, MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine @@ -63,82 +58,13 @@ STATIC mp_obj_tuple_t os_uname_info_obj = { }; STATIC mp_obj_t os_uname(void) { - if (os_uname_info_obj.items[2] == NULL) { - const char *ver = system_get_sdk_version(); - os_uname_info_obj.items[2] = mp_obj_new_str(ver, strlen(ver), false); - } + // We must populate the "release" field each time in case it was GC'd since the last call. + const char *ver = system_get_sdk_version(); + os_uname_info_obj.items[2] = mp_obj_new_str(ver, strlen(ver), false); return (mp_obj_t)&os_uname_info_obj; } STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_uname_obj, os_uname); -#if MICROPY_VFS_FAT -mp_obj_t vfs_proxy_call(qstr method_name, mp_uint_t n_args, const mp_obj_t *args) { - if (MP_STATE_PORT(fs_user_mount)[0] == NULL) { - mp_raise_OSError(MP_ENODEV); - } - - mp_obj_t meth[n_args + 2]; - mp_load_method(MP_STATE_PORT(fs_user_mount)[0], method_name, meth); - if (args != NULL) { - memcpy(meth + 2, args, n_args * sizeof(*args)); - } - return mp_call_method_n_kw(n_args, 0, meth); -} - -STATIC mp_obj_t os_listdir(mp_uint_t n_args, const mp_obj_t *args) { - return vfs_proxy_call(MP_QSTR_listdir, n_args, args); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir); - -STATIC mp_obj_t os_mkdir(mp_obj_t path_in) { - return vfs_proxy_call(MP_QSTR_mkdir, 1, &path_in); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir); - -STATIC mp_obj_t os_rmdir(mp_obj_t path_in) { - return vfs_proxy_call(MP_QSTR_rmdir, 1, &path_in); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_rmdir_obj, os_rmdir); - -STATIC mp_obj_t os_chdir(mp_obj_t path_in) { - return vfs_proxy_call(MP_QSTR_chdir, 1, &path_in); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_chdir_obj, os_chdir); - -STATIC mp_obj_t os_getcwd(void) { - return vfs_proxy_call(MP_QSTR_getcwd, 0, NULL); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_getcwd_obj, os_getcwd); - -STATIC mp_obj_t os_remove(mp_obj_t path_in) { - return vfs_proxy_call(MP_QSTR_remove, 1, &path_in); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove); - -STATIC mp_obj_t os_rename(mp_obj_t path_old, mp_obj_t path_new) { - mp_obj_t args[2]; - args[0] = path_old; - args[1] = path_new; - return vfs_proxy_call(MP_QSTR_rename, 2, args); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(os_rename_obj, os_rename); - -STATIC mp_obj_t os_stat(mp_obj_t path_in) { - return vfs_proxy_call(MP_QSTR_stat, 1, &path_in); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat); - -STATIC mp_obj_t os_statvfs(mp_obj_t path_in) { - return vfs_proxy_call(MP_QSTR_statvfs, 1, &path_in); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_statvfs_obj, os_statvfs); - -STATIC mp_obj_t os_umount(void) { - return vfs_proxy_call(MP_QSTR_umount, 0, NULL); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(os_umount_obj, os_umount); -#endif - STATIC mp_obj_t os_urandom(mp_obj_t num) { mp_int_t n = mp_obj_get_int(num); vstr_t vstr; @@ -167,16 +93,18 @@ STATIC const mp_rom_map_elem_t os_module_globals_table[] = { #endif #if MICROPY_VFS_FAT { MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) }, - { MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&os_listdir_obj) }, - { MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&os_mkdir_obj) }, - { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&os_rmdir_obj) }, - { MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&os_chdir_obj) }, - { MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&os_getcwd_obj) }, - { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&os_remove_obj) }, - { MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&os_rename_obj) }, - { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&os_stat_obj) }, - { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&os_statvfs_obj) }, - { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&os_umount_obj) }, + { MP_ROM_QSTR(MP_QSTR_ilistdir), MP_ROM_PTR(&mp_vfs_ilistdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mp_vfs_listdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mp_vfs_mkdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&mp_vfs_rmdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&mp_vfs_chdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&mp_vfs_getcwd_obj) }, + { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&mp_vfs_remove_obj) }, + { MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&mp_vfs_rename_obj) }, + { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mp_vfs_stat_obj) }, + { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mp_vfs_statvfs_obj) }, + { MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mp_vfs_mount_obj) }, + { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&mp_vfs_umount_obj) }, #endif }; diff --git a/esp8266/modutime.c b/esp8266/modutime.c index 2adb6c563..bdeb3bb45 100644 --- a/esp8266/modutime.c +++ b/esp8266/modutime.c @@ -34,8 +34,8 @@ #include "py/runtime.h" #include "py/mphal.h" #include "py/smallint.h" +#include "lib/timeutils/timeutils.h" #include "modmachine.h" -#include "timeutils.h" #include "user_interface.h" #include "extmod/utime_mphal.h" @@ -84,7 +84,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(time_localtime_obj, 0, 1, time_localtime); /// which expresses a time as per localtime. It returns an integer which is /// the number of seconds since Jan 1, 2000. STATIC mp_obj_t time_mktime(mp_obj_t tuple) { - mp_uint_t len; + size_t len; mp_obj_t *elem; mp_obj_get_array(tuple, &len, &elem); diff --git a/esp8266/mpconfigport.h b/esp8266/mpconfigport.h index c4a375200..fec1eb0f0 100644 --- a/esp8266/mpconfigport.h +++ b/esp8266/mpconfigport.h @@ -15,7 +15,7 @@ #define MICROPY_MEM_STATS (0) #define MICROPY_DEBUG_PRINTERS (1) #define MICROPY_DEBUG_PRINTER_DEST mp_debug_print -#define MICROPY_READER_FATFS (MICROPY_VFS_FAT) +#define MICROPY_READER_VFS (MICROPY_VFS) #define MICROPY_ENABLE_GC (1) #define MICROPY_STACK_CHECK (1) #define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1) @@ -28,6 +28,7 @@ #define MICROPY_MODULE_WEAK_LINKS (1) #define MICROPY_CAN_OVERRIDE_BUILTINS (1) #define MICROPY_USE_INTERNAL_ERRNO (1) +#define MICROPY_ENABLE_SCHEDULER (1) #define MICROPY_PY_ALL_SPECIAL_METHODS (1) #define MICROPY_PY_BUILTINS_COMPLEX (0) #define MICROPY_PY_BUILTINS_STR_UNICODE (1) @@ -39,6 +40,10 @@ #define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) #define MICROPY_PY_BUILTINS_PROPERTY (1) #define MICROPY_PY_DESCRIPTORS (1) +#define MICROPY_PY_BUILTINS_INPUT (1) +#define MICROPY_PY_BUILTINS_HELP (1) +#define MICROPY_PY_BUILTINS_HELP_TEXT esp_help_text +#define MICROPY_PY_BUILTINS_HELP_MODULES (1) #define MICROPY_PY___FILE__ (0) #define MICROPY_PY_GC (1) #define MICROPY_PY_ARRAY (1) @@ -70,6 +75,7 @@ #define MICROPY_PY_UZLIB (1) #define MICROPY_PY_LWIP (1) #define MICROPY_PY_MACHINE (1) +#define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new #define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_I2C (1) #define MICROPY_PY_MACHINE_SPI (1) @@ -93,12 +99,11 @@ #define MICROPY_MODULE_FROZEN_LEXER mp_lexer_new_from_str32 #define MICROPY_QSTR_EXTRA_POOL mp_qstr_frozen_const_pool +#define MICROPY_VFS (1) #define MICROPY_FATFS_ENABLE_LFN (1) #define MICROPY_FATFS_RPATH (2) -#define MICROPY_FATFS_VOLUMES (2) #define MICROPY_FATFS_MAX_SS (4096) #define MICROPY_FATFS_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */ -#define MICROPY_FSUSERMOUNT (1) #define MICROPY_VFS_FAT (1) #define MICROPY_ESP8266_APA102 (1) #define MICROPY_ESP8266_NEOPIXEL (1) @@ -117,8 +122,6 @@ extern void ets_event_poll(void); // type definitions for the specific machine -#define BYTES_PER_WORD (4) - #define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p))) #define MP_SSIZE_MAX (0x7fffffff) @@ -140,10 +143,13 @@ void *esp_native_code_commit(void*, size_t); #define mp_type_fileio fatfs_type_fileio #define mp_type_textio fatfs_type_textio +// use vfs's functions for import stat and builtin open +#define mp_import_stat mp_vfs_import_stat +#define mp_builtin_open mp_vfs_open +#define mp_builtin_open_obj mp_vfs_open_obj + // extra built in names to add to the global namespace #define MICROPY_PORT_BUILTINS \ - { MP_OBJ_NEW_QSTR(MP_QSTR_help), (mp_obj_t)&mp_builtin_help_obj }, \ - { MP_OBJ_NEW_QSTR(MP_QSTR_input), (mp_obj_t)&mp_builtin_input_obj }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj }, // extra built in modules to add to the list of known ones @@ -165,7 +171,6 @@ extern const struct _mp_obj_module_t time_module; #define MICROPY_PORT_BUILTIN_MODULES \ { MP_OBJ_NEW_QSTR(MP_QSTR_esp), (mp_obj_t)&esp_module }, \ - { MP_OBJ_NEW_QSTR(MP_QSTR_lwip), (mp_obj_t)&mp_module_lwip }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&mp_module_lwip }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_usocket), (mp_obj_t)&mp_module_lwip }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_network), (mp_obj_t)&network_module }, \ @@ -192,7 +197,6 @@ extern const struct _mp_obj_module_t time_module; #define MICROPY_PORT_ROOT_POINTERS \ const char *readline_hist[8]; \ - vstr_t *repl_line; \ mp_obj_t pin_irq_handler[16]; \ // We need to provide a declaration/definition of alloca() diff --git a/esp8266/mpconfigport_512k.h b/esp8266/mpconfigport_512k.h index d1d602579..322fb4151 100644 --- a/esp8266/mpconfigport_512k.h +++ b/esp8266/mpconfigport_512k.h @@ -5,8 +5,8 @@ #undef MICROPY_EMIT_INLINE_XTENSA #define MICROPY_EMIT_INLINE_XTENSA (0) -#undef MICROPY_FSUSERMOUNT -#define MICROPY_FSUSERMOUNT (0) +#undef MICROPY_VFS +#define MICROPY_VFS (0) #undef MICROPY_VFS_FAT #define MICROPY_VFS_FAT (0) @@ -25,3 +25,7 @@ #undef MICROPY_PY_FRAMEBUF #define MICROPY_PY_FRAMEBUF (0) + +#undef mp_import_stat +#undef mp_builtin_open +#undef mp_builtin_open_obj |
