diff options
| author | Scott Shawcroft <scott.shawcroft@gmail.com> | 2017-06-20 10:56:05 -0700 |
|---|---|---|
| committer | Scott Shawcroft <scott.shawcroft@gmail.com> | 2017-06-20 10:56:05 -0700 |
| commit | 30ee7019ca651bce1fe966c1089fe977d51dc92b (patch) | |
| tree | 0114b6f744dd175b7722dd8edcbe24f4ee84bb45 /esp8266 | |
| parent | 97fcdfbd08c922efd7470d6482d7c7c703ffc0ae (diff) | |
| parent | 869cdcfdfc860b1177baf9b0f8818915ba54f3f5 (diff) | |
Merge tag 'v1.9.1'2.0.0-alpha.0
Fixes for stmhal USB mass storage, lwIP bindings and VFS regressions
This release provides an important fix for the USB mass storage device in
the stmhal port by implementing the SCSI SYNCHRONIZE_CACHE command, which
is now require by some Operating Systems. There are also fixes for the
lwIP bindings to improve non-blocking sockets and error codes. The VFS has
some regressions fixed including the ability to statvfs the root.
All changes are listed below.
py core:
- modbuiltins: add core-provided version of input() function
- objstr: catch case of negative "maxsplit" arg to str.rsplit()
- persistentcode: allow to compile with complex numbers disabled
- objstr: allow to compile with obj-repr D, and unicode disabled
- modsys: allow to compile with obj-repr D and PY_ATTRTUPLE disabled
- provide mp_decode_uint_skip() to help reduce stack usage
- makeqstrdefs.py: make script run correctly with Python 2.6
- objstringio: if created from immutable object, follow copy on write policy
extmod:
- modlwip: connect: for non-blocking mode, return EINPROGRESS
- modlwip: fix error codes for duplicate calls to connect()
- modlwip: accept: fix error code for non-blocking mode
- vfs: allow to statvfs the root directory
- vfs: allow "buffering" and "encoding" args to VFS's open()
- modframebuf: fix signed/unsigned comparison pendantic warning
lib:
- libm: use isfinite instead of finitef, for C99 compatibility
- utils/interrupt_char: remove support for KBD_EXCEPTION disabled
tests:
- basics/string_rsplit: add tests for negative "maxsplit" argument
- float: convert "sys.exit()" to "raise SystemExit"
- float/builtin_float_minmax: PEP8 fixes
- basics: convert "sys.exit()" to "raise SystemExit"
- convert remaining "sys.exit()" to "raise SystemExit"
unix port:
- convert to use core-provided version of built-in import()
- Makefile: replace references to make with $(MAKE)
windows port:
- convert to use core-provided version of built-in import()
qemu-arm port:
- Makefile: adjust object-file lists to get correct dependencies
- enable micropython.mem_*() functions to allow more tests
stmhal port:
- boards: enable DAC for NUCLEO_F767ZI board
- add support for NUCLEO_F446RE board
- pass USB handler as parameter to allow more than one USB handler
- usb: use local USB handler variable in Start-of-Frame handler
- usb: make state for USB device private to top-level USB driver
- usbdev: for MSC implement SCSI SYNCHRONIZE_CACHE command
- convert from using stmhal's input() to core provided version
cc3200 port:
- convert from using stmhal's input() to core provided version
teensy port:
- convert from using stmhal's input() to core provided version
esp8266 port:
- Makefile: replace references to make with $(MAKE)
- Makefile: add clean-modules target
- convert from using stmhal's input() to core provided version
zephyr port:
- modusocket: getaddrinfo: Fix mp_obj_len() usage
- define MICROPY_PY_SYS_PLATFORM (to "zephyr")
- machine_pin: use native Zephyr types for Zephyr API calls
docs:
- machine.Pin: remove out_value() method
- machine.Pin: add on() and off() methods
- esp8266: consistently replace Pin.high/low methods with .on/off
- esp8266/quickref: polish Pin.on()/off() examples
- network: move confusingly-named cc3200 Server class to its reference
- uos: deconditionalize, remove minor port-specific details
- uos: move cc3200 port legacy VFS mounting functions to its ref doc
- machine: sort machine classes in logical order, not alphabetically
- network: first step to describe standard network class interface
examples:
- embedding: use core-provided KeyboardInterrupt object
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 |
