diff options
author | Damien George <damien.p.george@gmail.com> | 2017-08-14 16:39:40 +1000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2017-08-14 16:39:40 +1000 |
commit | 9624f10825851f5419cc0b21517580c4cb3838f0 (patch) | |
tree | feb035f907b56c0b933dbfbefe86ba7922814547 /esp8266 | |
parent | 545354cb2a428bd844878a7c8cfd6e67a415e699 (diff) | |
parent | 825460a093a6bcd8fb79119b5f6ee8408f63603b (diff) | |
download | micropython-9624f10825851f5419cc0b21517580c4cb3838f0.tar.gz micropython-9624f10825851f5419cc0b21517580c4cb3838f0.zip |
Merge tag 'v1.9' into parse-bytecode
New VFS subsystem and scheduling framework, and less need for the heap
This release adds some fundamental new components, allows for more Python
operations without using the heap and has reduced code size and stack
usage.
Changes in the way iterators are handled allows to iterate without
allocating on the heap for the types: tuple, list, str, bytes, bytearray,
array, dict, set, frozenset. It also allows to call the builtins all, any,
min max and sum without allocating heap memory for the iterator argument.
And improvements to the handling of super() means that super().foo() method
calls are now heap-less.
A new generic VFS subsystem has been added which allows to mount arbitrary
filesystems (even written in Python) at the root or at a mount-point within
the root. The FatFS driver has been replaced with an object-oriented
version (oofatfs) which allows a fully customisable filesystem layout.
A scheduling framework has been implemented in the core which gives the
ability to schedule callbacks to be called "as soon as possible". This
allows ports to implement "soft IRQs" which allow the programmer to
allocate memory during an interrupt handler, at the cost of some
performance related to response time of the handler. The new
micropython.schedule() function gives access to the scheduler.
Other improvements to the core include: consts can now be big-nums, for
example "X = const(1 << 100)"; addition of "help('modules')" to list
available modules; stack usage reduced for a Python call by 8 bytes on ARM
Cortex-M architectures; micropython.kbd_intr() function added to disable
Ctrl-C capture; addition of uio.resource_stream(); mpy-cross is built
automatically if needed; a helper tool mpy_cross_all.py is added to run
mpy-cross on an entire project.
The bytecode has changed in this version so existing .mpy files will need
recompiling. There have also been some changes to the C API, most notably
with mp_uint_t changed to size_t in many places.
In the extended modules the following main changes have been made: addition
of machine.Signal class to allow inversion on a Pin; framebuf has new
formats of the form MONO_xxx; addition of uselect.ipoll() for allocation-
free polling; addition of uos.ilistdir() for efficient iteration of a
directory listing; machine.Pin high/low methods are renamed to on/off in
esp8266 and zephyr (this is a backwards-incompatible change);
machine.time_pulse_us() function no longer throws exceptions, but returns
negative values instead.
For stmhal the pyb.fault_debug() function is added, and default behaviour
for a hard-fault is now an immediate reset. There is better support for F7
MCUs, in particular DMA and SD card support. A bug has been fixed with the
USB VCP (USB serial) where it would in rare cases (usually when the host PC
was under load) would lose characters. Pyboard now automatically mounts
all available partitions on the SD card. Multithreading has been
implemented and is available via the _thread module, but this feature is
disabled by default and must be enabled at compile time using the
MICROPY_THREAD and MICROPY_THREAD_GIL options. The ability to skip booting
from SD card is now available by creating an empty file on the flash called
"SKIPSD".
The cc3200 port has had some backwards incompatible changes, in particular
with I2C, Pin, UART and uos. Please see the documentation for the new
behaviour.
The esp8266 port has had a change in the size of the firmware in order to
accommodate additional features. As such the filesystem for this version
is incompatible with v1.8.7 and a device requires backup and erasure before
flashing this version. Soft IRQs are now implemented for Pin and Timer
callbacks, along with the general improvements described above.
In the documentation there is now a section describing the differences
between MicroPython and CPython. And code coverage is up to 98% across py/
and extmod/.
Changes in code size (in bytes) between v1.8.7 and this version are:
bare-arm: -1104
minimal: -1324
unix x64: -1115
unix nanbox: -11106
stmhal: +18116
cc3200: +1032
esp8266: +3060
Note that stmhal has increased significantly due to the addition of frozen
bytecode and the LCD160CR driver.
A detailed list of changes follows.
py core:
- builtinimport: raise ValueError for bad relative import, per CPython
- builtinimport: remove unreachable code and change obj-import comment
- runtime: refactor assert(0) to improve coverage
- runtime: fix handling of throw() when resuming generator
- objgenerator: when throwing an object, don't make an exc instance
- objgenerator: don't raise RuntimeError if GeneratorExit ignored
- parse: refactor code to remove assert(0)'s
- emitnative: remove assert(0)'s or replace with mp_not_implemented
- objexcept: replace if-cond and assert(0) with simple assert
- runtime: refactor default case of switch to remove assert(0)
- binary: mp_binary_get_size: Raise error on unsupported typecodes
- formatfloat: remove unreachable code
- objint_mpz: refactor switch-statement to remove unreachable default
- mpz: implement mpz_set_from_bytes() as a foundation for int.from_bytes()
- objint: from_bytes(): implement "byteorder" param and arbitrary precision
- objint_longlong: add stub for mp_obj_int_from_bytes_impl()
- add builtin help function to core, with default help msg
- move weak-link map to objmodule.c, and expose module maps as public
- builtinhelp: implement help('modules') to list available modules
- objint: fix left-shift overflow in checking for large int
- objmodule: move module init/deinit code into runtime functions
- objstr: optimize string concatenation with empty string
- showbc: make sure to set the const_table before printing bytecode
- py.mk: add CFLAGS_MOD flag to set config file for FatFs
- objstringio: allow to specify initial capacity by passing numeric argument
- objset: make inplace binary operators actually modify the set
- objfloat: raise ZeroDivisionError for 0 to negative power
- objcomplex: correctly handle case of 0j to power of something
- objset: fix inplace binary ops so frozensets are not modified
- added optimised support for 3-argument calls to builtin.pow()
- objstr: give correct behaviour when passing a dict to %-formatting
- mpconfig.h: move PY_BUILTINS_POW3 config option to diff part of file
- objstr: convert some instances of mp_uint_t to size_t
- objcomplex: fix typo in ternary expression
- asmxtensa.h: explicitly cast args to 32-bits so left-shift is legal
- map: change mp_uint_t to size_t where appropriate
- nlr: fix execstack builds for ARM
- objtype: add __delattr__/__setattr__ configured by MICROPY_PY_DELATTR_SETATTR
- emitbc: produce correct line number info for large bytecode chunks
- objtype: replace non-ASCII single-quote char with ASCII version
- modthread: use system-provided mutexs for _thread locks
- vm: add MICROPY_PY_THREAD_GIL_VM_DIVISOR option
- runtime: convert mp_uint_t to size_t where appropriate
- mpz: convert mp_uint_t to size_t where appropriate
- mpz: remove obsolete declaration of mpz_as_str_size
- mpz: change type of "base" args from mp_uint_t to unsigned int
- persistentcode: replace mp_uint_t with size_t where appropriate
- objtuple: convert mp_uint_t to size_t where appropriate
- objlist: convert mp_uint_t to size_t where appropriate
- objdict: convert mp_uint_t to size_t where appropriate
- objset: convert mp_uint_t to size_t where appropriate
- objstr: convert mp_uint_t to size_t (and use int) where appropriate
- objarray: convert mp_uint_t to size_t where appropriate
- objfun: convert mp_uint_t to size_t where appropriate
- objclosure: convert mp_uint_t to size_t where appropriate
- objexcept: convert mp_uint_t to size_t where appropriate
- objint: convert mp_uint_t to size_t where appropriate
- vm: convert mp_uint_t to size_t where appropriate
- add iter_buf to getiter type method
- allow bytecode/native to put iter_buf on stack for simple for loops
- make FOR_ITER opcode pop 1+4 slots from the stack when finished
- optimise storage of iterator so it takes only 4 slots on Py stack
- remove unused "use_stack" argument from for_iter_end emit function
- runtime: optimise case of identity iterator so it doesn't alloc RAM
- compile: optimise list/dict/set comprehensions to use stack iter
- de-optimise some uses of mp_getiter, so they don't use the C stack
- grammar: group no-compile grammar rules together to shrink tables
- lexer: don't generate string representation for period or ellipsis
- persistentcode: bump .mpy version due to change in bytecode
- lexer: simplify handling of indenting of very first token
- lexer: move check for keyword to name-tokenising block
- lexer: use strcmp to make keyword searching more efficient
- lexer: simplify handling of line-continuation error
- do adjacent str/bytes literal concatenation in lexer, not compiler
- lexer: convert mp_uint_t to size_t where appropriate
- grammar: remove unused rule
- objlist: for list slice assignment, allow RHS to be a tuple or list
- moduerrno: make uerrno.errorcode dict configurable
- moduerrno: make list of errno codes configurable
- parse: allow parser/compiler consts to be bignums
- create str/bytes objects in the parser, not the compiler
- parse: simplify handling of errors by raising them directly
- runtime: mp_raise_msg(): Accept NULL argument for message
- objarray: disallow slice-assignment to read-only memoryview
- map: fix bugs with deletion of elements from OrderedDict
- move locals/globals dicts to the thread-specific state
- nlr.h: mark nlr_jump_fail as NORETURN
- nlrxtensa: convert from assembler to C file with inline asm
- nlrx64: convert from assembler to C file with inline asm
- nlrx86: convert from assembler to C file with inline asm
- py.mk: force nlr files to be compiled with -Os
- modsys: use MP_SMALL_INT_MAX for sys.maxsize in case of LONGINT_IMPL_NONE
- runtime.c: remove optimization of '*a,=b', it caused a bug
- use mp_obj_get_array where sequence may be a tuple or a list
- nlrx86: add workaround for Zephyr
- nlrx64: fixes to support Mac OS
- objint_longlong: implement mp_obj_int_from_bytes_impl()
- allow lexer to raise exceptions during construction
- objint: allow to print long-long ints without using the heap
- emitnative: use assertions and mp_not_implemented correctly
- emitnative: remove obsolete commented out code
- mpprint: fix int formatting so "+" is printed for 0-valued integer
- mkrules.mk: remove special check for "-B" in qstr auto generation
- objstr: fix eager optimisation of str/bytes addition
- reduce size of mp_code_state_t structure
- provide mp_decode_uint_value to help optimise stack usage
- objstr: use better msg in bad implicit str/bytes conversion exception
- add micropython.schedule() function and associated runtime code
- vm: don't release the GIL if the scheduler is locked
- bc: provide better error message for an unexpected keyword argument
- use size_t as len argument and return type of mp_get_index
- sequence: convert mp_uint_t to size_t where appropriate
- define and use MP_OBJ_ITER_BUF_NSLOTS to get size of stack iter buf
- lexer: remove obsolete comment, since lexer can now raise exceptions
- modmath: allow trunc/ceil/floor to return a big int if necessary
- objint: handle special case of -0 when classifying fp as int
- modbuiltins: for round() builtin use nearbyint instead of round
- modbuiltins: allow round() to return a big int if necessary
- objtype: use size_t where appropriate, instead of mp_uint_t or uint
- objnamedtuple: use size_t where appropriate, instead of mp_uint_t
- use mp_locals/mp_globals accessor funcs instead of MP_STATE_CTX
- remove MP_STATE_CTX, use MP_STATE_THREAD instead (it's an alias)
- objarray: use mp_obj_str_get_str instead of mp_obj_str_get_data
- nlrx86: better check for Zephyr (requires 1.7)
- obj: change mp_uint_t to size_t for mp_obj_get_array_fixed_n len arg
- vm: fix VM opcode tracing to print correct stack pointer
- compile: when compiling super(), handle closed-over self variable
- objmap: convert mp_uint_t to size_t
- use mp_raise_TypeError/mp_raise_ValueError helpers where possible
- lexer: simplify and reduce code size for operator tokenising
- compile: simplify syntax-error messages for illegal assignments
- shorten a couple of error messages
- compile: provide terse error message for invalid dict/set literals
- convert mp_uint_t to size_t for tuple/list accessors
- change mp_uint_t to size_t for mp_obj_str_get_data len arg
- objzip: convert mp_uint_t to size_t
- obj.h: make sequence grow more efficient and support overlapping
- objstr: use MICROPY_FULL_CHECKS for range checking when constructing bytes
- add very simple but correct hashing for float and complex numbers
- objint: consolidate mp_obj_new_int_from_float to one implementation
- raise a ValueError if range() step is zero
- objtuple: add support for inplace add (same as normal add)
- make sure that static emg-exc-buffer is aligned to size of mp_obj_t
- runtime: when init'ing kbd intr exc, use tuple ptr instead of object
- objint: extract small int value directly because type is known
- objint: use unsigned arithmetic when formatting an integer
- obj: clean up and add comments describing mp_obj_type_t struct
- optimise types for common case where type has a single parent type
- objfloat: add implementation of high-quality float hashing
- nlrsetjmp: add check for failed NLR jump
- gc: execute finaliser code in a protected environment
- modmicropython: add micropython.kbd_intr() function
- reduce str/repr precision of float numbers when floats are 30-bit
- objtype: mp_obj_new_super doesn't need to be public, so inline it
- compile: don't do unnecessary check if parse node is a struct
- compile: extract parse-node kind at start of func for efficiency
- compile: add COMP_RETURN_IF_EXPR option to enable return-if-else opt
- compile: don't do unnecessary check if iter parse node is a struct
- compile: refactor handling of special super() call
- add LOAD_SUPER_METHOD bytecode to allow heap-free super meth calls
- mpz: strip trailing zeros from mpz value when set from bytes
- mpz: in mpn_sub, use existing function to remove trailing zeros
- cleanup use of global DEBUG preprocessor definition
- modio: implement uio.resource_stream(package, resource_path)
- objint: in int.from_bytes, only create big-int if really needed
- modio: resource_stream: Implement "package" param handling
- binary: handle storing big-ints to all arrays types
- lexer: simplify lexer startup by using dummy bytes and next_char()
- mkrules.mk: add dependency of .mpy files upon mpy-cross
- lexer: process CR earlier to allow newlines checks on chr1
- modsys: update conditionals for code referencing sys.stdout
- objstringio: fix StringIO reads at or beyond EOF
- sequence: fix boundary errors when slicing with a negative step
- objrange: fix slicing of range when step of slice is negative
- mkenv.mk: use $(TOP) instead of ".." to reference tools, mpy-cross
- vm: fix bug with stackless mode and unwinding of exceptions
- vm: fix bug with unwind jump popping the iterator from a for loop
- emitbc: fix bug with BC emitter computing Python stack size
- mkrules.mk: fix auto-qstr generation when "make -B" is used
- objstringio: catch mp_uint_t overflow of stream position in write()
- move BYTES_PER_WORD definition from ports to py/mpconfig.h
extmod:
- modframebuf: optimize fill_rect subroutine call
- modframebuf: clip pixels drawn by line method
- modframebuf: add GS4_HMSB format
- vfs_fat: rework so it can optionally use OO version of FatFS
- rename vfs_fat_file.h to vfs_fat.h
- add generic VFS sub-system
- vfs_fat: rework to support new generic VFS sub-system
- vfs: add ability for VFS sub-system to import using VfsFat
- modlwip: add socket.readinto() method
- vfs: expose mp_vfs_mount_t type
- vfs_fat: use SECSIZE macro to determine FatFs sector size
- machine_signal: implement "Signal" abstraction for machine module
- vfs_fat: update to use FF_DIR instead of DIR
- vfs: expose lookup_path_raw as mp_vfs_lookup_path
- vfs_fat: remove MICROPY_READER_FATFS component
- vfs_fat: remove MICROPY_FSUSERMOUNT_ADHOC config option
- remove MICROPY_FSUSERMOUNT and related files
- vfs_fat: remove MICROPY_FATFS_OO config option
- merge old fsusermount.h header into vfs.h and vfs_fat.h
- vfs_fat: remove unused fatfs_builtin_open function
- vfs_fat: remove unused function fat_vfs_listdir
- vfs_reader: fix use of NLR by popping context
- vfs_fat.c: use explicit include path for timeutils.h
- machine_pulse: make time_pulse_us() not throw exceptions
- machine_spi: remove EVENT_POLL_HOOK from soft-SPI transfer func
- machine_signal: implement Signal .on() and .off() methods
- vfs: allow to mount a block device, not just a VFS object
- vfs: raise OSError(EEXIST) on attempt to mkdir a mount point
- vfs: allow to stat the root directory
- modlwip: add my copyright
- modurandom: use mp_raise_ValueError()
- modutimeq: make scheduling fair (round-robin)
- modutimeq: add peektime() function (provisional)
- vfs_fat: remove obsolete and unused str/len members
- vfs_fat: allow to compile with MICROPY_VFS_FAT disabled
- vfs: rewrite path lookup algo to support relative paths from root
- modframebuf: add support for monochrome horizontal format
- utime_mphal: don't exit/enter the GIL in generic sleep functions
- modlwip: use mp_obj_str_get_str instead of mp_obj_str_get_data
- vfs_fat: fix calculation of total blocks in statvfs
- moduselect: update to use size_t for array accessor
- update for changes to mp_obj_str_get_data
- modframebuf: make monochrome bitmap formats start with MONO_
- machine_signal: support all Pin's arguments to the constructor
- machine_signal: rename "inverted" arg to "invert", it's shorter
- moductypes: fix bigint handling for 32-bit ports
- crypto-algorithms/sha256: remove non-standard memory.h header
- moduselect: convert to MP_ROM_QSTR and friends
- moduselect: refactor towards introduction of poll.ipoll()
- moduselect: implement ipoll() method for alloc-free polling
- modlwip: getaddrinfo: Allow to accept all 6 standard params
- modlwip: ioctl POLL: Fix handling of peer closed socket
- vfs: allow a VFS to be mounted at the root dir
- vfs: implement mp_vfs_ilistdir()
- vfs_fat: replace listdir() with implementation of ilistdir()
- vfs: use MP_S_IFDIR, MP_S_IFREG consts instead of magic numbers
- vfs_fat_misc: remove dot-dirs filter since FatFS already does it
lib:
- utils: remove old pyhelp helper, replaced with py/builtinhelp.c
- utils/pyexec: only print help prompt if HELP feature is enabled
- oofatfs: add OO version of FatFS library
- fatfs: remove old fatfs library component, it's replaced by oofatfs
- oofatfs/ffconf.h: allow to configure FS_EXFAT option
- oofatfs/ffconf.h: add MICROPY_FATFS_NORTC option
- utils/pyexec: allow to compile when the uPy compiler is disabled
- utils/pyexec: refactor to put lexer constructors all in one place
- memzip: make lexer constructor raise exception when file not found
- utils/pyexec: fix bug with pyexec_file not setting flag for source
- libm: add implementation of nearbyintf, from musl-1.1.16
- netutils: update for changes to mp_obj_str_get_data
- utils/pyexec: update event-driven REPL to match non-event REPL
drivers:
- fix some minor spelling mistakes
- display: add driver and test for uPy LCD160CR display
- memory: add SPI flash driver, written in C
- display/lcd160cr: use correct variable in set_power()
- display/lcd160cr: fix bugs with lcd.get_pixel()
- display/lcd160cr: fix bug with save_to_flash method
- display/lcd160cr: add check that JPEG size is less than 65536
- nrf24l01: update to work on newer ports, using machine, utime
- display/lcd160cr: fix get_line method and enhance screen_dump
- display/lcd160cr_test: allow test to take orientation parameter
- replace deprecated Pin.high()/low() methods with .__call__(1/0)
tools:
- tinytest-codegen.py: blacklist heapalloc_str.py test for qemu-arm
- upip: update to 1.1.5. Better and more user-friendly error handling
- add gen-cpydiff.py to generate docs differences
- gen-cpydiff.py: set the Python import path to find test modules
- gen-cpydiff.py: configurable CPython and micropython executables
- tinytest-codegen: update for recent test renaming ("intbig" suffix)
- pyboard: tighten up Pyboard object closure on errors
- pyboard: add "exec" and "execpty" pseudo-devices support
- pyboard: execpty: Use shell=False to workaround some curdir issues
- pyboard: processPtyToTerminal: Add workaround for PySerial bug
- pyboard: provide more details when expected reply not received
- mpy-tool: make work if run from another directory
- upip: upgrade to 1.1.6, supports commented lines in requirements.txt
- upip: upgrade to 1.2
- mpy-tool.py: use MP_ROM_xxx macros to support nanbox builds
- mpy_cross_all.py: helper tool to run mpy-cross on the entire project
- mpy-tool.py: fix regression with freezing floats in obj repr C
tests:
- add feature check for "const" keyword and skip related tests
- update test suite to be compatible with CPython 3.6
- improve stream.c test coverage
- import: improve builtinimport.c test coverage
- improve frozen import test coverage
- update tests, and add new ones, for recent generator tweaks
- io: improve test coverage of io.BufferedWriter
- basics: improve runtime.c test coverage
- extmod: improve test coverage of ure module
- float: add test for assigning to attribute of complex number
- extmod/framebuf1: add test for no-op fill_rect
- micropython/opt_level: add test for opt_level 3
- misc/non_compliant: add test for inability to assign func attrs
- basics: add test for assignment of attribute to bound method
- add test for int.from_bytes() for arbitrary-precision integer
- heapalloc_int_from_bytes: test that int.from_bytes() can work w/o alloc
- add test for builtin help function
- basics/builtin_help: add test for help('modules')
- make sure special tests can be skipped as well
- extmod/framebuf4: add tests for GS4_HMSB framebuf format
- extmod/framebuf1: fix test for framebuf invalid constructor
- extmod: add test for ure debug printing when compiling a regex
- heapalloc_str: test for alloc-free string operations
- extmod: update vfs_fat tests for new OO FatFs library
- extmod/vfs_fat: update tests to work with new VFS sub-system
- extmod/vfs_fat_ramdisk: make it work on pyboard
- run-tests: skip frozenset tests if set literal syntax is not available
- basics/zip: make skippable
- thread: make thread_exc2 runable on baremetal
- thread: fix stack size test so tests run reliably on baremetal
- heapalloc_bytesio: test for BytesIO with preallocates space
- basics/set_binop: add tests for inplace set operations
- float: add tests for zero to a negative power
- split tests for 2- and 3-arg pow()
- basics/string_format_modulo: add more tests for dict formatting
- pyb: adjust tests so they can run on PYB and PYBLITE
- misc: add test for line number printing with large bytecode chunk
- add option to not clear MICROPYPATH when running tests
- run-tests: allow to skip tests using async/await keywords
- comprehension1, containment: split set tests to separate files
- builtin_dir: the most expected thing in sys is exit, test for it
- basic/[a-f]*: make skippable
- dict_fromkeys: revert to use reversed() to run in native codegen mode
- extmod: make tests skippable
- thread: replace busy waiting loops with a loop that sleeps
- thread: add stress-test for creating many threads
- gen_yield_from_close: use range() instead of reversed()
- basic/: make various tests skippable
- cmdline: update tests to pass with latest changes to bytecode
- cmdline/cmd_showbc: update to work with recent changes
- micropython: add test for iterating with the heap locked
- micropython/heapalloc_iter: add tests for contains and unpack
- cmdline: update cmd_parsetree test for changes to grammar order
- cmdline/cmd_parsetree: update to work with changes to grammar
- basics/string_join: add more tests for string concatenation
- heapalloc_exc_raise.py: heap alloc test for raising/catching exc
- cpydiff: add initial set of tests for uPy-CPython differences
- cpydiff: add a test for storing iterable to a list slice
- micropython: add test for consts that are bignums
- extmod: add test for machine.Signal class
- basics: add further tests for OrderedDict
- run-tests: check for big int availability and skip related tests
- basic: split tests into working with small ints and not working
- float/complex1: split out intbig test
- float2int*: suffix with _intbig, don't run on any other int type
- string_format_modulo2: split off intbig test
- basics/string_join.py: add test case where argument is not iterable
- basics/unpack1.py: test if *a, = b copies b when b is a list
- micropython/: split off intbig tests
- uctypes_array_assign_native_le: split off intbig part
- basic: make various tests skippable
- float: make various tests skippable
- extmod: add very basic feature test for ussl module
- extmod: add websocket tests
- dict_fromkeys: split out skippable part
- micropython: make uio-using tests skippable
- micropython/heapalloc_traceback: fix backtrace line # after refactor
- micropython/opt_level: clarify the expected output for opt_level == 3
- feature_check/int_big: rework "big int" detection
- basics/fun_error: split out skippable test
- extmod: rename websocket test to websocket_basic
- misc/: make few tests skippable
- extmod: add a test for core VFS functionality, sans any filesystem
- extmod/vfs_basic: add more tests for basic VFS functionality
- extmod: improve re1.5/recursiveloop.c test coverage
- improve binary.c test coverage
- basics/struct_micropython: add test for 'S' typecode in ustruct
- run-tests: re-instate skipping of doubleprec test on pyboard
- extmod/vfs_basic: unmount all existing devices before doing test
- extmod: improve tinfgzip.c test coverage
- micropython/viper_error: add more tests to improve coverage
- basics/string_format2: adjust comment now that tests succeed
- basics: add test for string module formatting with int argument
- basics: move string-modulo-format int tests to dedicated file
- basics/bytes_add: add tests for optimised bytes addition
- micropython: add tests for micropython.schedule()
- heapalloc_str: test no-replacement case for str.replace()
- float: add tests for math funcs that return ints
- float: add tests for round() of inf, nan and large number
- basics: add test for super() when self is closed over
- basics: add tests for list and bytearray growing using themselves
- run-tests: be sure to close Pyboard object on completion
- vfs_fat_fileio.py is too big to be parsed in 16K heap, split in 2
- extmod/vfs_fat_fileio*: improve skippability
- float/byte*_construct: skip on missing array module
- micropython/heapalloc_iter: improve skippability
- run-tests: introduce generic "minimal" target
- float: add tests for hashing float and complex numbers
- run-tests: update names of tests that may need skipping
- basics: add tests for raising ValueError when range() gets 0 step
- basics: add test for tuple inplace add
- extmod/utimeq1: improve coverage of utimeq module
- run-tests: search feature checks wrt to main script location
- run-tests: don't post-process CRASH result in any way
- micropython: add test for micropython.kbd_intr()
- add tests for calling super and loading a method directly
- basics: add tests for int.from_bytes when src has trailing zeros
- cpydiff/core_arguments: fill in cause/workaround
- cpydiff/core_function_userattr: clarify, fill in cause and workaround
- cpydiff/core_import_prereg: fill in cause and workaround
- io/resource_stream: add test for uio.resource_stream()
- cpydiff/core_import_path: test showing difference in package.__path__
- cpydiff/core_import_split_ns_pkgs: test for split namespace packages
- cpydiff/core_function_unpacking: fill in workaround
- extmod: add more tests for VFS FAT
- extmod: add some more VFS tests
- micropython: add test for int.from_bytes with many zero bytes
- move super-as-local test from cpydiff to basic tests
- basics: update array test for big-int with lL typecodes
- basics: add memoryview test for big ints
- basics/lexer: add lexer tests for input starting with newlines
- extmod: make some vfs tests fully unmount FSs before running
- extmod/vfs: update tests to reflect new ilistdir() method
- basics/lexer: add line continuation tests for lexer
- extmod/vfs_fat: add test for ilistdir of a non-existent directory
- extmod/vfs_fat_more: make skippable is uos is not available
- io/bytesio_ext: test read() after seek() past end of BytesIO object
- basics/list_slice_3arg: add more tests for negative slicing
- basics/builtin_range: add tests for negative slicing of range
- basics: add more tests for unwind jumps from within a try-finally
mpy-cross:
- main: move lexer constructor to within NLR handler block
- fix compiler detection for including windows/fmode.c
- Makefile: override undefine any inherited variables
- Makefile: guard "override undefine" by test for make feature
bare-arm port:
- main: move lexer constructor to within NLR handler block
- Makefile: change C standard from gnu99 to c99
minimal port:
- update frozentest.mpy file for new .mpy version
- add ability and description to build without the compiler
- main: move lexer constructor to within NLR handler block
- Makefile: change C standard from gnu99 to c99
- main: make Cortex-M vector table constant
unix port:
- coverage: move coverage #if guard back to top of file
- enable builtin help function in coverage build
- enable MICROPY_PY_BUILTINS_HELP_MODULES in coverage build
- switch to OO version of FatFS library
- get minimal version compiling again
- change to use new generic VFS sub-system in coverage build
- fatfs_port: include new oofatfs header
- mpconfigport.h: remove obsolete MICROPY_FATFS_VOLUMES config
- modos: remove VfsFat from uos module, it's now in uos_vfs module
- make stack be non-executable
- fix freedos port build problems
- main: properly handle MICROPYPATH starting with ':'
- moduselect: implement ipoll() method with no-allocation policy
- modmachine: add Signal class to machine module
- remove remaining, obsolete traces of GNU readline support
- moduselect: properly implement ipoll object iteration
- main: refactor to put lexer constructors all in one place
- use mp_handle_pending() in time.sleep()
- coverage: enable scheduler and add tests for it
- use mp_obj_str_get_str instead of mp_obj_str_get_data
- convert mp_uint_t to size_t for use of mp_obj_list_get
- convert mp_uint_t to size_t in alloc.c
- enabled high-quality float hashing in coverage build
- remove obsolete MICROPY_FATFS macro
- main: ignore SIGPIPE signal, instead make EPIPE arrive
- main: don't allow to specify too small heap size
- main: implement -m option for packages
- Makefile: enable frozen bytecode modules dir
- move upip to frozen bytecode dir
- Makefile: don't add frozen bytecode to minimal build
- add ilistdir in uos module
- use core-provided KeyboardInterrupt exception object
windows port:
- .gitignore: ignore VC.db and VC.opendb files from VS2015
- make msvc project file support any version from VS2013 to VS2017
- bring mpconfigport.h up-to-date with unix port
- README: convert to Markdown
- README: fix some typos and grammar
- README: add a note about stack usage for msvc
- use core-provided KeyboardInterrupt exception object
- msvc: add machine/pin-related sources to build
- msvc: remove directory with generated files when cleaning
- msvc: do not define DEBUG for debug builds
- msvc: rebuild all qstrs when mpconfig headers are modified
- msvc: workaround parser bug in older MSBuild versions
qemu-arm port:
- don't compile tests in "REPL" mode
- mpconfigport.h: enable MICROPY_PY_BUILTINS_POW3 option
- enable machine module and associated tests
- add basic uos module with generic VFS capabilities
- move lexer constructors to within NLR handler block
stmhal port:
- support PortG on STM32L476 and STM32L486
- fix wrong usage of gcc -print-libgcc-file-name
- fix USB HID receive not receiving the first packet
- implement ioctl for USB HID read
- implement SNAK/CNAK mechanism for USB HID receive
- convert to use builtin help function
- enable help('modules') feature
- add default frozen-bytecode directory and link lcd160cr driver
- fix examples in openocd configs to include addresses
- add ability to have filesystem stored on external SPI flash
- boards/STM32L476DISC: use external SPI flash for filesystem
- mpconfigport.h: reorganise the config options into groups
- usbd_msc_storage: use storage functions instead of disk ones
- convert to use VFS sub-system and new ooFatFs component
- fix name of automatically created boot.py
- moduos: remove duplicated chdir
- use LED constants from PYBv4 onwards
- set the FatFs partition number when initialising VFS object
- fix stack pointer initialisation for F411 and F429 boards
- README: add paragraph about building mpy-cross
- on boot, mount all available partitions of the SD card
- main: put /sd directory before /flash in sys.path
- pin: add C-level pin ioctl method
- modmachine: add machine.Signal type
- main: guard init_sdcard_fs with MICROPY_HW_HAS_SDCARD
- pendsv: fill in comments about what the stack contains
- initial implementation of multithreading, currently disabled
- main: use _estack value to initialise stack extents
- fix build issue when MICROPY_PY_THREAD is disabled
- mpconfigport.h: enable MICROPY_PY_BUILTINS_POW3 option
- on HardFault, print stack pointer and do a stack dump
- add pyb.fault_debug() function, to control hard-fault behaviour
- use MICROPY_EVENT_POLL_HOOK instead of __WFI where appropriate
- add ability to skip booting from SD card via /flash/SKIPSD file
- Makefile: drop use of -mabi=aapcs-linux; link libgcc by default
- boards: for STM32F411DISC, change I2C pin according to datasheet
- implement a proper thread scheduler
- use generic interrupt char code
- main: remove unnecessary header includes
- use mp_hal_delay_ms instead of HAL_Delay
- rename sys_tick ticks/delay functions to corresp. mp_hal ones
- modpyb: use utime ticks ms/us functions instead of custom ones
- modnwcc3k: add include for mp_hal_delay_ms
- mphalport: get ticks_cpu() working on F7 MCUs
- main: allocate flash's VFS struct on the heap to trace root ptrs
- enable micropython.schedule()
- pendsv: disable interrupts during a thread switch
- irq: shift IRQ priorities of TIM and EXTINT to be above PENDSV
- pybthread: allow interrupts to work during lock/unlock of mutex
- systick: make mp_hal_delay_ms release the GIL when sleeping
- boards: fix alt-func config for PA5 of STM32F767
- board: fix existing and add more pin defs for NUCLEO_F767ZI
- spi: clean and/or invalidate D-cache before SPI DMA transfers
- hal: for F7 MCUs, expose DMA_CalcBaseAndBitshift function
- dma: fix reinitialisation of DMA on F7 MCUs, following F4
- update to use size_t for tuple/list accessors
- update for changes to mp_obj_str_get_data
- spi: increase SPI transfer timeout, proportional to num bytes
- support SDMMC alternate functions in pin generation
- sdcard: add support for SDMMC2 on F7 MCUs
- boards: update F76x alternate function table to add SDMMC2
- boards/STM32F769DISC: get SD card working by using SDMMC2
- boards/STM32F769DISC: fix user switch pin, and document stlink
- boards: remove F769 alt function table, it's same as for F767
- dma: don't include SDMMC2 struct if SDMMC2 is not available
- move L4/F7 I2C timing constants from mpconfigboard.h to i2c.c
- i2c: clean the cache so that I2C DMA works on F7 MCUs
- usbd_cdc_interface: increase in-endpoint timeout to 500ms
- usbd_cdc_interface: change CDC RX to use a circular buffer
- enable parsing of all Pin constructor args by machine.Signal
- timer: clear interrupt flag before setting callback
- convert all module and method tables to use MP_ROM macros
- modmachine: add machine.UART class, linking to pyb.UART
- modmachine: remove TODO comment that is now implemented
- add machine.Pin on/off methods
- add ilistdir in uos module
cc3200 port:
- convert to use builtin help function
- add implementations of mp_import_stat and builtin_open
- modusocket: remove deprecated socket.error
- convert to use new VFS sub-system and new ooFatFs library
- refactor "ticks" functions to use common extmod implementation
- move stoupper to ftp.c and define in terms of unichar_toupper
- use simplelink API instead of emulated BSD API
- remove util/std.h, can just use stdio.h instead
- mods/modwlan: remove unused header includes; simplify others
- mods/modwlan: make multi-threaded a proper compile-time option
- mods/modwlan: allow antenna diversity to be fully compiled out
- mods/modwlan: add int casts to silence compiler warnings
- remove remaining references to std.h
- move wlan socket glue functions from modwlan to modusocket
- convert to using uPy internal errno numbers
- when raising OSError's use MP_Exxx as arg instead of a string
- enable uerrno module with short, custom list of error codes
- mods/modusocket: init vars to 0 to silence compiler warnings
- remove socket.timeout class, use OSError(ETIMEDOUT) instead
- moduos: remove uos.sep, as it's strictly optional
- mptask: allocate flash VFS struct on the heap to trace root ptrs
- mods/modutime: use generic sleep_ms and sleep_us implementations
- update to use size_t for tuple/list accessors
- update for changes to mp_obj_str_get_data
- mods/pybi2c: raise OSError if readfrom_mem fails to write addr
- modmachine: return frequency value directly, like other ports
- pybuart: make parity specifications consistent with HW API
- mods/pybi2c: make machine.I2C constructor/init conform to HW API
- mods/pybi2c: make readfnom_mem_into/writeto_mem return None
- mods/pybpin: remove toggle() method
teensy port:
- convert to use builtin help function
- main: remove unnecessary header includes
- lexerfrozen: make mp_lexer_new_from_file raise an exception
esp8266 port:
- convert to use builtin help function
- factor out common linker code to esp8266_common.ld
- switch to use OO version of FatFs library
- change to use new generic VFS sub-system
- fatfs_port: include new oofatfs header
- machine_pin: implement pin ioctl protocol
- modmachine: add Signal class
- mpconfigport.h: remove obsolete MICROPY_FATFS_VOLUMES config
- uart: add support for polling uart device
- moduos: populate release field of uname in case it was GC'd
- mpconfigport.h: enable help('modules') feature
- update lexer constructors so they can raise exceptions
- only execute main.py if in friendly REPL mode
- enable micropython.schedule() with locking in pin callback
- change machine.Timer callback to soft callback
- machine_pin: add "hard" parameter to pin.irq, soft by default
- machine_pin: make pin.irq arguments positional
- machine_pin: fix memset size for zeroing of pin_irq_is_hard
- machine_pin: fix pin.irq() to work when all args are keywords
- modesp: use mp_obj_str_get_str instead of mp_obj_str_get_data
- modesp: remove long-obsolete and unused espconn bindings
- update to use size_t for tuple/list accessors
- update for changes to mp_obj_str_get_data
- remove unused entry in port root pointers
- README: replace reference of alpha status to beta status
- README: add notice about 512K version
- change default settings to mount flash at root dir
- esp8266.ld, esp8266_ota.ld: grow main firmware size by 32KB
- modesp: flash_user_start: Use value from linker script
- modules/flashbdev: reserve one sector for native code storage
- scripts: move drivers/modules to modules/ (frozen bytecode)
- scripts: move initsetup & port_diag tools to modules/
- ets_alt_task.c: prevent spurious large increment of ticks_ms()
- modnetwork: in connect, fix potential buffer overflows
- machine_uart: add uart.any() method
- modules: mount filesystem at root when creating for first time
- mpconfigport.h: remove duplicate link to lwip module
- rename machine.Pin high/low methods to on/off
- add ilistdir in uos module
zephyr port:
- help: update n_args param type to size_t
- remove deprecated .mdef file
- add separate Zephyr config for "minimal" build
- enable SLIP networking for the default build
- convert to use builtin help function
- make sure that correct Zephyr config is used for "minimal" build
- allow to have per-board Zephyr config fragments
- prj_frdm_k64f.conf: add, enable Ethernet support
- Makefile.zephyr: support and default to networked (SLIP) QEMU
- README: describe many gotchas of networked builds
- enable IPv6 networking in addition to IPv4
- add qemu_cortex_m3 config fragment
- main: don't unconditionally dump stats on each GC
- README: network startup issues with frdm_k64f resolved
- modzephyr: add a module for Zephyr-specific things
- modzephyr: fix typo in identifier
- make sure that generated prj.conf is updated only on content changes
- move "minimal" configuration building to a separate wrapper script
- main: nlr_jump_fail: Fix noreturn warning
- main: remove unused __fatal_error()
- main: move lexer constructor to within NLR handler block
- zephyr_getchar: use native k_sem instead of legacy nano_sem
- prj_base.conf: disable legacy kernel compatibility
- prj_base.conf: enable TCP (and UDP explicitly)
- Makefile: rework to use modern, official build integration
- Makefile: add workaround (fix?) for broken builds for DTS targets
- fix NLR segfault in minimal build
- modusocket: initial version of usocket module for Zephyr
- integrate modusocket into build
- modusocket: implement bind() and connect()
- modusocket: implement send()
- modusocket: implement recv() for UDP sockets
- modusocket: implement recv() for TCP sockets
- prj_base.conf: add config for net_buf logging
- modusocket: be sure to use MP_OBJ_FROM_PTR
- modusocket: factor out socket_new() function
- zephyr_getchar: explicitly yield to other threads on char availability
- Makefile: add "test" target, runs testsuite in QEMU
- modusocket: factor out "extended k_fifo API"
- modusocket: implement listen()
- modusocket: socket_bind: Don't set recv callback on STREAM sockets
- modusocket: implement accept()
- mpconfigport.h: fix build if usocket module is disabled
- modmachine: add Signal class
- machine_pin: implement pin protocol for machine.Signal support
- modusocket: call net_nbuf_print_frags() in recv callback if DEBUG > 1
- modusocket: strip packet header right in the receive callback
- modmachine: implement machine.reset()
- main: configure IPv4 netmask and gateway to allow Internet access
- add 96b_carbon configuration
- modusocket: refactor send() into stream write() method
- modusocket: enable stream write() method
- modusocket: refactor recv() into stream read() method
- modusocket: add read/readline/readinto stream methods
- modusocket: sock_read: Check socket status only at the start of packet
- modusocket: add dummy makefile() implementation
- Makefile: add debugserver Zephyr target
- mpconfigport.h: enable line number information for scripts
- main: remove superfluous include
- modusocket: add dummy setsockopt() implementation
- modusocket: add SOL_SOCKET and SO_REUSEADDR constants
- prj_qemu_x86.conf: bump RAM size to 320K
- README: update to require Zephyr 1.8
- modusocket: wrap pkt_get_info() call
- modusocket: update for net_pkt refactor
- modusocket: switch to net_pkt_append() returning length
- modusocket: if there're no packets in recv_q, cancel waiter
- modusocket: implement getaddrinfo()
- modusocket: first step to switch to alternative FIFO processing
- modusocket: get rid of cur_pkt object member
- main: check default netif before applying operations to it
- modusocket: getaddrinfo: Use RAISE_ERRNO for proper error decoding
- modusocket: getaddrinfo: Raise OSError on resolution timeout, etc
- modusocket: use DEBUG_PRINT macro name as other modules do
- rename machine.Pin high/low methods to on/off
- don't send more than MTU allows
- modusocket: handle a case when recv_q is empty when EOF is signaled
pic16bit port:
- main: make nlr_jump_fail never return
- main: make mp_lexer_new_from_file raise an exception
README:
- explicitly mention "await" support, and formatting for keywords
- add link to docs.micropython.org
- describe extmod/ dir
- change Travis & Coveralls badges to not use link references
travis:
- unconditionally run coveralls analysis, even if others failed
- change an stmhal rule to build PYBV11 instead of default PYBV10
gitattributes:
- add .mpy files to list of binary files
- remove obsolete lines
docs:
- fix some minor spelling mistakes
- add documentation for lcd160cr module
- pyboard/tutorial: add tutorial for LCD160CR
- library/lcd160cr: fix set_brightness range, should be 0..31
- machine.Timer: move WiPy adhoc parts to its documentation
- machine: add explicit note on machine module level and scope
- usocket: clarify exceptions used
- usocket: elaborate "Constants" section
- usocket: clarify description of various methods
- usocket: dedent Methods section
- uio: describe differences between uPy an CPy stream hierarchy
- conf.py: add myself as a copyright holder on the docs
- uio: typo fixes/lexical improvements
- pyboard/tutorial/lcd160cr_skin: fix typo, get_touched->get_touch
- for LCD160CR driver and tutorial, add link to positioning image
- esp8266/tutorial: specify the baudrate in picocom example command
- add M-logo as favicon
- library/pyb.Pin: minor typo fix, B6 should be A0
- library/machine: make separate TOC for WiPy vs non-WiPy
- uos: remove mention of uos.sep
- library/lcd160cr: mention the valid values for set_power() method
- modify Makefile and indexes to generate cPy-differences pages
- uhashlib: provide port-neutral description
- Makefile: define and use PYTHON as the interpreter for CPYDIFF
- machine: fix formatting of Constants section
- library/lcd160cr: add note about supported JPEG format/encodings
- library: add framebuf documentation
- library/lcd160cr: add link to framebuf page
- esp8266/tutorial: update since esptool 1.3 added Python 3 support
- library/framebuf: fix typo in bit-width for MVLSB description
- library/machine.I2C: fix scan() doc to match implementation
- library/btree: add btree module docs
- utime: de-conditionalize description of sleep_ms() and friends
- uos: de-conditionalize statvfs() description
- machine.SPI: remove outdated wipy chunk
- machine.Pin: move wipy-specific details to its own docs
- machine.Pin: move wipy-specific methods to its docs
- esp8266/general: start explicit "Known Issues", mentioned RTC inaccuracy
- library/builtins: int: Add notice on byteorder param for to/from_bytes
- library/machine.UART: remove some conditionals
- utime: deconditionalize description of sleep()
- usocket: deconditionalize
- uhashlib: deconditionalize
- esp8266/tutorial/intro: reword section on flash size requirement
- library/micropython: deconditionalize
- library/uos: urandom: Generalize description
- library/ussl: deconditionalize, wipy notes moved to its documentation
- machine.UART: deconditionalize normal methods
- machine: move machine.main() misnomer to wipy's known issues
- library/machine: typo fix in machine_callbacks section
- library/machine.UART: remove pyboard-specific section
- wipy/quickref: update reference for change to I2C API
- wipy/general: add section about specifics of I2C implementation
- library/machine.I2C: deconditionalise all methods
- library/machine.*: add cross-reference label to individual classes
- esp8266/quickref: add links from quickref page to machine classes
- library/machine.I2C: remove WiPy-specific return values
- library/machine.SPI: fix formatting of bullet list to stop warning
- library/uos: add description of uos.ilistdir() function
- machine.Pin: there's no toggle() method in MicroPython hardware API
- machine.Signal: add initial draft description of Signal class
- library/index: add important summary of the intro section as warning
- change single occurrence of "Micropython" to "MicroPython"
- library/micropython: document the newer micropython functions
- library/machine.UART: update and improve uart.any() docs
- library/machine.Pin: remove .id() method and .board class attr
examples:
- hwapi: use Signal for inverted LED on ESP-12
- hwapi: consistently use Signal class to define LEDs
- button_reaction: update for time_pulse_us() no longer raising exc
- hwapi: add hwconfig_pyboard.py for pyboard
- hwapi: be sure to import Signal when it's used
- hwapi/soft_pwm: use Signal on()/off() methods
- embedding/README: convert to markdown, grammar and clarity fixes
- embedding: place lexer constructor within NLR handler block
- hwapi: add config for Zephyr port of 96Boards Carbon
- hwapi/hwconfig*: use inline Signal() args where possible
- hwapi/soft_pwm2_uasyncio: update for call_later_ms()
Diffstat (limited to 'esp8266')
32 files changed, 491 insertions, 1558 deletions
diff --git a/esp8266/Makefile b/esp8266/Makefile index 1d50a0fb31..a3da9d3986 100644 --- a/esp8266/Makefile +++ b/esp8266/Makefile @@ -25,9 +25,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 @@ -41,7 +38,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 @@ -108,7 +105,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 \ @@ -128,14 +125,13 @@ LIB_SRC_C = $(addprefix lib/,\ netutils/netutils.c \ timeutils/timeutils.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/,\ diff --git a/esp8266/README.md b/esp8266/README.md index 54591fcc13..897bb47377 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 ----------- @@ -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 a6a4b930bb..deeb82b456 100644 --- a/esp8266/esp8266.ld +++ b/esp8266/esp8266.ld @@ -5,301 +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 */ - - *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 2bffcab80d..0ae663db11 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 0000000000..bc983df700 --- /dev/null +++ b/esp8266/esp8266_common.ld @@ -0,0 +1,300 @@ +/* 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 */ + + *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 aceeb25a51..604480a0a9 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 f5e284fde6..7ecc7776aa 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/ets_alt_task.c b/esp8266/ets_alt_task.c index 6434f23660..ff7dba1869 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 9c84f04e45..02384f6055 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 5370ee71ea..2035cdd6cb 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 3fc62399e7..6fb84bb74e 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 e10b2cfb79..385551578e 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 8c1fe0779c..019b705ba2 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" diff --git a/esp8266/machine_uart.c b/esp8266/machine_uart.c index 9bc6422cc7..4d9f343db1 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 da37706fcd..e3188dfe40 100644 --- a/esp8266/main.c +++ b/esp8266/main.c @@ -32,6 +32,7 @@ #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/mp-readline/readline.h" @@ -64,7 +65,9 @@ STATIC void mp_reset(void) { #if MICROPY_MODULE_FROZEN pyexec_frozen_module("_boot.py"); pyexec_file("boot.py"); - pyexec_file("main.py"); + if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) { + pyexec_file("main.py"); + } #endif } @@ -109,34 +112,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 b7ce122b17..5eaae27d6a 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 "uart.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); @@ -834,10 +359,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 a5073d96c0..c26c633967 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 1d8a02bc9b..eb9d75e284 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 c200b3d3f9..81eb20dd63 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 41b7c0485c..41b7c0485c 100644 --- a/esp8266/scripts/apa102.py +++ b/esp8266/modules/apa102.py diff --git a/esp8266/scripts/dht.py b/esp8266/modules/dht.py index 9a69e7e07e..9a69e7e07e 100644 --- a/esp8266/scripts/dht.py +++ b/esp8266/modules/dht.py diff --git a/esp8266/modules/flashbdev.py b/esp8266/modules/flashbdev.py index 8f8df0b640..40ba655c64 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 3930089db6..af78dfad51 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 b13424d7d8..b13424d7d8 100644 --- a/esp8266/scripts/neopixel.py +++ b/esp8266/modules/neopixel.py diff --git a/esp8266/scripts/ntptime.py b/esp8266/modules/ntptime.py index a97e08e60d..a97e08e60d 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 ef8800355a..ef8800355a 100644 --- a/esp8266/scripts/port_diag.py +++ b/esp8266/modules/port_diag.py diff --git a/esp8266/moduos.c b/esp8266/moduos.c index e9c4c3e8cc..807d2e18a5 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 2adb6c563b..bdeb3bb453 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 5ba153ce5f..c286bdcdd9 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) @@ -38,6 +39,9 @@ #define MICROPY_PY_BUILTINS_SLICE (1) #define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) #define MICROPY_PY_BUILTINS_PROPERTY (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) @@ -69,6 +73,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) @@ -92,12 +97,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) @@ -115,8 +119,6 @@ // 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) @@ -138,9 +140,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 }, @@ -155,7 +161,6 @@ extern const struct _mp_obj_module_t onewire_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 }, \ @@ -175,7 +180,6 @@ extern const struct _mp_obj_module_t onewire_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 d1d6025793..322fb4151a 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 diff --git a/esp8266/uart.c b/esp8266/uart.c index 001a9c673c..6c1f9e095d 100644 --- a/esp8266/uart.c +++ b/esp8266/uart.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/uart.h b/esp8266/uart.h index 2b97683ff8..f6850c42db 100644 --- a/esp8266/uart.h +++ b/esp8266/uart.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_ |