initial v1.19.1 merge; not compiled yet
This commit is contained in:
commit
0d4bc8c163
@ -1,3 +1,15 @@
|
|||||||
|
#all: Reformat remaining C code that doesn't have a space after a comma.
|
||||||
|
5b700b0af90591d6b1a2c087bb8de6b7f1bfdd2d
|
||||||
|
|
||||||
|
# ports: Reformat more C and Python source code.
|
||||||
|
5c32111fa0e31e451b0f1666bdf926be2fdfd82c
|
||||||
|
|
||||||
|
# all: Update Python formatting to latest Black version 22.1.0.
|
||||||
|
ab2923dfa1174dc177f0a90cb00a7e4ff87958d2
|
||||||
|
|
||||||
|
# all: Update Python formatting to latest Black version 21.12b0.
|
||||||
|
3770fab33449a5dadf8eb06edfae0767e75320a6
|
||||||
|
|
||||||
# tools/gen-cpydiff.py: Fix formatting of doc strings for new Black.
|
# tools/gen-cpydiff.py: Fix formatting of doc strings for new Black.
|
||||||
0f78c36c5aa458a954eed39a46942209107a553e
|
0f78c36c5aa458a954eed39a46942209107a553e
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
:mod:`array` -- arrays of numeric data
|
:mod:`array` -- arrays of numeric data
|
||||||
=======================================
|
======================================
|
||||||
|
|
||||||
.. module:: array
|
.. module:: array
|
||||||
:synopsis: efficient arrays of numeric data
|
:synopsis: efficient arrays of numeric data
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:array`.
|
|see_cpython_module| :mod:`python:array`.
|
||||||
|
|
||||||
Supported format codes: ``b``, ``B``, ``h``, ``H``, ``i``, ``I``, ``l``,
|
Supported format codes: ``b``, ``B``, ``h``, ``H``, ``i``, ``I``, ``l``,
|
||||||
``L``, ``q``, ``Q``, ``f``, ``d`` (the latter 2 depending on the
|
``L``, ``q``, ``Q``, ``f``, ``d`` (the latter 2 depending on the
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
:mod:`binascii` -- binary/ASCII conversions
|
:mod:`binascii` -- binary/ASCII conversions
|
||||||
============================================
|
===========================================
|
||||||
|
|
||||||
.. module:: binascii
|
.. module:: binascii
|
||||||
:synopsis: binary/ASCII conversions
|
:synopsis: binary/ASCII conversions
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:binascii`.
|
|see_cpython_module| :mod:`python:binascii`.
|
||||||
|
|
||||||
This module implements conversions between binary data and various
|
This module implements conversions between binary data and various
|
||||||
encodings of it in ASCII form (in both directions).
|
encodings of it in ASCII form (in both directions).
|
||||||
@ -31,11 +31,11 @@ Functions
|
|||||||
Conforms to `RFC 2045 s.6.8 <https://tools.ietf.org/html/rfc2045#section-6.8>`_.
|
Conforms to `RFC 2045 s.6.8 <https://tools.ietf.org/html/rfc2045#section-6.8>`_.
|
||||||
Returns a bytes object.
|
Returns a bytes object.
|
||||||
|
|
||||||
.. function:: b2a_base64(data)
|
.. function:: b2a_base64(data, *, newline=True)
|
||||||
|
|
||||||
Encode binary data in base64 format, as in `RFC 3548
|
Encode binary data in base64 format, as in `RFC 3548
|
||||||
<https://tools.ietf.org/html/rfc3548.html>`_. Returns the encoded data
|
<https://tools.ietf.org/html/rfc3548.html>`_. Returns the encoded data
|
||||||
followed by a newline character, as a bytes object.
|
followed by a newline character if ``newline``is true, as a bytes object.
|
||||||
|
|
||||||
.. function:: crc32(data, value=0, /)
|
.. function:: crc32(data, value=0, /)
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
:synopsis: simple BTree database
|
:synopsis: simple BTree database
|
||||||
|
|
||||||
The ``btree`` module implements a simple key-value database using external
|
The ``btree`` module implements a simple key-value database using external
|
||||||
storage (disk files, or in general case, a random-access ``stream``). Keys are
|
storage (disk files, or in general case, a random-access `stream`). Keys are
|
||||||
stored sorted in the database, and besides efficient retrieval by a key
|
stored sorted in the database, and besides efficient retrieval by a key
|
||||||
value, a database also supports efficient ordered range scans (retrieval
|
value, a database also supports efficient ordered range scans (retrieval
|
||||||
of values with the keys in a given range). On the application interface
|
of values with the keys in a given range). On the application interface
|
||||||
@ -80,7 +80,7 @@ Functions
|
|||||||
|
|
||||||
.. function:: open(stream, *, flags=0, pagesize=0, cachesize=0, minkeypage=0)
|
.. function:: open(stream, *, flags=0, pagesize=0, cachesize=0, minkeypage=0)
|
||||||
|
|
||||||
Open a database from a random-access ``stream`` (like an open file). All
|
Open a database from a random-access `stream` (like an open file). All
|
||||||
other parameters are optional and keyword-only, and allow to tweak advanced
|
other parameters are optional and keyword-only, and allow to tweak advanced
|
||||||
parameters of the database operation (most users will not need them):
|
parameters of the database operation (most users will not need them):
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ Functions and types
|
|||||||
|
|
||||||
.. class:: bytes()
|
.. class:: bytes()
|
||||||
|
|
||||||
|see_cpython| `bytes`.
|
|see_cpython| `python:bytes`.
|
||||||
|
|
||||||
.. function:: callable()
|
.. function:: callable()
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ Functions and types
|
|||||||
|
|
||||||
.. class:: frozenset()
|
.. class:: frozenset()
|
||||||
|
|
||||||
`frozenset()` is not enabled on non-Express CircuitPython boards.
|
`frozenset()` is not enabled on the smallest CircuitPython boards for space reasons.
|
||||||
|
|
||||||
.. function:: getattr()
|
.. function:: getattr()
|
||||||
|
|
||||||
@ -88,12 +88,12 @@ Functions and types
|
|||||||
|
|
||||||
.. classmethod:: from_bytes(bytes, byteorder)
|
.. classmethod:: from_bytes(bytes, byteorder)
|
||||||
|
|
||||||
In CircuitPython, ``byteorder`` parameter must be positional (this is
|
In CircuitPython, the ``byteorder`` parameter must be positional (this is
|
||||||
compatible with CPython).
|
compatible with CPython).
|
||||||
|
|
||||||
.. method:: to_bytes(size, byteorder)
|
.. method:: to_bytes(size, byteorder)
|
||||||
|
|
||||||
In CircuitPython, ``byteorder`` parameter must be positional (this is
|
In CircuitPython, the ``byteorder`` parameter must be positional (this is
|
||||||
compatible with CPython).
|
compatible with CPython).
|
||||||
|
|
||||||
.. function:: isinstance()
|
.. function:: isinstance()
|
||||||
@ -138,7 +138,7 @@ Functions and types
|
|||||||
|
|
||||||
.. function:: reversed()
|
.. function:: reversed()
|
||||||
|
|
||||||
`reversed()` is not enabled on non-Express CircuitPython boards.
|
`reversed()` is not enabled on the smallest CircuitPython boards for space reasons.
|
||||||
|
|
||||||
.. function:: round()
|
.. function:: round()
|
||||||
|
|
||||||
@ -224,10 +224,14 @@ Exceptions
|
|||||||
|
|
||||||
.. exception:: SystemExit
|
.. exception:: SystemExit
|
||||||
|
|
||||||
|
|see_cpython| `python:SystemExit`.
|
||||||
|
|
||||||
.. exception:: TimeoutError
|
.. exception:: TimeoutError
|
||||||
|
|
||||||
.. exception:: TypeError
|
.. exception:: TypeError
|
||||||
|
|
||||||
|
|see_cpython| `python:TypeError`.
|
||||||
|
|
||||||
.. exception:: UnicodeError
|
.. exception:: UnicodeError
|
||||||
|
|
||||||
.. exception:: ValueError
|
.. exception:: ValueError
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
:mod:`collections` -- collection and container types
|
:mod:`collections` -- collection and container types
|
||||||
=====================================================
|
====================================================
|
||||||
|
|
||||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
**Limitations:** Not implemented on the smallest CircuitPython boards for space reasons.
|
||||||
|
|
||||||
.. module:: collections
|
.. module:: collections
|
||||||
:synopsis: collection and container types
|
:synopsis: collection and container types
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:collections`.
|
|see_cpython_module| :mod:`python:collections`.
|
||||||
|
|
||||||
This module implements advanced collection and container types to
|
This module implements advanced collection and container types to
|
||||||
hold/accumulate various objects.
|
hold/accumulate various objects.
|
||||||
@ -14,7 +14,7 @@ hold/accumulate various objects.
|
|||||||
Classes
|
Classes
|
||||||
-------
|
-------
|
||||||
|
|
||||||
.. function:: deque(iterable, maxlen[, flags])
|
.. class:: deque(iterable, maxlen[, flags])
|
||||||
|
|
||||||
Deques (double-ended queues) are a list-like container that support O(1)
|
Deques (double-ended queues) are a list-like container that support O(1)
|
||||||
appends and pops from either side of the deque. New deques are created
|
appends and pops from either side of the deque. New deques are created
|
||||||
@ -59,7 +59,7 @@ Classes
|
|||||||
print(t1.name)
|
print(t1.name)
|
||||||
assert t2.name == t2[1]
|
assert t2.name == t2[1]
|
||||||
|
|
||||||
.. function:: OrderedDict(...)
|
.. class:: OrderedDict(...)
|
||||||
|
|
||||||
``dict`` type subclass which remembers and preserves the order of keys
|
``dict`` type subclass which remembers and preserves the order of keys
|
||||||
added. When ordered dict is iterated over, keys/items are returned in
|
added. When ordered dict is iterated over, keys/items are returned in
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
.. module:: errno
|
.. module:: errno
|
||||||
:synopsis: system error codes
|
:synopsis: system error codes
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:errno`.
|
|see_cpython_module| :mod:`python:errno`.
|
||||||
|
|
||||||
This module provides access to symbolic error codes for `OSError` exception.
|
This module provides access to symbolic error codes for `OSError` exception.
|
||||||
A particular inventory of codes depends on :term:`MicroPython port`.
|
The codes available may vary per CircuitPython build.
|
||||||
|
|
||||||
Constants
|
Constants
|
||||||
---------
|
---------
|
||||||
@ -15,14 +15,13 @@ Constants
|
|||||||
.. data:: EEXIST, EAGAIN, etc.
|
.. data:: EEXIST, EAGAIN, etc.
|
||||||
|
|
||||||
Error codes, based on ANSI C/POSIX standard. All error codes start with
|
Error codes, based on ANSI C/POSIX standard. All error codes start with
|
||||||
"E". As mentioned above, inventory of the codes depends on
|
"E". Errors are usually accessible as ``exc.errno``
|
||||||
:term:`MicroPython port`. Errors are usually accessible as ``exc.args[0]``
|
|
||||||
where ``exc`` is an instance of `OSError`. Usage example::
|
where ``exc`` is an instance of `OSError`. Usage example::
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.mkdir("my_dir")
|
os.mkdir("my_dir")
|
||||||
except OSError as exc:
|
except OSError as exc:
|
||||||
if exc.args[0] == errno.EEXIST:
|
if exc.errno == errno.EEXIST:
|
||||||
print("Directory already exists")
|
print("Directory already exists")
|
||||||
|
|
||||||
.. data:: errorcode
|
.. data:: errorcode
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
:mod:`gc` -- control the garbage collector
|
:mod:`gc` -- control the garbage collector
|
||||||
==========================================
|
==========================================
|
||||||
|
|
||||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
|
||||||
|
|
||||||
.. module:: gc
|
.. module:: gc
|
||||||
:synopsis: control the garbage collector
|
:synopsis: control the garbage collector
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:gc`.
|
|see_cpython_module| :mod:`python:gc`.
|
||||||
|
|
||||||
Functions
|
Functions
|
||||||
---------
|
---------
|
||||||
@ -63,6 +61,6 @@ Functions
|
|||||||
.. admonition:: Difference to CPython
|
.. admonition:: Difference to CPython
|
||||||
:class: attention
|
:class: attention
|
||||||
|
|
||||||
This function is a a MicroPython extension. CPython has a similar
|
This function is a MicroPython extension. CPython has a similar
|
||||||
function - ``set_threshold()``, but due to different GC
|
function - ``set_threshold()``, but due to different GC
|
||||||
implementations, its signature and semantics are different.
|
implementations, its signature and semantics are different.
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
.. module:: heapq
|
.. module:: heapq
|
||||||
:synopsis: heap queue algorithm
|
:synopsis: heap queue algorithm
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:heapq`.
|
|see_cpython_module| :mod:`python:heapq`.
|
||||||
|
|
||||||
This module implements the
|
This module implements the
|
||||||
`min heap queue algorithm <https://en.wikipedia.org/wiki/Heap_%28data_structure%29>`_.
|
`min heap queue algorithm <https://en.wikipedia.org/wiki/Heap_%28data_structure%29>`_.
|
||||||
|
@ -15,7 +15,7 @@ CircuitPython's long-term goal is that code written in CircuitPython
|
|||||||
using Python standard libraries will be runnable on CPython without changes.
|
using Python standard libraries will be runnable on CPython without changes.
|
||||||
|
|
||||||
These libraries are not enabled on CircuitPython builds with
|
These libraries are not enabled on CircuitPython builds with
|
||||||
limited flash memory, usually on non-Express builds:
|
limited flash memory:
|
||||||
``binascii``, ``errno``, ``json``, ``re``.
|
``binascii``, ``errno``, ``json``, ``re``.
|
||||||
|
|
||||||
These libraries are not currently enabled in any CircuitPython build, but may be in the future:
|
These libraries are not currently enabled in any CircuitPython build, but may be in the future:
|
||||||
@ -42,21 +42,6 @@ Omitted functions in the ``string`` library
|
|||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
|
|
||||||
A few string operations are not enabled on small builds
|
A few string operations are not enabled on small builds
|
||||||
(usually non-Express), due to limited flash memory:
|
due to limited flash memory:
|
||||||
``string.center()``, ``string.partition()``, ``string.splitlines()``,
|
``string.center()``, ``string.partition()``, ``string.splitlines()``,
|
||||||
``string.reversed()``.
|
``string.reversed()``.
|
||||||
|
|
||||||
|
|
||||||
CircuitPython/MicroPython-specific libraries
|
|
||||||
--------------------------------------------
|
|
||||||
|
|
||||||
Functionality specific to the CircuitPython/MicroPython implementation is available in
|
|
||||||
the following libraries. These libraries may change significantly or be removed in future
|
|
||||||
versions of CircuitPython.
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 1
|
|
||||||
|
|
||||||
btree.rst
|
|
||||||
framebuf.rst
|
|
||||||
micropython.rst
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
:mod:`io` -- input/output streams
|
:mod:`io` -- input/output streams
|
||||||
==================================
|
=================================
|
||||||
|
|
||||||
.. module:: io
|
.. module:: io
|
||||||
:synopsis: input/output streams
|
:synopsis: input/output streams
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:io`.
|
|see_cpython_module| :mod:`python:io`.
|
||||||
|
|
||||||
This module contains additional types of ``stream`` (file-like) objects
|
This module contains additional types of ``stream`` (file-like) objects
|
||||||
and helper functions.
|
and helper functions.
|
||||||
@ -112,3 +112,20 @@ Classes
|
|||||||
.. method:: getvalue()
|
.. method:: getvalue()
|
||||||
|
|
||||||
Get the current contents of the underlying buffer which holds data.
|
Get the current contents of the underlying buffer which holds data.
|
||||||
|
|
||||||
|
.. class:: StringIO(alloc_size)
|
||||||
|
:noindex:
|
||||||
|
.. class:: BytesIO(alloc_size)
|
||||||
|
:noindex:
|
||||||
|
|
||||||
|
Create an empty `StringIO`/`BytesIO` object, preallocated to hold up
|
||||||
|
to *alloc_size* number of bytes. That means that writing that amount
|
||||||
|
of bytes won't lead to reallocation of the buffer, and thus won't hit
|
||||||
|
out-of-memory situation or lead to memory fragmentation. These constructors
|
||||||
|
are a MicroPython extension and are recommended for usage only in special
|
||||||
|
cases and in system-level libraries, not for end-user applications.
|
||||||
|
|
||||||
|
.. admonition:: Difference to CPython
|
||||||
|
:class: attention
|
||||||
|
|
||||||
|
These constructors are a MicroPython extension.
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
:mod:`json` -- JSON encoding and decoding
|
:mod:`json` -- JSON encoding and decoding
|
||||||
==========================================
|
=========================================
|
||||||
|
|
||||||
.. module:: json
|
.. module:: json
|
||||||
:synopsis: JSON encoding and decoding
|
:synopsis: JSON encoding and decoding
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:json`.
|
|see_cpython_module| :mod:`python:json`.
|
||||||
|
|
||||||
This modules allows to convert between Python objects and the JSON
|
This modules allows to convert between Python objects and the JSON
|
||||||
data format.
|
data format.
|
||||||
@ -12,14 +12,20 @@ data format.
|
|||||||
Functions
|
Functions
|
||||||
---------
|
---------
|
||||||
|
|
||||||
.. function:: dump(obj, stream)
|
.. function:: dump(obj, stream, separators=None)
|
||||||
|
|
||||||
Serialise ``obj`` to a JSON string, writing it to the given *stream*.
|
Serialise ``obj`` to a JSON string, writing it to the given *stream*.
|
||||||
|
|
||||||
.. function:: dumps(obj)
|
If specified, separators should be an ``(item_separator, key_separator)``
|
||||||
|
tuple. The default is ``(', ', ': ')``. To get the most compact JSON
|
||||||
|
representation, you should specify ``(',', ':')`` to eliminate whitespace.
|
||||||
|
|
||||||
|
.. function:: dumps(obj, separators=None)
|
||||||
|
|
||||||
Return ``obj`` represented as a JSON string.
|
Return ``obj`` represented as a JSON string.
|
||||||
|
|
||||||
|
The arguments have the same meaning as in `dump`.
|
||||||
|
|
||||||
.. function:: load(stream)
|
.. function:: load(stream)
|
||||||
|
|
||||||
Parse the given ``stream``, interpreting it as a JSON string and
|
Parse the given ``stream``, interpreting it as a JSON string and
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
:mod:`micropython` -- access and control MicroPython internals
|
:mod:`micropython` -- MicroPython extensions and internals
|
||||||
==============================================================
|
==========================================================
|
||||||
|
|
||||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
|
||||||
|
|
||||||
.. module:: micropython
|
.. module:: micropython
|
||||||
:synopsis: access and control MicroPython internals
|
:synopsis: access and control MicroPython internals
|
||||||
@ -11,7 +9,7 @@ Functions
|
|||||||
|
|
||||||
.. function:: const(expr)
|
.. function:: const(expr)
|
||||||
|
|
||||||
Used to declare that the expression is a constant so that the compile can
|
Used to declare that the expression is a constant so that the compiler can
|
||||||
optimise it. The use of this function should be as follows::
|
optimise it. The use of this function should be as follows::
|
||||||
|
|
||||||
from micropython import const
|
from micropython import const
|
||||||
@ -28,111 +26,3 @@ Functions
|
|||||||
provided as part of the :mod:`micropython` module mainly so that scripts can be
|
provided as part of the :mod:`micropython` module mainly so that scripts can be
|
||||||
written which run under both CPython and MicroPython, by following the above
|
written which run under both CPython and MicroPython, by following the above
|
||||||
pattern.
|
pattern.
|
||||||
|
|
||||||
.. function:: opt_level([level])
|
|
||||||
|
|
||||||
If *level* is given then this function sets the optimisation level for subsequent
|
|
||||||
compilation of scripts, and returns ``None``. Otherwise it returns the current
|
|
||||||
optimisation level.
|
|
||||||
|
|
||||||
The optimisation level controls the following compilation features:
|
|
||||||
|
|
||||||
- Assertions: at level 0 assertion statements are enabled and compiled into the
|
|
||||||
bytecode; at levels 1 and higher assertions are not compiled.
|
|
||||||
- Built-in ``__debug__`` variable: at level 0 this variable expands to ``True``;
|
|
||||||
at levels 1 and higher it expands to ``False``.
|
|
||||||
- Source-code line numbers: at levels 0, 1 and 2 source-code line number are
|
|
||||||
stored along with the bytecode so that exceptions can report the line number
|
|
||||||
they occurred at; at levels 3 and higher line numbers are not stored.
|
|
||||||
|
|
||||||
The default optimisation level is usually level 0.
|
|
||||||
|
|
||||||
.. function:: mem_info([verbose])
|
|
||||||
|
|
||||||
Print information about currently used memory. If the *verbose* argument
|
|
||||||
is given then extra information is printed.
|
|
||||||
|
|
||||||
The information that is printed is implementation dependent, but currently
|
|
||||||
includes the amount of stack and heap used. In verbose mode it prints out
|
|
||||||
the entire heap indicating which blocks are used and which are free.
|
|
||||||
|
|
||||||
.. function:: qstr_info([verbose])
|
|
||||||
|
|
||||||
Print information about currently interned strings. If the *verbose*
|
|
||||||
argument is given then extra information is printed.
|
|
||||||
|
|
||||||
The information that is printed is implementation dependent, but currently
|
|
||||||
includes the number of interned strings and the amount of RAM they use. In
|
|
||||||
verbose mode it prints out the names of all RAM-interned strings.
|
|
||||||
|
|
||||||
.. function:: stack_use()
|
|
||||||
|
|
||||||
Return an integer representing the current amount of stack that is being
|
|
||||||
used. The absolute value of this is not particularly useful, rather it
|
|
||||||
should be used to compute differences in stack usage at different points.
|
|
||||||
|
|
||||||
.. function:: heap_lock()
|
|
||||||
.. function:: heap_unlock()
|
|
||||||
.. function:: heap_locked()
|
|
||||||
|
|
||||||
Lock or unlock the heap. When locked no memory allocation can occur and a
|
|
||||||
``MemoryError`` will be raised if any heap allocation is attempted.
|
|
||||||
`heap_locked()` returns a true value if the heap is currently locked.
|
|
||||||
|
|
||||||
These functions can be nested, ie `heap_lock()` can be called multiple times
|
|
||||||
in a row and the lock-depth will increase, and then `heap_unlock()` must be
|
|
||||||
called the same number of times to make the heap available again.
|
|
||||||
|
|
||||||
Both `heap_unlock()` and `heap_locked()` return the current lock depth
|
|
||||||
(after unlocking for the former) as a non-negative integer, with 0 meaning
|
|
||||||
the heap is not locked.
|
|
||||||
|
|
||||||
If the REPL becomes active with the heap locked then it will be forcefully
|
|
||||||
unlocked.
|
|
||||||
|
|
||||||
Note: `heap_locked()` is not enabled on most ports by default,
|
|
||||||
requires ``MICROPY_PY_MICROPYTHON_HEAP_LOCKED``.
|
|
||||||
|
|
||||||
.. function:: kbd_intr(chr)
|
|
||||||
|
|
||||||
Set the character that will raise a `KeyboardInterrupt` exception. By
|
|
||||||
default this is set to 3 during script execution, corresponding to Ctrl-C.
|
|
||||||
Passing -1 to this function will disable capture of Ctrl-C, and passing 3
|
|
||||||
will restore it.
|
|
||||||
|
|
||||||
This function can be used to prevent the capturing of Ctrl-C on the
|
|
||||||
incoming stream of characters that is usually used for the REPL, in case
|
|
||||||
that stream is used for other purposes.
|
|
||||||
|
|
||||||
.. function:: schedule(func, arg)
|
|
||||||
|
|
||||||
Schedule the function *func* to be executed "very soon". The function
|
|
||||||
is passed the value *arg* as its single argument. "Very soon" means that
|
|
||||||
the MicroPython runtime will do its best to execute the function at the
|
|
||||||
earliest possible time, given that it is also trying to be efficient, and
|
|
||||||
that the following conditions hold:
|
|
||||||
|
|
||||||
- A scheduled function will never preempt another scheduled function.
|
|
||||||
- Scheduled functions are always executed "between opcodes" which means
|
|
||||||
that all fundamental Python operations (such as appending to a list)
|
|
||||||
are guaranteed to be atomic.
|
|
||||||
- A given port may define "critical regions" within which scheduled
|
|
||||||
functions will never be executed. Functions may be scheduled within
|
|
||||||
a critical region but they will not be executed until that region
|
|
||||||
is exited. An example of a critical region is a preempting interrupt
|
|
||||||
handler (an IRQ).
|
|
||||||
|
|
||||||
A use for this function is to schedule a callback from a preempting IRQ.
|
|
||||||
Such an IRQ puts restrictions on the code that runs in the IRQ (for example
|
|
||||||
the heap may be locked) and scheduling a function to call later will lift
|
|
||||||
those restrictions.
|
|
||||||
|
|
||||||
Note: If `schedule()` is called from a preempting IRQ, when memory
|
|
||||||
allocation is not allowed and the callback to be passed to `schedule()` is
|
|
||||||
a bound method, passing this directly will fail. This is because creating a
|
|
||||||
reference to a bound method causes memory allocation. A solution is to
|
|
||||||
create a reference to the method in the class constructor and to pass that
|
|
||||||
reference to `schedule()`.
|
|
||||||
|
|
||||||
There is a finite queue to hold the scheduled functions and `schedule()`
|
|
||||||
will raise a `RuntimeError` if the queue is full.
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
:mod:`re` -- simple regular expressions
|
:mod:`re` -- simple regular expressions
|
||||||
========================================
|
=======================================
|
||||||
|
|
||||||
.. module:: re
|
.. module:: re
|
||||||
:synopsis: regular expressions
|
:synopsis: regular expressions
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:re`.
|
|see_cpython_module| :mod:`python:re`.
|
||||||
|
|
||||||
This module implements regular expression operations. Regular expression
|
This module implements regular expression operations. Regular expression
|
||||||
syntax supported is a subset of CPython ``re`` module (and actually is
|
syntax supported is a subset of CPython ``re`` module (and actually is
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
:mod:`select` -- wait for events on a set of streams
|
:mod:`select` -- wait for events on a set of streams
|
||||||
====================================================
|
====================================================
|
||||||
|
|
||||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
|
||||||
|
|
||||||
.. module:: select
|
.. module:: select
|
||||||
:synopsis: wait for events on a set of streams
|
:synopsis: wait for events on a set of streams
|
||||||
|
|
||||||
@ -86,7 +84,7 @@ Methods
|
|||||||
.. method:: poll.ipoll(timeout=-1, flags=0, /)
|
.. method:: poll.ipoll(timeout=-1, flags=0, /)
|
||||||
|
|
||||||
Like :meth:`poll.poll`, but instead returns an iterator which yields a
|
Like :meth:`poll.poll`, but instead returns an iterator which yields a
|
||||||
``callee-owned tuples``. This function provides efficient, allocation-free
|
"callee-owned tuple". This function provides an efficient, allocation-free
|
||||||
way to poll on streams.
|
way to poll on streams.
|
||||||
|
|
||||||
If *flags* is 1, one-shot behaviour for events is employed: streams for
|
If *flags* is 1, one-shot behaviour for events is employed: streams for
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
:mod:`sys` -- system specific functions
|
:mod:`sys` -- system specific functions
|
||||||
========================================
|
=======================================
|
||||||
|
|
||||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
|
||||||
|
|
||||||
.. module:: sys
|
.. module:: sys
|
||||||
:synopsis: system specific functions
|
:synopsis: system specific functions
|
||||||
|
|
||||||
|see_cpython_module| :mod:`cpython:sys`.
|
|see_cpython_module| :mod:`python:sys`.
|
||||||
|
|
||||||
Functions
|
Functions
|
||||||
---------
|
---------
|
||||||
@ -35,6 +33,7 @@ Constants
|
|||||||
|
|
||||||
* *name* - string "circuitpython"
|
* *name* - string "circuitpython"
|
||||||
* *version* - tuple (major, minor, micro), e.g. (1, 7, 0)
|
* *version* - tuple (major, minor, micro), e.g. (1, 7, 0)
|
||||||
|
* *_mpy* - supported mpy file-format version (optional attribute)
|
||||||
|
|
||||||
This object is the recommended way to distinguish CircuitPython from other
|
This object is the recommended way to distinguish CircuitPython from other
|
||||||
Python implementations (note that it still may not exist in the very
|
Python implementations (note that it still may not exist in the very
|
||||||
@ -97,6 +96,12 @@ Constants
|
|||||||
If you need to check whether your program runs on CircuitPython (vs other
|
If you need to check whether your program runs on CircuitPython (vs other
|
||||||
Python implementation), use `sys.implementation` instead.
|
Python implementation), use `sys.implementation` instead.
|
||||||
|
|
||||||
|
.. data:: ps1
|
||||||
|
ps2
|
||||||
|
|
||||||
|
Mutable attributes holding strings, which are used for the REPL prompt. The defaults
|
||||||
|
give the standard Python prompt of ``>>>`` and ``...``.
|
||||||
|
|
||||||
.. data:: stderr
|
.. data:: stderr
|
||||||
|
|
||||||
Standard error ``stream``.
|
Standard error ``stream``.
|
||||||
@ -109,6 +114,14 @@ Constants
|
|||||||
|
|
||||||
Standard output ``stream``.
|
Standard output ``stream``.
|
||||||
|
|
||||||
|
.. data:: tracebacklimit
|
||||||
|
|
||||||
|
A mutable attribute holding an integer value which is the maximum number of traceback
|
||||||
|
entries to store in an exception. Set to 0 to disable adding tracebacks. Defaults
|
||||||
|
to 1000.
|
||||||
|
|
||||||
|
Note: this is not available on all ports.
|
||||||
|
|
||||||
.. data:: version
|
.. data:: version
|
||||||
|
|
||||||
Python language version that this implementation conforms to, as a string.
|
Python language version that this implementation conforms to, as a string.
|
||||||
|
@ -159,7 +159,7 @@ Glossary
|
|||||||
typically accessible on a host PC via USB.
|
typically accessible on a host PC via USB.
|
||||||
|
|
||||||
stream
|
stream
|
||||||
Also known as a "file-like object". An Python object which provides
|
Also known as a "file-like object". A Python object which provides
|
||||||
sequential read-write access to the underlying data. A stream object
|
sequential read-write access to the underlying data. A stream object
|
||||||
implements a corresponding interface, which consists of methods like
|
implements a corresponding interface, which consists of methods like
|
||||||
``read()``, ``write()``, ``readinto()``, ``seek()``, ``flush()``,
|
``read()``, ``write()``, ``readinto()``, ``seek()``, ``flush()``,
|
||||||
|
199
docs/reference/mpyfiles.rst
Normal file
199
docs/reference/mpyfiles.rst
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
.. _mpy_files:
|
||||||
|
|
||||||
|
MicroPython .mpy files
|
||||||
|
======================
|
||||||
|
|
||||||
|
MicroPython defines the concept of an .mpy file which is a binary container
|
||||||
|
file format that holds precompiled code, and which can be imported like a
|
||||||
|
normal .py module. The file ``foo.mpy`` can be imported via ``import foo``,
|
||||||
|
as long as ``foo.mpy`` can be found in the usual way by the import machinery.
|
||||||
|
Usually, each directory listed in ``sys.path`` is searched in order. When
|
||||||
|
searching a particular directory ``foo.py`` is looked for first and if that
|
||||||
|
is not found then ``foo.mpy`` is looked for, then the search continues in the
|
||||||
|
next directory if neither is found. As such, ``foo.py`` will take precedence
|
||||||
|
over ``foo.mpy``.
|
||||||
|
|
||||||
|
These .mpy files can contain bytecode which is usually generated from Python
|
||||||
|
source files (.py files) via the ``mpy-cross`` program. For some architectures
|
||||||
|
an .mpy file can also contain native machine code, which can be generated in
|
||||||
|
a variety of ways, most notably from C source code.
|
||||||
|
|
||||||
|
Versioning and compatibility of .mpy files
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
A given .mpy file may or may not be compatible with a given MicroPython system.
|
||||||
|
Compatibility is based on the following:
|
||||||
|
|
||||||
|
* Version of the .mpy file: the version of the file must match the version
|
||||||
|
supported by the system loading it.
|
||||||
|
|
||||||
|
* Sub-version of the .mpy file: if the .mpy file contains native machine code
|
||||||
|
then the sub-version of the file must match the version support by the
|
||||||
|
system loading it. Otherwise, if there is no native machine code in the .mpy
|
||||||
|
file, then the sub-version is ignored when loading.
|
||||||
|
|
||||||
|
* Small integer bits: the .mpy file will require a minimum number of bits in
|
||||||
|
a small integer and the system loading it must support at least this many
|
||||||
|
bits.
|
||||||
|
|
||||||
|
* Native architecture: if the .mpy file contains native machine code then
|
||||||
|
it will specify the architecture of that machine code and the system
|
||||||
|
loading it must support execution of that architecture's code.
|
||||||
|
|
||||||
|
If a MicroPython system supports importing .mpy files then the
|
||||||
|
``sys.implementation._mpy`` field will exist and return an integer which
|
||||||
|
encodes the version (lower 8 bits), features and native architecture.
|
||||||
|
|
||||||
|
Trying to import an .mpy file that fails one of the first four tests will
|
||||||
|
raise ``ValueError('incompatible .mpy file')``. Trying to import an .mpy
|
||||||
|
file that fails the native architecture test (if it contains native machine
|
||||||
|
code) will raise ``ValueError('incompatible .mpy arch')``.
|
||||||
|
|
||||||
|
If importing an .mpy file fails then try the following:
|
||||||
|
|
||||||
|
* Determine the .mpy version and flags supported by your MicroPython system
|
||||||
|
by executing::
|
||||||
|
|
||||||
|
import sys
|
||||||
|
sys_mpy = sys.implementation._mpy
|
||||||
|
arch = [None, 'x86', 'x64',
|
||||||
|
'armv6', 'armv6m', 'armv7m', 'armv7em', 'armv7emsp', 'armv7emdp',
|
||||||
|
'xtensa', 'xtensawin'][sys_mpy >> 10]
|
||||||
|
print('mpy version:', sys_mpy & 0xff)
|
||||||
|
print('mpy flags:', end='')
|
||||||
|
if arch:
|
||||||
|
print(' -march=' + arch, end='')
|
||||||
|
print()
|
||||||
|
|
||||||
|
* Check the validity of the .mpy file by inspecting the first two bytes of
|
||||||
|
the file. The first byte should be an uppercase 'M' and the second byte
|
||||||
|
will be the version number, which should match the system version from above.
|
||||||
|
If it doesn't match then rebuild the .mpy file.
|
||||||
|
|
||||||
|
* Check if the system .mpy version matches the version emitted by ``mpy-cross``
|
||||||
|
that was used to build the .mpy file, found by ``mpy-cross --version``.
|
||||||
|
If it doesn't match then recompile ``mpy-cross`` from the Git repository
|
||||||
|
checked out at the tag (or hash) reported by ``mpy-cross --version``.
|
||||||
|
|
||||||
|
* Make sure you are using the correct ``mpy-cross`` flags, found by the code
|
||||||
|
above, or by inspecting the ``MPY_CROSS_FLAGS`` Makefile variable for the
|
||||||
|
port that you are using.
|
||||||
|
|
||||||
|
The following table shows the correspondence between MicroPython release
|
||||||
|
and .mpy version.
|
||||||
|
|
||||||
|
=================== ============
|
||||||
|
MicroPython release .mpy version
|
||||||
|
=================== ============
|
||||||
|
v1.19 and up 6
|
||||||
|
v1.12 - v1.18 5
|
||||||
|
v1.11 4
|
||||||
|
v1.9.3 - v1.10 3
|
||||||
|
v1.9 - v1.9.2 2
|
||||||
|
v1.5.1 - v1.8.7 0
|
||||||
|
=================== ============
|
||||||
|
|
||||||
|
For completeness, the next table shows the Git commit of the main
|
||||||
|
MicroPython repository at which the .mpy version was changed.
|
||||||
|
|
||||||
|
=================== ========================================
|
||||||
|
.mpy version change Git commit
|
||||||
|
=================== ========================================
|
||||||
|
5 to 6 f2040bfc7ee033e48acef9f289790f3b4e6b74e5
|
||||||
|
4 to 5 5716c5cf65e9b2cb46c2906f40302401bdd27517
|
||||||
|
3 to 4 9a5f92ea72754c01cc03e5efcdfe94021120531e
|
||||||
|
2 to 3 ff93fd4f50321c6190e1659b19e64fef3045a484
|
||||||
|
1 to 2 dd11af209d226b7d18d5148b239662e30ed60bad
|
||||||
|
0 to 1 6a11048af1d01c78bdacddadd1b72dc7ba7c6478
|
||||||
|
initial version 0 d8c834c95d506db979ec871417de90b7951edc30
|
||||||
|
=================== ========================================
|
||||||
|
|
||||||
|
Binary encoding of .mpy files
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
MicroPython .mpy files are a binary container format with code objects (bytecode
|
||||||
|
and native machine code) stored internally in a nested hierarchy. The code for
|
||||||
|
the outer module is stored first, and then its children follow. Each child may
|
||||||
|
have further children, for example in the case of a class having methods, or a
|
||||||
|
function defining a lambda or comprehension. To keep files small while still
|
||||||
|
providing a large range of possible values it uses the concept of a
|
||||||
|
variably-encoded-unsigned-integer (vuint) in many places. Similar to utf-8
|
||||||
|
encoding, this encoding stores 7 bits per byte with the 8th bit (MSB) set
|
||||||
|
if one or more bytes follow. The bits of the unsigned integer are stored
|
||||||
|
in the vuint in LSB form.
|
||||||
|
|
||||||
|
The top-level of an .mpy file consists of three parts:
|
||||||
|
|
||||||
|
* The header.
|
||||||
|
|
||||||
|
* The global qstr and constant tables.
|
||||||
|
|
||||||
|
* The raw-code for the outer scope of the module.
|
||||||
|
This outer scope is executed when the .mpy file is imported.
|
||||||
|
|
||||||
|
You can inspect the contents of a .mpy file by using ``mpy-tool.py``, for
|
||||||
|
example (run from the root of the main MicroPython repository)::
|
||||||
|
|
||||||
|
$ ./tools/mpy-tool.py -xd myfile.mpy
|
||||||
|
|
||||||
|
The header
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
The .mpy header is:
|
||||||
|
|
||||||
|
====== ================================
|
||||||
|
size field
|
||||||
|
====== ================================
|
||||||
|
byte value 0x4d (ASCII 'M')
|
||||||
|
byte .mpy version number
|
||||||
|
byte feature flags
|
||||||
|
byte number of bits in a small int
|
||||||
|
====== ================================
|
||||||
|
|
||||||
|
The global qstr and constant tables
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
An .mpy file contains a single qstr table, and a single constant object table.
|
||||||
|
These are global to the .mpy file, they are referenced by all nested raw-code
|
||||||
|
objects. The qstr table maps internal qstr number (internal to the .mpy file)
|
||||||
|
to the resolved qstr number of the runtime that the .mpy file is imported into.
|
||||||
|
This links the .mpy file with the rest of the system that it executes within.
|
||||||
|
The constant object table is populated with references to all constant objects
|
||||||
|
that the .mpy file needs.
|
||||||
|
|
||||||
|
====== ================================
|
||||||
|
size field
|
||||||
|
====== ================================
|
||||||
|
vuint number of qstrs
|
||||||
|
vuint number of constant objects
|
||||||
|
... qstr data
|
||||||
|
... encoded constant objects
|
||||||
|
====== ================================
|
||||||
|
|
||||||
|
Raw code elements
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
A raw-code element contains code, either bytecode or native machine code. Its
|
||||||
|
contents are:
|
||||||
|
|
||||||
|
====== ================================
|
||||||
|
size field
|
||||||
|
====== ================================
|
||||||
|
vuint type, size and whether there are sub-raw-code elements
|
||||||
|
... code (bytecode or machine code)
|
||||||
|
vuint number of sub-raw-code elements (only if non-zero)
|
||||||
|
... sub-raw-code elements
|
||||||
|
====== ================================
|
||||||
|
|
||||||
|
The first vuint in a raw-code element encodes the type of code stored in this
|
||||||
|
element (the two least-significant bits), whether this raw-code has any
|
||||||
|
children (the third least-significant bit), and the length of the code that
|
||||||
|
follows (the amount of RAM to allocate for it).
|
||||||
|
|
||||||
|
Following the vuint comes the code itself. Unless the code type is viper code
|
||||||
|
with relocations, this code is constant data and does not need to be modified.
|
||||||
|
|
||||||
|
If this raw-code has any children (as indicated by a bit in the first vuint),
|
||||||
|
following the code comes a vuint counting the number of sub-raw-code elements.
|
||||||
|
|
||||||
|
Finally any sub-raw-code elements are stored, recursively.
|
@ -94,6 +94,10 @@ MDNS is used to resolve [`circuitpython.local`](http://circuitpython.local) to a
|
|||||||
hostname of the form `cpy-XXXXXX.local`. The `XXXXXX` is based on network MAC address. The device
|
hostname of the form `cpy-XXXXXX.local`. The `XXXXXX` is based on network MAC address. The device
|
||||||
also provides the MDNS service with service type `_circuitpython` and protocol `_tcp`.
|
also provides the MDNS service with service type `_circuitpython` and protocol `_tcp`.
|
||||||
|
|
||||||
|
Since port 80 (or the port assigned to `CIRCUITPY_WEB_API_PORT`) is used for web workflow, the `mdns`
|
||||||
|
[module](https://docs.circuitpython.org/en/latest/shared-bindings/mdns/index.html#mdns.Server.advertise_service)
|
||||||
|
can't advertise an additional service on that port.
|
||||||
|
|
||||||
### HTTP
|
### HTTP
|
||||||
The web server is HTTP 1.1 and may use chunked responses so that it doesn't need to precompute
|
The web server is HTTP 1.1 and may use chunked responses so that it doesn't need to precompute
|
||||||
content length.
|
content length.
|
||||||
|
1
examples/natmod/.gitignore
vendored
1
examples/natmod/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
*.mpy
|
|
@ -1,37 +0,0 @@
|
|||||||
# Location of top-level MicroPython directory
|
|
||||||
MPY_DIR = ../../..
|
|
||||||
|
|
||||||
# Name of module (different to built-in btree so it can coexist)
|
|
||||||
MOD = btree_$(ARCH)
|
|
||||||
|
|
||||||
# Source files (.c or .py)
|
|
||||||
SRC = btree_c.c btree_py.py
|
|
||||||
|
|
||||||
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
|
|
||||||
ARCH = x64
|
|
||||||
|
|
||||||
BTREE_DIR = $(MPY_DIR)/lib/berkeley-db-1.xx
|
|
||||||
BTREE_DEFS = -D__DBINTERFACE_PRIVATE=1 -Dmpool_error="(void)" -Dabort=abort_ "-Dvirt_fd_t=void*" $(BTREE_DEFS_EXTRA)
|
|
||||||
CFLAGS += -I$(BTREE_DIR)/PORT/include
|
|
||||||
CFLAGS += -Wno-old-style-definition -Wno-sign-compare -Wno-unused-parameter $(BTREE_DEFS)
|
|
||||||
|
|
||||||
SRC += $(addprefix $(realpath $(BTREE_DIR))/,\
|
|
||||||
btree/bt_close.c \
|
|
||||||
btree/bt_conv.c \
|
|
||||||
btree/bt_delete.c \
|
|
||||||
btree/bt_get.c \
|
|
||||||
btree/bt_open.c \
|
|
||||||
btree/bt_overflow.c \
|
|
||||||
btree/bt_page.c \
|
|
||||||
btree/bt_put.c \
|
|
||||||
btree/bt_search.c \
|
|
||||||
btree/bt_seq.c \
|
|
||||||
btree/bt_split.c \
|
|
||||||
btree/bt_utils.c \
|
|
||||||
mpool/mpool.c \
|
|
||||||
)
|
|
||||||
|
|
||||||
include $(MPY_DIR)/py/dynruntime.mk
|
|
||||||
|
|
||||||
# btree needs gnu99 defined
|
|
||||||
CFLAGS += -std=gnu99
|
|
@ -1,148 +0,0 @@
|
|||||||
#define MICROPY_PY_BTREE (1)
|
|
||||||
|
|
||||||
#include "py/dynruntime.h"
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#if !defined(__linux__)
|
|
||||||
void *memcpy(void *dst, const void *src, size_t n) {
|
|
||||||
return mp_fun_table.memmove_(dst, src, n);
|
|
||||||
}
|
|
||||||
void *memset(void *s, int c, size_t n) {
|
|
||||||
return mp_fun_table.memset_(s, c, n);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *memmove(void *dest, const void *src, size_t n) {
|
|
||||||
return mp_fun_table.memmove_(dest, src, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *malloc(size_t n) {
|
|
||||||
void *ptr = m_malloc(n, false);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
void *realloc(void *ptr, size_t n) {
|
|
||||||
mp_printf(&mp_plat_print, "UNDEF %d\n", __LINE__);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
void *calloc(size_t n, size_t m) {
|
|
||||||
void *ptr = m_malloc(n * m, false);
|
|
||||||
// memory already cleared by conservative GC
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void free(void *ptr) {
|
|
||||||
m_free(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void abort_(void) {
|
|
||||||
nlr_raise(mp_obj_new_exception(mp_load_global(MP_QSTR_RuntimeError)));
|
|
||||||
}
|
|
||||||
|
|
||||||
int native_errno;
|
|
||||||
#if defined(__linux__)
|
|
||||||
int *__errno_location (void)
|
|
||||||
#else
|
|
||||||
int *__errno (void)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
return &native_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t mp_stream_posix_write(void *stream, const void *buf, size_t len) {
|
|
||||||
mp_obj_base_t* o = stream;
|
|
||||||
const mp_stream_p_t *stream_p = o->type->ext[0].protocol;
|
|
||||||
mp_uint_t out_sz = stream_p->write(MP_OBJ_FROM_PTR(stream), buf, len, &native_errno);
|
|
||||||
if (out_sz == MP_STREAM_ERROR) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return out_sz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t mp_stream_posix_read(void *stream, void *buf, size_t len) {
|
|
||||||
mp_obj_base_t* o = stream;
|
|
||||||
const mp_stream_p_t *stream_p = o->type->ext[0].protocol;
|
|
||||||
mp_uint_t out_sz = stream_p->read(MP_OBJ_FROM_PTR(stream), buf, len, &native_errno);
|
|
||||||
if (out_sz == MP_STREAM_ERROR) {
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
return out_sz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
off_t mp_stream_posix_lseek(void *stream, off_t offset, int whence) {
|
|
||||||
const mp_obj_base_t* o = stream;
|
|
||||||
const mp_stream_p_t *stream_p = o->type->ext[0].protocol;
|
|
||||||
struct mp_stream_seek_t seek_s;
|
|
||||||
seek_s.offset = offset;
|
|
||||||
seek_s.whence = whence;
|
|
||||||
mp_uint_t res = stream_p->ioctl(MP_OBJ_FROM_PTR(stream), MP_STREAM_SEEK, (mp_uint_t)(uintptr_t)&seek_s, &native_errno);
|
|
||||||
if (res == MP_STREAM_ERROR) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return seek_s.offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mp_stream_posix_fsync(void *stream) {
|
|
||||||
mp_obj_base_t* o = stream;
|
|
||||||
const mp_stream_p_t *stream_p = o->type->ext[0].protocol;
|
|
||||||
mp_uint_t res = stream_p->ioctl(MP_OBJ_FROM_PTR(stream), MP_STREAM_FLUSH, 0, &native_errno);
|
|
||||||
if (res == MP_STREAM_ERROR) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_obj_full_type_t btree_type;
|
|
||||||
|
|
||||||
#include "extmod/modbtree.c"
|
|
||||||
|
|
||||||
mp_map_elem_t btree_locals_dict_table[8];
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(btree_locals_dict, btree_locals_dict_table);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_open(size_t n_args, const mp_obj_t *args) {
|
|
||||||
// Make sure we got a stream object
|
|
||||||
mp_get_stream_raise(args[0], MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL);
|
|
||||||
|
|
||||||
BTREEINFO openinfo = {0};
|
|
||||||
openinfo.flags = mp_obj_get_int(args[1]);
|
|
||||||
openinfo.cachesize = mp_obj_get_int(args[2]);
|
|
||||||
openinfo.psize = mp_obj_get_int(args[3]);
|
|
||||||
openinfo.minkeypage = mp_obj_get_int(args[4]);
|
|
||||||
DB *db = __bt_open(MP_OBJ_TO_PTR(args[0]), &btree_stream_fvtable, &openinfo, 0);
|
|
||||||
if (db == NULL) {
|
|
||||||
mp_raise_OSError(native_errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
return MP_OBJ_FROM_PTR(btree_new(db, args[0]));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_open_obj, 5, 5, btree_open);
|
|
||||||
|
|
||||||
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
|
|
||||||
MP_DYNRUNTIME_INIT_ENTRY
|
|
||||||
|
|
||||||
btree_type.base.type = (void*)&mp_fun_table.type_type;
|
|
||||||
btree_type.flags = MP_TYPE_FLAG_EXTENDED;
|
|
||||||
btree_type.name = MP_QSTR_btree;
|
|
||||||
btree_type.print = btree_print;
|
|
||||||
btree_type.ext[0].getiter = btree_getiter;
|
|
||||||
btree_type.ext[0].iternext = btree_iternext;
|
|
||||||
btree_type.ext[0].binary_op = btree_binary_op;
|
|
||||||
btree_type.ext[0].subscr = btree_subscr;
|
|
||||||
btree_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_close), MP_OBJ_FROM_PTR(&btree_close_obj) };
|
|
||||||
btree_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_flush), MP_OBJ_FROM_PTR(&btree_flush_obj) };
|
|
||||||
btree_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_get), MP_OBJ_FROM_PTR(&btree_get_obj) };
|
|
||||||
btree_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_put), MP_OBJ_FROM_PTR(&btree_put_obj) };
|
|
||||||
btree_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_seq), MP_OBJ_FROM_PTR(&btree_seq_obj) };
|
|
||||||
btree_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_keys), MP_OBJ_FROM_PTR(&btree_keys_obj) };
|
|
||||||
btree_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_values), MP_OBJ_FROM_PTR(&btree_values_obj) };
|
|
||||||
btree_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_items), MP_OBJ_FROM_PTR(&btree_items_obj) };
|
|
||||||
btree_type.locals_dict = (void*)&btree_locals_dict;
|
|
||||||
|
|
||||||
mp_store_global(MP_QSTR__open, MP_OBJ_FROM_PTR(&btree_open_obj));
|
|
||||||
mp_store_global(MP_QSTR_INCL, MP_OBJ_NEW_SMALL_INT(FLAG_END_KEY_INCL));
|
|
||||||
mp_store_global(MP_QSTR_DESC, MP_OBJ_NEW_SMALL_INT(FLAG_DESC));
|
|
||||||
|
|
||||||
MP_DYNRUNTIME_INIT_EXIT
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
# Implemented in Python to support keyword arguments
|
|
||||||
def open(stream, *, flags=0, cachesize=0, pagesize=0, minkeypage=0):
|
|
||||||
return _open(stream, flags, cachesize, pagesize, minkeypage)
|
|
@ -1,14 +0,0 @@
|
|||||||
# Location of top-level MicroPython directory
|
|
||||||
MPY_DIR = ../../..
|
|
||||||
|
|
||||||
# Name of module
|
|
||||||
MOD = features0
|
|
||||||
|
|
||||||
# Source files (.c or .py)
|
|
||||||
SRC = features0.c
|
|
||||||
|
|
||||||
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
|
|
||||||
ARCH = x64
|
|
||||||
|
|
||||||
# Include to get the rules for compiling and linking the module
|
|
||||||
include $(MPY_DIR)/py/dynruntime.mk
|
|
@ -1,40 +0,0 @@
|
|||||||
/* This example demonstrates the following features in a native module:
|
|
||||||
- defining a simple function exposed to Python
|
|
||||||
- defining a local, helper C function
|
|
||||||
- getting and creating integer objects
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Include the header file to get access to the MicroPython API
|
|
||||||
#include "py/dynruntime.h"
|
|
||||||
|
|
||||||
// Helper function to compute factorial
|
|
||||||
STATIC mp_int_t factorial_helper(mp_int_t x) {
|
|
||||||
if (x == 0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return x * factorial_helper(x - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is the function which will be called from Python, as factorial(x)
|
|
||||||
STATIC mp_obj_t factorial(mp_obj_t x_obj) {
|
|
||||||
// Extract the integer from the MicroPython input object
|
|
||||||
mp_int_t x = mp_obj_get_int(x_obj);
|
|
||||||
// Calculate the factorial
|
|
||||||
mp_int_t result = factorial_helper(x);
|
|
||||||
// Convert the result to a MicroPython integer object and return it
|
|
||||||
return mp_obj_new_int(result);
|
|
||||||
}
|
|
||||||
// Define a Python reference to the function above
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(factorial_obj, factorial);
|
|
||||||
|
|
||||||
// This is the entry point and is called when the module is imported
|
|
||||||
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
|
|
||||||
// This must be first, it sets up the globals dict and other things
|
|
||||||
MP_DYNRUNTIME_INIT_ENTRY
|
|
||||||
|
|
||||||
// Make the function available in the module's namespace
|
|
||||||
mp_store_global(MP_QSTR_factorial, MP_OBJ_FROM_PTR(&factorial_obj));
|
|
||||||
|
|
||||||
// This must be last, it restores the globals dict
|
|
||||||
MP_DYNRUNTIME_INIT_EXIT
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
# Location of top-level MicroPython directory
|
|
||||||
MPY_DIR = ../../..
|
|
||||||
|
|
||||||
# Name of module
|
|
||||||
MOD = features1
|
|
||||||
|
|
||||||
# Source files (.c or .py)
|
|
||||||
SRC = features1.c
|
|
||||||
|
|
||||||
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
|
|
||||||
ARCH = x64
|
|
||||||
|
|
||||||
# Include to get the rules for compiling and linking the module
|
|
||||||
include $(MPY_DIR)/py/dynruntime.mk
|
|
@ -1,106 +0,0 @@
|
|||||||
/* This example demonstrates the following features in a native module:
|
|
||||||
- defining simple functions exposed to Python
|
|
||||||
- defining local, helper C functions
|
|
||||||
- defining constant integers and strings exposed to Python
|
|
||||||
- getting and creating integer objects
|
|
||||||
- creating Python lists
|
|
||||||
- raising exceptions
|
|
||||||
- allocating memory
|
|
||||||
- BSS and constant data (rodata)
|
|
||||||
- relocated pointers in rodata
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Include the header file to get access to the MicroPython API
|
|
||||||
#include "py/dynruntime.h"
|
|
||||||
|
|
||||||
// BSS (zero) data
|
|
||||||
uint16_t data16[4];
|
|
||||||
|
|
||||||
// Constant data (rodata)
|
|
||||||
const uint8_t table8[] = { 0, 1, 1, 2, 3, 5, 8, 13 };
|
|
||||||
const uint16_t table16[] = { 0x1000, 0x2000 };
|
|
||||||
|
|
||||||
// Constant data pointing to BSS/constant data
|
|
||||||
uint16_t *const table_ptr16a[] = { &data16[0], &data16[1], &data16[2], &data16[3] };
|
|
||||||
const uint16_t *const table_ptr16b[] = { &table16[0], &table16[1] };
|
|
||||||
|
|
||||||
// A simple function that adds its 2 arguments (must be integers)
|
|
||||||
STATIC mp_obj_t add(mp_obj_t x_in, mp_obj_t y_in) {
|
|
||||||
mp_int_t x = mp_obj_get_int(x_in);
|
|
||||||
mp_int_t y = mp_obj_get_int(y_in);
|
|
||||||
return mp_obj_new_int(x + y);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(add_obj, add);
|
|
||||||
|
|
||||||
// A local helper function (not exposed to Python)
|
|
||||||
STATIC mp_int_t fibonacci_helper(mp_int_t x) {
|
|
||||||
if (x < MP_ARRAY_SIZE(table8)) {
|
|
||||||
return table8[x];
|
|
||||||
} else {
|
|
||||||
return fibonacci_helper(x - 1) + fibonacci_helper(x - 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A function which computes Fibonacci numbers
|
|
||||||
STATIC mp_obj_t fibonacci(mp_obj_t x_in) {
|
|
||||||
mp_int_t x = mp_obj_get_int(x_in);
|
|
||||||
if (x < 0) {
|
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("can't compute negative Fibonacci number"));
|
|
||||||
}
|
|
||||||
return mp_obj_new_int(fibonacci_helper(x));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(fibonacci_obj, fibonacci);
|
|
||||||
|
|
||||||
// A function that accesses the BSS data
|
|
||||||
STATIC mp_obj_t access(size_t n_args, const mp_obj_t *args) {
|
|
||||||
if (n_args == 0) {
|
|
||||||
// Create a list holding all items from data16
|
|
||||||
mp_obj_list_t *lst = MP_OBJ_TO_PTR(mp_obj_new_list(MP_ARRAY_SIZE(data16), NULL));
|
|
||||||
for (int i = 0; i < MP_ARRAY_SIZE(data16); ++i) {
|
|
||||||
lst->items[i] = mp_obj_new_int(data16[i]);
|
|
||||||
}
|
|
||||||
return MP_OBJ_FROM_PTR(lst);
|
|
||||||
} else if (n_args == 1) {
|
|
||||||
// Get one item from data16
|
|
||||||
mp_int_t idx = mp_obj_get_int(args[0]) & 3;
|
|
||||||
return mp_obj_new_int(data16[idx]);
|
|
||||||
} else {
|
|
||||||
// Set one item in data16 (via table_ptr16a)
|
|
||||||
mp_int_t idx = mp_obj_get_int(args[0]) & 3;
|
|
||||||
*table_ptr16a[idx] = mp_obj_get_int(args[1]);
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(access_obj, 0, 2, access);
|
|
||||||
|
|
||||||
// A function that allocates memory and creates a bytearray
|
|
||||||
STATIC mp_obj_t make_array(void) {
|
|
||||||
uint16_t *ptr = m_new(uint16_t, MP_ARRAY_SIZE(table_ptr16b));
|
|
||||||
for (int i = 0; i < MP_ARRAY_SIZE(table_ptr16b); ++i) {
|
|
||||||
ptr[i] = *table_ptr16b[i];
|
|
||||||
}
|
|
||||||
return mp_obj_new_bytearray_by_ref(sizeof(uint16_t) * MP_ARRAY_SIZE(table_ptr16b), ptr);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(make_array_obj, make_array);
|
|
||||||
|
|
||||||
// This is the entry point and is called when the module is imported
|
|
||||||
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
|
|
||||||
// This must be first, it sets up the globals dict and other things
|
|
||||||
MP_DYNRUNTIME_INIT_ENTRY
|
|
||||||
|
|
||||||
// Messages can be printed as usually
|
|
||||||
mp_printf(&mp_plat_print, "initialising module self=%p\n", self);
|
|
||||||
|
|
||||||
// Make the functions available in the module's namespace
|
|
||||||
mp_store_global(MP_QSTR_add, MP_OBJ_FROM_PTR(&add_obj));
|
|
||||||
mp_store_global(MP_QSTR_fibonacci, MP_OBJ_FROM_PTR(&fibonacci_obj));
|
|
||||||
mp_store_global(MP_QSTR_access, MP_OBJ_FROM_PTR(&access_obj));
|
|
||||||
mp_store_global(MP_QSTR_make_array, MP_OBJ_FROM_PTR(&make_array_obj));
|
|
||||||
|
|
||||||
// Add some constants to the module's namespace
|
|
||||||
mp_store_global(MP_QSTR_VAL, MP_OBJ_NEW_SMALL_INT(42));
|
|
||||||
mp_store_global(MP_QSTR_MSG, MP_OBJ_NEW_QSTR(MP_QSTR_HELLO_MICROPYTHON));
|
|
||||||
|
|
||||||
// This must be last, it restores the globals dict
|
|
||||||
MP_DYNRUNTIME_INIT_EXIT
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
# Location of top-level MicroPython directory
|
|
||||||
MPY_DIR = ../../..
|
|
||||||
|
|
||||||
# Name of module
|
|
||||||
MOD = features2
|
|
||||||
|
|
||||||
# Source files (.c or .py)
|
|
||||||
SRC = main.c prod.c test.py
|
|
||||||
|
|
||||||
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
|
|
||||||
ARCH = x64
|
|
||||||
|
|
||||||
# Include to get the rules for compiling and linking the module
|
|
||||||
include $(MPY_DIR)/py/dynruntime.mk
|
|
@ -1,83 +0,0 @@
|
|||||||
/* This example demonstrates the following features in a native module:
|
|
||||||
- using floats
|
|
||||||
- defining additional code in Python (see test.py)
|
|
||||||
- have extra C code in a separate file (see prod.c)
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Include the header file to get access to the MicroPython API
|
|
||||||
#include "py/dynruntime.h"
|
|
||||||
|
|
||||||
// Include the header for auxiliary C code for this module
|
|
||||||
#include "prod.h"
|
|
||||||
|
|
||||||
// Automatically detect if this module should include double-precision code.
|
|
||||||
// If double precision is supported by the target architecture then it can
|
|
||||||
// be used in native module regardless of what float setting the target
|
|
||||||
// MicroPython runtime uses (being none, float or double).
|
|
||||||
#if defined(__i386__) || defined(__x86_64__) || (defined(__ARM_FP) && (__ARM_FP & 8))
|
|
||||||
#define USE_DOUBLE 1
|
|
||||||
#else
|
|
||||||
#define USE_DOUBLE 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// A function that uses the default float type configured for the current target
|
|
||||||
// This default can be overridden by specifying MICROPY_FLOAT_IMPL at the make level
|
|
||||||
STATIC mp_obj_t add(mp_obj_t x, mp_obj_t y) {
|
|
||||||
return mp_obj_new_float(mp_obj_get_float(x) + mp_obj_get_float(y));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(add_obj, add);
|
|
||||||
|
|
||||||
// A function that explicitly uses single precision floats
|
|
||||||
STATIC mp_obj_t add_f(mp_obj_t x, mp_obj_t y) {
|
|
||||||
return mp_obj_new_float_from_f(mp_obj_get_float_to_f(x) + mp_obj_get_float_to_f(y));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(add_f_obj, add_f);
|
|
||||||
|
|
||||||
#if USE_DOUBLE
|
|
||||||
// A function that explicitly uses double precision floats
|
|
||||||
STATIC mp_obj_t add_d(mp_obj_t x, mp_obj_t y) {
|
|
||||||
return mp_obj_new_float_from_d(mp_obj_get_float_to_d(x) + mp_obj_get_float_to_d(y));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(add_d_obj, add_d);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// A function that computes the product of floats in an array.
|
|
||||||
// This function uses the most general C argument interface, which is more difficult
|
|
||||||
// to use but has access to the globals dict of the module via self->globals.
|
|
||||||
STATIC mp_obj_t productf(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
|
|
||||||
// Check number of arguments is valid
|
|
||||||
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
|
||||||
|
|
||||||
// Extract buffer pointer and verify typecode
|
|
||||||
mp_buffer_info_t bufinfo;
|
|
||||||
mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_RW);
|
|
||||||
if (bufinfo.typecode != 'f') {
|
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("expecting float array"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute product, store result back in first element of array
|
|
||||||
float *ptr = bufinfo.buf;
|
|
||||||
float prod = prod_array(bufinfo.len / sizeof(*ptr), ptr);
|
|
||||||
ptr[0] = prod;
|
|
||||||
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is the entry point and is called when the module is imported
|
|
||||||
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
|
|
||||||
// This must be first, it sets up the globals dict and other things
|
|
||||||
MP_DYNRUNTIME_INIT_ENTRY
|
|
||||||
|
|
||||||
// Make the functions available in the module's namespace
|
|
||||||
mp_store_global(MP_QSTR_add, MP_OBJ_FROM_PTR(&add_obj));
|
|
||||||
mp_store_global(MP_QSTR_add_f, MP_OBJ_FROM_PTR(&add_f_obj));
|
|
||||||
#if USE_DOUBLE
|
|
||||||
mp_store_global(MP_QSTR_add_d, MP_OBJ_FROM_PTR(&add_d_obj));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// The productf function uses the most general C argument interface
|
|
||||||
mp_store_global(MP_QSTR_productf, MP_DYNRUNTIME_MAKE_FUNCTION(productf));
|
|
||||||
|
|
||||||
// This must be last, it restores the globals dict
|
|
||||||
MP_DYNRUNTIME_INIT_EXIT
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
#include "prod.h"
|
|
||||||
|
|
||||||
float prod_array(int n, float *ar) {
|
|
||||||
float ans = 1;
|
|
||||||
for (int i = 0; i < n; ++i) {
|
|
||||||
ans *= ar[i];
|
|
||||||
}
|
|
||||||
return ans;
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
float prod_array(int n, float *ar);
|
|
@ -1,29 +0,0 @@
|
|||||||
# This Python code will be merged with the C code in main.c
|
|
||||||
|
|
||||||
import array
|
|
||||||
|
|
||||||
|
|
||||||
def isclose(a, b):
|
|
||||||
return abs(a - b) < 1e-3
|
|
||||||
|
|
||||||
|
|
||||||
def test():
|
|
||||||
tests = [
|
|
||||||
isclose(add(0.1, 0.2), 0.3),
|
|
||||||
isclose(add_f(0.1, 0.2), 0.3),
|
|
||||||
]
|
|
||||||
|
|
||||||
ar = array.array("f", [1, 2, 3.5])
|
|
||||||
productf(ar)
|
|
||||||
tests.append(isclose(ar[0], 7))
|
|
||||||
|
|
||||||
if "add_d" in globals():
|
|
||||||
tests.append(isclose(add_d(0.1, 0.2), 0.3))
|
|
||||||
|
|
||||||
print(tests)
|
|
||||||
|
|
||||||
if not all(tests):
|
|
||||||
raise SystemExit(1)
|
|
||||||
|
|
||||||
|
|
||||||
test()
|
|
@ -1,13 +0,0 @@
|
|||||||
# Location of top-level MicroPython directory
|
|
||||||
MPY_DIR = ../../..
|
|
||||||
|
|
||||||
# Name of module (different to built-in framebuf so it can coexist)
|
|
||||||
MOD = framebuf_$(ARCH)
|
|
||||||
|
|
||||||
# Source files (.c or .py)
|
|
||||||
SRC = framebuf.c
|
|
||||||
|
|
||||||
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
|
|
||||||
ARCH = x64
|
|
||||||
|
|
||||||
include $(MPY_DIR)/py/dynruntime.mk
|
|
@ -1,50 +0,0 @@
|
|||||||
#define MICROPY_PY_FRAMEBUF (1)
|
|
||||||
|
|
||||||
#include "py/dynruntime.h"
|
|
||||||
|
|
||||||
#if !defined(__linux__)
|
|
||||||
void *memset(void *s, int c, size_t n) {
|
|
||||||
return mp_fun_table.memset_(s, c, n);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mp_obj_full_type_t mp_type_framebuf;
|
|
||||||
|
|
||||||
#include "extmod/modframebuf.c"
|
|
||||||
|
|
||||||
mp_map_elem_t framebuf_locals_dict_table[10];
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(framebuf_locals_dict, framebuf_locals_dict_table);
|
|
||||||
|
|
||||||
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
|
|
||||||
MP_DYNRUNTIME_INIT_ENTRY
|
|
||||||
|
|
||||||
mp_type_framebuf.base.type = (void*)&mp_type_type;
|
|
||||||
mp_type_framebuf.flags = MP_TYPE_FLAG_EXTENDED;
|
|
||||||
mp_type_framebuf.name = MP_QSTR_FrameBuffer;
|
|
||||||
mp_type_framebuf.make_new = framebuf_make_new;
|
|
||||||
mp_type_framebuf.ext[0].buffer_p.get_buffer = framebuf_get_buffer;
|
|
||||||
framebuf_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill), MP_OBJ_FROM_PTR(&framebuf_fill_obj) };
|
|
||||||
framebuf_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill_rect), MP_OBJ_FROM_PTR(&framebuf_fill_rect_obj) };
|
|
||||||
framebuf_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_pixel), MP_OBJ_FROM_PTR(&framebuf_pixel_obj) };
|
|
||||||
framebuf_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_hline), MP_OBJ_FROM_PTR(&framebuf_hline_obj) };
|
|
||||||
framebuf_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_vline), MP_OBJ_FROM_PTR(&framebuf_vline_obj) };
|
|
||||||
framebuf_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_rect), MP_OBJ_FROM_PTR(&framebuf_rect_obj) };
|
|
||||||
framebuf_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_line), MP_OBJ_FROM_PTR(&framebuf_line_obj) };
|
|
||||||
framebuf_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_blit), MP_OBJ_FROM_PTR(&framebuf_blit_obj) };
|
|
||||||
framebuf_locals_dict_table[8] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_scroll), MP_OBJ_FROM_PTR(&framebuf_scroll_obj) };
|
|
||||||
framebuf_locals_dict_table[9] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_text), MP_OBJ_FROM_PTR(&framebuf_text_obj) };
|
|
||||||
mp_type_framebuf.locals_dict = (void*)&framebuf_locals_dict;
|
|
||||||
|
|
||||||
mp_store_global(MP_QSTR_FrameBuffer, MP_OBJ_FROM_PTR(&mp_type_framebuf));
|
|
||||||
mp_store_global(MP_QSTR_FrameBuffer1, MP_OBJ_FROM_PTR(&legacy_framebuffer1_obj));
|
|
||||||
mp_store_global(MP_QSTR_MVLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB));
|
|
||||||
mp_store_global(MP_QSTR_MONO_VLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB));
|
|
||||||
mp_store_global(MP_QSTR_RGB565, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_RGB565));
|
|
||||||
mp_store_global(MP_QSTR_GS2_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS2_HMSB));
|
|
||||||
mp_store_global(MP_QSTR_GS4_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS4_HMSB));
|
|
||||||
mp_store_global(MP_QSTR_GS8, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS8));
|
|
||||||
mp_store_global(MP_QSTR_MONO_HLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MHLSB));
|
|
||||||
mp_store_global(MP_QSTR_MONO_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MHMSB));
|
|
||||||
|
|
||||||
MP_DYNRUNTIME_INIT_EXIT
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
# Location of top-level MicroPython directory
|
|
||||||
MPY_DIR = ../../..
|
|
||||||
|
|
||||||
# Name of module (different to built-in uheapq so it can coexist)
|
|
||||||
MOD = uheapq_$(ARCH)
|
|
||||||
|
|
||||||
# Source files (.c or .py)
|
|
||||||
SRC = uheapq.c
|
|
||||||
|
|
||||||
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
|
|
||||||
ARCH = x64
|
|
||||||
|
|
||||||
include $(MPY_DIR)/py/dynruntime.mk
|
|
@ -1,16 +0,0 @@
|
|||||||
#define MICROPY_PY_UHEAPQ (1)
|
|
||||||
|
|
||||||
#include "py/dynruntime.h"
|
|
||||||
|
|
||||||
#include "extmod/moduheapq.c"
|
|
||||||
|
|
||||||
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
|
|
||||||
MP_DYNRUNTIME_INIT_ENTRY
|
|
||||||
|
|
||||||
mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_uheapq));
|
|
||||||
mp_store_global(MP_QSTR_heappush, MP_OBJ_FROM_PTR(&mod_uheapq_heappush_obj));
|
|
||||||
mp_store_global(MP_QSTR_heappop, MP_OBJ_FROM_PTR(&mod_uheapq_heappop_obj));
|
|
||||||
mp_store_global(MP_QSTR_heapify, MP_OBJ_FROM_PTR(&mod_uheapq_heapify_obj));
|
|
||||||
|
|
||||||
MP_DYNRUNTIME_INIT_EXIT
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
# Location of top-level MicroPython directory
|
|
||||||
MPY_DIR = ../../..
|
|
||||||
|
|
||||||
# Name of module (different to built-in urandom so it can coexist)
|
|
||||||
MOD = urandom_$(ARCH)
|
|
||||||
|
|
||||||
# Source files (.c or .py)
|
|
||||||
SRC = urandom.c
|
|
||||||
|
|
||||||
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
|
|
||||||
ARCH = x64
|
|
||||||
|
|
||||||
include $(MPY_DIR)/py/dynruntime.mk
|
|
@ -1,33 +0,0 @@
|
|||||||
#define MICROPY_PY_URANDOM (1)
|
|
||||||
#define MICROPY_PY_URANDOM_EXTRA_FUNCS (1)
|
|
||||||
|
|
||||||
#include "py/dynruntime.h"
|
|
||||||
|
|
||||||
// Dynamic native modules don't support a data section so these must go in the BSS
|
|
||||||
uint32_t yasmarang_pad, yasmarang_n, yasmarang_d;
|
|
||||||
uint8_t yasmarang_dat;
|
|
||||||
|
|
||||||
#include "extmod/modurandom.c"
|
|
||||||
|
|
||||||
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
|
|
||||||
MP_DYNRUNTIME_INIT_ENTRY
|
|
||||||
|
|
||||||
yasmarang_pad = 0xeda4baba;
|
|
||||||
yasmarang_n = 69;
|
|
||||||
yasmarang_d = 233;
|
|
||||||
|
|
||||||
mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_urandom));
|
|
||||||
mp_store_global(MP_QSTR_getrandbits, MP_OBJ_FROM_PTR(&mod_urandom_getrandbits_obj));
|
|
||||||
mp_store_global(MP_QSTR_seed, MP_OBJ_FROM_PTR(&mod_urandom_seed_obj));
|
|
||||||
#if MICROPY_PY_URANDOM_EXTRA_FUNCS
|
|
||||||
mp_store_global(MP_QSTR_randrange, MP_OBJ_FROM_PTR(&mod_urandom_randrange_obj));
|
|
||||||
mp_store_global(MP_QSTR_randint, MP_OBJ_FROM_PTR(&mod_urandom_randint_obj));
|
|
||||||
mp_store_global(MP_QSTR_choice, MP_OBJ_FROM_PTR(&mod_urandom_choice_obj));
|
|
||||||
#if MICROPY_PY_BUILTINS_FLOAT
|
|
||||||
mp_store_global(MP_QSTR_random, MP_OBJ_FROM_PTR(&mod_urandom_random_obj));
|
|
||||||
mp_store_global(MP_QSTR_uniform, MP_OBJ_FROM_PTR(&mod_urandom_uniform_obj));
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MP_DYNRUNTIME_INIT_EXIT
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
# Location of top-level MicroPython directory
|
|
||||||
MPY_DIR = ../../..
|
|
||||||
|
|
||||||
# Name of module (different to built-in ure so it can coexist)
|
|
||||||
MOD = ure_$(ARCH)
|
|
||||||
|
|
||||||
# Source files (.c or .py)
|
|
||||||
SRC = ure.c
|
|
||||||
|
|
||||||
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
|
|
||||||
ARCH = x64
|
|
||||||
|
|
||||||
include $(MPY_DIR)/py/dynruntime.mk
|
|
@ -1,78 +0,0 @@
|
|||||||
#define MICROPY_STACK_CHECK (1)
|
|
||||||
#define MICROPY_PY_URE (1)
|
|
||||||
#define MICROPY_PY_URE_MATCH_GROUPS (1)
|
|
||||||
#define MICROPY_PY_URE_MATCH_SPAN_START_END (1)
|
|
||||||
#define MICROPY_PY_URE_SUB (0) // requires vstr interface
|
|
||||||
|
|
||||||
#include <alloca.h>
|
|
||||||
#include "py/dynruntime.h"
|
|
||||||
|
|
||||||
#define STACK_LIMIT (2048)
|
|
||||||
|
|
||||||
const char *stack_top;
|
|
||||||
|
|
||||||
void mp_stack_check(void) {
|
|
||||||
// Assumes descending stack on target
|
|
||||||
volatile char dummy;
|
|
||||||
if (stack_top - &dummy >= STACK_LIMIT) {
|
|
||||||
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("maximum recursion depth exceeded"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(__linux__)
|
|
||||||
void *memcpy(void *dst, const void *src, size_t n) {
|
|
||||||
return mp_fun_table.memmove_(dst, src, n);
|
|
||||||
}
|
|
||||||
void *memset(void *s, int c, size_t n) {
|
|
||||||
return mp_fun_table.memset_(s, c, n);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void *memmove(void *dest, const void *src, size_t n) {
|
|
||||||
return mp_fun_table.memmove_(dest, src, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_obj_type_t match_type;
|
|
||||||
mp_obj_type_t re_type;
|
|
||||||
|
|
||||||
#include "extmod/modure.c"
|
|
||||||
|
|
||||||
mp_map_elem_t match_locals_dict_table[5];
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(match_locals_dict, match_locals_dict_table);
|
|
||||||
|
|
||||||
mp_map_elem_t re_locals_dict_table[3];
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(re_locals_dict, re_locals_dict_table);
|
|
||||||
|
|
||||||
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
|
|
||||||
MP_DYNRUNTIME_INIT_ENTRY
|
|
||||||
|
|
||||||
char dummy;
|
|
||||||
stack_top = &dummy;
|
|
||||||
|
|
||||||
// Because MP_QSTR_start/end/split are static, xtensa and xtensawin will make a small data section
|
|
||||||
// to copy in this key/value pair if they are specified as a struct, so assign them separately.
|
|
||||||
|
|
||||||
match_type.base.type = (void*)&mp_fun_table.type_type;
|
|
||||||
match_type.name = MP_QSTR_match;
|
|
||||||
match_type.print = match_print;
|
|
||||||
match_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_group), MP_OBJ_FROM_PTR(&match_group_obj) };
|
|
||||||
match_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_groups), MP_OBJ_FROM_PTR(&match_groups_obj) };
|
|
||||||
match_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_span), MP_OBJ_FROM_PTR(&match_span_obj) };
|
|
||||||
match_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_start), MP_OBJ_FROM_PTR(&match_start_obj) };
|
|
||||||
match_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_end), MP_OBJ_FROM_PTR(&match_end_obj) };
|
|
||||||
match_type.locals_dict = (void*)&match_locals_dict;
|
|
||||||
|
|
||||||
re_type.base.type = (void*)&mp_fun_table.type_type;
|
|
||||||
re_type.name = MP_QSTR_ure;
|
|
||||||
re_type.print = re_print;
|
|
||||||
re_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_match), MP_OBJ_FROM_PTR(&re_match_obj) };
|
|
||||||
re_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_search), MP_OBJ_FROM_PTR(&re_search_obj) };
|
|
||||||
re_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_split), MP_OBJ_FROM_PTR(&re_split_obj) };
|
|
||||||
re_type.locals_dict = (void*)&re_locals_dict;
|
|
||||||
|
|
||||||
mp_store_global(MP_QSTR_compile, MP_OBJ_FROM_PTR(&mod_re_compile_obj));
|
|
||||||
mp_store_global(MP_QSTR_match, MP_OBJ_FROM_PTR(&re_match_obj));
|
|
||||||
mp_store_global(MP_QSTR_search, MP_OBJ_FROM_PTR(&re_search_obj));
|
|
||||||
|
|
||||||
MP_DYNRUNTIME_INIT_EXIT
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
# Location of top-level MicroPython directory
|
|
||||||
MPY_DIR = ../../..
|
|
||||||
|
|
||||||
# Name of module (different to built-in uzlib so it can coexist)
|
|
||||||
MOD = uzlib_$(ARCH)
|
|
||||||
|
|
||||||
# Source files (.c or .py)
|
|
||||||
SRC = uzlib.c
|
|
||||||
|
|
||||||
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
|
|
||||||
ARCH = x64
|
|
||||||
|
|
||||||
include $(MPY_DIR)/py/dynruntime.mk
|
|
@ -1,40 +0,0 @@
|
|||||||
#define MICROPY_PY_UZLIB (1)
|
|
||||||
|
|
||||||
#include "py/dynruntime.h"
|
|
||||||
|
|
||||||
#if !defined(__linux__)
|
|
||||||
void *memset(void *s, int c, size_t n) {
|
|
||||||
return mp_fun_table.memset_(s, c, n);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mp_obj_full_type_t decompio_type;
|
|
||||||
mp_stream_p_t decompio_stream_p;
|
|
||||||
|
|
||||||
#include "extmod/moduzlib.c"
|
|
||||||
|
|
||||||
mp_map_elem_t decompio_locals_dict_table[3];
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(decompio_locals_dict, decompio_locals_dict_table);
|
|
||||||
|
|
||||||
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
|
|
||||||
MP_DYNRUNTIME_INIT_ENTRY
|
|
||||||
|
|
||||||
decompio_stream_p.name = MP_QSTR_protocol_stream;
|
|
||||||
decompio_stream_p.read = decompio_read;
|
|
||||||
|
|
||||||
decompio_type.base.type = mp_fun_table.type_type;
|
|
||||||
decompio_type.flags = MP_TYPE_FLAG_EXTENDED;
|
|
||||||
decompio_type.name = MP_QSTR_DecompIO;
|
|
||||||
decompio_type.make_new = decompio_make_new;
|
|
||||||
decompio_type.ext[0].protocol = &decompio_stream_p;
|
|
||||||
decompio_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_OBJ_FROM_PTR(&mp_stream_read_obj) };
|
|
||||||
decompio_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_OBJ_FROM_PTR(&mp_stream_readinto_obj) };
|
|
||||||
decompio_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_OBJ_FROM_PTR(&mp_stream_unbuffered_readline_obj) };
|
|
||||||
decompio_type.locals_dict = (void*)&decompio_locals_dict;
|
|
||||||
|
|
||||||
mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_uzlib));
|
|
||||||
mp_store_global(MP_QSTR_decompress, MP_OBJ_FROM_PTR(&mod_uzlib_decompress_obj));
|
|
||||||
mp_store_global(MP_QSTR_DecompIO, MP_OBJ_FROM_PTR(&decompio_type));
|
|
||||||
|
|
||||||
MP_DYNRUNTIME_INIT_EXIT
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
// Include MicroPython API.
|
|
||||||
#include "py/runtime.h"
|
|
||||||
|
|
||||||
// This is the function which will be called from Python as cexample.add_ints(a, b).
|
|
||||||
STATIC mp_obj_t example_add_ints(mp_obj_t a_obj, mp_obj_t b_obj) {
|
|
||||||
// Extract the ints from the micropython input objects.
|
|
||||||
int a = mp_obj_get_int(a_obj);
|
|
||||||
int b = mp_obj_get_int(b_obj);
|
|
||||||
|
|
||||||
// Calculate the addition and convert to MicroPython object.
|
|
||||||
return mp_obj_new_int(a + b);
|
|
||||||
}
|
|
||||||
// Define a Python reference to the function above.
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(example_add_ints_obj, example_add_ints);
|
|
||||||
|
|
||||||
// Define all properties of the module.
|
|
||||||
// Table entries are key/value pairs of the attribute name (a string)
|
|
||||||
// and the MicroPython object reference.
|
|
||||||
// All identifiers and strings are written as MP_QSTR_xxx and will be
|
|
||||||
// optimized to word-sized integers by the build system (interned strings).
|
|
||||||
STATIC const mp_rom_map_elem_t example_module_globals_table[] = {
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cexample) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_add_ints), MP_ROM_PTR(&example_add_ints_obj) },
|
|
||||||
};
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(example_module_globals, example_module_globals_table);
|
|
||||||
|
|
||||||
// Define module object.
|
|
||||||
const mp_obj_module_t example_user_cmodule = {
|
|
||||||
.base = { &mp_type_module },
|
|
||||||
.globals = (mp_obj_dict_t *)&example_module_globals,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Register the module to make it available in Python.
|
|
||||||
// Note: the "1" in the third argument means this module is always enabled.
|
|
||||||
// This "1" can be optionally replaced with a macro like MODULE_CEXAMPLE_ENABLED
|
|
||||||
// which can then be used to conditionally enable this module.
|
|
||||||
MP_REGISTER_MODULE(MP_QSTR_cexample, example_user_cmodule, 1);
|
|
@ -1,15 +0,0 @@
|
|||||||
# Create an INTERFACE library for our C module.
|
|
||||||
add_library(usermod_cexample INTERFACE)
|
|
||||||
|
|
||||||
# Add our source files to the lib
|
|
||||||
target_sources(usermod_cexample INTERFACE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/examplemodule.c
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add the current directory as an include directory.
|
|
||||||
target_include_directories(usermod_cexample INTERFACE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Link our INTERFACE library to the usermod target.
|
|
||||||
target_link_libraries(usermod INTERFACE usermod_cexample)
|
|
@ -1,9 +0,0 @@
|
|||||||
EXAMPLE_MOD_DIR := $(USERMOD_DIR)
|
|
||||||
|
|
||||||
# Add all C files to SRC_USERMOD.
|
|
||||||
SRC_USERMOD += $(EXAMPLE_MOD_DIR)/examplemodule.c
|
|
||||||
|
|
||||||
# We can add our module folder to include paths if needed
|
|
||||||
# This is not actually needed in this example.
|
|
||||||
CFLAGS_USERMOD += -I$(EXAMPLE_MOD_DIR)
|
|
||||||
CEXAMPLE_MOD_DIR := $(USERMOD_DIR)
|
|
@ -1,17 +0,0 @@
|
|||||||
extern "C" {
|
|
||||||
#include <examplemodule.h>
|
|
||||||
|
|
||||||
// Here we implement the function using C++ code, but since it's
|
|
||||||
// declaration has to be compatible with C everything goes in extern "C" scope.
|
|
||||||
mp_obj_t cppfunc(mp_obj_t a_obj, mp_obj_t b_obj) {
|
|
||||||
// Prove we have (at least) C++11 features.
|
|
||||||
const auto a = mp_obj_get_int(a_obj);
|
|
||||||
const auto b = mp_obj_get_int(b_obj);
|
|
||||||
const auto sum = [&]() {
|
|
||||||
return mp_obj_new_int(a + b);
|
|
||||||
} ();
|
|
||||||
// Prove we're being scanned for QSTRs.
|
|
||||||
mp_obj_t tup[] = {sum, MP_ROM_QSTR(MP_QSTR_hellocpp)};
|
|
||||||
return mp_obj_new_tuple(2, tup);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
#include <examplemodule.h>
|
|
||||||
|
|
||||||
// Define a Python reference to the function we'll make available.
|
|
||||||
// See example.cpp for the definition.
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(cppfunc_obj, cppfunc);
|
|
||||||
|
|
||||||
// Define all properties of the module.
|
|
||||||
// Table entries are key/value pairs of the attribute name (a string)
|
|
||||||
// and the MicroPython object reference.
|
|
||||||
// All identifiers and strings are written as MP_QSTR_xxx and will be
|
|
||||||
// optimized to word-sized integers by the build system (interned strings).
|
|
||||||
STATIC const mp_rom_map_elem_t cppexample_module_globals_table[] = {
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cppexample) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_cppfunc), MP_ROM_PTR(&cppfunc_obj) },
|
|
||||||
};
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(cppexample_module_globals, cppexample_module_globals_table);
|
|
||||||
|
|
||||||
// Define module object.
|
|
||||||
const mp_obj_module_t cppexample_user_cmodule = {
|
|
||||||
.base = { &mp_type_module },
|
|
||||||
.globals = (mp_obj_dict_t *)&cppexample_module_globals,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Register the module to make it available in Python.
|
|
||||||
// Note: the "1" in the third argument means this module is always enabled.
|
|
||||||
// This "1" can be optionally replaced with a macro like MODULE_CPPEXAMPLE_ENABLED
|
|
||||||
// which can then be used to conditionally enable this module.
|
|
||||||
MP_REGISTER_MODULE(MP_QSTR_cppexample, cppexample_user_cmodule, 1);
|
|
@ -1,5 +0,0 @@
|
|||||||
// Include MicroPython API.
|
|
||||||
#include "py/runtime.h"
|
|
||||||
|
|
||||||
// Declare the function we'll make available in Python as cppexample.cppfunc().
|
|
||||||
extern mp_obj_t cppfunc(mp_obj_t a_obj, mp_obj_t b_obj);
|
|
@ -1,16 +0,0 @@
|
|||||||
# Create an INTERFACE library for our CPP module.
|
|
||||||
add_library(usermod_cppexample INTERFACE)
|
|
||||||
|
|
||||||
# Add our source files to the library.
|
|
||||||
target_sources(usermod_cppexample INTERFACE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/example.cpp
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/examplemodule.c
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add the current directory as an include directory.
|
|
||||||
target_include_directories(usermod_cppexample INTERFACE
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Link our INTERFACE library to the usermod target.
|
|
||||||
target_link_libraries(usermod INTERFACE usermod_cppexample)
|
|
@ -1,12 +0,0 @@
|
|||||||
CPPEXAMPLE_MOD_DIR := $(USERMOD_DIR)
|
|
||||||
|
|
||||||
# Add our source files to the respective variables.
|
|
||||||
SRC_USERMOD += $(CPPEXAMPLE_MOD_DIR)/examplemodule.c
|
|
||||||
SRC_USERMOD_CXX += $(CPPEXAMPLE_MOD_DIR)/example.cpp
|
|
||||||
|
|
||||||
# Add our module directory to the include path.
|
|
||||||
CFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR)
|
|
||||||
CXXFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR)
|
|
||||||
|
|
||||||
# We use C++ features so have to link against the standard library.
|
|
||||||
LDFLAGS_USERMOD += -lstdc++
|
|
@ -1,10 +0,0 @@
|
|||||||
# This top-level micropython.cmake is responsible for listing
|
|
||||||
# the individual modules we want to include.
|
|
||||||
# Paths are absolute, and ${CMAKE_CURRENT_LIST_DIR} can be
|
|
||||||
# used to prefix subdirectories.
|
|
||||||
|
|
||||||
# Add the C example.
|
|
||||||
include(${CMAKE_CURRENT_LIST_DIR}/cexample/micropython.cmake)
|
|
||||||
|
|
||||||
# Add the CPP example.
|
|
||||||
include(${CMAKE_CURRENT_LIST_DIR}/cppexample/micropython.cmake)
|
|
@ -26,7 +26,11 @@
|
|||||||
#ifndef AXTLS_OS_PORT_H
|
#ifndef AXTLS_OS_PORT_H
|
||||||
#define AXTLS_OS_PORT_H
|
#define AXTLS_OS_PORT_H
|
||||||
|
|
||||||
|
#ifndef __ets__
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#endif
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include "py/stream.h"
|
#include "py/stream.h"
|
||||||
#include "lib/crypto-algorithms/sha256.h"
|
#include "lib/crypto-algorithms/sha256.h"
|
||||||
|
|
||||||
|
@ -1,98 +0,0 @@
|
|||||||
# CMake fragment for MicroPython extmod component
|
|
||||||
|
|
||||||
set(MICROPY_EXTMOD_DIR "${MICROPY_DIR}/extmod")
|
|
||||||
set(MICROPY_OOFATFS_DIR "${MICROPY_DIR}/lib/oofatfs")
|
|
||||||
|
|
||||||
set(MICROPY_SOURCE_EXTMOD
|
|
||||||
${MICROPY_DIR}/shared/libc/abort_.c
|
|
||||||
${MICROPY_DIR}/shared/libc/printf.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/machine_bitstream.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/machine_i2c.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/machine_mem.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/machine_pulse.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/machine_pwm.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/machine_signal.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/machine_spi.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modbluetooth.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modbtree.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modframebuf.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modnetwork.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modonewire.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moduasyncio.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modubinascii.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moducryptolib.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moductypes.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moduhashlib.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moduheapq.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modujson.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moduplatform.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modurandom.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modure.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moduselect.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modusocket.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modussl_axtls.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modussl_mbedtls.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modutimeq.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moduwebsocket.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/moduzlib.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/modwebrepl.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/uos_dupterm.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/utime_mphal.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs_blockdev.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs_fat.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs_fat_diskio.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs_fat_file.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs_lfs.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs_posix.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs_posix_file.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/vfs_reader.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/virtpin.c
|
|
||||||
${MICROPY_EXTMOD_DIR}/nimble/modbluetooth_nimble.c
|
|
||||||
)
|
|
||||||
|
|
||||||
# Library for btree module and associated code
|
|
||||||
|
|
||||||
set(MICROPY_LIB_BERKELEY_DIR "${MICROPY_DIR}/lib/berkeley-db-1.xx")
|
|
||||||
|
|
||||||
if(EXISTS "${MICROPY_LIB_BERKELEY_DIR}/btree/bt_close.c")
|
|
||||||
add_library(micropy_extmod_btree OBJECT
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_close.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_conv.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_debug.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_delete.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_get.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_open.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_overflow.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_page.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_put.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_search.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_seq.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_split.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_utils.c
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/mpool/mpool.c
|
|
||||||
)
|
|
||||||
|
|
||||||
target_include_directories(micropy_extmod_btree PRIVATE
|
|
||||||
${MICROPY_LIB_BERKELEY_DIR}/PORT/include
|
|
||||||
)
|
|
||||||
|
|
||||||
target_compile_definitions(micropy_extmod_btree PRIVATE
|
|
||||||
__DBINTERFACE_PRIVATE=1
|
|
||||||
mpool_error=printf
|
|
||||||
abort=abort_
|
|
||||||
"virt_fd_t=void*"
|
|
||||||
)
|
|
||||||
|
|
||||||
# The include directories and compile definitions below are needed to build
|
|
||||||
# modbtree.c and should be added to the main MicroPython target.
|
|
||||||
|
|
||||||
list(APPEND MICROPY_INC_CORE
|
|
||||||
"${MICROPY_LIB_BERKELEY_DIR}/PORT/include"
|
|
||||||
)
|
|
||||||
|
|
||||||
list(APPEND MICROPY_DEF_CORE
|
|
||||||
__DBINTERFACE_PRIVATE=1
|
|
||||||
"virt_fd_t=void*"
|
|
||||||
)
|
|
||||||
endif()
|
|
@ -28,8 +28,6 @@ SRC_MOD += $(addprefix $(LITTLEFS_DIR)/,\
|
|||||||
lfs1.c \
|
lfs1.c \
|
||||||
lfs1_util.c \
|
lfs1_util.c \
|
||||||
)
|
)
|
||||||
else
|
|
||||||
CFLAGS_MOD += -DMICROPY_VFS_LFS1=0
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(MICROPY_VFS_LFS2),1)
|
ifeq ($(MICROPY_VFS_LFS2),1)
|
||||||
@ -39,8 +37,6 @@ SRC_MOD += $(addprefix $(LITTLEFS_DIR)/,\
|
|||||||
lfs2.c \
|
lfs2.c \
|
||||||
lfs2_util.c \
|
lfs2_util.c \
|
||||||
)
|
)
|
||||||
else
|
|
||||||
CFLAGS_MOD += -DMICROPY_VFS_LFS2=0
|
|
||||||
|
|
||||||
$(BUILD)/$(LITTLEFS_DIR)/lfs2.o: CFLAGS += -Wno-missing-field-initializers
|
$(BUILD)/$(LITTLEFS_DIR)/lfs2.o: CFLAGS += -Wno-missing-field-initializers
|
||||||
endif
|
endif
|
||||||
@ -232,3 +228,4 @@ CFLAGS_MOD += -DMICROPY_PY_BTREE=1
|
|||||||
$(BUILD)/$(BTREE_DIR)/%.o: CFLAGS += -Wno-old-style-definition -Wno-sign-compare -Wno-unused-parameter $(BTREE_DEFS)
|
$(BUILD)/$(BTREE_DIR)/%.o: CFLAGS += -Wno-old-style-definition -Wno-sign-compare -Wno-unused-parameter $(BTREE_DEFS)
|
||||||
$(BUILD)/extmod/modbtree.o: CFLAGS += $(BTREE_DEFS)
|
$(BUILD)/extmod/modbtree.o: CFLAGS += $(BTREE_DEFS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -1,108 +1,128 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 2014 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
#ifndef MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H
|
#ifndef MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H
|
||||||
#define MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H
|
#define MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H
|
||||||
|
|
||||||
static const uint8_t font_petme128_8x8[] = {
|
static const uint8_t font_petme128_8x8[] = {
|
||||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 32=
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 32=
|
||||||
0x00,0x00,0x00,0x4f,0x4f,0x00,0x00,0x00, // 33=!
|
0x00, 0x00, 0x00, 0x4f, 0x4f, 0x00, 0x00, 0x00, // 33=!
|
||||||
0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, // 34="
|
0x00, 0x07, 0x07, 0x00, 0x00, 0x07, 0x07, 0x00, // 34="
|
||||||
0x14,0x7f,0x7f,0x14,0x14,0x7f,0x7f,0x14, // 35=#
|
0x14, 0x7f, 0x7f, 0x14, 0x14, 0x7f, 0x7f, 0x14, // 35=#
|
||||||
0x00,0x24,0x2e,0x6b,0x6b,0x3a,0x12,0x00, // 36=$
|
0x00, 0x24, 0x2e, 0x6b, 0x6b, 0x3a, 0x12, 0x00, // 36=$
|
||||||
0x00,0x63,0x33,0x18,0x0c,0x66,0x63,0x00, // 37=%
|
0x00, 0x63, 0x33, 0x18, 0x0c, 0x66, 0x63, 0x00, // 37=%
|
||||||
0x00,0x32,0x7f,0x4d,0x4d,0x77,0x72,0x50, // 38=&
|
0x00, 0x32, 0x7f, 0x4d, 0x4d, 0x77, 0x72, 0x50, // 38=&
|
||||||
0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x00, // 39='
|
0x00, 0x00, 0x00, 0x04, 0x06, 0x03, 0x01, 0x00, // 39='
|
||||||
0x00,0x00,0x1c,0x3e,0x63,0x41,0x00,0x00, // 40=(
|
0x00, 0x00, 0x1c, 0x3e, 0x63, 0x41, 0x00, 0x00, // 40=(
|
||||||
0x00,0x00,0x41,0x63,0x3e,0x1c,0x00,0x00, // 41=)
|
0x00, 0x00, 0x41, 0x63, 0x3e, 0x1c, 0x00, 0x00, // 41=)
|
||||||
0x08,0x2a,0x3e,0x1c,0x1c,0x3e,0x2a,0x08, // 42=*
|
0x08, 0x2a, 0x3e, 0x1c, 0x1c, 0x3e, 0x2a, 0x08, // 42=*
|
||||||
0x00,0x08,0x08,0x3e,0x3e,0x08,0x08,0x00, // 43=+
|
0x00, 0x08, 0x08, 0x3e, 0x3e, 0x08, 0x08, 0x00, // 43=+
|
||||||
0x00,0x00,0x80,0xe0,0x60,0x00,0x00,0x00, // 44=,
|
0x00, 0x00, 0x80, 0xe0, 0x60, 0x00, 0x00, 0x00, // 44=,
|
||||||
0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, // 45=-
|
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, // 45=-
|
||||||
0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, // 46=.
|
0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, // 46=.
|
||||||
0x00,0x40,0x60,0x30,0x18,0x0c,0x06,0x02, // 47=/
|
0x00, 0x40, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, // 47=/
|
||||||
0x00,0x3e,0x7f,0x49,0x45,0x7f,0x3e,0x00, // 48=0
|
0x00, 0x3e, 0x7f, 0x49, 0x45, 0x7f, 0x3e, 0x00, // 48=0
|
||||||
0x00,0x40,0x44,0x7f,0x7f,0x40,0x40,0x00, // 49=1
|
0x00, 0x40, 0x44, 0x7f, 0x7f, 0x40, 0x40, 0x00, // 49=1
|
||||||
0x00,0x62,0x73,0x51,0x49,0x4f,0x46,0x00, // 50=2
|
0x00, 0x62, 0x73, 0x51, 0x49, 0x4f, 0x46, 0x00, // 50=2
|
||||||
0x00,0x22,0x63,0x49,0x49,0x7f,0x36,0x00, // 51=3
|
0x00, 0x22, 0x63, 0x49, 0x49, 0x7f, 0x36, 0x00, // 51=3
|
||||||
0x00,0x18,0x18,0x14,0x16,0x7f,0x7f,0x10, // 52=4
|
0x00, 0x18, 0x18, 0x14, 0x16, 0x7f, 0x7f, 0x10, // 52=4
|
||||||
0x00,0x27,0x67,0x45,0x45,0x7d,0x39,0x00, // 53=5
|
0x00, 0x27, 0x67, 0x45, 0x45, 0x7d, 0x39, 0x00, // 53=5
|
||||||
0x00,0x3e,0x7f,0x49,0x49,0x7b,0x32,0x00, // 54=6
|
0x00, 0x3e, 0x7f, 0x49, 0x49, 0x7b, 0x32, 0x00, // 54=6
|
||||||
0x00,0x03,0x03,0x79,0x7d,0x07,0x03,0x00, // 55=7
|
0x00, 0x03, 0x03, 0x79, 0x7d, 0x07, 0x03, 0x00, // 55=7
|
||||||
0x00,0x36,0x7f,0x49,0x49,0x7f,0x36,0x00, // 56=8
|
0x00, 0x36, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00, // 56=8
|
||||||
0x00,0x26,0x6f,0x49,0x49,0x7f,0x3e,0x00, // 57=9
|
0x00, 0x26, 0x6f, 0x49, 0x49, 0x7f, 0x3e, 0x00, // 57=9
|
||||||
0x00,0x00,0x00,0x24,0x24,0x00,0x00,0x00, // 58=:
|
0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x00, // 58=:
|
||||||
0x00,0x00,0x80,0xe4,0x64,0x00,0x00,0x00, // 59=;
|
0x00, 0x00, 0x80, 0xe4, 0x64, 0x00, 0x00, 0x00, // 59=;
|
||||||
0x00,0x08,0x1c,0x36,0x63,0x41,0x41,0x00, // 60=<
|
0x00, 0x08, 0x1c, 0x36, 0x63, 0x41, 0x41, 0x00, // 60=<
|
||||||
0x00,0x14,0x14,0x14,0x14,0x14,0x14,0x00, // 61==
|
0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, // 61==
|
||||||
0x00,0x41,0x41,0x63,0x36,0x1c,0x08,0x00, // 62=>
|
0x00, 0x41, 0x41, 0x63, 0x36, 0x1c, 0x08, 0x00, // 62=>
|
||||||
0x00,0x02,0x03,0x51,0x59,0x0f,0x06,0x00, // 63=?
|
0x00, 0x02, 0x03, 0x51, 0x59, 0x0f, 0x06, 0x00, // 63=?
|
||||||
0x00,0x3e,0x7f,0x41,0x4d,0x4f,0x2e,0x00, // 64=@
|
0x00, 0x3e, 0x7f, 0x41, 0x4d, 0x4f, 0x2e, 0x00, // 64=@
|
||||||
0x00,0x7c,0x7e,0x0b,0x0b,0x7e,0x7c,0x00, // 65=A
|
0x00, 0x7c, 0x7e, 0x0b, 0x0b, 0x7e, 0x7c, 0x00, // 65=A
|
||||||
0x00,0x7f,0x7f,0x49,0x49,0x7f,0x36,0x00, // 66=B
|
0x00, 0x7f, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00, // 66=B
|
||||||
0x00,0x3e,0x7f,0x41,0x41,0x63,0x22,0x00, // 67=C
|
0x00, 0x3e, 0x7f, 0x41, 0x41, 0x63, 0x22, 0x00, // 67=C
|
||||||
0x00,0x7f,0x7f,0x41,0x63,0x3e,0x1c,0x00, // 68=D
|
0x00, 0x7f, 0x7f, 0x41, 0x63, 0x3e, 0x1c, 0x00, // 68=D
|
||||||
0x00,0x7f,0x7f,0x49,0x49,0x41,0x41,0x00, // 69=E
|
0x00, 0x7f, 0x7f, 0x49, 0x49, 0x41, 0x41, 0x00, // 69=E
|
||||||
0x00,0x7f,0x7f,0x09,0x09,0x01,0x01,0x00, // 70=F
|
0x00, 0x7f, 0x7f, 0x09, 0x09, 0x01, 0x01, 0x00, // 70=F
|
||||||
0x00,0x3e,0x7f,0x41,0x49,0x7b,0x3a,0x00, // 71=G
|
0x00, 0x3e, 0x7f, 0x41, 0x49, 0x7b, 0x3a, 0x00, // 71=G
|
||||||
0x00,0x7f,0x7f,0x08,0x08,0x7f,0x7f,0x00, // 72=H
|
0x00, 0x7f, 0x7f, 0x08, 0x08, 0x7f, 0x7f, 0x00, // 72=H
|
||||||
0x00,0x00,0x41,0x7f,0x7f,0x41,0x00,0x00, // 73=I
|
0x00, 0x00, 0x41, 0x7f, 0x7f, 0x41, 0x00, 0x00, // 73=I
|
||||||
0x00,0x20,0x60,0x41,0x7f,0x3f,0x01,0x00, // 74=J
|
0x00, 0x20, 0x60, 0x41, 0x7f, 0x3f, 0x01, 0x00, // 74=J
|
||||||
0x00,0x7f,0x7f,0x1c,0x36,0x63,0x41,0x00, // 75=K
|
0x00, 0x7f, 0x7f, 0x1c, 0x36, 0x63, 0x41, 0x00, // 75=K
|
||||||
0x00,0x7f,0x7f,0x40,0x40,0x40,0x40,0x00, // 76=L
|
0x00, 0x7f, 0x7f, 0x40, 0x40, 0x40, 0x40, 0x00, // 76=L
|
||||||
0x00,0x7f,0x7f,0x06,0x0c,0x06,0x7f,0x7f, // 77=M
|
0x00, 0x7f, 0x7f, 0x06, 0x0c, 0x06, 0x7f, 0x7f, // 77=M
|
||||||
0x00,0x7f,0x7f,0x0e,0x1c,0x7f,0x7f,0x00, // 78=N
|
0x00, 0x7f, 0x7f, 0x0e, 0x1c, 0x7f, 0x7f, 0x00, // 78=N
|
||||||
0x00,0x3e,0x7f,0x41,0x41,0x7f,0x3e,0x00, // 79=O
|
0x00, 0x3e, 0x7f, 0x41, 0x41, 0x7f, 0x3e, 0x00, // 79=O
|
||||||
0x00,0x7f,0x7f,0x09,0x09,0x0f,0x06,0x00, // 80=P
|
0x00, 0x7f, 0x7f, 0x09, 0x09, 0x0f, 0x06, 0x00, // 80=P
|
||||||
0x00,0x1e,0x3f,0x21,0x61,0x7f,0x5e,0x00, // 81=Q
|
0x00, 0x1e, 0x3f, 0x21, 0x61, 0x7f, 0x5e, 0x00, // 81=Q
|
||||||
0x00,0x7f,0x7f,0x19,0x39,0x6f,0x46,0x00, // 82=R
|
0x00, 0x7f, 0x7f, 0x19, 0x39, 0x6f, 0x46, 0x00, // 82=R
|
||||||
0x00,0x26,0x6f,0x49,0x49,0x7b,0x32,0x00, // 83=S
|
0x00, 0x26, 0x6f, 0x49, 0x49, 0x7b, 0x32, 0x00, // 83=S
|
||||||
0x00,0x01,0x01,0x7f,0x7f,0x01,0x01,0x00, // 84=T
|
0x00, 0x01, 0x01, 0x7f, 0x7f, 0x01, 0x01, 0x00, // 84=T
|
||||||
0x00,0x3f,0x7f,0x40,0x40,0x7f,0x3f,0x00, // 85=U
|
0x00, 0x3f, 0x7f, 0x40, 0x40, 0x7f, 0x3f, 0x00, // 85=U
|
||||||
0x00,0x1f,0x3f,0x60,0x60,0x3f,0x1f,0x00, // 86=V
|
0x00, 0x1f, 0x3f, 0x60, 0x60, 0x3f, 0x1f, 0x00, // 86=V
|
||||||
0x00,0x7f,0x7f,0x30,0x18,0x30,0x7f,0x7f, // 87=W
|
0x00, 0x7f, 0x7f, 0x30, 0x18, 0x30, 0x7f, 0x7f, // 87=W
|
||||||
0x00,0x63,0x77,0x1c,0x1c,0x77,0x63,0x00, // 88=X
|
0x00, 0x63, 0x77, 0x1c, 0x1c, 0x77, 0x63, 0x00, // 88=X
|
||||||
0x00,0x07,0x0f,0x78,0x78,0x0f,0x07,0x00, // 89=Y
|
0x00, 0x07, 0x0f, 0x78, 0x78, 0x0f, 0x07, 0x00, // 89=Y
|
||||||
0x00,0x61,0x71,0x59,0x4d,0x47,0x43,0x00, // 90=Z
|
0x00, 0x61, 0x71, 0x59, 0x4d, 0x47, 0x43, 0x00, // 90=Z
|
||||||
0x00,0x00,0x7f,0x7f,0x41,0x41,0x00,0x00, // 91=[
|
0x00, 0x00, 0x7f, 0x7f, 0x41, 0x41, 0x00, 0x00, // 91=[
|
||||||
0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0x40, // 92='\'
|
0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x40, // 92='\'
|
||||||
0x00,0x00,0x41,0x41,0x7f,0x7f,0x00,0x00, // 93=]
|
0x00, 0x00, 0x41, 0x41, 0x7f, 0x7f, 0x00, 0x00, // 93=]
|
||||||
0x00,0x08,0x0c,0x06,0x06,0x0c,0x08,0x00, // 94=^
|
0x00, 0x08, 0x0c, 0x06, 0x06, 0x0c, 0x08, 0x00, // 94=^
|
||||||
0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, // 95=_
|
0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, // 95=_
|
||||||
0x00,0x00,0x01,0x03,0x06,0x04,0x00,0x00, // 96=`
|
0x00, 0x00, 0x01, 0x03, 0x06, 0x04, 0x00, 0x00, // 96=`
|
||||||
0x00,0x20,0x74,0x54,0x54,0x7c,0x78,0x00, // 97=a
|
0x00, 0x20, 0x74, 0x54, 0x54, 0x7c, 0x78, 0x00, // 97=a
|
||||||
0x00,0x7f,0x7f,0x44,0x44,0x7c,0x38,0x00, // 98=b
|
0x00, 0x7f, 0x7f, 0x44, 0x44, 0x7c, 0x38, 0x00, // 98=b
|
||||||
0x00,0x38,0x7c,0x44,0x44,0x6c,0x28,0x00, // 99=c
|
0x00, 0x38, 0x7c, 0x44, 0x44, 0x6c, 0x28, 0x00, // 99=c
|
||||||
0x00,0x38,0x7c,0x44,0x44,0x7f,0x7f,0x00, // 100=d
|
0x00, 0x38, 0x7c, 0x44, 0x44, 0x7f, 0x7f, 0x00, // 100=d
|
||||||
0x00,0x38,0x7c,0x54,0x54,0x5c,0x58,0x00, // 101=e
|
0x00, 0x38, 0x7c, 0x54, 0x54, 0x5c, 0x58, 0x00, // 101=e
|
||||||
0x00,0x08,0x7e,0x7f,0x09,0x03,0x02,0x00, // 102=f
|
0x00, 0x08, 0x7e, 0x7f, 0x09, 0x03, 0x02, 0x00, // 102=f
|
||||||
0x00,0x98,0xbc,0xa4,0xa4,0xfc,0x7c,0x00, // 103=g
|
0x00, 0x98, 0xbc, 0xa4, 0xa4, 0xfc, 0x7c, 0x00, // 103=g
|
||||||
0x00,0x7f,0x7f,0x04,0x04,0x7c,0x78,0x00, // 104=h
|
0x00, 0x7f, 0x7f, 0x04, 0x04, 0x7c, 0x78, 0x00, // 104=h
|
||||||
0x00,0x00,0x00,0x7d,0x7d,0x00,0x00,0x00, // 105=i
|
0x00, 0x00, 0x00, 0x7d, 0x7d, 0x00, 0x00, 0x00, // 105=i
|
||||||
0x00,0x40,0xc0,0x80,0x80,0xfd,0x7d,0x00, // 106=j
|
0x00, 0x40, 0xc0, 0x80, 0x80, 0xfd, 0x7d, 0x00, // 106=j
|
||||||
0x00,0x7f,0x7f,0x30,0x38,0x6c,0x44,0x00, // 107=k
|
0x00, 0x7f, 0x7f, 0x30, 0x38, 0x6c, 0x44, 0x00, // 107=k
|
||||||
0x00,0x00,0x41,0x7f,0x7f,0x40,0x00,0x00, // 108=l
|
0x00, 0x00, 0x41, 0x7f, 0x7f, 0x40, 0x00, 0x00, // 108=l
|
||||||
0x00,0x7c,0x7c,0x18,0x30,0x18,0x7c,0x7c, // 109=m
|
0x00, 0x7c, 0x7c, 0x18, 0x30, 0x18, 0x7c, 0x7c, // 109=m
|
||||||
0x00,0x7c,0x7c,0x04,0x04,0x7c,0x78,0x00, // 110=n
|
0x00, 0x7c, 0x7c, 0x04, 0x04, 0x7c, 0x78, 0x00, // 110=n
|
||||||
0x00,0x38,0x7c,0x44,0x44,0x7c,0x38,0x00, // 111=o
|
0x00, 0x38, 0x7c, 0x44, 0x44, 0x7c, 0x38, 0x00, // 111=o
|
||||||
0x00,0xfc,0xfc,0x24,0x24,0x3c,0x18,0x00, // 112=p
|
0x00, 0xfc, 0xfc, 0x24, 0x24, 0x3c, 0x18, 0x00, // 112=p
|
||||||
0x00,0x18,0x3c,0x24,0x24,0xfc,0xfc,0x00, // 113=q
|
0x00, 0x18, 0x3c, 0x24, 0x24, 0xfc, 0xfc, 0x00, // 113=q
|
||||||
0x00,0x7c,0x7c,0x04,0x04,0x0c,0x08,0x00, // 114=r
|
0x00, 0x7c, 0x7c, 0x04, 0x04, 0x0c, 0x08, 0x00, // 114=r
|
||||||
0x00,0x48,0x5c,0x54,0x54,0x74,0x20,0x00, // 115=s
|
0x00, 0x48, 0x5c, 0x54, 0x54, 0x74, 0x20, 0x00, // 115=s
|
||||||
0x04,0x04,0x3f,0x7f,0x44,0x64,0x20,0x00, // 116=t
|
0x04, 0x04, 0x3f, 0x7f, 0x44, 0x64, 0x20, 0x00, // 116=t
|
||||||
0x00,0x3c,0x7c,0x40,0x40,0x7c,0x3c,0x00, // 117=u
|
0x00, 0x3c, 0x7c, 0x40, 0x40, 0x7c, 0x3c, 0x00, // 117=u
|
||||||
0x00,0x1c,0x3c,0x60,0x60,0x3c,0x1c,0x00, // 118=v
|
0x00, 0x1c, 0x3c, 0x60, 0x60, 0x3c, 0x1c, 0x00, // 118=v
|
||||||
0x00,0x1c,0x7c,0x30,0x18,0x30,0x7c,0x1c, // 119=w
|
0x00, 0x1c, 0x7c, 0x30, 0x18, 0x30, 0x7c, 0x1c, // 119=w
|
||||||
0x00,0x44,0x6c,0x38,0x38,0x6c,0x44,0x00, // 120=x
|
0x00, 0x44, 0x6c, 0x38, 0x38, 0x6c, 0x44, 0x00, // 120=x
|
||||||
0x00,0x9c,0xbc,0xa0,0xa0,0xfc,0x7c,0x00, // 121=y
|
0x00, 0x9c, 0xbc, 0xa0, 0xa0, 0xfc, 0x7c, 0x00, // 121=y
|
||||||
0x00,0x44,0x64,0x74,0x5c,0x4c,0x44,0x00, // 122=z
|
0x00, 0x44, 0x64, 0x74, 0x5c, 0x4c, 0x44, 0x00, // 122=z
|
||||||
0x00,0x08,0x08,0x3e,0x77,0x41,0x41,0x00, // 123={
|
0x00, 0x08, 0x08, 0x3e, 0x77, 0x41, 0x41, 0x00, // 123={
|
||||||
0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00, // 124=|
|
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, // 124=|
|
||||||
0x00,0x41,0x41,0x77,0x3e,0x08,0x08,0x00, // 125=}
|
0x00, 0x41, 0x41, 0x77, 0x3e, 0x08, 0x08, 0x00, // 125=}
|
||||||
0x00,0x02,0x03,0x01,0x03,0x02,0x03,0x01, // 126=~
|
0x00, 0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, // 126=~
|
||||||
0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55, // 127
|
0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, // 127
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H
|
#endif // MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H
|
||||||
|
@ -1,367 +0,0 @@
|
|||||||
// Copyright (c) 2016 Paul Sokolovsky
|
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h> // for declaration of global errno variable
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include "py/runtime.h"
|
|
||||||
#include "py/stream.h"
|
|
||||||
|
|
||||||
#if MICROPY_PY_BTREE
|
|
||||||
|
|
||||||
#include <db.h>
|
|
||||||
#include <../../btree/btree.h>
|
|
||||||
|
|
||||||
typedef struct _mp_obj_btree_t {
|
|
||||||
mp_obj_base_t base;
|
|
||||||
mp_obj_t stream; // retain a reference to prevent GC from reclaiming it
|
|
||||||
DB *db;
|
|
||||||
mp_obj_t start_key;
|
|
||||||
mp_obj_t end_key;
|
|
||||||
#define FLAG_END_KEY_INCL 1
|
|
||||||
#define FLAG_DESC 2
|
|
||||||
#define FLAG_ITER_TYPE_MASK 0xc0
|
|
||||||
#define FLAG_ITER_KEYS 0x40
|
|
||||||
#define FLAG_ITER_VALUES 0x80
|
|
||||||
#define FLAG_ITER_ITEMS 0xc0
|
|
||||||
byte flags;
|
|
||||||
byte next_flags;
|
|
||||||
} mp_obj_btree_t;
|
|
||||||
|
|
||||||
#if !MICROPY_ENABLE_DYNRUNTIME
|
|
||||||
STATIC const mp_obj_type_t btree_type;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CHECK_ERROR(res) \
|
|
||||||
if (res == RET_ERROR) { \
|
|
||||||
mp_raise_OSError(errno); \
|
|
||||||
}
|
|
||||||
|
|
||||||
void __dbpanic(DB *db) {
|
|
||||||
mp_printf(&mp_plat_print, "__dbpanic(%p)\n", db);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_btree_t *btree_new(DB *db, mp_obj_t stream) {
|
|
||||||
mp_obj_btree_t *o = m_new_obj(mp_obj_btree_t);
|
|
||||||
o->base.type = (mp_obj_type_t *)&btree_type;
|
|
||||||
o->stream = stream;
|
|
||||||
o->db = db;
|
|
||||||
o->start_key = mp_const_none;
|
|
||||||
o->end_key = mp_const_none;
|
|
||||||
o->next_flags = 0;
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void btree_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
|
||||||
(void)kind;
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
|
||||||
mp_printf(print, "<btree %p>", self->db);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_flush(mp_obj_t self_in) {
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(__bt_sync(self->db, 0));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(btree_flush_obj, btree_flush);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_close(mp_obj_t self_in) {
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(__bt_close(self->db));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(btree_close_obj, btree_close);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_put(size_t n_args, const mp_obj_t *args) {
|
|
||||||
(void)n_args;
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]);
|
|
||||||
DBT key, val;
|
|
||||||
key.data = (void *)mp_obj_str_get_data(args[1], &key.size);
|
|
||||||
val.data = (void *)mp_obj_str_get_data(args[2], &val.size);
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(__bt_put(self->db, &key, &val, 0));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_put_obj, 3, 4, btree_put);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_get(size_t n_args, const mp_obj_t *args) {
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]);
|
|
||||||
DBT key, val;
|
|
||||||
key.data = (void *)mp_obj_str_get_data(args[1], &key.size);
|
|
||||||
int res = __bt_get(self->db, &key, &val, 0);
|
|
||||||
if (res == RET_SPECIAL) {
|
|
||||||
if (n_args > 2) {
|
|
||||||
return args[2];
|
|
||||||
} else {
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CHECK_ERROR(res);
|
|
||||||
return mp_obj_new_bytes(val.data, val.size);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_get_obj, 2, 3, btree_get);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_seq(size_t n_args, const mp_obj_t *args) {
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]);
|
|
||||||
int flags = MP_OBJ_SMALL_INT_VALUE(args[1]);
|
|
||||||
DBT key, val;
|
|
||||||
if (n_args > 2) {
|
|
||||||
key.data = (void *)mp_obj_str_get_data(args[2], &key.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
int res = __bt_seq(self->db, &key, &val, flags);
|
|
||||||
CHECK_ERROR(res);
|
|
||||||
if (res == RET_SPECIAL) {
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_obj_t pair_o = mp_obj_new_tuple(2, NULL);
|
|
||||||
mp_obj_tuple_t *pair = MP_OBJ_TO_PTR(pair_o);
|
|
||||||
pair->items[0] = mp_obj_new_bytes(key.data, key.size);
|
|
||||||
pair->items[1] = mp_obj_new_bytes(val.data, val.size);
|
|
||||||
return pair_o;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_seq_obj, 2, 4, btree_seq);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_init_iter(size_t n_args, const mp_obj_t *args, byte type) {
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]);
|
|
||||||
self->next_flags = type;
|
|
||||||
self->start_key = mp_const_none;
|
|
||||||
self->end_key = mp_const_none;
|
|
||||||
if (n_args > 1) {
|
|
||||||
self->start_key = args[1];
|
|
||||||
if (n_args > 2) {
|
|
||||||
self->end_key = args[2];
|
|
||||||
if (n_args > 3) {
|
|
||||||
self->next_flags = type | MP_OBJ_SMALL_INT_VALUE(args[3]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_keys(size_t n_args, const mp_obj_t *args) {
|
|
||||||
return btree_init_iter(n_args, args, FLAG_ITER_KEYS);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_keys_obj, 1, 4, btree_keys);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_values(size_t n_args, const mp_obj_t *args) {
|
|
||||||
return btree_init_iter(n_args, args, FLAG_ITER_VALUES);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_values_obj, 1, 4, btree_values);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_items(size_t n_args, const mp_obj_t *args) {
|
|
||||||
return btree_init_iter(n_args, args, FLAG_ITER_ITEMS);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_items_obj, 1, 4, btree_items);
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) {
|
|
||||||
(void)iter_buf;
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
|
||||||
if (self->next_flags != 0) {
|
|
||||||
// If we're called immediately after keys(), values(), or items(),
|
|
||||||
// use their setup for iteration.
|
|
||||||
self->flags = self->next_flags;
|
|
||||||
self->next_flags = 0;
|
|
||||||
} else {
|
|
||||||
// Otherwise, iterate over all keys.
|
|
||||||
self->flags = FLAG_ITER_KEYS;
|
|
||||||
self->start_key = mp_const_none;
|
|
||||||
self->end_key = mp_const_none;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self_in;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_iternext(mp_obj_t self_in) {
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in);
|
|
||||||
DBT key, val;
|
|
||||||
int res;
|
|
||||||
bool desc = self->flags & FLAG_DESC;
|
|
||||||
if (self->start_key != MP_OBJ_NULL) {
|
|
||||||
int flags = R_FIRST;
|
|
||||||
if (self->start_key != mp_const_none) {
|
|
||||||
key.data = (void *)mp_obj_str_get_data(self->start_key, &key.size);
|
|
||||||
flags = R_CURSOR;
|
|
||||||
} else if (desc) {
|
|
||||||
flags = R_LAST;
|
|
||||||
}
|
|
||||||
res = __bt_seq(self->db, &key, &val, flags);
|
|
||||||
self->start_key = MP_OBJ_NULL;
|
|
||||||
} else {
|
|
||||||
res = __bt_seq(self->db, &key, &val, desc ? R_PREV : R_NEXT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res == RET_SPECIAL) {
|
|
||||||
return MP_OBJ_STOP_ITERATION;
|
|
||||||
}
|
|
||||||
CHECK_ERROR(res);
|
|
||||||
|
|
||||||
if (self->end_key != mp_const_none) {
|
|
||||||
DBT end_key;
|
|
||||||
end_key.data = (void *)mp_obj_str_get_data(self->end_key, &end_key.size);
|
|
||||||
BTREE *t = self->db->internal;
|
|
||||||
int cmp = t->bt_cmp(&key, &end_key);
|
|
||||||
if (desc) {
|
|
||||||
cmp = -cmp;
|
|
||||||
}
|
|
||||||
if (self->flags & FLAG_END_KEY_INCL) {
|
|
||||||
cmp--;
|
|
||||||
}
|
|
||||||
if (cmp >= 0) {
|
|
||||||
self->end_key = MP_OBJ_NULL;
|
|
||||||
return MP_OBJ_STOP_ITERATION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (self->flags & FLAG_ITER_TYPE_MASK) {
|
|
||||||
case FLAG_ITER_KEYS:
|
|
||||||
return mp_obj_new_bytes(key.data, key.size);
|
|
||||||
case FLAG_ITER_VALUES:
|
|
||||||
return mp_obj_new_bytes(val.data, val.size);
|
|
||||||
default: {
|
|
||||||
mp_obj_t pair_o = mp_obj_new_tuple(2, NULL);
|
|
||||||
mp_obj_tuple_t *pair = MP_OBJ_TO_PTR(pair_o);
|
|
||||||
pair->items[0] = mp_obj_new_bytes(key.data, key.size);
|
|
||||||
pair->items[1] = mp_obj_new_bytes(val.data, val.size);
|
|
||||||
return pair_o;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
|
|
||||||
mp_obj_btree_t *self = mp_obj_cast_to_native_base(self_in, &btree_type);
|
|
||||||
if (value == MP_OBJ_NULL) {
|
|
||||||
// delete
|
|
||||||
DBT key;
|
|
||||||
key.data = (void *)mp_obj_str_get_data(index, &key.size);
|
|
||||||
int res = __bt_delete(self->db, &key, 0);
|
|
||||||
if (res == RET_SPECIAL) {
|
|
||||||
mp_raise_type(&mp_type_KeyError);
|
|
||||||
}
|
|
||||||
CHECK_ERROR(res);
|
|
||||||
return mp_const_none;
|
|
||||||
} else if (value == MP_OBJ_SENTINEL) {
|
|
||||||
// load
|
|
||||||
DBT key, val;
|
|
||||||
key.data = (void *)mp_obj_str_get_data(index, &key.size);
|
|
||||||
int res = __bt_get(self->db, &key, &val, 0);
|
|
||||||
if (res == RET_SPECIAL) {
|
|
||||||
mp_raise_type(&mp_type_KeyError);
|
|
||||||
}
|
|
||||||
CHECK_ERROR(res);
|
|
||||||
return mp_obj_new_bytes(val.data, val.size);
|
|
||||||
} else {
|
|
||||||
// store
|
|
||||||
DBT key, val;
|
|
||||||
key.data = (void *)mp_obj_str_get_data(index, &key.size);
|
|
||||||
val.data = (void *)mp_obj_str_get_data(value, &val.size);
|
|
||||||
int res = __bt_put(self->db, &key, &val, 0);
|
|
||||||
CHECK_ERROR(res);
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t btree_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
|
|
||||||
mp_obj_btree_t *self = MP_OBJ_TO_PTR(lhs_in);
|
|
||||||
switch (op) {
|
|
||||||
case MP_BINARY_OP_CONTAINS: {
|
|
||||||
DBT key, val;
|
|
||||||
key.data = (void *)mp_obj_str_get_data(rhs_in, &key.size);
|
|
||||||
int res = __bt_get(self->db, &key, &val, 0);
|
|
||||||
CHECK_ERROR(res);
|
|
||||||
return mp_obj_new_bool(res != RET_SPECIAL);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
// op not supported
|
|
||||||
return MP_OBJ_NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !MICROPY_ENABLE_DYNRUNTIME
|
|
||||||
STATIC const mp_rom_map_elem_t btree_locals_dict_table[] = {
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&btree_close_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&btree_flush_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_get), MP_ROM_PTR(&btree_get_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_put), MP_ROM_PTR(&btree_put_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_seq), MP_ROM_PTR(&btree_seq_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_keys), MP_ROM_PTR(&btree_keys_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_values), MP_ROM_PTR(&btree_values_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_items), MP_ROM_PTR(&btree_items_obj) },
|
|
||||||
};
|
|
||||||
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(btree_locals_dict, btree_locals_dict_table);
|
|
||||||
|
|
||||||
STATIC const mp_obj_type_t btree_type = {
|
|
||||||
{ &mp_type_type },
|
|
||||||
// Save on qstr's, reuse same as for module
|
|
||||||
.flags = MP_TYPE_FLAG_EXTENDED,
|
|
||||||
.name = MP_QSTR_btree,
|
|
||||||
.print = btree_print,
|
|
||||||
.locals_dict = (void *)&btree_locals_dict,
|
|
||||||
MP_TYPE_EXTENDED_FIELDS(
|
|
||||||
.getiter = btree_getiter,
|
|
||||||
.iternext = btree_iternext,
|
|
||||||
.binary_op = btree_binary_op,
|
|
||||||
.subscr = btree_subscr,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
STATIC const FILEVTABLE btree_stream_fvtable = {
|
|
||||||
mp_stream_posix_read,
|
|
||||||
mp_stream_posix_write,
|
|
||||||
mp_stream_posix_lseek,
|
|
||||||
mp_stream_posix_fsync
|
|
||||||
};
|
|
||||||
|
|
||||||
#if !MICROPY_ENABLE_DYNRUNTIME
|
|
||||||
STATIC mp_obj_t mod_btree_open(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
|
||||||
static const mp_arg_t allowed_args[] = {
|
|
||||||
{ MP_QSTR_flags, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
|
||||||
{ MP_QSTR_cachesize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
|
||||||
{ MP_QSTR_pagesize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
|
||||||
{ MP_QSTR_minkeypage, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
|
||||||
};
|
|
||||||
|
|
||||||
// Make sure we got a stream object
|
|
||||||
mp_get_stream_raise(pos_args[0], MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL);
|
|
||||||
|
|
||||||
struct {
|
|
||||||
mp_arg_val_t flags;
|
|
||||||
mp_arg_val_t cachesize;
|
|
||||||
mp_arg_val_t pagesize;
|
|
||||||
mp_arg_val_t minkeypage;
|
|
||||||
} args;
|
|
||||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args,
|
|
||||||
MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args);
|
|
||||||
BTREEINFO openinfo = {0};
|
|
||||||
openinfo.flags = args.flags.u_int;
|
|
||||||
openinfo.cachesize = args.cachesize.u_int;
|
|
||||||
openinfo.psize = args.pagesize.u_int;
|
|
||||||
openinfo.minkeypage = args.minkeypage.u_int;
|
|
||||||
|
|
||||||
DB *db = __bt_open(MP_OBJ_TO_PTR(pos_args[0]), &btree_stream_fvtable, &openinfo, /*dflags*/ 0);
|
|
||||||
if (db == NULL) {
|
|
||||||
mp_raise_OSError(errno);
|
|
||||||
}
|
|
||||||
return MP_OBJ_FROM_PTR(btree_new(db, pos_args[0]));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_btree_open_obj, 1, mod_btree_open);
|
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t mp_module_btree_globals_table[] = {
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_btree) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mod_btree_open_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_INCL), MP_ROM_INT(FLAG_END_KEY_INCL) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_DESC), MP_ROM_INT(FLAG_DESC) },
|
|
||||||
};
|
|
||||||
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(mp_module_btree_globals, mp_module_btree_globals_table);
|
|
||||||
|
|
||||||
const mp_obj_module_t mp_module_btree = {
|
|
||||||
.base = { &mp_type_module },
|
|
||||||
.globals = (mp_obj_dict_t *)&mp_module_btree_globals,
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // MICROPY_PY_BTREE
|
|
@ -1,667 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "py/runtime.h"
|
|
||||||
#include "py/objtype.h"
|
|
||||||
#include "py/proto.h"
|
|
||||||
|
|
||||||
#if MICROPY_PY_FRAMEBUF
|
|
||||||
|
|
||||||
#include "font_petme128_8x8.h"
|
|
||||||
|
|
||||||
typedef struct _mp_obj_framebuf_t {
|
|
||||||
mp_obj_base_t base;
|
|
||||||
mp_obj_t buf_obj; // need to store this to prevent GC from reclaiming buf
|
|
||||||
void *buf;
|
|
||||||
uint16_t width, height, stride;
|
|
||||||
uint8_t format;
|
|
||||||
} mp_obj_framebuf_t;
|
|
||||||
|
|
||||||
#if !MICROPY_ENABLE_DYNRUNTIME
|
|
||||||
STATIC const mp_obj_type_t mp_type_framebuf;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef void (*setpixel_t)(const mp_obj_framebuf_t *, unsigned int, unsigned int, uint32_t);
|
|
||||||
typedef uint32_t (*getpixel_t)(const mp_obj_framebuf_t *, unsigned int, unsigned int);
|
|
||||||
typedef void (*fill_rect_t)(const mp_obj_framebuf_t *, unsigned int, unsigned int, unsigned int, unsigned int, uint32_t);
|
|
||||||
|
|
||||||
typedef struct _mp_framebuf_p_t {
|
|
||||||
setpixel_t setpixel;
|
|
||||||
getpixel_t getpixel;
|
|
||||||
fill_rect_t fill_rect;
|
|
||||||
} mp_framebuf_p_t;
|
|
||||||
|
|
||||||
// constants for formats
|
|
||||||
#define FRAMEBUF_MVLSB (0)
|
|
||||||
#define FRAMEBUF_RGB565 (1)
|
|
||||||
#define FRAMEBUF_GS2_HMSB (5)
|
|
||||||
#define FRAMEBUF_GS4_HMSB (2)
|
|
||||||
#define FRAMEBUF_GS8 (6)
|
|
||||||
#define FRAMEBUF_MHLSB (3)
|
|
||||||
#define FRAMEBUF_MHMSB (4)
|
|
||||||
|
|
||||||
// Functions for MHLSB and MHMSB
|
|
||||||
|
|
||||||
STATIC void mono_horiz_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
|
|
||||||
size_t index = (x + y * fb->stride) >> 3;
|
|
||||||
unsigned int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07);
|
|
||||||
((uint8_t *)fb->buf)[index] = (((uint8_t *)fb->buf)[index] & ~(0x01 << offset)) | ((col != 0) << offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC uint32_t mono_horiz_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
|
|
||||||
size_t index = (x + y * fb->stride) >> 3;
|
|
||||||
unsigned int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07);
|
|
||||||
return (((uint8_t *)fb->buf)[index] >> (offset)) & 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void mono_horiz_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
|
|
||||||
unsigned int reverse = fb->format == FRAMEBUF_MHMSB;
|
|
||||||
unsigned int advance = fb->stride >> 3;
|
|
||||||
while (w--) {
|
|
||||||
uint8_t *b = &((uint8_t *)fb->buf)[(x >> 3) + y * advance];
|
|
||||||
unsigned int offset = reverse ? x & 7 : 7 - (x & 7);
|
|
||||||
for (unsigned int hh = h; hh; --hh) {
|
|
||||||
*b = (*b & ~(0x01 << offset)) | ((col != 0) << offset);
|
|
||||||
b += advance;
|
|
||||||
}
|
|
||||||
++x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Functions for MVLSB format
|
|
||||||
|
|
||||||
STATIC void mvlsb_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
|
|
||||||
size_t index = (y >> 3) * fb->stride + x;
|
|
||||||
uint8_t offset = y & 0x07;
|
|
||||||
((uint8_t *)fb->buf)[index] = (((uint8_t *)fb->buf)[index] & ~(0x01 << offset)) | ((col != 0) << offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC uint32_t mvlsb_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
|
|
||||||
return (((uint8_t *)fb->buf)[(y >> 3) * fb->stride + x] >> (y & 0x07)) & 0x01;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void mvlsb_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
|
|
||||||
while (h--) {
|
|
||||||
uint8_t *b = &((uint8_t *)fb->buf)[(y >> 3) * fb->stride + x];
|
|
||||||
uint8_t offset = y & 0x07;
|
|
||||||
for (unsigned int ww = w; ww; --ww) {
|
|
||||||
*b = (*b & ~(0x01 << offset)) | ((col != 0) << offset);
|
|
||||||
++b;
|
|
||||||
}
|
|
||||||
++y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Functions for RGB565 format
|
|
||||||
|
|
||||||
STATIC void rgb565_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
|
|
||||||
((uint16_t *)fb->buf)[x + y * fb->stride] = col;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC uint32_t rgb565_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
|
|
||||||
return ((uint16_t *)fb->buf)[x + y * fb->stride];
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void rgb565_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
|
|
||||||
uint16_t *b = &((uint16_t *)fb->buf)[x + y * fb->stride];
|
|
||||||
while (h--) {
|
|
||||||
for (unsigned int ww = w; ww; --ww) {
|
|
||||||
*b++ = col;
|
|
||||||
}
|
|
||||||
b += fb->stride - w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Functions for GS2_HMSB format
|
|
||||||
|
|
||||||
STATIC void gs2_hmsb_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
|
|
||||||
uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 2];
|
|
||||||
uint8_t shift = (x & 0x3) << 1;
|
|
||||||
uint8_t mask = 0x3 << shift;
|
|
||||||
uint8_t color = (col & 0x3) << shift;
|
|
||||||
*pixel = color | (*pixel & (~mask));
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC uint32_t gs2_hmsb_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
|
|
||||||
uint8_t pixel = ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 2];
|
|
||||||
uint8_t shift = (x & 0x3) << 1;
|
|
||||||
return (pixel >> shift) & 0x3;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void gs2_hmsb_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
|
|
||||||
for (unsigned int xx = x; xx < x + w; xx++) {
|
|
||||||
for (unsigned int yy = y; yy < y + h; yy++) {
|
|
||||||
gs2_hmsb_setpixel(fb, xx, yy, col);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Functions for GS4_HMSB format
|
|
||||||
|
|
||||||
STATIC void gs4_hmsb_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
|
|
||||||
uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1];
|
|
||||||
|
|
||||||
if (x % 2) {
|
|
||||||
*pixel = ((uint8_t)col & 0x0f) | (*pixel & 0xf0);
|
|
||||||
} else {
|
|
||||||
*pixel = ((uint8_t)col << 4) | (*pixel & 0x0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC uint32_t gs4_hmsb_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
|
|
||||||
if (x % 2) {
|
|
||||||
return ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1] & 0x0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1] >> 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void gs4_hmsb_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
|
|
||||||
col &= 0x0f;
|
|
||||||
uint8_t *pixel_pair = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1];
|
|
||||||
uint8_t col_shifted_left = col << 4;
|
|
||||||
uint8_t col_pixel_pair = col_shifted_left | col;
|
|
||||||
unsigned int pixel_count_till_next_line = (fb->stride - w) >> 1;
|
|
||||||
bool odd_x = (x % 2 == 1);
|
|
||||||
|
|
||||||
while (h--) {
|
|
||||||
unsigned int ww = w;
|
|
||||||
|
|
||||||
if (odd_x && ww > 0) {
|
|
||||||
*pixel_pair = (*pixel_pair & 0xf0) | col;
|
|
||||||
pixel_pair++;
|
|
||||||
ww--;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(pixel_pair, col_pixel_pair, ww >> 1);
|
|
||||||
pixel_pair += ww >> 1;
|
|
||||||
|
|
||||||
if (ww % 2) {
|
|
||||||
*pixel_pair = col_shifted_left | (*pixel_pair & 0x0f);
|
|
||||||
if (!odd_x) {
|
|
||||||
pixel_pair++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pixel_pair += pixel_count_till_next_line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Functions for GS8 format
|
|
||||||
|
|
||||||
STATIC void gs8_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
|
|
||||||
uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride)];
|
|
||||||
*pixel = col & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC uint32_t gs8_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
|
|
||||||
return ((uint8_t *)fb->buf)[(x + y * fb->stride)];
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void gs8_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
|
|
||||||
uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride)];
|
|
||||||
while (h--) {
|
|
||||||
memset(pixel, col, w);
|
|
||||||
pixel += fb->stride;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC const mp_framebuf_p_t formats[] = {
|
|
||||||
[FRAMEBUF_MVLSB] = {mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect},
|
|
||||||
[FRAMEBUF_RGB565] = {rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect},
|
|
||||||
[FRAMEBUF_GS2_HMSB] = {gs2_hmsb_setpixel, gs2_hmsb_getpixel, gs2_hmsb_fill_rect},
|
|
||||||
[FRAMEBUF_GS4_HMSB] = {gs4_hmsb_setpixel, gs4_hmsb_getpixel, gs4_hmsb_fill_rect},
|
|
||||||
[FRAMEBUF_GS8] = {gs8_setpixel, gs8_getpixel, gs8_fill_rect},
|
|
||||||
[FRAMEBUF_MHLSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
|
|
||||||
[FRAMEBUF_MHMSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
|
|
||||||
formats[fb->format].setpixel(fb, x, y, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
|
|
||||||
return formats[fb->format].getpixel(fb, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
|
|
||||||
if (h < 1 || w < 1 || x + w <= 0 || y + h <= 0 || y >= fb->height || x >= fb->width) {
|
|
||||||
// No operation needed.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// clip to the framebuffer
|
|
||||||
int xend = MIN(fb->width, x + w);
|
|
||||||
int yend = MIN(fb->height, y + h);
|
|
||||||
x = MAX(x, 0);
|
|
||||||
y = MAX(y, 0);
|
|
||||||
|
|
||||||
formats[fb->format].fill_rect(fb, x, y, xend - x, yend - y, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_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, 4, 5, false);
|
|
||||||
|
|
||||||
mp_obj_framebuf_t *o = m_new_obj(mp_obj_framebuf_t);
|
|
||||||
o->base.type = type;
|
|
||||||
o->buf_obj = args[0];
|
|
||||||
|
|
||||||
mp_buffer_info_t bufinfo;
|
|
||||||
mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_WRITE);
|
|
||||||
o->buf = bufinfo.buf;
|
|
||||||
|
|
||||||
o->width = mp_obj_get_int(args[1]);
|
|
||||||
o->height = mp_obj_get_int(args[2]);
|
|
||||||
o->format = mp_obj_get_int(args[3]);
|
|
||||||
if (n_args >= 5) {
|
|
||||||
o->stride = mp_obj_get_int(args[4]);
|
|
||||||
} else {
|
|
||||||
o->stride = o->width;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (o->format) {
|
|
||||||
case FRAMEBUF_MVLSB:
|
|
||||||
case FRAMEBUF_RGB565:
|
|
||||||
break;
|
|
||||||
case FRAMEBUF_MHLSB:
|
|
||||||
case FRAMEBUF_MHMSB:
|
|
||||||
o->stride = (o->stride + 7) & ~7;
|
|
||||||
break;
|
|
||||||
case FRAMEBUF_GS2_HMSB:
|
|
||||||
o->stride = (o->stride + 3) & ~3;
|
|
||||||
break;
|
|
||||||
case FRAMEBUF_GS4_HMSB:
|
|
||||||
o->stride = (o->stride + 1) & ~1;
|
|
||||||
break;
|
|
||||||
case FRAMEBUF_GS8:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("invalid format"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return MP_OBJ_FROM_PTR(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !(defined(MICROPY_ENABLE_DYNRUNTIME) && MICROPY_ENABLE_DYNRUNTIME)
|
|
||||||
STATIC const mp_obj_type_t mp_type_framebuf;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Helper to ensure we have the native super class instead of a subclass.
|
|
||||||
static mp_obj_framebuf_t *native_framebuf(mp_obj_t framebuf_obj) {
|
|
||||||
mp_obj_t native_framebuf = mp_obj_cast_to_native_base(framebuf_obj, &mp_type_framebuf);
|
|
||||||
mp_obj_assert_native_inited(native_framebuf);
|
|
||||||
if (native_framebuf == MP_OBJ_NULL) {
|
|
||||||
mp_raise_TypeError(NULL);
|
|
||||||
}
|
|
||||||
return MP_OBJ_TO_PTR(native_framebuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_int_t framebuf_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
|
|
||||||
(void)flags;
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(self_in);
|
|
||||||
bufinfo->buf = self->buf;
|
|
||||||
bufinfo->len = self->stride * self->height * (self->format == FRAMEBUF_RGB565 ? 2 : 1);
|
|
||||||
bufinfo->typecode = 'B'; // view framebuf as bytes
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_fill(mp_obj_t self_in, mp_obj_t col_in) {
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(self_in);
|
|
||||||
mp_int_t col = mp_obj_get_int(col_in);
|
|
||||||
formats[self->format].fill_rect(self, 0, 0, self->width, self->height, col);
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(framebuf_fill_obj, framebuf_fill);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_fill_rect(size_t n_args, const mp_obj_t *args) {
|
|
||||||
(void)n_args;
|
|
||||||
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
|
||||||
mp_int_t x = mp_obj_get_int(args[1]);
|
|
||||||
mp_int_t y = mp_obj_get_int(args[2]);
|
|
||||||
mp_int_t width = mp_obj_get_int(args[3]);
|
|
||||||
mp_int_t height = mp_obj_get_int(args[4]);
|
|
||||||
mp_int_t col = mp_obj_get_int(args[5]);
|
|
||||||
|
|
||||||
fill_rect(self, x, y, width, height, col);
|
|
||||||
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_fill_rect_obj, 6, 6, framebuf_fill_rect);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_pixel(size_t n_args, const mp_obj_t *args) {
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
|
||||||
mp_int_t x = mp_obj_get_int(args[1]);
|
|
||||||
mp_int_t y = mp_obj_get_int(args[2]);
|
|
||||||
if (0 <= x && x < self->width && 0 <= y && y < self->height) {
|
|
||||||
if (n_args == 3) {
|
|
||||||
// get
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(getpixel(self, x, y));
|
|
||||||
} else {
|
|
||||||
// set
|
|
||||||
setpixel(self, x, y, mp_obj_get_int(args[3]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_pixel_obj, 3, 4, framebuf_pixel);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_hline(size_t n_args, const mp_obj_t *args) {
|
|
||||||
(void)n_args;
|
|
||||||
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
|
||||||
mp_int_t x = mp_obj_get_int(args[1]);
|
|
||||||
mp_int_t y = mp_obj_get_int(args[2]);
|
|
||||||
mp_int_t w = mp_obj_get_int(args[3]);
|
|
||||||
mp_int_t col = mp_obj_get_int(args[4]);
|
|
||||||
|
|
||||||
fill_rect(self, x, y, w, 1, col);
|
|
||||||
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_hline_obj, 5, 5, framebuf_hline);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_vline(size_t n_args, const mp_obj_t *args) {
|
|
||||||
(void)n_args;
|
|
||||||
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
|
||||||
mp_int_t x = mp_obj_get_int(args[1]);
|
|
||||||
mp_int_t y = mp_obj_get_int(args[2]);
|
|
||||||
mp_int_t h = mp_obj_get_int(args[3]);
|
|
||||||
mp_int_t col = mp_obj_get_int(args[4]);
|
|
||||||
|
|
||||||
fill_rect(self, x, y, 1, h, col);
|
|
||||||
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_vline_obj, 5, 5, framebuf_vline);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_rect(size_t n_args, const mp_obj_t *args) {
|
|
||||||
(void)n_args;
|
|
||||||
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
|
||||||
mp_int_t x = mp_obj_get_int(args[1]);
|
|
||||||
mp_int_t y = mp_obj_get_int(args[2]);
|
|
||||||
mp_int_t w = mp_obj_get_int(args[3]);
|
|
||||||
mp_int_t h = mp_obj_get_int(args[4]);
|
|
||||||
mp_int_t col = mp_obj_get_int(args[5]);
|
|
||||||
|
|
||||||
fill_rect(self, x, y, w, 1, col);
|
|
||||||
fill_rect(self, x, y + h - 1, w, 1, col);
|
|
||||||
fill_rect(self, x, y, 1, h, col);
|
|
||||||
fill_rect(self, x + w - 1, y, 1, h, col);
|
|
||||||
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_rect_obj, 6, 6, framebuf_rect);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args) {
|
|
||||||
(void)n_args;
|
|
||||||
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
|
||||||
mp_int_t x1 = mp_obj_get_int(args[1]);
|
|
||||||
mp_int_t y1 = mp_obj_get_int(args[2]);
|
|
||||||
mp_int_t x2 = mp_obj_get_int(args[3]);
|
|
||||||
mp_int_t y2 = mp_obj_get_int(args[4]);
|
|
||||||
mp_int_t col = mp_obj_get_int(args[5]);
|
|
||||||
|
|
||||||
mp_int_t dx = x2 - x1;
|
|
||||||
mp_int_t sx;
|
|
||||||
if (dx > 0) {
|
|
||||||
sx = 1;
|
|
||||||
} else {
|
|
||||||
dx = -dx;
|
|
||||||
sx = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_int_t dy = y2 - y1;
|
|
||||||
mp_int_t sy;
|
|
||||||
if (dy > 0) {
|
|
||||||
sy = 1;
|
|
||||||
} else {
|
|
||||||
dy = -dy;
|
|
||||||
sy = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool steep;
|
|
||||||
if (dy > dx) {
|
|
||||||
mp_int_t temp;
|
|
||||||
temp = x1;
|
|
||||||
x1 = y1;
|
|
||||||
y1 = temp;
|
|
||||||
temp = dx;
|
|
||||||
dx = dy;
|
|
||||||
dy = temp;
|
|
||||||
temp = sx;
|
|
||||||
sx = sy;
|
|
||||||
sy = temp;
|
|
||||||
steep = true;
|
|
||||||
} else {
|
|
||||||
steep = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_int_t e = 2 * dy - dx;
|
|
||||||
for (mp_int_t i = 0; i < dx; ++i) {
|
|
||||||
if (steep) {
|
|
||||||
if (0 <= y1 && y1 < self->width && 0 <= x1 && x1 < self->height) {
|
|
||||||
setpixel(self, y1, x1, col);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (0 <= x1 && x1 < self->width && 0 <= y1 && y1 < self->height) {
|
|
||||||
setpixel(self, x1, y1, col);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (e >= 0) {
|
|
||||||
y1 += sy;
|
|
||||||
e -= 2 * dx;
|
|
||||||
}
|
|
||||||
x1 += sx;
|
|
||||||
e += 2 * dy;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 <= x2 && x2 < self->width && 0 <= y2 && y2 < self->height) {
|
|
||||||
setpixel(self, x2, y2, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_line_obj, 6, 6, framebuf_line);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args) {
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
|
||||||
mp_obj_framebuf_t *source = native_framebuf(args[1]);
|
|
||||||
mp_int_t x = mp_obj_get_int(args[2]);
|
|
||||||
mp_int_t y = mp_obj_get_int(args[3]);
|
|
||||||
mp_int_t key = -1;
|
|
||||||
if (n_args > 4) {
|
|
||||||
key = mp_obj_get_int(args[4]);
|
|
||||||
}
|
|
||||||
mp_obj_framebuf_t *palette = NULL;
|
|
||||||
if (n_args > 5 && args[5] != mp_const_none) {
|
|
||||||
palette = MP_OBJ_TO_PTR(mp_obj_cast_to_native_base(args[5], MP_OBJ_FROM_PTR(&mp_type_framebuf)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(x >= self->width) ||
|
|
||||||
(y >= self->height) ||
|
|
||||||
(-x >= source->width) ||
|
|
||||||
(-y >= source->height)
|
|
||||||
) {
|
|
||||||
// Out of bounds, no-op.
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clip.
|
|
||||||
int x0 = MAX(0, x);
|
|
||||||
int y0 = MAX(0, y);
|
|
||||||
int x1 = MAX(0, -x);
|
|
||||||
int y1 = MAX(0, -y);
|
|
||||||
int x0end = MIN(self->width, x + source->width);
|
|
||||||
int y0end = MIN(self->height, y + source->height);
|
|
||||||
|
|
||||||
for (; y0 < y0end; ++y0) {
|
|
||||||
int cx1 = x1;
|
|
||||||
for (int cx0 = x0; cx0 < x0end; ++cx0) {
|
|
||||||
uint32_t col = getpixel(source, cx1, y1);
|
|
||||||
if (palette) {
|
|
||||||
col = getpixel(palette, col, 0);
|
|
||||||
}
|
|
||||||
if (col != (uint32_t)key) {
|
|
||||||
setpixel(self, cx0, y0, col);
|
|
||||||
}
|
|
||||||
++cx1;
|
|
||||||
}
|
|
||||||
++y1;
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_blit_obj, 4, 6, framebuf_blit);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t ystep_in) {
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(self_in);
|
|
||||||
mp_int_t xstep = mp_obj_get_int(xstep_in);
|
|
||||||
mp_int_t ystep = mp_obj_get_int(ystep_in);
|
|
||||||
int sx, y, xend, yend, dx, dy;
|
|
||||||
if (xstep < 0) {
|
|
||||||
sx = 0;
|
|
||||||
xend = self->width + xstep;
|
|
||||||
dx = 1;
|
|
||||||
} else {
|
|
||||||
sx = self->width - 1;
|
|
||||||
xend = xstep - 1;
|
|
||||||
dx = -1;
|
|
||||||
}
|
|
||||||
if (ystep < 0) {
|
|
||||||
y = 0;
|
|
||||||
yend = self->height + ystep;
|
|
||||||
dy = 1;
|
|
||||||
} else {
|
|
||||||
y = self->height - 1;
|
|
||||||
yend = ystep - 1;
|
|
||||||
dy = -1;
|
|
||||||
}
|
|
||||||
for (; y != yend; y += dy) {
|
|
||||||
for (int x = sx; x != xend; x += dx) {
|
|
||||||
setpixel(self, x, y, getpixel(self, x - xstep, y - ystep));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(framebuf_scroll_obj, framebuf_scroll);
|
|
||||||
|
|
||||||
STATIC mp_obj_t framebuf_text(size_t n_args, const mp_obj_t *args) {
|
|
||||||
// extract arguments
|
|
||||||
mp_obj_framebuf_t *self = native_framebuf(args[0]);
|
|
||||||
const char *str = mp_obj_str_get_str(args[1]);
|
|
||||||
mp_int_t x0 = mp_obj_get_int(args[2]);
|
|
||||||
mp_int_t y0 = mp_obj_get_int(args[3]);
|
|
||||||
mp_int_t col = 1;
|
|
||||||
if (n_args >= 5) {
|
|
||||||
col = mp_obj_get_int(args[4]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// loop over chars
|
|
||||||
for (; *str; ++str) {
|
|
||||||
// get char and make sure its in range of font
|
|
||||||
int chr = *(uint8_t *)str;
|
|
||||||
if (chr < 32 || chr > 127) {
|
|
||||||
chr = 127;
|
|
||||||
}
|
|
||||||
// get char data
|
|
||||||
const uint8_t *chr_data = &font_petme128_8x8[(chr - 32) * 8];
|
|
||||||
// loop over char data
|
|
||||||
for (int j = 0; j < 8; j++, x0++) {
|
|
||||||
if (0 <= x0 && x0 < self->width) { // clip x
|
|
||||||
uint vline_data = chr_data[j]; // each byte is a column of 8 pixels, LSB at top
|
|
||||||
for (int y = y0; vline_data; vline_data >>= 1, y++) { // scan over vertical column
|
|
||||||
if (vline_data & 1) { // only draw if pixel set
|
|
||||||
if (0 <= y && y < self->height) { // clip y
|
|
||||||
setpixel(self, x0, y, col);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_text_obj, 4, 5, framebuf_text);
|
|
||||||
|
|
||||||
#if !MICROPY_ENABLE_DYNRUNTIME
|
|
||||||
STATIC const mp_rom_map_elem_t framebuf_locals_dict_table[] = {
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_fill), MP_ROM_PTR(&framebuf_fill_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_fill_rect), MP_ROM_PTR(&framebuf_fill_rect_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_pixel), MP_ROM_PTR(&framebuf_pixel_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_hline), MP_ROM_PTR(&framebuf_hline_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_vline), MP_ROM_PTR(&framebuf_vline_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_rect), MP_ROM_PTR(&framebuf_rect_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_line), MP_ROM_PTR(&framebuf_line_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_blit), MP_ROM_PTR(&framebuf_blit_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_scroll), MP_ROM_PTR(&framebuf_scroll_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_text), MP_ROM_PTR(&framebuf_text_obj) },
|
|
||||||
};
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(framebuf_locals_dict, framebuf_locals_dict_table);
|
|
||||||
|
|
||||||
STATIC const mp_obj_type_t mp_type_framebuf = {
|
|
||||||
{ &mp_type_type },
|
|
||||||
.flags = MP_TYPE_FLAG_EXTENDED,
|
|
||||||
.name = MP_QSTR_FrameBuffer,
|
|
||||||
.make_new = framebuf_make_new,
|
|
||||||
.locals_dict = (mp_obj_dict_t *)&framebuf_locals_dict,
|
|
||||||
MP_TYPE_EXTENDED_FIELDS(
|
|
||||||
.buffer_p = { .get_buffer = framebuf_get_buffer },
|
|
||||||
),
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// this factory function is provided for backwards compatibility with old FrameBuffer1 class
|
|
||||||
STATIC mp_obj_t legacy_framebuffer1(size_t n_args, const mp_obj_t *args) {
|
|
||||||
mp_obj_framebuf_t *o = m_new_obj(mp_obj_framebuf_t);
|
|
||||||
o->base.type = (mp_obj_type_t *)&mp_type_framebuf;
|
|
||||||
|
|
||||||
mp_buffer_info_t bufinfo;
|
|
||||||
mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_WRITE);
|
|
||||||
o->buf = bufinfo.buf;
|
|
||||||
|
|
||||||
o->width = mp_obj_get_int(args[1]);
|
|
||||||
o->height = mp_obj_get_int(args[2]);
|
|
||||||
o->format = FRAMEBUF_MVLSB;
|
|
||||||
if (n_args >= 4) {
|
|
||||||
o->stride = mp_obj_get_int(args[3]);
|
|
||||||
} else {
|
|
||||||
o->stride = o->width;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MP_OBJ_FROM_PTR(o);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(legacy_framebuffer1_obj, 3, 4, legacy_framebuffer1);
|
|
||||||
|
|
||||||
#if !MICROPY_ENABLE_DYNRUNTIME
|
|
||||||
STATIC const mp_rom_map_elem_t framebuf_module_globals_table[] = {
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_framebuf) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_FrameBuffer), MP_ROM_PTR(&mp_type_framebuf) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_FrameBuffer1), MP_ROM_PTR(&legacy_framebuffer1_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_MVLSB), MP_ROM_INT(FRAMEBUF_MVLSB) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_MONO_VLSB), MP_ROM_INT(FRAMEBUF_MVLSB) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_RGB565), MP_ROM_INT(FRAMEBUF_RGB565) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_GS2_HMSB), MP_ROM_INT(FRAMEBUF_GS2_HMSB) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_GS4_HMSB), MP_ROM_INT(FRAMEBUF_GS4_HMSB) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_GS8), MP_ROM_INT(FRAMEBUF_GS8) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_MONO_HLSB), MP_ROM_INT(FRAMEBUF_MHLSB) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_MONO_HMSB), MP_ROM_INT(FRAMEBUF_MHMSB) },
|
|
||||||
};
|
|
||||||
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(framebuf_module_globals, framebuf_module_globals_table);
|
|
||||||
|
|
||||||
const mp_obj_module_t mp_module_framebuf = {
|
|
||||||
.base = { &mp_type_module },
|
|
||||||
.globals = (mp_obj_dict_t *)&framebuf_module_globals,
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // MICROPY_PY_FRAMEBUF
|
|
@ -1,145 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2015-2017 Damien P. George
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "py/obj.h"
|
|
||||||
#include "py/mphal.h"
|
|
||||||
|
|
||||||
#if MICROPY_PY_ONEWIRE
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
// Low-level 1-Wire routines
|
|
||||||
|
|
||||||
#define TIMING_RESET1 (480)
|
|
||||||
#define TIMING_RESET2 (70)
|
|
||||||
#define TIMING_RESET3 (410)
|
|
||||||
#define TIMING_READ1 (5)
|
|
||||||
#define TIMING_READ2 (5)
|
|
||||||
#define TIMING_READ3 (40)
|
|
||||||
#define TIMING_WRITE1 (10)
|
|
||||||
#define TIMING_WRITE2 (50)
|
|
||||||
#define TIMING_WRITE3 (10)
|
|
||||||
|
|
||||||
STATIC int onewire_bus_reset(mp_hal_pin_obj_t pin) {
|
|
||||||
mp_hal_pin_od_low(pin);
|
|
||||||
mp_hal_delay_us(TIMING_RESET1);
|
|
||||||
uint32_t i = mp_hal_quiet_timing_enter();
|
|
||||||
mp_hal_pin_od_high(pin);
|
|
||||||
mp_hal_delay_us_fast(TIMING_RESET2);
|
|
||||||
int status = !mp_hal_pin_read(pin);
|
|
||||||
mp_hal_quiet_timing_exit(i);
|
|
||||||
mp_hal_delay_us(TIMING_RESET3);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC int onewire_bus_readbit(mp_hal_pin_obj_t pin) {
|
|
||||||
mp_hal_pin_od_high(pin);
|
|
||||||
uint32_t i = mp_hal_quiet_timing_enter();
|
|
||||||
mp_hal_pin_od_low(pin);
|
|
||||||
mp_hal_delay_us_fast(TIMING_READ1);
|
|
||||||
mp_hal_pin_od_high(pin);
|
|
||||||
mp_hal_delay_us_fast(TIMING_READ2);
|
|
||||||
int value = mp_hal_pin_read(pin);
|
|
||||||
mp_hal_quiet_timing_exit(i);
|
|
||||||
mp_hal_delay_us_fast(TIMING_READ3);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void onewire_bus_writebit(mp_hal_pin_obj_t pin, int value) {
|
|
||||||
uint32_t i = mp_hal_quiet_timing_enter();
|
|
||||||
mp_hal_pin_od_low(pin);
|
|
||||||
mp_hal_delay_us_fast(TIMING_WRITE1);
|
|
||||||
if (value) {
|
|
||||||
mp_hal_pin_od_high(pin);
|
|
||||||
}
|
|
||||||
mp_hal_delay_us_fast(TIMING_WRITE2);
|
|
||||||
mp_hal_pin_od_high(pin);
|
|
||||||
mp_hal_delay_us_fast(TIMING_WRITE3);
|
|
||||||
mp_hal_quiet_timing_exit(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
// MicroPython bindings
|
|
||||||
|
|
||||||
STATIC mp_obj_t onewire_reset(mp_obj_t pin_in) {
|
|
||||||
return mp_obj_new_bool(onewire_bus_reset(mp_hal_get_pin_obj(pin_in)));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(onewire_reset_obj, onewire_reset);
|
|
||||||
|
|
||||||
STATIC mp_obj_t onewire_readbit(mp_obj_t pin_in) {
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(onewire_bus_readbit(mp_hal_get_pin_obj(pin_in)));
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(onewire_readbit_obj, onewire_readbit);
|
|
||||||
|
|
||||||
STATIC mp_obj_t onewire_readbyte(mp_obj_t pin_in) {
|
|
||||||
mp_hal_pin_obj_t pin = mp_hal_get_pin_obj(pin_in);
|
|
||||||
uint8_t value = 0;
|
|
||||||
for (int i = 0; i < 8; ++i) {
|
|
||||||
value |= onewire_bus_readbit(pin) << i;
|
|
||||||
}
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(value);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(onewire_readbyte_obj, onewire_readbyte);
|
|
||||||
|
|
||||||
STATIC mp_obj_t onewire_writebit(mp_obj_t pin_in, mp_obj_t value_in) {
|
|
||||||
onewire_bus_writebit(mp_hal_get_pin_obj(pin_in), mp_obj_get_int(value_in));
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(onewire_writebit_obj, onewire_writebit);
|
|
||||||
|
|
||||||
STATIC mp_obj_t onewire_writebyte(mp_obj_t pin_in, mp_obj_t value_in) {
|
|
||||||
mp_hal_pin_obj_t pin = mp_hal_get_pin_obj(pin_in);
|
|
||||||
int value = mp_obj_get_int(value_in);
|
|
||||||
for (int i = 0; i < 8; ++i) {
|
|
||||||
onewire_bus_writebit(pin, value & 1);
|
|
||||||
value >>= 1;
|
|
||||||
}
|
|
||||||
return mp_const_none;
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(onewire_writebyte_obj, onewire_writebyte);
|
|
||||||
|
|
||||||
STATIC mp_obj_t onewire_crc8(mp_obj_t data) {
|
|
||||||
mp_buffer_info_t bufinfo;
|
|
||||||
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
|
|
||||||
uint8_t crc = 0;
|
|
||||||
for (size_t i = 0; i < bufinfo.len; ++i) {
|
|
||||||
uint8_t byte = ((uint8_t *)bufinfo.buf)[i];
|
|
||||||
for (int b = 0; b < 8; ++b) {
|
|
||||||
uint8_t fb_bit = (crc ^ byte) & 0x01;
|
|
||||||
if (fb_bit == 0x01) {
|
|
||||||
crc = crc ^ 0x18;
|
|
||||||
}
|
|
||||||
crc = (crc >> 1) & 0x7f;
|
|
||||||
if (fb_bit == 0x01) {
|
|
||||||
crc = crc | 0x80;
|
|
||||||
}
|
|
||||||
byte = byte >> 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return MP_OBJ_NEW_SMALL_INT(crc);
|
|
||||||
}
|
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(onewire_crc8_obj, onewire_crc8);
|
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t onewire_module_globals_table[] = {
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_onewire) },
|
|
||||||
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&onewire_reset_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_readbit), MP_ROM_PTR(&onewire_readbit_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_readbyte), MP_ROM_PTR(&onewire_readbyte_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_writebit), MP_ROM_PTR(&onewire_writebit_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_writebyte), MP_ROM_PTR(&onewire_writebyte_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_crc8), MP_ROM_PTR(&onewire_crc8_obj) },
|
|
||||||
};
|
|
||||||
|
|
||||||
STATIC MP_DEFINE_CONST_DICT(onewire_module_globals, onewire_module_globals_table);
|
|
||||||
|
|
||||||
const mp_obj_module_t mp_module_onewire = {
|
|
||||||
.base = { &mp_type_module },
|
|
||||||
.globals = (mp_obj_dict_t *)&onewire_module_globals,
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MICROPY_PY_ONEWIRE
|
|
@ -70,6 +70,7 @@ STATIC mp_obj_t task_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf);
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
// Ticks for task ordering in pairing heap
|
// Ticks for task ordering in pairing heap
|
||||||
|
|
||||||
|
// CIRCUITPY-style ticks
|
||||||
#define _TICKS_PERIOD (1lu << 29)
|
#define _TICKS_PERIOD (1lu << 29)
|
||||||
#define _TICKS_MAX (_TICKS_PERIOD - 1)
|
#define _TICKS_MAX (_TICKS_PERIOD - 1)
|
||||||
#define _TICKS_HALFPERIOD (_TICKS_PERIOD >> 1)
|
#define _TICKS_HALFPERIOD (_TICKS_PERIOD >> 1)
|
||||||
@ -105,8 +106,7 @@ STATIC int task_lt(mp_pairheap_t *n1, mp_pairheap_t *n2) {
|
|||||||
STATIC mp_obj_t task_queue_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
STATIC mp_obj_t task_queue_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||||
(void)args;
|
(void)args;
|
||||||
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
||||||
mp_obj_task_queue_t *self = m_new_obj(mp_obj_task_queue_t);
|
mp_obj_task_queue_t *self = mp_obj_malloc(mp_obj_task_queue_t, type);
|
||||||
self->base.type = type;
|
|
||||||
self->heap = (mp_obj_task_t *)mp_pairheap_new(task_lt);
|
self->heap = (mp_obj_task_t *)mp_pairheap_new(task_lt);
|
||||||
return MP_OBJ_FROM_PTR(self);
|
return MP_OBJ_FROM_PTR(self);
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ STATIC mp_obj_t task_queue_peek(mp_obj_t self_in) {
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_peek_obj, task_queue_peek);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_peek_obj, task_queue_peek);
|
||||||
|
|
||||||
STATIC mp_obj_t task_queue_push_sorted(size_t n_args, const mp_obj_t *args) {
|
STATIC mp_obj_t task_queue_push(size_t n_args, const mp_obj_t *args) {
|
||||||
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(args[0]);
|
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||||
mp_obj_task_t *task = MP_OBJ_TO_PTR(args[1]);
|
mp_obj_task_t *task = MP_OBJ_TO_PTR(args[1]);
|
||||||
task->data = mp_const_none;
|
task->data = mp_const_none;
|
||||||
@ -134,9 +134,9 @@ STATIC mp_obj_t task_queue_push_sorted(size_t n_args, const mp_obj_t *args) {
|
|||||||
self->heap = (mp_obj_task_t *)mp_pairheap_push(task_lt, TASK_PAIRHEAP(self->heap), TASK_PAIRHEAP(task));
|
self->heap = (mp_obj_task_t *)mp_pairheap_push(task_lt, TASK_PAIRHEAP(self->heap), TASK_PAIRHEAP(task));
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(task_queue_push_sorted_obj, 2, 3, task_queue_push_sorted);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(task_queue_push_obj, 2, 3, task_queue_push);
|
||||||
|
|
||||||
STATIC mp_obj_t task_queue_pop_head(mp_obj_t self_in) {
|
STATIC mp_obj_t task_queue_pop(mp_obj_t self_in) {
|
||||||
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
mp_obj_task_t *head = (mp_obj_task_t *)mp_pairheap_peek(task_lt, &self->heap->pairheap);
|
mp_obj_task_t *head = (mp_obj_task_t *)mp_pairheap_peek(task_lt, &self->heap->pairheap);
|
||||||
if (head == NULL) {
|
if (head == NULL) {
|
||||||
@ -145,7 +145,7 @@ STATIC mp_obj_t task_queue_pop_head(mp_obj_t self_in) {
|
|||||||
self->heap = (mp_obj_task_t *)mp_pairheap_pop(task_lt, &self->heap->pairheap);
|
self->heap = (mp_obj_task_t *)mp_pairheap_pop(task_lt, &self->heap->pairheap);
|
||||||
return MP_OBJ_FROM_PTR(head);
|
return MP_OBJ_FROM_PTR(head);
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_pop_head_obj, task_queue_pop_head);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_pop_obj, task_queue_pop);
|
||||||
|
|
||||||
STATIC mp_obj_t task_queue_remove(mp_obj_t self_in, mp_obj_t task_in) {
|
STATIC mp_obj_t task_queue_remove(mp_obj_t self_in, mp_obj_t task_in) {
|
||||||
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
@ -157,9 +157,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(task_queue_remove_obj, task_queue_remove);
|
|||||||
|
|
||||||
STATIC const mp_rom_map_elem_t task_queue_locals_dict_table[] = {
|
STATIC const mp_rom_map_elem_t task_queue_locals_dict_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_peek), MP_ROM_PTR(&task_queue_peek_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_peek), MP_ROM_PTR(&task_queue_peek_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_push_sorted), MP_ROM_PTR(&task_queue_push_sorted_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_push), MP_ROM_PTR(&task_queue_push_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_push_head), MP_ROM_PTR(&task_queue_push_sorted_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_pop), MP_ROM_PTR(&task_queue_pop_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_pop_head), MP_ROM_PTR(&task_queue_pop_head_obj) },
|
|
||||||
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&task_queue_remove_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&task_queue_remove_obj) },
|
||||||
};
|
};
|
||||||
STATIC MP_DEFINE_CONST_DICT(task_queue_locals_dict, task_queue_locals_dict_table);
|
STATIC MP_DEFINE_CONST_DICT(task_queue_locals_dict, task_queue_locals_dict_table);
|
||||||
@ -223,18 +222,18 @@ STATIC mp_obj_t task_cancel(mp_obj_t self_in) {
|
|||||||
// Not on the main running queue, remove the task from the queue it's on.
|
// Not on the main running queue, remove the task from the queue it's on.
|
||||||
dest[2] = MP_OBJ_FROM_PTR(self);
|
dest[2] = MP_OBJ_FROM_PTR(self);
|
||||||
mp_call_method_n_kw(1, 0, dest);
|
mp_call_method_n_kw(1, 0, dest);
|
||||||
// _task_queue.push_head(self)
|
// _task_queue.push(self)
|
||||||
dest[0] = _task_queue;
|
dest[0] = _task_queue;
|
||||||
dest[1] = MP_OBJ_FROM_PTR(self);
|
dest[1] = MP_OBJ_FROM_PTR(self);
|
||||||
task_queue_push_sorted(2, dest);
|
task_queue_push(2, dest);
|
||||||
} else if (ticks_diff(self->ph_key, ticks()) > 0) {
|
} else if (ticks_diff(self->ph_key, ticks()) > 0) {
|
||||||
// On the main running queue but scheduled in the future, so bring it forward to now.
|
// On the main running queue but scheduled in the future, so bring it forward to now.
|
||||||
// _task_queue.remove(self)
|
// _task_queue.remove(self)
|
||||||
task_queue_remove(_task_queue, MP_OBJ_FROM_PTR(self));
|
task_queue_remove(_task_queue, MP_OBJ_FROM_PTR(self));
|
||||||
// _task_queue.push_head(self)
|
// _task_queue.push(self)
|
||||||
dest[0] = _task_queue;
|
dest[0] = _task_queue;
|
||||||
dest[1] = MP_OBJ_FROM_PTR(self);
|
dest[1] = MP_OBJ_FROM_PTR(self);
|
||||||
task_queue_push_sorted(2, dest);
|
task_queue_push(2, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
self->data = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_CancelledError));
|
self->data = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_CancelledError));
|
||||||
@ -243,6 +242,7 @@ STATIC mp_obj_t task_cancel(mp_obj_t self_in) {
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_cancel_obj, task_cancel);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_cancel_obj, task_cancel);
|
||||||
|
|
||||||
|
// CIRCUITPY provides __await__().
|
||||||
STATIC mp_obj_t task_await(mp_obj_t self_in) {
|
STATIC mp_obj_t task_await(mp_obj_t self_in) {
|
||||||
return task_getiter(self_in, NULL);
|
return task_getiter(self_in, NULL);
|
||||||
}
|
}
|
||||||
@ -266,6 +266,7 @@ STATIC void task_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
|||||||
dest[1] = self_in;
|
dest[1] = self_in;
|
||||||
} else if (attr == MP_QSTR_ph_key) {
|
} else if (attr == MP_QSTR_ph_key) {
|
||||||
dest[0] = self->ph_key;
|
dest[0] = self->ph_key;
|
||||||
|
// CIRCUITPY provides __await__().
|
||||||
} else if (attr == MP_QSTR___await__) {
|
} else if (attr == MP_QSTR___await__) {
|
||||||
dest[0] = MP_OBJ_FROM_PTR(&task_await_obj);
|
dest[0] = MP_OBJ_FROM_PTR(&task_await_obj);
|
||||||
dest[1] = self_in;
|
dest[1] = self_in;
|
||||||
@ -291,6 +292,9 @@ STATIC mp_obj_t task_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) {
|
|||||||
} else if (self->state == TASK_STATE_RUNNING_NOT_WAITED_ON) {
|
} else if (self->state == TASK_STATE_RUNNING_NOT_WAITED_ON) {
|
||||||
// Allocate the waiting queue.
|
// Allocate the waiting queue.
|
||||||
self->state = task_queue_make_new(&task_queue_type, 0, 0, NULL);
|
self->state = task_queue_make_new(&task_queue_type, 0, 0, NULL);
|
||||||
|
} else if (mp_obj_get_type(self->state) != &task_queue_type) {
|
||||||
|
// Task has state used for another purpose, so can't also wait on it.
|
||||||
|
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("can't wait"));
|
||||||
}
|
}
|
||||||
return self_in;
|
return self_in;
|
||||||
}
|
}
|
||||||
@ -298,6 +302,7 @@ STATIC mp_obj_t task_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) {
|
|||||||
STATIC mp_obj_t task_iternext(mp_obj_t self_in) {
|
STATIC mp_obj_t task_iternext(mp_obj_t self_in) {
|
||||||
mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
if (TASK_IS_DONE(self)) {
|
if (TASK_IS_DONE(self)) {
|
||||||
|
// CIRCUITPY
|
||||||
if (self->data == mp_const_none) {
|
if (self->data == mp_const_none) {
|
||||||
// Task finished but has already been sent to the loop's exception handler.
|
// Task finished but has already been sent to the loop's exception handler.
|
||||||
mp_raise_StopIteration(MP_OBJ_NULL);
|
mp_raise_StopIteration(MP_OBJ_NULL);
|
||||||
@ -309,7 +314,7 @@ STATIC mp_obj_t task_iternext(mp_obj_t self_in) {
|
|||||||
// Put calling task on waiting queue.
|
// Put calling task on waiting queue.
|
||||||
mp_obj_t cur_task = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task));
|
mp_obj_t cur_task = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task));
|
||||||
mp_obj_t args[2] = { self->state, cur_task };
|
mp_obj_t args[2] = { self->state, cur_task };
|
||||||
task_queue_push_sorted(2, args);
|
task_queue_push(2, args);
|
||||||
// Set calling task's data to this task that it waits on, to double-link it.
|
// Set calling task's data to this task that it waits on, to double-link it.
|
||||||
((mp_obj_task_t *)MP_OBJ_TO_PTR(cur_task))->data = self_in;
|
((mp_obj_task_t *)MP_OBJ_TO_PTR(cur_task))->data = self_in;
|
||||||
}
|
}
|
||||||
@ -347,6 +352,6 @@ const mp_obj_module_t mp_module_uasyncio = {
|
|||||||
.globals = (mp_obj_dict_t *)&mp_module_uasyncio_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_uasyncio_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
MP_REGISTER_MODULE(MP_QSTR__asyncio, mp_module_uasyncio, MICROPY_PY_UASYNCIO);
|
MP_REGISTER_MODULE(MP_QSTR__uasyncio, mp_module_uasyncio);
|
||||||
|
|
||||||
#endif // MICROPY_PY_UASYNCIO
|
#endif // MICROPY_PY_UASYNCIO
|
||||||
|
@ -1,8 +1,28 @@
|
|||||||
// Copyright (c) 2014 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
// SPDX-FileCopyrightText: 2022 Beat Ludin for Adafruit Industries
|
*
|
||||||
//
|
* The MIT License (MIT)
|
||||||
// SPDX-License-Identifier: MIT
|
*
|
||||||
|
* Copyright (c) 2014 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -20,6 +40,7 @@ static void check_not_unicode(const mp_obj_t arg) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#if MICROPY_PY_UBINASCII
|
||||||
|
|
||||||
STATIC mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) {
|
STATIC mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) {
|
||||||
// First argument is the data to convert.
|
// First argument is the data to convert.
|
||||||
@ -154,13 +175,20 @@ STATIC mp_obj_t mod_binascii_a2b_base64(mp_obj_t data) {
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_a2b_base64_obj, mod_binascii_a2b_base64);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_a2b_base64_obj, mod_binascii_a2b_base64);
|
||||||
|
|
||||||
STATIC mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
|
STATIC mp_obj_t mod_binascii_b2a_base64(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||||
check_not_unicode(data);
|
enum { ARG_newline };
|
||||||
|
static const mp_arg_t allowed_args[] = {
|
||||||
|
{ MP_QSTR_newline, MP_ARG_BOOL, {.u_bool = true} },
|
||||||
|
};
|
||||||
|
|
||||||
|
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||||
|
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||||
|
uint8_t newline = args[ARG_newline].u_bool;
|
||||||
mp_buffer_info_t bufinfo;
|
mp_buffer_info_t bufinfo;
|
||||||
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
|
mp_get_buffer_raise(pos_args[0], &bufinfo, MP_BUFFER_READ);
|
||||||
|
|
||||||
vstr_t vstr;
|
vstr_t vstr;
|
||||||
vstr_init_len(&vstr, ((bufinfo.len != 0) ? (((bufinfo.len - 1) / 3) + 1) * 4 : 0) + 1);
|
vstr_init_len(&vstr, ((bufinfo.len != 0) ? (((bufinfo.len - 1) / 3) + 1) * 4 : 0) + newline);
|
||||||
|
|
||||||
// First pass, we convert input buffer to numeric base 64 values
|
// First pass, we convert input buffer to numeric base 64 values
|
||||||
byte *in = bufinfo.buf, *out = (byte *)vstr.buf;
|
byte *in = bufinfo.buf, *out = (byte *)vstr.buf;
|
||||||
@ -186,7 +214,7 @@ STATIC mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
|
|||||||
|
|
||||||
// Second pass, we convert number base 64 values to actual base64 ascii encoding
|
// Second pass, we convert number base 64 values to actual base64 ascii encoding
|
||||||
out = (byte *)vstr.buf;
|
out = (byte *)vstr.buf;
|
||||||
for (mp_uint_t j = vstr.len - 1; j--;) {
|
for (mp_uint_t j = vstr.len - newline; j--;) {
|
||||||
if (*out < 26) {
|
if (*out < 26) {
|
||||||
*out += 'A';
|
*out += 'A';
|
||||||
} else if (*out < 52) {
|
} else if (*out < 52) {
|
||||||
@ -202,10 +230,15 @@ STATIC mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
|
|||||||
}
|
}
|
||||||
out++;
|
out++;
|
||||||
}
|
}
|
||||||
*out = '\n';
|
if (newline) {
|
||||||
|
*out = '\n';
|
||||||
|
}
|
||||||
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_b2a_base64_obj, mod_binascii_b2a_base64);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_binascii_b2a_base64_obj, 1, mod_binascii_b2a_base64);
|
||||||
|
|
||||||
|
// CIRCUITPY uses a self-contained implementation of CRC32,
|
||||||
|
// instead of depending on uzlib, like MicroPython.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CRC32 checksum
|
* CRC32 checksum
|
||||||
@ -296,4 +329,6 @@ const mp_obj_module_t mp_module_ubinascii = {
|
|||||||
.globals = (mp_obj_dict_t *)&mp_module_binascii_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_binascii_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
MP_REGISTER_MODULE(MP_QSTR_binascii, mp_module_ubinascii, MICROPY_PY_UBINASCII);
|
MP_REGISTER_MODULE(MP_QSTR_ubinascii, mp_module_ubinascii);
|
||||||
|
|
||||||
|
#endif // MICROPY_PY_UBINASCII
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// Copyright (c) 2014-2018 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014-2018 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -76,8 +97,7 @@ STATIC NORETURN void syntax_error(void) {
|
|||||||
|
|
||||||
STATIC mp_obj_t uctypes_struct_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
STATIC mp_obj_t uctypes_struct_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, 2, 3, false);
|
mp_arg_check_num(n_args, n_kw, 2, 3, false);
|
||||||
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
|
mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, type);
|
||||||
o->base.type = type;
|
|
||||||
o->addr = (void *)(uintptr_t)mp_obj_int_get_truncated(args[0]);
|
o->addr = (void *)(uintptr_t)mp_obj_int_get_truncated(args[0]);
|
||||||
o->desc = args[1];
|
o->desc = args[1];
|
||||||
o->flags = LAYOUT_NATIVE;
|
o->flags = LAYOUT_NATIVE;
|
||||||
@ -444,8 +464,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set
|
|||||||
|
|
||||||
switch (agg_type) {
|
switch (agg_type) {
|
||||||
case STRUCT: {
|
case STRUCT: {
|
||||||
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
|
mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type);
|
||||||
o->base.type = &uctypes_struct_type;
|
|
||||||
o->desc = sub->items[1];
|
o->desc = sub->items[1];
|
||||||
o->addr = self->addr + offset;
|
o->addr = self->addr + offset;
|
||||||
o->flags = self->flags;
|
o->flags = self->flags;
|
||||||
@ -460,8 +479,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set
|
|||||||
MP_FALLTHROUGH
|
MP_FALLTHROUGH
|
||||||
}
|
}
|
||||||
case PTR: {
|
case PTR: {
|
||||||
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
|
mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type);
|
||||||
o->base.type = &uctypes_struct_type;
|
|
||||||
o->desc = MP_OBJ_FROM_PTR(sub);
|
o->desc = MP_OBJ_FROM_PTR(sub);
|
||||||
o->addr = self->addr + offset;
|
o->addr = self->addr + offset;
|
||||||
o->flags = self->flags;
|
o->flags = self->flags;
|
||||||
@ -533,8 +551,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_ob
|
|||||||
} else if (value == MP_OBJ_SENTINEL) {
|
} else if (value == MP_OBJ_SENTINEL) {
|
||||||
mp_uint_t dummy = 0;
|
mp_uint_t dummy = 0;
|
||||||
mp_uint_t size = uctypes_struct_size(t->items[2], self->flags, &dummy);
|
mp_uint_t size = uctypes_struct_size(t->items[2], self->flags, &dummy);
|
||||||
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
|
mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type);
|
||||||
o->base.type = &uctypes_struct_type;
|
|
||||||
o->desc = t->items[2];
|
o->desc = t->items[2];
|
||||||
o->addr = self->addr + size * index;
|
o->addr = self->addr + size * index;
|
||||||
o->flags = self->flags;
|
o->flags = self->flags;
|
||||||
@ -551,8 +568,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_ob
|
|||||||
} else {
|
} else {
|
||||||
mp_uint_t dummy = 0;
|
mp_uint_t dummy = 0;
|
||||||
mp_uint_t size = uctypes_struct_size(t->items[1], self->flags, &dummy);
|
mp_uint_t size = uctypes_struct_size(t->items[1], self->flags, &dummy);
|
||||||
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
|
mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type);
|
||||||
o->base.type = &uctypes_struct_type;
|
|
||||||
o->desc = t->items[1];
|
o->desc = t->items[1];
|
||||||
o->addr = p + size * index;
|
o->addr = p + size * index;
|
||||||
o->flags = self->flags;
|
o->flags = self->flags;
|
||||||
@ -706,4 +722,6 @@ const mp_obj_module_t mp_module_uctypes = {
|
|||||||
.globals = (mp_obj_dict_t *)&mp_module_uctypes_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_uctypes_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR_uctypes, mp_module_uctypes);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// Copyright (c) 2014 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -39,7 +60,6 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef struct _mp_obj_hash_t {
|
typedef struct _mp_obj_hash_t {
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
bool final; // if set, update and digest raise an exception
|
bool final; // if set, update and digest raise an exception
|
||||||
@ -65,8 +85,7 @@ STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg);
|
|||||||
|
|
||||||
STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
STATIC mp_obj_t uhashlib_sha256_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, 0, 1, false);
|
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||||
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context));
|
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context), type);
|
||||||
o->base.type = type;
|
|
||||||
o->final = false;
|
o->final = false;
|
||||||
mbedtls_sha256_init((mbedtls_sha256_context *)&o->state);
|
mbedtls_sha256_init((mbedtls_sha256_context *)&o->state);
|
||||||
mbedtls_sha256_starts_ret((mbedtls_sha256_context *)&o->state, 0);
|
mbedtls_sha256_starts_ret((mbedtls_sha256_context *)&o->state, 0);
|
||||||
@ -110,8 +129,7 @@ static void check_not_unicode(const mp_obj_t arg) {
|
|||||||
|
|
||||||
STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
STATIC mp_obj_t uhashlib_sha256_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, 0, 1, false);
|
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||||
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX));
|
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX), type);
|
||||||
o->base.type = type;
|
|
||||||
o->final = false;
|
o->final = false;
|
||||||
sha256_init((CRYAL_SHA256_CTX *)o->state);
|
sha256_init((CRYAL_SHA256_CTX *)o->state);
|
||||||
if (n_args == 1) {
|
if (n_args == 1) {
|
||||||
@ -159,16 +177,13 @@ STATIC const mp_obj_type_t uhashlib_sha256_type = {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MICROPY_PY_UHASHLIB_SHA1
|
#if MICROPY_PY_UHASHLIB_SHA1
|
||||||
STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg);
|
STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg);
|
||||||
|
|
||||||
#if MICROPY_SSL_AXTLS
|
#if MICROPY_SSL_AXTLS
|
||||||
STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
STATIC mp_obj_t uhashlib_sha1_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, kw_args, 0, 1, false);
|
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||||
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(SHA1_CTX));
|
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(SHA1_CTX), type);
|
||||||
o->base.type = type;
|
|
||||||
o->final = false;
|
o->final = false;
|
||||||
SHA1_Init((SHA1_CTX *)o->state);
|
SHA1_Init((SHA1_CTX *)o->state);
|
||||||
if (n_args == 1) {
|
if (n_args == 1) {
|
||||||
@ -178,7 +193,6 @@ STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args,
|
|||||||
}
|
}
|
||||||
|
|
||||||
STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) {
|
STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) {
|
||||||
check_not_unicode(arg);
|
|
||||||
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
uhashlib_ensure_not_final(self);
|
uhashlib_ensure_not_final(self);
|
||||||
mp_buffer_info_t bufinfo;
|
mp_buffer_info_t bufinfo;
|
||||||
@ -208,8 +222,7 @@ STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) {
|
|||||||
|
|
||||||
STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
STATIC mp_obj_t uhashlib_sha1_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, 0, 1, false);
|
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||||
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha1_context));
|
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_sha1_context), type);
|
||||||
o->base.type = type;
|
|
||||||
o->final = false;
|
o->final = false;
|
||||||
mbedtls_sha1_init((mbedtls_sha1_context *)o->state);
|
mbedtls_sha1_init((mbedtls_sha1_context *)o->state);
|
||||||
mbedtls_sha1_starts_ret((mbedtls_sha1_context *)o->state);
|
mbedtls_sha1_starts_ret((mbedtls_sha1_context *)o->state);
|
||||||
@ -263,8 +276,7 @@ STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg);
|
|||||||
#if MICROPY_SSL_AXTLS
|
#if MICROPY_SSL_AXTLS
|
||||||
STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
STATIC mp_obj_t uhashlib_md5_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, 0, 1, false);
|
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||||
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(MD5_CTX));
|
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(MD5_CTX), type);
|
||||||
o->base.type = type;
|
|
||||||
o->final = false;
|
o->final = false;
|
||||||
MD5_Init((MD5_CTX *)o->state);
|
MD5_Init((MD5_CTX *)o->state);
|
||||||
if (n_args == 1) {
|
if (n_args == 1) {
|
||||||
@ -303,8 +315,7 @@ STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) {
|
|||||||
|
|
||||||
STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
STATIC mp_obj_t uhashlib_md5_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, 0, 1, false);
|
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||||
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_md5_context));
|
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_md5_context), type);
|
||||||
o->base.type = type;
|
|
||||||
o->final = false;
|
o->final = false;
|
||||||
mbedtls_md5_init((mbedtls_md5_context *)o->state);
|
mbedtls_md5_init((mbedtls_md5_context *)o->state);
|
||||||
mbedtls_md5_starts_ret((mbedtls_md5_context *)o->state);
|
mbedtls_md5_starts_ret((mbedtls_md5_context *)o->state);
|
||||||
@ -372,4 +383,6 @@ const mp_obj_module_t mp_module_uhashlib = {
|
|||||||
.globals = (mp_obj_dict_t *)&mp_module_uhashlib_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_uhashlib_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR_uhashlib, mp_module_uhashlib, MICROPY_PY_UHASHLIB);
|
||||||
|
|
||||||
#endif // MICROPY_PY_UHASHLIB
|
#endif // MICROPY_PY_UHASHLIB
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "py/objlist.h"
|
#include "py/objlist.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
@ -98,6 +119,8 @@ const mp_obj_module_t mp_module_uheapq = {
|
|||||||
.base = { &mp_type_module },
|
.base = { &mp_type_module },
|
||||||
.globals = (mp_obj_dict_t *)&mp_module_uheapq_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_uheapq_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR_uheapq, mp_module_uheapq);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // MICROPY_PY_UHEAPQ
|
#endif // MICROPY_PY_UHEAPQ
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2014-2019 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014-2019 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@ -112,6 +133,7 @@ typedef struct _ujson_stream_t {
|
|||||||
mp_obj_t stream_obj;
|
mp_obj_t stream_obj;
|
||||||
mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode);
|
mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode);
|
||||||
int errcode;
|
int errcode;
|
||||||
|
// CIRCUITPY
|
||||||
mp_obj_t python_readinto[2 + 1];
|
mp_obj_t python_readinto[2 + 1];
|
||||||
mp_obj_array_t bytearray_obj;
|
mp_obj_array_t bytearray_obj;
|
||||||
size_t start;
|
size_t start;
|
||||||
@ -136,6 +158,8 @@ STATIC byte ujson_stream_next(ujson_stream_t *s) {
|
|||||||
return s->cur;
|
return s->cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CIRCUITPY
|
||||||
|
|
||||||
// We read from an object's `readinto` method in chunks larger than the json
|
// We read from an object's `readinto` method in chunks larger than the json
|
||||||
// parser needs to reduce the number of function calls done.
|
// parser needs to reduce the number of function calls done.
|
||||||
|
|
||||||
@ -375,6 +399,8 @@ STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
success:
|
success:
|
||||||
|
// CIRCUITPY
|
||||||
|
|
||||||
// It is legal for a stream to have contents after JSON.
|
// It is legal for a stream to have contents after JSON.
|
||||||
// E.g., A UART is not closed after receiving an object; in load() we will
|
// E.g., A UART is not closed after receiving an object; in load() we will
|
||||||
// return the first complete JSON object, while in loads() we will retain
|
// return the first complete JSON object, while in loads() we will retain
|
||||||
@ -432,6 +458,6 @@ const mp_obj_module_t mp_module_ujson = {
|
|||||||
.globals = (mp_obj_dict_t *)&mp_module_ujson_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_ujson_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
MP_REGISTER_MODULE(MP_QSTR_json, mp_module_ujson, MICROPY_PY_UJSON);
|
MP_REGISTER_MODULE(MP_QSTR_ujson, mp_module_ujson);
|
||||||
|
|
||||||
#endif // MICROPY_PY_UJSON
|
#endif // MICROPY_PY_UJSON
|
||||||
|
181
extmod/moduos.c
Normal file
181
extmod/moduos.c
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016-2022 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "py/objstr.h"
|
||||||
|
#include "py/runtime.h"
|
||||||
|
|
||||||
|
#if MICROPY_PY_UOS
|
||||||
|
|
||||||
|
#include "extmod/misc.h"
|
||||||
|
#include "extmod/vfs.h"
|
||||||
|
|
||||||
|
#if MICROPY_VFS_FAT
|
||||||
|
#include "extmod/vfs_fat.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MICROPY_VFS_LFS1 || MICROPY_VFS_LFS2
|
||||||
|
#include "extmod/vfs_lfs.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MICROPY_VFS_POSIX
|
||||||
|
#include "extmod/vfs_posix.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MICROPY_PY_UOS_UNAME
|
||||||
|
#include "genhdr/mpversion.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MICROPY_PY_UOS_INCLUDEFILE
|
||||||
|
#include MICROPY_PY_UOS_INCLUDEFILE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MICROPY_BUILD_TYPE
|
||||||
|
#define MICROPY_BUILD_TYPE_PAREN " (" MICROPY_BUILD_TYPE ")"
|
||||||
|
#else
|
||||||
|
#define MICROPY_BUILD_TYPE_PAREN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MICROPY_PY_UOS_UNAME
|
||||||
|
|
||||||
|
#if MICROPY_PY_UOS_UNAME_RELEASE_DYNAMIC
|
||||||
|
#define CONST_RELEASE
|
||||||
|
#else
|
||||||
|
#define CONST_RELEASE const
|
||||||
|
#endif
|
||||||
|
|
||||||
|
STATIC const qstr mp_uos_uname_info_fields[] = {
|
||||||
|
MP_QSTR_sysname,
|
||||||
|
MP_QSTR_nodename,
|
||||||
|
MP_QSTR_release,
|
||||||
|
MP_QSTR_version,
|
||||||
|
MP_QSTR_machine
|
||||||
|
};
|
||||||
|
STATIC const MP_DEFINE_STR_OBJ(mp_uos_uname_info_sysname_obj, MICROPY_PY_SYS_PLATFORM);
|
||||||
|
STATIC const MP_DEFINE_STR_OBJ(mp_uos_uname_info_nodename_obj, MICROPY_PY_SYS_PLATFORM);
|
||||||
|
STATIC CONST_RELEASE MP_DEFINE_STR_OBJ(mp_uos_uname_info_release_obj, MICROPY_VERSION_STRING);
|
||||||
|
STATIC const MP_DEFINE_STR_OBJ(mp_uos_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE MICROPY_BUILD_TYPE_PAREN);
|
||||||
|
STATIC const MP_DEFINE_STR_OBJ(mp_uos_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME);
|
||||||
|
|
||||||
|
STATIC MP_DEFINE_ATTRTUPLE(
|
||||||
|
mp_uos_uname_info_obj,
|
||||||
|
mp_uos_uname_info_fields,
|
||||||
|
5,
|
||||||
|
MP_ROM_PTR(&mp_uos_uname_info_sysname_obj),
|
||||||
|
MP_ROM_PTR(&mp_uos_uname_info_nodename_obj),
|
||||||
|
MP_ROM_PTR(&mp_uos_uname_info_release_obj),
|
||||||
|
MP_ROM_PTR(&mp_uos_uname_info_version_obj),
|
||||||
|
MP_ROM_PTR(&mp_uos_uname_info_machine_obj)
|
||||||
|
);
|
||||||
|
|
||||||
|
STATIC mp_obj_t mp_uos_uname(void) {
|
||||||
|
#if MICROPY_PY_UOS_UNAME_RELEASE_DYNAMIC
|
||||||
|
const char *release = mp_uos_uname_release();
|
||||||
|
mp_uos_uname_info_release_obj.len = strlen(release);
|
||||||
|
mp_uos_uname_info_release_obj.data = (const byte *)release;
|
||||||
|
#endif
|
||||||
|
return MP_OBJ_FROM_PTR(&mp_uos_uname_info_obj);
|
||||||
|
}
|
||||||
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_uos_uname_obj, mp_uos_uname);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) },
|
||||||
|
|
||||||
|
#if MICROPY_PY_UOS_GETENV_PUTENV_UNSETENV
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_getenv), MP_ROM_PTR(&mp_uos_getenv_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_putenv), MP_ROM_PTR(&mp_uos_putenv_obj) },
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_unsetenv), MP_ROM_PTR(&mp_uos_unsetenv_obj) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_PY_UOS_SEP
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_sep), MP_ROM_QSTR(MP_QSTR__slash_) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_PY_UOS_SYNC
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_sync), MP_ROM_PTR(&mp_uos_sync_obj) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_PY_UOS_SYSTEM
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_system), MP_ROM_PTR(&mp_uos_system_obj) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_PY_UOS_UNAME
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_uname), MP_ROM_PTR(&mp_uos_uname_obj) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_PY_UOS_URANDOM
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&mp_uos_urandom_obj) },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MICROPY_VFS
|
||||||
|
{ 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_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_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_rmdir), MP_ROM_PTR(&mp_vfs_rmdir_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_unlink), MP_ROM_PTR(&mp_vfs_remove_obj) }, // unlink aliases to remove
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The following are MicroPython extensions.
|
||||||
|
|
||||||
|
#if MICROPY_PY_OS_DUPTERM
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&mp_uos_dupterm_obj) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_PY_UOS_DUPTERM_NOTIFY
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_dupterm_notify), MP_ROM_PTR(&mp_uos_dupterm_notify_obj) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_PY_UOS_ERRNO
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mp_uos_errno_obj) },
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MICROPY_VFS
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_ilistdir), MP_ROM_PTR(&mp_vfs_ilistdir_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) },
|
||||||
|
#if MICROPY_VFS_FAT
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_VFS_LFS1
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_VfsLfs1), MP_ROM_PTR(&mp_type_vfs_lfs1) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_VFS_LFS2
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_VfsLfs2), MP_ROM_PTR(&mp_type_vfs_lfs2) },
|
||||||
|
#endif
|
||||||
|
#if MICROPY_VFS_POSIX
|
||||||
|
{ MP_ROM_QSTR(MP_QSTR_VfsPosix), MP_ROM_PTR(&mp_type_vfs_posix) },
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table);
|
||||||
|
|
||||||
|
const mp_obj_module_t mp_module_uos = {
|
||||||
|
.base = { &mp_type_module },
|
||||||
|
.globals = (mp_obj_dict_t *)&os_module_globals,
|
||||||
|
};
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR_uos, mp_module_uos);
|
||||||
|
|
||||||
|
#endif // MICROPY_PY_UOS
|
@ -29,87 +29,19 @@
|
|||||||
#include "py/objtuple.h"
|
#include "py/objtuple.h"
|
||||||
#include "py/objstr.h"
|
#include "py/objstr.h"
|
||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
|
#include "extmod/moduplatform.h"
|
||||||
#include "genhdr/mpversion.h"
|
#include "genhdr/mpversion.h"
|
||||||
|
|
||||||
#if MICROPY_PY_UPLATFORM
|
#if MICROPY_PY_UPLATFORM
|
||||||
|
|
||||||
// platform - Access to underlying platform's identifying data
|
// platform - Access to underlying platform's identifying data
|
||||||
|
|
||||||
// TODO: Add more architectures, compilers and libraries.
|
STATIC const MP_DEFINE_STR_OBJ(info_platform_obj, MICROPY_PLATFORM_SYSTEM "-" \
|
||||||
// See: https://sourceforge.net/p/predef/wiki/Home/
|
MICROPY_VERSION_STRING "-" MICROPY_PLATFORM_ARCH "-" MICROPY_PLATFORM_VERSION "-with-" \
|
||||||
|
MICROPY_PLATFORM_LIBC_LIB "" MICROPY_PLATFORM_LIBC_VER);
|
||||||
#if defined(__ARM_ARCH)
|
STATIC const MP_DEFINE_STR_OBJ(info_python_compiler_obj, MICROPY_PLATFORM_COMPILER);
|
||||||
#define PLATFORM_ARCH "arm"
|
STATIC const MP_DEFINE_STR_OBJ(info_libc_lib_obj, MICROPY_PLATFORM_LIBC_LIB);
|
||||||
#elif defined(__x86_64__) || defined(_WIN64)
|
STATIC const MP_DEFINE_STR_OBJ(info_libc_ver_obj, MICROPY_PLATFORM_LIBC_VER);
|
||||||
#define PLATFORM_ARCH "x86_64"
|
|
||||||
#elif defined(__i386__) || defined(_M_IX86)
|
|
||||||
#define PLATFORM_ARCH "x86"
|
|
||||||
#elif defined(__xtensa__) || defined(_M_IX86)
|
|
||||||
#define PLATFORM_ARCH "xtensa"
|
|
||||||
#else
|
|
||||||
#define PLATFORM_ARCH ""
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#define PLATFORM_COMPILER \
|
|
||||||
"GCC " \
|
|
||||||
MP_STRINGIFY(__GNUC__) "." \
|
|
||||||
MP_STRINGIFY(__GNUC_MINOR__) "." \
|
|
||||||
MP_STRINGIFY(__GNUC_PATCHLEVEL__)
|
|
||||||
#elif defined(__ARMCC_VERSION)
|
|
||||||
#define PLATFORM_COMPILER \
|
|
||||||
"ARMCC " \
|
|
||||||
MP_STRINGIFY((__ARMCC_VERSION / 1000000)) "." \
|
|
||||||
MP_STRINGIFY((__ARMCC_VERSION / 10000 % 100)) "." \
|
|
||||||
MP_STRINGIFY((__ARMCC_VERSION % 10000))
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#if defined(_WIN64)
|
|
||||||
#define COMPILER_BITS "64 bit"
|
|
||||||
#elif defined(_M_IX86)
|
|
||||||
#define COMPILER_BITS "32 bit"
|
|
||||||
#else
|
|
||||||
#define COMPILER_BITS ""
|
|
||||||
#endif
|
|
||||||
#define PLATFORM_COMPILER \
|
|
||||||
"MSC v." MP_STRINGIFY(_MSC_VER) " " COMPILER_BITS
|
|
||||||
#else
|
|
||||||
#define PLATFORM_COMPILER ""
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__GLIBC__)
|
|
||||||
#define PLATFORM_LIBC_LIB "glibc"
|
|
||||||
#define PLATFORM_LIBC_VER \
|
|
||||||
MP_STRINGIFY(__GLIBC__) "." \
|
|
||||||
MP_STRINGIFY(__GLIBC_MINOR__)
|
|
||||||
#elif defined(__NEWLIB__)
|
|
||||||
#define PLATFORM_LIBC_LIB "newlib"
|
|
||||||
#define PLATFORM_LIBC_VER _NEWLIB_VERSION
|
|
||||||
#else
|
|
||||||
#define PLATFORM_LIBC_LIB ""
|
|
||||||
#define PLATFORM_LIBC_VER ""
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__linux)
|
|
||||||
#define PLATFORM_SYSTEM "Linux"
|
|
||||||
#elif defined(__unix__)
|
|
||||||
#define PLATFORM_SYSTEM "Unix"
|
|
||||||
#elif defined(__CYGWIN__)
|
|
||||||
#define PLATFORM_SYSTEM "Cygwin"
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
#define PLATFORM_SYSTEM "Windows"
|
|
||||||
#else
|
|
||||||
#define PLATFORM_SYSTEM "MicroPython"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MICROPY_PLATFORM_VERSION
|
|
||||||
#define MICROPY_PLATFORM_VERSION ""
|
|
||||||
#endif
|
|
||||||
|
|
||||||
STATIC const MP_DEFINE_STR_OBJ(info_platform_obj, PLATFORM_SYSTEM "-" MICROPY_VERSION_STRING "-" \
|
|
||||||
PLATFORM_ARCH "-" MICROPY_PLATFORM_VERSION "-with-" PLATFORM_LIBC_LIB "" PLATFORM_LIBC_VER);
|
|
||||||
STATIC const MP_DEFINE_STR_OBJ(info_python_compiler_obj, PLATFORM_COMPILER);
|
|
||||||
STATIC const MP_DEFINE_STR_OBJ(info_libc_lib_obj, PLATFORM_LIBC_LIB);
|
|
||||||
STATIC const MP_DEFINE_STR_OBJ(info_libc_ver_obj, PLATFORM_LIBC_VER);
|
|
||||||
STATIC const mp_rom_obj_tuple_t info_libc_tuple_obj = {
|
STATIC const mp_rom_obj_tuple_t info_libc_tuple_obj = {
|
||||||
{&mp_type_tuple}, 2, {MP_ROM_PTR(&info_libc_lib_obj), MP_ROM_PTR(&info_libc_ver_obj)}
|
{&mp_type_tuple}, 2, {MP_ROM_PTR(&info_libc_lib_obj), MP_ROM_PTR(&info_libc_ver_obj)}
|
||||||
};
|
};
|
||||||
@ -143,4 +75,6 @@ const mp_obj_module_t mp_module_uplatform = {
|
|||||||
.globals = (mp_obj_dict_t *)&modplatform_globals,
|
.globals = (mp_obj_dict_t *)&modplatform_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR_uplatform, mp_module_uplatform);
|
||||||
|
|
||||||
#endif // MICROPY_PY_UPLATFORM
|
#endif // MICROPY_PY_UPLATFORM
|
||||||
|
105
extmod/moduplatform.h
Normal file
105
extmod/moduplatform.h
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
#ifndef MICROPY_INCLUDED_MODUPLATFORM_H
|
||||||
|
#define MICROPY_INCLUDED_MODUPLATFORM_H
|
||||||
|
|
||||||
|
#include "py/misc.h" // For MP_STRINGIFY.
|
||||||
|
#include "py/mpconfig.h"
|
||||||
|
|
||||||
|
// Preprocessor directives indentifying the platform.
|
||||||
|
// The (u)platform module itself is guarded by MICROPY_PY_UPLATFORM, see the
|
||||||
|
// .c file, but these are made available because they're generally usable.
|
||||||
|
// TODO: Add more architectures, compilers and libraries.
|
||||||
|
// See: https://sourceforge.net/p/predef/wiki/Home/
|
||||||
|
|
||||||
|
#if defined(__ARM_ARCH)
|
||||||
|
#define MICROPY_PLATFORM_ARCH "arm"
|
||||||
|
#elif defined(__x86_64__) || defined(_WIN64)
|
||||||
|
#define MICROPY_PLATFORM_ARCH "x86_64"
|
||||||
|
#elif defined(__i386__) || defined(_M_IX86)
|
||||||
|
#define MICROPY_PLATFORM_ARCH "x86"
|
||||||
|
#elif defined(__xtensa__) || defined(_M_IX86)
|
||||||
|
#define MICROPY_PLATFORM_ARCH "xtensa"
|
||||||
|
#else
|
||||||
|
#define MICROPY_PLATFORM_ARCH ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define MICROPY_PLATFORM_COMPILER \
|
||||||
|
"GCC " \
|
||||||
|
MP_STRINGIFY(__GNUC__) "." \
|
||||||
|
MP_STRINGIFY(__GNUC_MINOR__) "." \
|
||||||
|
MP_STRINGIFY(__GNUC_PATCHLEVEL__)
|
||||||
|
#elif defined(__ARMCC_VERSION)
|
||||||
|
#define MICROPY_PLATFORM_COMPILER \
|
||||||
|
"ARMCC " \
|
||||||
|
MP_STRINGIFY((__ARMCC_VERSION / 1000000)) "." \
|
||||||
|
MP_STRINGIFY((__ARMCC_VERSION / 10000 % 100)) "." \
|
||||||
|
MP_STRINGIFY((__ARMCC_VERSION % 10000))
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#if defined(_WIN64)
|
||||||
|
#define MICROPY_PLATFORM_COMPILER_BITS "64 bit"
|
||||||
|
#elif defined(_M_IX86)
|
||||||
|
#define MICROPY_PLATFORM_COMPILER_BITS "32 bit"
|
||||||
|
#else
|
||||||
|
#define MICROPY_PLATFORM_COMPILER_BITS ""
|
||||||
|
#endif
|
||||||
|
#define MICROPY_PLATFORM_COMPILER \
|
||||||
|
"MSC v." MP_STRINGIFY(_MSC_VER) " " MICROPY_PLATFORM_COMPILER_BITS
|
||||||
|
#else
|
||||||
|
#define MICROPY_PLATFORM_COMPILER ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GLIBC__)
|
||||||
|
#define MICROPY_PLATFORM_LIBC_LIB "glibc"
|
||||||
|
#define MICROPY_PLATFORM_LIBC_VER \
|
||||||
|
MP_STRINGIFY(__GLIBC__) "." \
|
||||||
|
MP_STRINGIFY(__GLIBC_MINOR__)
|
||||||
|
#elif defined(__NEWLIB__)
|
||||||
|
#define MICROPY_PLATFORM_LIBC_LIB "newlib"
|
||||||
|
#define MICROPY_PLATFORM_LIBC_VER _NEWLIB_VERSION
|
||||||
|
#else
|
||||||
|
#define MICROPY_PLATFORM_LIBC_LIB ""
|
||||||
|
#define MICROPY_PLATFORM_LIBC_VER ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__linux)
|
||||||
|
#define MICROPY_PLATFORM_SYSTEM "Linux"
|
||||||
|
#elif defined(__unix__)
|
||||||
|
#define MICROPY_PLATFORM_SYSTEM "Unix"
|
||||||
|
#elif defined(__CYGWIN__)
|
||||||
|
#define MICROPY_PLATFORM_SYSTEM "Cygwin"
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
#define MICROPY_PLATFORM_SYSTEM "Windows"
|
||||||
|
#else
|
||||||
|
#define MICROPY_PLATFORM_SYSTEM "MicroPython"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MICROPY_PLATFORM_VERSION
|
||||||
|
#define MICROPY_PLATFORM_VERSION ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // MICROPY_INCLUDED_MODUPLATFORM_H
|
@ -1,7 +1,28 @@
|
|||||||
// Copyright (c) 2016 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -195,7 +216,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_urandom_uniform_obj, mod_urandom_uniform);
|
|||||||
#endif // MICROPY_PY_URANDOM_EXTRA_FUNCS
|
#endif // MICROPY_PY_URANDOM_EXTRA_FUNCS
|
||||||
|
|
||||||
#if SEED_ON_IMPORT
|
#if SEED_ON_IMPORT
|
||||||
STATIC mp_obj_t mod_urandom___init__() {
|
STATIC mp_obj_t mod_urandom___init__(void) {
|
||||||
// This module may be imported by more than one name so need to ensure
|
// This module may be imported by more than one name so need to ensure
|
||||||
// that it's only ever seeded once.
|
// that it's only ever seeded once.
|
||||||
static bool seeded = false;
|
static bool seeded = false;
|
||||||
@ -233,6 +254,8 @@ const mp_obj_module_t mp_module_urandom = {
|
|||||||
.base = { &mp_type_module },
|
.base = { &mp_type_module },
|
||||||
.globals = (mp_obj_dict_t *)&mp_module_urandom_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_urandom_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR_urandom, mp_module_urandom);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // MICROPY_PY_URANDOM
|
#endif // MICROPY_PY_URANDOM
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// Copyright (c) 2014 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -18,6 +39,7 @@
|
|||||||
|
|
||||||
#include "lib/re1.5/re1.5.h"
|
#include "lib/re1.5/re1.5.h"
|
||||||
|
|
||||||
|
//CIRCUITPY
|
||||||
#if MICROPY_PY_URE_DEBUG
|
#if MICROPY_PY_URE_DEBUG
|
||||||
#define FLAG_DEBUG 0x1000
|
#define FLAG_DEBUG 0x1000
|
||||||
#endif
|
#endif
|
||||||
@ -168,7 +190,7 @@ STATIC mp_obj_t ure_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
|
|||||||
}
|
}
|
||||||
Subject subj;
|
Subject subj;
|
||||||
size_t len;
|
size_t len;
|
||||||
subj.begin = mp_obj_str_get_data(args[1], &len);
|
subj.begin_line = subj.begin = mp_obj_str_get_data(args[1], &len);
|
||||||
subj.end = subj.begin + len;
|
subj.end = subj.begin + len;
|
||||||
#if MICROPY_PY_URE_MATCH_SPAN_START_END && !(defined(MICROPY_ENABLE_DYNRUNTIME) && MICROPY_ENABLE_DYNRUNTIME)
|
#if MICROPY_PY_URE_MATCH_SPAN_START_END && !(defined(MICROPY_ENABLE_DYNRUNTIME) && MICROPY_ENABLE_DYNRUNTIME)
|
||||||
|
|
||||||
@ -231,7 +253,7 @@ STATIC mp_obj_t re_split(size_t n_args, const mp_obj_t *args) {
|
|||||||
Subject subj;
|
Subject subj;
|
||||||
size_t len;
|
size_t len;
|
||||||
const mp_obj_type_t *str_type = mp_obj_get_type(args[1]);
|
const mp_obj_type_t *str_type = mp_obj_get_type(args[1]);
|
||||||
subj.begin = mp_obj_str_get_data(args[1], &len);
|
subj.begin_line = subj.begin = mp_obj_str_get_data(args[1], &len);
|
||||||
subj.end = subj.begin + len;
|
subj.end = subj.begin + len;
|
||||||
int caps_num = (self->re.sub + 1) * 2;
|
int caps_num = (self->re.sub + 1) * 2;
|
||||||
|
|
||||||
@ -291,7 +313,7 @@ STATIC mp_obj_t re_sub_helper(size_t n_args, const mp_obj_t *args) {
|
|||||||
size_t where_len;
|
size_t where_len;
|
||||||
const char *where_str = mp_obj_str_get_data(where, &where_len);
|
const char *where_str = mp_obj_str_get_data(where, &where_len);
|
||||||
Subject subj;
|
Subject subj;
|
||||||
subj.begin = where_str;
|
subj.begin_line = subj.begin = where_str;
|
||||||
subj.end = subj.begin + where_len;
|
subj.end = subj.begin + where_len;
|
||||||
int caps_num = (self->re.sub + 1) * 2;
|
int caps_num = (self->re.sub + 1) * 2;
|
||||||
|
|
||||||
@ -421,8 +443,7 @@ STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) {
|
|||||||
if (size == -1) {
|
if (size == -1) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
mp_obj_re_t *o = m_new_obj_var(mp_obj_re_t, char, size);
|
mp_obj_re_t *o = mp_obj_malloc_var(mp_obj_re_t, char, size, &re_type);
|
||||||
o->base.type = &re_type;
|
|
||||||
#if MICROPY_PY_URE_DEBUG
|
#if MICROPY_PY_URE_DEBUG
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
if (n_args > 1) {
|
if (n_args > 1) {
|
||||||
@ -470,7 +491,7 @@ const mp_obj_module_t mp_module_ure = {
|
|||||||
.globals = (mp_obj_dict_t *)&mp_module_re_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_re_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
MP_REGISTER_MODULE(MP_QSTR_re, mp_module_ure, MICROPY_PY_URE);
|
MP_REGISTER_MODULE(MP_QSTR_ure, mp_module_ure);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Source files #include'd here to make sure they're compiled in
|
// Source files #include'd here to make sure they're compiled in
|
||||||
|
@ -1,8 +1,29 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2015-2017 Paul Sokolovsky
|
*
|
||||||
//
|
* The MIT License (MIT)
|
||||||
// SPDX-License-Identifier: MIT
|
*
|
||||||
|
* Copyright (c) 2014 Damien P. George
|
||||||
|
* Copyright (c) 2015-2017 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#if MICROPY_PY_USELECT
|
#if MICROPY_PY_USELECT
|
||||||
@ -151,6 +172,7 @@ STATIC mp_obj_t select_select(size_t n_args, const mp_obj_t *args) {
|
|||||||
mp_map_deinit(&poll_map);
|
mp_map_deinit(&poll_map);
|
||||||
return mp_obj_new_tuple(3, list_array);
|
return mp_obj_new_tuple(3, list_array);
|
||||||
}
|
}
|
||||||
|
// CIRCUITPY
|
||||||
RUN_BACKGROUND_TASKS;
|
RUN_BACKGROUND_TASKS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,6 +252,7 @@ STATIC mp_uint_t poll_poll_internal(uint n_args, const mp_obj_t *args) {
|
|||||||
if (n_ready > 0 || (timeout != (mp_uint_t)-1 && mp_hal_ticks_ms() - start_tick >= timeout)) {
|
if (n_ready > 0 || (timeout != (mp_uint_t)-1 && mp_hal_ticks_ms() - start_tick >= timeout)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// CIRCUITPY
|
||||||
RUN_BACKGROUND_TASKS;
|
RUN_BACKGROUND_TASKS;
|
||||||
if (mp_hal_is_interrupted()) {
|
if (mp_hal_is_interrupted()) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -324,6 +347,8 @@ STATIC const mp_obj_type_t mp_type_poll = {
|
|||||||
{ &mp_type_type },
|
{ &mp_type_type },
|
||||||
.flags = MP_TYPE_FLAG_EXTENDED,
|
.flags = MP_TYPE_FLAG_EXTENDED,
|
||||||
.name = MP_QSTR_poll,
|
.name = MP_QSTR_poll,
|
||||||
|
.getiter = mp_identity_getiter,
|
||||||
|
.iternext = poll_iternext,
|
||||||
.locals_dict = (void *)&poll_locals_dict,
|
.locals_dict = (void *)&poll_locals_dict,
|
||||||
MP_TYPE_EXTENDED_FIELDS(
|
MP_TYPE_EXTENDED_FIELDS(
|
||||||
.getiter = mp_identity_getiter,
|
.getiter = mp_identity_getiter,
|
||||||
@ -333,8 +358,7 @@ STATIC const mp_obj_type_t mp_type_poll = {
|
|||||||
|
|
||||||
// poll()
|
// poll()
|
||||||
STATIC mp_obj_t select_poll(void) {
|
STATIC mp_obj_t select_poll(void) {
|
||||||
mp_obj_poll_t *poll = m_new_obj(mp_obj_poll_t);
|
mp_obj_poll_t *poll = mp_obj_malloc(mp_obj_poll_t, &mp_type_poll);
|
||||||
poll->base.type = &mp_type_poll;
|
|
||||||
mp_map_init(&poll->poll_map, 0);
|
mp_map_init(&poll->poll_map, 0);
|
||||||
poll->iter_cnt = 0;
|
poll->iter_cnt = 0;
|
||||||
poll->ret_tuple = MP_OBJ_NULL;
|
poll->ret_tuple = MP_OBJ_NULL;
|
||||||
@ -361,6 +385,6 @@ const mp_obj_module_t mp_module_uselect = {
|
|||||||
.globals = (mp_obj_dict_t *)&mp_module_select_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_select_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
MP_REGISTER_MODULE(MP_QSTR_select, mp_module_uselect, MICROPY_PY_USELECT);
|
MP_REGISTER_MODULE(MP_QSTR_uselect, mp_module_uselect);
|
||||||
|
|
||||||
#endif // MICROPY_PY_USELECT
|
#endif // MICROPY_PY_USELECT
|
||||||
|
@ -1,8 +1,29 @@
|
|||||||
// Copyright (c) 2016-2017 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George
|
*
|
||||||
//
|
* The MIT License (MIT)
|
||||||
// SPDX-License-Identifier: MIT
|
*
|
||||||
|
* Copyright (c) 2014 Damien P. George
|
||||||
|
* Copyright (c) 2016-2017 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -58,8 +79,7 @@ STATIC bool time_less_than(struct qentry *item, struct qentry *parent) {
|
|||||||
STATIC mp_obj_t utimeq_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
STATIC mp_obj_t utimeq_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, 1, false);
|
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
||||||
mp_uint_t alloc = mp_obj_get_int(args[0]);
|
mp_uint_t alloc = mp_obj_get_int(args[0]);
|
||||||
mp_obj_utimeq_t *o = m_new_obj_var(mp_obj_utimeq_t, struct qentry, alloc);
|
mp_obj_utimeq_t *o = mp_obj_malloc_var(mp_obj_utimeq_t, struct qentry, alloc, type);
|
||||||
o->base.type = type;
|
|
||||||
memset(o->items, 0, sizeof(*o->items) * alloc);
|
memset(o->items, 0, sizeof(*o->items) * alloc);
|
||||||
o->alloc = alloc;
|
o->alloc = alloc;
|
||||||
o->len = 0;
|
o->len = 0;
|
||||||
@ -214,4 +234,6 @@ const mp_obj_module_t mp_module_utimeq = {
|
|||||||
.globals = (mp_obj_dict_t *)&mp_module_utimeq_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_utimeq_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR_utimeq, mp_module_utimeq);
|
||||||
|
|
||||||
#endif // MICROPY_PY_UTIMEQ
|
#endif // MICROPY_PY_UTIMEQ
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// Copyright (c) 2014-2016 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014-2016 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -51,15 +72,14 @@ STATIC int read_src_stream(TINF_DATA *data) {
|
|||||||
STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
STATIC mp_obj_t decompio_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, 2, false);
|
mp_arg_check_num(n_args, n_kw, 1, 2, false);
|
||||||
mp_get_stream_raise(args[0], MP_STREAM_OP_READ);
|
mp_get_stream_raise(args[0], MP_STREAM_OP_READ);
|
||||||
mp_obj_decompio_t *o = m_new_obj(mp_obj_decompio_t);
|
mp_obj_decompio_t *o = mp_obj_malloc(mp_obj_decompio_t, type);
|
||||||
o->base.type = type;
|
|
||||||
memset(&o->decomp, 0, sizeof(o->decomp));
|
memset(&o->decomp, 0, sizeof(o->decomp));
|
||||||
o->decomp.readSource = read_src_stream;
|
o->decomp.readSource = read_src_stream;
|
||||||
o->src_stream = args[0];
|
o->src_stream = args[0];
|
||||||
o->eof = false;
|
o->eof = false;
|
||||||
|
|
||||||
mp_int_t dict_opt = 0;
|
mp_int_t dict_opt = 0;
|
||||||
int dict_sz;
|
uint dict_sz;
|
||||||
if (n_args > 1) {
|
if (n_args > 1) {
|
||||||
dict_opt = mp_obj_get_int(args[1]);
|
dict_opt = mp_obj_get_int(args[1]);
|
||||||
}
|
}
|
||||||
@ -76,7 +96,10 @@ STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size
|
|||||||
header_error:
|
header_error:
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("compression header"));
|
mp_raise_ValueError(MP_ERROR_TEXT("compression header"));
|
||||||
}
|
}
|
||||||
dict_sz = 1 << dict_opt;
|
// RFC 1950 section 2.2:
|
||||||
|
// CINFO is the base-2 logarithm of the LZ77 window size,
|
||||||
|
// minus eight (CINFO=7 indicates a 32K window size)
|
||||||
|
dict_sz = 1 << (dict_opt + 8);
|
||||||
} else {
|
} else {
|
||||||
dict_sz = 1 << -dict_opt;
|
dict_sz = 1 << -dict_opt;
|
||||||
}
|
}
|
||||||
@ -92,12 +115,13 @@ STATIC mp_uint_t decompio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *er
|
|||||||
}
|
}
|
||||||
|
|
||||||
o->decomp.dest = buf;
|
o->decomp.dest = buf;
|
||||||
o->decomp.dest_limit = (unsigned char *)buf + size;
|
o->decomp.dest_limit = (byte *)buf + size;
|
||||||
int st = uzlib_uncompress_chksum(&o->decomp);
|
int st = uzlib_uncompress_chksum(&o->decomp);
|
||||||
if (st == TINF_DONE) {
|
if (st == TINF_DONE) {
|
||||||
o->eof = true;
|
o->eof = true;
|
||||||
}
|
}
|
||||||
if (st < 0) {
|
if (st < 0) {
|
||||||
|
DEBUG_printf("uncompress error=" INT_FMT "\n", st);
|
||||||
*errcode = MP_EINVAL;
|
*errcode = MP_EINVAL;
|
||||||
return MP_STREAM_ERROR;
|
return MP_STREAM_ERROR;
|
||||||
}
|
}
|
||||||
@ -146,9 +170,10 @@ STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) {
|
|||||||
|
|
||||||
decomp->dest = dest_buf;
|
decomp->dest = dest_buf;
|
||||||
decomp->dest_limit = dest_buf + dest_buf_size;
|
decomp->dest_limit = dest_buf + dest_buf_size;
|
||||||
DEBUG_printf("uzlib: Initial out buffer: " UINT_FMT " bytes\n", decomp->destSize);
|
DEBUG_printf("uzlib: Initial out buffer: " UINT_FMT " bytes\n", dest_buf_size);
|
||||||
decomp->source = bufinfo.buf;
|
decomp->source = bufinfo.buf;
|
||||||
decomp->source_limit = (unsigned char *)bufinfo.buf + bufinfo.len;
|
decomp->source_limit = (byte *)bufinfo.buf + bufinfo.len;
|
||||||
|
|
||||||
int st;
|
int st;
|
||||||
bool is_zlib = true;
|
bool is_zlib = true;
|
||||||
|
|
||||||
@ -175,7 +200,7 @@ STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) {
|
|||||||
dest_buf = m_renew(byte, dest_buf, dest_buf_size, dest_buf_size + 256);
|
dest_buf = m_renew(byte, dest_buf, dest_buf_size, dest_buf_size + 256);
|
||||||
dest_buf_size += 256;
|
dest_buf_size += 256;
|
||||||
decomp->dest = dest_buf + offset;
|
decomp->dest = dest_buf + offset;
|
||||||
decomp->dest_limit = dest_buf + offset + 256;
|
decomp->dest_limit = decomp->dest + 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_uint_t final_sz = decomp->dest - dest_buf;
|
mp_uint_t final_sz = decomp->dest - dest_buf;
|
||||||
@ -203,6 +228,9 @@ const mp_obj_module_t mp_module_uzlib = {
|
|||||||
.base = { &mp_type_module },
|
.base = { &mp_type_module },
|
||||||
.globals = (mp_obj_dict_t *)&mp_module_uzlib_globals,
|
.globals = (mp_obj_dict_t *)&mp_module_uzlib_globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
MP_REGISTER_MODULE(MP_QSTR_uzlib, mp_module_uzlib);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Source files #include'd here to make sure they're compiled in
|
// Source files #include'd here to make sure they're compiled in
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
# MicroPython uasyncio module
|
|
||||||
# MIT license; Copyright (c) 2019 Damien P. George
|
|
||||||
|
|
||||||
from .core import *
|
|
||||||
|
|
||||||
__version__ = (3, 0, 0)
|
|
||||||
|
|
||||||
_attrs = {
|
|
||||||
"wait_for": "funcs",
|
|
||||||
"wait_for_ms": "funcs",
|
|
||||||
"gather": "funcs",
|
|
||||||
"Event": "event",
|
|
||||||
"ThreadSafeFlag": "event",
|
|
||||||
"Lock": "lock",
|
|
||||||
"open_connection": "stream",
|
|
||||||
"start_server": "stream",
|
|
||||||
"StreamReader": "stream",
|
|
||||||
"StreamWriter": "stream",
|
|
||||||
}
|
|
||||||
|
|
||||||
# Lazy loader, effectively does:
|
|
||||||
# global attr
|
|
||||||
# from .mod import attr
|
|
||||||
def __getattr__(attr):
|
|
||||||
mod = _attrs.get(attr, None)
|
|
||||||
if mod is None:
|
|
||||||
raise AttributeError(attr)
|
|
||||||
value = getattr(__import__(mod, None, None, True, 1), attr)
|
|
||||||
globals()[attr] = value
|
|
||||||
return value
|
|
@ -1,295 +0,0 @@
|
|||||||
# MicroPython uasyncio module
|
|
||||||
# MIT license; Copyright (c) 2019 Damien P. George
|
|
||||||
|
|
||||||
from time import ticks_ms as ticks, ticks_diff, ticks_add
|
|
||||||
import sys, select
|
|
||||||
|
|
||||||
# Import TaskQueue and Task, preferring built-in C code over Python code
|
|
||||||
try:
|
|
||||||
from _uasyncio import TaskQueue, Task
|
|
||||||
except:
|
|
||||||
from .task import TaskQueue, Task
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Exceptions
|
|
||||||
|
|
||||||
|
|
||||||
class CancelledError(BaseException):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class TimeoutError(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# Used when calling Loop.call_exception_handler
|
|
||||||
_exc_context = {"message": "Task exception wasn't retrieved", "exception": None, "future": None}
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Sleep functions
|
|
||||||
|
|
||||||
# "Yield" once, then raise StopIteration
|
|
||||||
class SingletonGenerator:
|
|
||||||
def __init__(self):
|
|
||||||
self.state = None
|
|
||||||
self.exc = StopIteration()
|
|
||||||
|
|
||||||
def __await__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __next__(self):
|
|
||||||
if self.state is not None:
|
|
||||||
_task_queue.push_sorted(cur_task, self.state)
|
|
||||||
self.state = None
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
self.exc.__traceback__ = None
|
|
||||||
raise self.exc
|
|
||||||
|
|
||||||
|
|
||||||
# Pause task execution for the given time (integer in milliseconds, uPy extension)
|
|
||||||
# Use a SingletonGenerator to do it without allocating on the heap
|
|
||||||
def sleep_ms(t, sgen=SingletonGenerator()):
|
|
||||||
assert sgen.state is None
|
|
||||||
sgen.state = ticks_add(ticks(), max(0, t))
|
|
||||||
return sgen
|
|
||||||
|
|
||||||
|
|
||||||
# Pause task execution for the given time (in seconds)
|
|
||||||
def sleep(t):
|
|
||||||
return sleep_ms(int(t * 1000))
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Queue and poller for stream IO
|
|
||||||
|
|
||||||
|
|
||||||
class IOQueue:
|
|
||||||
def __init__(self):
|
|
||||||
self.poller = select.poll()
|
|
||||||
self.map = {} # maps id(stream) to [task_waiting_read, task_waiting_write, stream]
|
|
||||||
|
|
||||||
def _enqueue(self, s, idx):
|
|
||||||
if id(s) not in self.map:
|
|
||||||
entry = [None, None, s]
|
|
||||||
entry[idx] = cur_task
|
|
||||||
self.map[id(s)] = entry
|
|
||||||
self.poller.register(s, select.POLLIN if idx == 0 else select.POLLOUT)
|
|
||||||
else:
|
|
||||||
sm = self.map[id(s)]
|
|
||||||
assert sm[idx] is None
|
|
||||||
assert sm[1 - idx] is not None
|
|
||||||
sm[idx] = cur_task
|
|
||||||
self.poller.modify(s, select.POLLIN | select.POLLOUT)
|
|
||||||
# Link task to this IOQueue so it can be removed if needed
|
|
||||||
cur_task.data = self
|
|
||||||
|
|
||||||
def _dequeue(self, s):
|
|
||||||
del self.map[id(s)]
|
|
||||||
self.poller.unregister(s)
|
|
||||||
|
|
||||||
def queue_read(self, s):
|
|
||||||
self._enqueue(s, 0)
|
|
||||||
|
|
||||||
def queue_write(self, s):
|
|
||||||
self._enqueue(s, 1)
|
|
||||||
|
|
||||||
def remove(self, task):
|
|
||||||
while True:
|
|
||||||
del_s = None
|
|
||||||
for k in self.map: # Iterate without allocating on the heap
|
|
||||||
q0, q1, s = self.map[k]
|
|
||||||
if q0 is task or q1 is task:
|
|
||||||
del_s = s
|
|
||||||
break
|
|
||||||
if del_s is not None:
|
|
||||||
self._dequeue(s)
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
def wait_io_event(self, dt):
|
|
||||||
for s, ev in self.poller.ipoll(dt):
|
|
||||||
sm = self.map[id(s)]
|
|
||||||
# print('poll', s, sm, ev)
|
|
||||||
if ev & ~select.POLLOUT and sm[0] is not None:
|
|
||||||
# POLLIN or error
|
|
||||||
_task_queue.push_head(sm[0])
|
|
||||||
sm[0] = None
|
|
||||||
if ev & ~select.POLLIN and sm[1] is not None:
|
|
||||||
# POLLOUT or error
|
|
||||||
_task_queue.push_head(sm[1])
|
|
||||||
sm[1] = None
|
|
||||||
if sm[0] is None and sm[1] is None:
|
|
||||||
self._dequeue(s)
|
|
||||||
elif sm[0] is None:
|
|
||||||
self.poller.modify(s, select.POLLOUT)
|
|
||||||
else:
|
|
||||||
self.poller.modify(s, select.POLLIN)
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Main run loop
|
|
||||||
|
|
||||||
# Ensure the awaitable is a task
|
|
||||||
def _promote_to_task(aw):
|
|
||||||
return aw if isinstance(aw, Task) else create_task(aw)
|
|
||||||
|
|
||||||
|
|
||||||
# Create and schedule a new task from a coroutine
|
|
||||||
def create_task(coro):
|
|
||||||
if not hasattr(coro, "send"):
|
|
||||||
raise TypeError("coroutine expected")
|
|
||||||
t = Task(coro, globals())
|
|
||||||
_task_queue.push_head(t)
|
|
||||||
return t
|
|
||||||
|
|
||||||
|
|
||||||
# Keep scheduling tasks until there are none left to schedule
|
|
||||||
def run_until_complete(main_task=None):
|
|
||||||
global cur_task
|
|
||||||
excs_all = (CancelledError, Exception) # To prevent heap allocation in loop
|
|
||||||
excs_stop = (CancelledError, StopIteration) # To prevent heap allocation in loop
|
|
||||||
while True:
|
|
||||||
# Wait until the head of _task_queue is ready to run
|
|
||||||
dt = 1
|
|
||||||
while dt > 0:
|
|
||||||
dt = -1
|
|
||||||
t = _task_queue.peek()
|
|
||||||
if t:
|
|
||||||
# A task waiting on _task_queue; "ph_key" is time to schedule task at
|
|
||||||
dt = max(0, ticks_diff(t.ph_key, ticks()))
|
|
||||||
elif not _io_queue.map:
|
|
||||||
# No tasks can be woken so finished running
|
|
||||||
return
|
|
||||||
# print('(poll {})'.format(dt), len(_io_queue.map))
|
|
||||||
_io_queue.wait_io_event(dt)
|
|
||||||
|
|
||||||
# Get next task to run and continue it
|
|
||||||
t = _task_queue.pop_head()
|
|
||||||
cur_task = t
|
|
||||||
try:
|
|
||||||
# Continue running the coroutine, it's responsible for rescheduling itself
|
|
||||||
exc = t.data
|
|
||||||
if not exc:
|
|
||||||
t.coro.send(None)
|
|
||||||
else:
|
|
||||||
# If the task is finished and on the run queue and gets here, then it
|
|
||||||
# had an exception and was not await'ed on. Throwing into it now will
|
|
||||||
# raise StopIteration and the code below will catch this and run the
|
|
||||||
# call_exception_handler function.
|
|
||||||
t.data = None
|
|
||||||
t.coro.throw(exc)
|
|
||||||
except excs_all as er:
|
|
||||||
# Check the task is not on any event queue
|
|
||||||
assert t.data is None
|
|
||||||
# This task is done, check if it's the main task and then loop should stop
|
|
||||||
if t is main_task:
|
|
||||||
if isinstance(er, StopIteration):
|
|
||||||
return er.value
|
|
||||||
raise er
|
|
||||||
if t.state:
|
|
||||||
# Task was running but is now finished.
|
|
||||||
waiting = False
|
|
||||||
if t.state is True:
|
|
||||||
# "None" indicates that the task is complete and not await'ed on (yet).
|
|
||||||
t.state = None
|
|
||||||
else:
|
|
||||||
# Schedule any other tasks waiting on the completion of this task.
|
|
||||||
while t.state.peek():
|
|
||||||
_task_queue.push_head(t.state.pop_head())
|
|
||||||
waiting = True
|
|
||||||
# "False" indicates that the task is complete and has been await'ed on.
|
|
||||||
t.state = False
|
|
||||||
if not waiting and not isinstance(er, excs_stop):
|
|
||||||
# An exception ended this detached task, so queue it for later
|
|
||||||
# execution to handle the uncaught exception if no other task retrieves
|
|
||||||
# the exception in the meantime (this is handled by Task.throw).
|
|
||||||
_task_queue.push_head(t)
|
|
||||||
# Save return value of coro to pass up to caller.
|
|
||||||
t.data = er
|
|
||||||
elif t.state is None:
|
|
||||||
# Task is already finished and nothing await'ed on the task,
|
|
||||||
# so call the exception handler.
|
|
||||||
_exc_context["exception"] = exc
|
|
||||||
_exc_context["future"] = t
|
|
||||||
Loop.call_exception_handler(_exc_context)
|
|
||||||
|
|
||||||
|
|
||||||
# Create a new task from a coroutine and run it until it finishes
|
|
||||||
def run(coro):
|
|
||||||
return run_until_complete(create_task(coro))
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Event loop wrapper
|
|
||||||
|
|
||||||
|
|
||||||
async def _stopper():
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
_stop_task = None
|
|
||||||
|
|
||||||
|
|
||||||
class Loop:
|
|
||||||
_exc_handler = None
|
|
||||||
|
|
||||||
def create_task(coro):
|
|
||||||
return create_task(coro)
|
|
||||||
|
|
||||||
def run_forever():
|
|
||||||
global _stop_task
|
|
||||||
_stop_task = Task(_stopper(), globals())
|
|
||||||
run_until_complete(_stop_task)
|
|
||||||
# TODO should keep running until .stop() is called, even if there're no tasks left
|
|
||||||
|
|
||||||
def run_until_complete(aw):
|
|
||||||
return run_until_complete(_promote_to_task(aw))
|
|
||||||
|
|
||||||
def stop():
|
|
||||||
global _stop_task
|
|
||||||
if _stop_task is not None:
|
|
||||||
_task_queue.push_head(_stop_task)
|
|
||||||
# If stop() is called again, do nothing
|
|
||||||
_stop_task = None
|
|
||||||
|
|
||||||
def close():
|
|
||||||
pass
|
|
||||||
|
|
||||||
def set_exception_handler(handler):
|
|
||||||
Loop._exc_handler = handler
|
|
||||||
|
|
||||||
def get_exception_handler():
|
|
||||||
return Loop._exc_handler
|
|
||||||
|
|
||||||
def default_exception_handler(loop, context):
|
|
||||||
print(context["message"])
|
|
||||||
print("future:", context["future"], "coro=", context["future"].coro)
|
|
||||||
sys.print_exception(context["exception"])
|
|
||||||
|
|
||||||
def call_exception_handler(context):
|
|
||||||
(Loop._exc_handler or Loop.default_exception_handler)(Loop, context)
|
|
||||||
|
|
||||||
|
|
||||||
# The runq_len and waitq_len arguments are for legacy uasyncio compatibility
|
|
||||||
def get_event_loop(runq_len=0, waitq_len=0):
|
|
||||||
return Loop
|
|
||||||
|
|
||||||
|
|
||||||
def current_task():
|
|
||||||
return cur_task
|
|
||||||
|
|
||||||
|
|
||||||
def new_event_loop():
|
|
||||||
global _task_queue, _io_queue
|
|
||||||
# TaskQueue of Task instances
|
|
||||||
_task_queue = TaskQueue()
|
|
||||||
# Task queue and poller for stream IO
|
|
||||||
_io_queue = IOQueue()
|
|
||||||
return Loop
|
|
||||||
|
|
||||||
|
|
||||||
# Initialise default event loop
|
|
||||||
new_event_loop()
|
|
@ -1,33 +0,0 @@
|
|||||||
# MicroPython uasyncio module
|
|
||||||
# MIT license; Copyright (c) 2019-2020 Damien P. George
|
|
||||||
|
|
||||||
from . import core
|
|
||||||
|
|
||||||
# Event class for primitive events that can be waited on, set, and cleared
|
|
||||||
class Event:
|
|
||||||
def __init__(self):
|
|
||||||
self.state = False # False=unset; True=set
|
|
||||||
self.waiting = core.TaskQueue() # Queue of Tasks waiting on completion of this event
|
|
||||||
|
|
||||||
def is_set(self):
|
|
||||||
return self.state
|
|
||||||
|
|
||||||
def set(self):
|
|
||||||
# Event becomes set, schedule any tasks waiting on it
|
|
||||||
# Note: This must not be called from anything except the thread running
|
|
||||||
# the asyncio loop (i.e. neither hard or soft IRQ, or a different thread).
|
|
||||||
while self.waiting.peek():
|
|
||||||
core._task_queue.push_head(self.waiting.pop_head())
|
|
||||||
self.state = True
|
|
||||||
|
|
||||||
def clear(self):
|
|
||||||
self.state = False
|
|
||||||
|
|
||||||
async def wait(self):
|
|
||||||
if not self.state:
|
|
||||||
# Event not set, put the calling task on the event's waiting queue
|
|
||||||
self.waiting.push_head(core.cur_task)
|
|
||||||
# Set calling task's data to the event's queue so it can be removed if needed
|
|
||||||
core.cur_task.data = self.waiting
|
|
||||||
yield
|
|
||||||
return True
|
|
@ -1,74 +0,0 @@
|
|||||||
# MicroPython uasyncio module
|
|
||||||
# MIT license; Copyright (c) 2019-2020 Damien P. George
|
|
||||||
|
|
||||||
from . import core
|
|
||||||
|
|
||||||
|
|
||||||
async def wait_for(aw, timeout, sleep=core.sleep):
|
|
||||||
aw = core._promote_to_task(aw)
|
|
||||||
if timeout is None:
|
|
||||||
return await aw
|
|
||||||
|
|
||||||
def runner(waiter, aw):
|
|
||||||
nonlocal status, result
|
|
||||||
try:
|
|
||||||
result = await aw
|
|
||||||
s = True
|
|
||||||
except BaseException as er:
|
|
||||||
s = er
|
|
||||||
if status is None:
|
|
||||||
# The waiter is still waiting, set status for it and cancel it.
|
|
||||||
status = s
|
|
||||||
waiter.cancel()
|
|
||||||
|
|
||||||
# Run aw in a separate runner task that manages its exceptions.
|
|
||||||
status = None
|
|
||||||
result = None
|
|
||||||
runner_task = core.create_task(runner(core.cur_task, aw))
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Wait for the timeout to elapse.
|
|
||||||
await sleep(timeout)
|
|
||||||
except core.CancelledError as er:
|
|
||||||
if status is True:
|
|
||||||
# aw completed successfully and cancelled the sleep, so return aw's result.
|
|
||||||
return result
|
|
||||||
elif status is None:
|
|
||||||
# This wait_for was cancelled externally, so cancel aw and re-raise.
|
|
||||||
status = True
|
|
||||||
runner_task.cancel()
|
|
||||||
raise er
|
|
||||||
else:
|
|
||||||
# aw raised an exception, propagate it out to the caller.
|
|
||||||
raise status
|
|
||||||
|
|
||||||
# The sleep finished before aw, so cancel aw and raise TimeoutError.
|
|
||||||
status = True
|
|
||||||
runner_task.cancel()
|
|
||||||
await runner_task
|
|
||||||
raise core.TimeoutError
|
|
||||||
|
|
||||||
|
|
||||||
def wait_for_ms(aw, timeout):
|
|
||||||
return wait_for(aw, timeout, core.sleep_ms)
|
|
||||||
|
|
||||||
|
|
||||||
async def gather(*aws, return_exceptions=False):
|
|
||||||
ts = [core._promote_to_task(aw) for aw in aws]
|
|
||||||
for i in range(len(ts)):
|
|
||||||
try:
|
|
||||||
# TODO handle cancel of gather itself
|
|
||||||
# if ts[i].coro:
|
|
||||||
# iter(ts[i]).waiting.push_head(cur_task)
|
|
||||||
# try:
|
|
||||||
# yield
|
|
||||||
# except CancelledError as er:
|
|
||||||
# # cancel all waiting tasks
|
|
||||||
# raise er
|
|
||||||
ts[i] = await ts[i]
|
|
||||||
except (core.CancelledError, Exception) as er:
|
|
||||||
if return_exceptions:
|
|
||||||
ts[i] = er
|
|
||||||
else:
|
|
||||||
raise er
|
|
||||||
return ts
|
|
@ -1,53 +0,0 @@
|
|||||||
# MicroPython uasyncio module
|
|
||||||
# MIT license; Copyright (c) 2019-2020 Damien P. George
|
|
||||||
|
|
||||||
from . import core
|
|
||||||
|
|
||||||
# Lock class for primitive mutex capability
|
|
||||||
class Lock:
|
|
||||||
def __init__(self):
|
|
||||||
# The state can take the following values:
|
|
||||||
# - 0: unlocked
|
|
||||||
# - 1: locked
|
|
||||||
# - <Task>: unlocked but this task has been scheduled to acquire the lock next
|
|
||||||
self.state = 0
|
|
||||||
# Queue of Tasks waiting to acquire this Lock
|
|
||||||
self.waiting = core.TaskQueue()
|
|
||||||
|
|
||||||
def locked(self):
|
|
||||||
return self.state == 1
|
|
||||||
|
|
||||||
def release(self):
|
|
||||||
if self.state != 1:
|
|
||||||
raise RuntimeError("Lock not acquired")
|
|
||||||
if self.waiting.peek():
|
|
||||||
# Task(s) waiting on lock, schedule next Task
|
|
||||||
self.state = self.waiting.pop_head()
|
|
||||||
core._task_queue.push_head(self.state)
|
|
||||||
else:
|
|
||||||
# No Task waiting so unlock
|
|
||||||
self.state = 0
|
|
||||||
|
|
||||||
async def acquire(self):
|
|
||||||
if self.state != 0:
|
|
||||||
# Lock unavailable, put the calling Task on the waiting queue
|
|
||||||
self.waiting.push_head(core.cur_task)
|
|
||||||
# Set calling task's data to the lock's queue so it can be removed if needed
|
|
||||||
core.cur_task.data = self.waiting
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
except core.CancelledError as er:
|
|
||||||
if self.state == core.cur_task:
|
|
||||||
# Cancelled while pending on resume, schedule next waiting Task
|
|
||||||
self.state = 1
|
|
||||||
self.release()
|
|
||||||
raise er
|
|
||||||
# Lock available, set it as locked
|
|
||||||
self.state = 1
|
|
||||||
return True
|
|
||||||
|
|
||||||
async def __aenter__(self):
|
|
||||||
return await self.acquire()
|
|
||||||
|
|
||||||
async def __aexit__(self, exc_type, exc, tb):
|
|
||||||
return self.release()
|
|
@ -1,13 +0,0 @@
|
|||||||
# This list of frozen files doesn't include task.py because that's provided by the C module.
|
|
||||||
freeze(
|
|
||||||
"..",
|
|
||||||
(
|
|
||||||
"uasyncio/__init__.py",
|
|
||||||
"uasyncio/core.py",
|
|
||||||
"uasyncio/event.py",
|
|
||||||
"uasyncio/funcs.py",
|
|
||||||
"uasyncio/lock.py",
|
|
||||||
"uasyncio/stream.py",
|
|
||||||
),
|
|
||||||
opt=3,
|
|
||||||
)
|
|
@ -1,164 +0,0 @@
|
|||||||
# MicroPython uasyncio module
|
|
||||||
# MIT license; Copyright (c) 2019-2020 Damien P. George
|
|
||||||
|
|
||||||
from . import core
|
|
||||||
|
|
||||||
|
|
||||||
class Stream:
|
|
||||||
def __init__(self, s, e={}):
|
|
||||||
self.s = s
|
|
||||||
self.e = e
|
|
||||||
self.out_buf = b""
|
|
||||||
|
|
||||||
def get_extra_info(self, v):
|
|
||||||
return self.e[v]
|
|
||||||
|
|
||||||
async def __aenter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
async def __aexit__(self, exc_type, exc, tb):
|
|
||||||
await self.close()
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
async def wait_closed(self):
|
|
||||||
# TODO yield?
|
|
||||||
self.s.close()
|
|
||||||
|
|
||||||
async def read(self, n):
|
|
||||||
yield core._io_queue.queue_read(self.s)
|
|
||||||
return self.s.read(n)
|
|
||||||
|
|
||||||
async def readinto(self, buf):
|
|
||||||
yield core._io_queue.queue_read(self.s)
|
|
||||||
return self.s.readinto(buf)
|
|
||||||
|
|
||||||
async def readexactly(self, n):
|
|
||||||
r = b""
|
|
||||||
while n:
|
|
||||||
yield core._io_queue.queue_read(self.s)
|
|
||||||
r2 = self.s.read(n)
|
|
||||||
if r2 is not None:
|
|
||||||
if not len(r2):
|
|
||||||
raise EOFError
|
|
||||||
r += r2
|
|
||||||
n -= len(r2)
|
|
||||||
return r
|
|
||||||
|
|
||||||
async def readline(self):
|
|
||||||
l = b""
|
|
||||||
while True:
|
|
||||||
yield core._io_queue.queue_read(self.s)
|
|
||||||
l2 = self.s.readline() # may do multiple reads but won't block
|
|
||||||
l += l2
|
|
||||||
if not l2 or l[-1] == 10: # \n (check l in case l2 is str)
|
|
||||||
return l
|
|
||||||
|
|
||||||
def write(self, buf):
|
|
||||||
self.out_buf += buf
|
|
||||||
|
|
||||||
async def drain(self):
|
|
||||||
mv = memoryview(self.out_buf)
|
|
||||||
off = 0
|
|
||||||
while off < len(mv):
|
|
||||||
yield core._io_queue.queue_write(self.s)
|
|
||||||
ret = self.s.write(mv[off:])
|
|
||||||
if ret is not None:
|
|
||||||
off += ret
|
|
||||||
self.out_buf = b""
|
|
||||||
|
|
||||||
|
|
||||||
# Stream can be used for both reading and writing to save code size
|
|
||||||
StreamReader = Stream
|
|
||||||
StreamWriter = Stream
|
|
||||||
|
|
||||||
|
|
||||||
# Create a TCP stream connection to a remote host
|
|
||||||
async def open_connection(host, port):
|
|
||||||
from uerrno import EINPROGRESS
|
|
||||||
import usocket as socket
|
|
||||||
|
|
||||||
ai = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM)[0] # TODO this is blocking!
|
|
||||||
s = socket.socket(ai[0], ai[1], ai[2])
|
|
||||||
s.setblocking(False)
|
|
||||||
ss = Stream(s)
|
|
||||||
try:
|
|
||||||
s.connect(ai[-1])
|
|
||||||
except OSError as er:
|
|
||||||
if er.errno != EINPROGRESS:
|
|
||||||
raise er
|
|
||||||
yield core._io_queue.queue_write(s)
|
|
||||||
return ss, ss
|
|
||||||
|
|
||||||
|
|
||||||
# Class representing a TCP stream server, can be closed and used in "async with"
|
|
||||||
class Server:
|
|
||||||
async def __aenter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
async def __aexit__(self, exc_type, exc, tb):
|
|
||||||
self.close()
|
|
||||||
await self.wait_closed()
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
self.task.cancel()
|
|
||||||
|
|
||||||
async def wait_closed(self):
|
|
||||||
await self.task
|
|
||||||
|
|
||||||
async def _serve(self, s, cb):
|
|
||||||
# Accept incoming connections
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
yield core._io_queue.queue_read(s)
|
|
||||||
except core.CancelledError:
|
|
||||||
# Shutdown server
|
|
||||||
s.close()
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
s2, addr = s.accept()
|
|
||||||
except:
|
|
||||||
# Ignore a failed accept
|
|
||||||
continue
|
|
||||||
s2.setblocking(False)
|
|
||||||
s2s = Stream(s2, {"peername": addr})
|
|
||||||
core.create_task(cb(s2s, s2s))
|
|
||||||
|
|
||||||
|
|
||||||
# Helper function to start a TCP stream server, running as a new task
|
|
||||||
# TODO could use an accept-callback on socket read activity instead of creating a task
|
|
||||||
async def start_server(cb, host, port, backlog=5):
|
|
||||||
import usocket as socket
|
|
||||||
|
|
||||||
# Create and bind server socket.
|
|
||||||
host = socket.getaddrinfo(host, port)[0] # TODO this is blocking!
|
|
||||||
s = socket.socket()
|
|
||||||
s.setblocking(False)
|
|
||||||
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
||||||
s.bind(host[-1])
|
|
||||||
s.listen(backlog)
|
|
||||||
|
|
||||||
# Create and return server object and task.
|
|
||||||
srv = Server()
|
|
||||||
srv.task = core.create_task(srv._serve(s, cb))
|
|
||||||
return srv
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Legacy uasyncio compatibility
|
|
||||||
|
|
||||||
|
|
||||||
async def stream_awrite(self, buf, off=0, sz=-1):
|
|
||||||
if off != 0 or sz != -1:
|
|
||||||
buf = memoryview(buf)
|
|
||||||
if sz == -1:
|
|
||||||
sz = len(buf)
|
|
||||||
buf = buf[off : off + sz]
|
|
||||||
self.write(buf)
|
|
||||||
await self.drain()
|
|
||||||
|
|
||||||
|
|
||||||
Stream.aclose = Stream.wait_closed
|
|
||||||
Stream.awrite = stream_awrite
|
|
||||||
Stream.awritestr = stream_awrite # TODO explicitly convert to bytes?
|
|
@ -1,179 +0,0 @@
|
|||||||
# MicroPython uasyncio module
|
|
||||||
# MIT license; Copyright (c) 2019-2020 Damien P. George
|
|
||||||
|
|
||||||
# This file contains the core TaskQueue based on a pairing heap, and the core Task class.
|
|
||||||
# They can optionally be replaced by C implementations.
|
|
||||||
|
|
||||||
from . import core
|
|
||||||
|
|
||||||
|
|
||||||
# pairing-heap meld of 2 heaps; O(1)
|
|
||||||
def ph_meld(h1, h2):
|
|
||||||
if h1 is None:
|
|
||||||
return h2
|
|
||||||
if h2 is None:
|
|
||||||
return h1
|
|
||||||
lt = core.ticks_diff(h1.ph_key, h2.ph_key) < 0
|
|
||||||
if lt:
|
|
||||||
if h1.ph_child is None:
|
|
||||||
h1.ph_child = h2
|
|
||||||
else:
|
|
||||||
h1.ph_child_last.ph_next = h2
|
|
||||||
h1.ph_child_last = h2
|
|
||||||
h2.ph_next = None
|
|
||||||
h2.ph_rightmost_parent = h1
|
|
||||||
return h1
|
|
||||||
else:
|
|
||||||
h1.ph_next = h2.ph_child
|
|
||||||
h2.ph_child = h1
|
|
||||||
if h1.ph_next is None:
|
|
||||||
h2.ph_child_last = h1
|
|
||||||
h1.ph_rightmost_parent = h2
|
|
||||||
return h2
|
|
||||||
|
|
||||||
|
|
||||||
# pairing-heap pairing operation; amortised O(log N)
|
|
||||||
def ph_pairing(child):
|
|
||||||
heap = None
|
|
||||||
while child is not None:
|
|
||||||
n1 = child
|
|
||||||
child = child.ph_next
|
|
||||||
n1.ph_next = None
|
|
||||||
if child is not None:
|
|
||||||
n2 = child
|
|
||||||
child = child.ph_next
|
|
||||||
n2.ph_next = None
|
|
||||||
n1 = ph_meld(n1, n2)
|
|
||||||
heap = ph_meld(heap, n1)
|
|
||||||
return heap
|
|
||||||
|
|
||||||
|
|
||||||
# pairing-heap delete of a node; stable, amortised O(log N)
|
|
||||||
def ph_delete(heap, node):
|
|
||||||
if node is heap:
|
|
||||||
child = heap.ph_child
|
|
||||||
node.ph_child = None
|
|
||||||
return ph_pairing(child)
|
|
||||||
# Find parent of node
|
|
||||||
parent = node
|
|
||||||
while parent.ph_next is not None:
|
|
||||||
parent = parent.ph_next
|
|
||||||
parent = parent.ph_rightmost_parent
|
|
||||||
# Replace node with pairing of its children
|
|
||||||
if node is parent.ph_child and node.ph_child is None:
|
|
||||||
parent.ph_child = node.ph_next
|
|
||||||
node.ph_next = None
|
|
||||||
return heap
|
|
||||||
elif node is parent.ph_child:
|
|
||||||
child = node.ph_child
|
|
||||||
next = node.ph_next
|
|
||||||
node.ph_child = None
|
|
||||||
node.ph_next = None
|
|
||||||
node = ph_pairing(child)
|
|
||||||
parent.ph_child = node
|
|
||||||
else:
|
|
||||||
n = parent.ph_child
|
|
||||||
while node is not n.ph_next:
|
|
||||||
n = n.ph_next
|
|
||||||
child = node.ph_child
|
|
||||||
next = node.ph_next
|
|
||||||
node.ph_child = None
|
|
||||||
node.ph_next = None
|
|
||||||
node = ph_pairing(child)
|
|
||||||
if node is None:
|
|
||||||
node = n
|
|
||||||
else:
|
|
||||||
n.ph_next = node
|
|
||||||
node.ph_next = next
|
|
||||||
if next is None:
|
|
||||||
node.ph_rightmost_parent = parent
|
|
||||||
parent.ph_child_last = node
|
|
||||||
return heap
|
|
||||||
|
|
||||||
|
|
||||||
# TaskQueue class based on the above pairing-heap functions.
|
|
||||||
class TaskQueue:
|
|
||||||
def __init__(self):
|
|
||||||
self.heap = None
|
|
||||||
|
|
||||||
def peek(self):
|
|
||||||
return self.heap
|
|
||||||
|
|
||||||
def push_sorted(self, v, key):
|
|
||||||
v.data = None
|
|
||||||
v.ph_key = key
|
|
||||||
v.ph_child = None
|
|
||||||
v.ph_next = None
|
|
||||||
self.heap = ph_meld(v, self.heap)
|
|
||||||
|
|
||||||
def push_head(self, v):
|
|
||||||
self.push_sorted(v, core.ticks())
|
|
||||||
|
|
||||||
def pop_head(self):
|
|
||||||
v = self.heap
|
|
||||||
self.heap = ph_pairing(self.heap.ph_child)
|
|
||||||
return v
|
|
||||||
|
|
||||||
def remove(self, v):
|
|
||||||
self.heap = ph_delete(self.heap, v)
|
|
||||||
|
|
||||||
|
|
||||||
# Task class representing a coroutine, can be waited on and cancelled.
|
|
||||||
class Task:
|
|
||||||
def __init__(self, coro, globals=None):
|
|
||||||
self.coro = coro # Coroutine of this Task
|
|
||||||
self.data = None # General data for queue it is waiting on
|
|
||||||
self.state = True # None, False, True or a TaskQueue instance
|
|
||||||
self.ph_key = 0 # Pairing heap
|
|
||||||
self.ph_child = None # Paring heap
|
|
||||||
self.ph_child_last = None # Paring heap
|
|
||||||
self.ph_next = None # Paring heap
|
|
||||||
self.ph_rightmost_parent = None # Paring heap
|
|
||||||
|
|
||||||
def __await__(self):
|
|
||||||
if not self.state:
|
|
||||||
# Task finished, signal that is has been await'ed on.
|
|
||||||
self.state = False
|
|
||||||
elif self.state is True:
|
|
||||||
# Allocated head of linked list of Tasks waiting on completion of this task.
|
|
||||||
self.state = TaskQueue()
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __next__(self):
|
|
||||||
if not self.state:
|
|
||||||
if self.data is None:
|
|
||||||
# Task finished but has already been sent to the loop's exception handler.
|
|
||||||
raise StopIteration
|
|
||||||
else:
|
|
||||||
# Task finished, raise return value to caller so it can continue.
|
|
||||||
raise self.data
|
|
||||||
else:
|
|
||||||
# Put calling task on waiting queue.
|
|
||||||
self.state.push_head(core.cur_task)
|
|
||||||
# Set calling task's data to this task that it waits on, to double-link it.
|
|
||||||
core.cur_task.data = self
|
|
||||||
|
|
||||||
def done(self):
|
|
||||||
return not self.state
|
|
||||||
|
|
||||||
def cancel(self):
|
|
||||||
# Check if task is already finished.
|
|
||||||
if not self.state:
|
|
||||||
return False
|
|
||||||
# Can't cancel self (not supported yet).
|
|
||||||
if self is core.cur_task:
|
|
||||||
raise RuntimeError("can't cancel self")
|
|
||||||
# If Task waits on another task then forward the cancel to the one it's waiting on.
|
|
||||||
while isinstance(self.data, Task):
|
|
||||||
self = self.data
|
|
||||||
# Reschedule Task as a cancelled task.
|
|
||||||
if hasattr(self.data, "remove"):
|
|
||||||
# Not on the main running queue, remove the task from the queue it's on.
|
|
||||||
self.data.remove(self)
|
|
||||||
core._task_queue.push_head(self)
|
|
||||||
elif core.ticks_diff(self.ph_key, core.ticks()) > 0:
|
|
||||||
# On the main running queue but scheduled in the future, so bring it forward to now.
|
|
||||||
core._task_queue.remove(self)
|
|
||||||
core._task_queue.push_head(self)
|
|
||||||
self.data = core.CancelledError
|
|
||||||
return True
|
|
@ -1,8 +1,29 @@
|
|||||||
// Copyright (c) 2016 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2013-2016 Damien P. George
|
*
|
||||||
//
|
* The MIT License (MIT)
|
||||||
// SPDX-License-Identifier: MIT
|
*
|
||||||
|
* Copyright (c) 2013-2016 Damien P. George
|
||||||
|
* Copyright (c) 2016 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#if MICROPY_PY_UTIME_MP_HAL
|
#if MICROPY_PY_UTIME_MP_HAL
|
||||||
|
@ -1,9 +1,29 @@
|
|||||||
// Copyright (c) 2016 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2013-2016 Damien P. George
|
*
|
||||||
//
|
* The MIT License (MIT)
|
||||||
// SPDX-License-Identifier: MIT
|
*
|
||||||
|
* Copyright (c) 2013-2016 Damien P. George
|
||||||
|
* Copyright (c) 2016 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
#ifndef MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H
|
#ifndef MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H
|
||||||
#define MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H
|
#define MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H
|
||||||
|
|
||||||
|
32
extmod/vfs.c
32
extmod/vfs.c
@ -1,7 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2017 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -386,8 +407,7 @@ mp_obj_t mp_vfs_ilistdir(size_t n_args, const mp_obj_t *args) {
|
|||||||
|
|
||||||
if (vfs == MP_VFS_ROOT) {
|
if (vfs == MP_VFS_ROOT) {
|
||||||
// list the root directory
|
// list the root directory
|
||||||
mp_vfs_ilistdir_it_t *iter = m_new_obj(mp_vfs_ilistdir_it_t);
|
mp_vfs_ilistdir_it_t *iter = mp_obj_malloc(mp_vfs_ilistdir_it_t, &mp_type_polymorph_iter);
|
||||||
iter->base.type = &mp_type_polymorph_iter;
|
|
||||||
iter->iternext = mp_vfs_ilistdir_it_iternext;
|
iter->iternext = mp_vfs_ilistdir_it_iternext;
|
||||||
iter->cur.vfs = MP_STATE_VM(vfs_mount_table);
|
iter->cur.vfs = MP_STATE_VM(vfs_mount_table);
|
||||||
iter->is_str = mp_obj_get_type(path_in) == &mp_type_str;
|
iter->is_str = mp_obj_get_type(path_in) == &mp_type_str;
|
||||||
|
32
extmod/vfs.h
32
extmod/vfs.h
@ -1,12 +1,32 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2017 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
#ifndef MICROPY_INCLUDED_EXTMOD_VFS_H
|
#ifndef MICROPY_INCLUDED_EXTMOD_VFS_H
|
||||||
#define MICROPY_INCLUDED_EXTMOD_VFS_H
|
#define MICROPY_INCLUDED_EXTMOD_VFS_H
|
||||||
|
|
||||||
#include "py/lexer.h"
|
#include "py/builtin.h"
|
||||||
#include "py/obj.h"
|
#include "py/obj.h"
|
||||||
#include "py/proto.h"
|
#include "py/proto.h"
|
||||||
|
|
||||||
|
@ -1,8 +1,29 @@
|
|||||||
// Copyright (c) 2016 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George
|
*
|
||||||
//
|
* The MIT License (MIT)
|
||||||
// SPDX-License-Identifier: MIT
|
*
|
||||||
|
* Copyright (c) 2014 Damien P. George
|
||||||
|
* Copyright (c) 2016 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#if MICROPY_VFS_FAT
|
#if MICROPY_VFS_FAT
|
||||||
@ -54,8 +75,7 @@ STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, size_
|
|||||||
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
||||||
|
|
||||||
// create new object
|
// create new object
|
||||||
fs_user_mount_t *vfs = m_new_obj(fs_user_mount_t);
|
fs_user_mount_t *vfs = mp_obj_malloc(fs_user_mount_t, type);
|
||||||
vfs->base.type = type;
|
|
||||||
vfs->fatfs.drv = vfs;
|
vfs->fatfs.drv = vfs;
|
||||||
|
|
||||||
// Initialise underlying block device
|
// Initialise underlying block device
|
||||||
@ -171,8 +191,7 @@ STATIC mp_obj_t fat_vfs_ilistdir_func(size_t n_args, const mp_obj_t *args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new iterator object to list the dir
|
// Create a new iterator object to list the dir
|
||||||
mp_vfs_fat_ilistdir_it_t *iter = m_new_obj(mp_vfs_fat_ilistdir_it_t);
|
mp_vfs_fat_ilistdir_it_t *iter = mp_obj_malloc(mp_vfs_fat_ilistdir_it_t, &mp_type_polymorph_iter);
|
||||||
iter->base.type = &mp_type_polymorph_iter;
|
|
||||||
iter->iternext = mp_vfs_fat_ilistdir_it_iternext;
|
iter->iternext = mp_vfs_fat_ilistdir_it_iternext;
|
||||||
iter->is_str = is_str_type;
|
iter->is_str = is_str_type;
|
||||||
FRESULT res = f_opendir(&self->fatfs, &iter->dir, path);
|
FRESULT res = f_opendir(&self->fatfs, &iter->dir, path);
|
||||||
|
@ -1,8 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 2014 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
#ifndef MICROPY_INCLUDED_EXTMOD_VFS_FAT_H
|
#ifndef MICROPY_INCLUDED_EXTMOD_VFS_FAT_H
|
||||||
#define MICROPY_INCLUDED_EXTMOD_VFS_FAT_H
|
#define MICROPY_INCLUDED_EXTMOD_VFS_FAT_H
|
||||||
|
|
||||||
|
@ -1,7 +1,31 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* Original template for this file comes from:
|
||||||
|
* Low level disk I/O module skeleton for FatFs, (C)ChaN, 2013
|
||||||
|
*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 2014 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#if MICROPY_VFS && MICROPY_VFS_FAT
|
#if MICROPY_VFS && MICROPY_VFS_FAT
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013, 2014 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#if MICROPY_VFS && MICROPY_VFS_FAT
|
#if MICROPY_VFS && MICROPY_VFS_FAT
|
||||||
@ -136,6 +157,7 @@ STATIC const mp_arg_t file_open_args[] = {
|
|||||||
};
|
};
|
||||||
#define FILE_OPEN_NUM_ARGS MP_ARRAY_SIZE(file_open_args)
|
#define FILE_OPEN_NUM_ARGS MP_ARRAY_SIZE(file_open_args)
|
||||||
|
|
||||||
|
// CIRCUITPY is more careful about validating the open mode.
|
||||||
STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_arg_val_t *args) {
|
STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_arg_val_t *args) {
|
||||||
int mode = 0;
|
int mode = 0;
|
||||||
const char *mode_s = mp_obj_str_get_str(args[1].u_obj);
|
const char *mode_s = mp_obj_str_get_str(args[1].u_obj);
|
||||||
|
@ -203,8 +203,7 @@ STATIC mp_obj_t MP_VFS_LFSx(ilistdir_func)(size_t n_args, const mp_obj_t *args)
|
|||||||
path = vstr_null_terminated_str(&self->cur_dir);
|
path = vstr_null_terminated_str(&self->cur_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
MP_VFS_LFSx(ilistdir_it_t) * iter = m_new_obj(MP_VFS_LFSx(ilistdir_it_t));
|
MP_VFS_LFSx(ilistdir_it_t) * iter = mp_obj_malloc(MP_VFS_LFSx(ilistdir_it_t), &mp_type_polymorph_iter);
|
||||||
iter->base.type = &mp_type_polymorph_iter;
|
|
||||||
iter->iternext = MP_VFS_LFSx(ilistdir_it_iternext);
|
iter->iternext = MP_VFS_LFSx(ilistdir_it_iternext);
|
||||||
iter->is_str = is_str_type;
|
iter->is_str = is_str_type;
|
||||||
iter->vfs = self;
|
iter->vfs = self;
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2017-2018 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2018 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "py/mperrno.h"
|
#include "py/mperrno.h"
|
||||||
@ -16,6 +37,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <direct.h> // For mkdir etc.
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct _mp_obj_vfs_posix_t {
|
typedef struct _mp_obj_vfs_posix_t {
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
@ -74,8 +98,7 @@ STATIC mp_import_stat_t mp_vfs_posix_import_stat(void *self_in, const char *path
|
|||||||
STATIC mp_obj_t vfs_posix_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
STATIC mp_obj_t vfs_posix_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, 0, 1, false);
|
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||||
|
|
||||||
mp_obj_vfs_posix_t *vfs = m_new_obj(mp_obj_vfs_posix_t);
|
mp_obj_vfs_posix_t *vfs = mp_obj_malloc(mp_obj_vfs_posix_t, type);
|
||||||
vfs->base.type = type;
|
|
||||||
vstr_init(&vfs->root, 0);
|
vstr_init(&vfs->root, 0);
|
||||||
if (n_args == 1) {
|
if (n_args == 1) {
|
||||||
vstr_add_str(&vfs->root, mp_obj_str_get_str(args[0]));
|
vstr_add_str(&vfs->root, mp_obj_str_get_str(args[0]));
|
||||||
@ -205,8 +228,7 @@ STATIC mp_obj_t vfs_posix_ilistdir_it_iternext(mp_obj_t self_in) {
|
|||||||
|
|
||||||
STATIC mp_obj_t vfs_posix_ilistdir(mp_obj_t self_in, mp_obj_t path_in) {
|
STATIC mp_obj_t vfs_posix_ilistdir(mp_obj_t self_in, mp_obj_t path_in) {
|
||||||
mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
vfs_posix_ilistdir_it_t *iter = m_new_obj(vfs_posix_ilistdir_it_t);
|
vfs_posix_ilistdir_it_t *iter = mp_obj_malloc(vfs_posix_ilistdir_it_t, &mp_type_polymorph_iter);
|
||||||
iter->base.type = &mp_type_polymorph_iter;
|
|
||||||
iter->iternext = vfs_posix_ilistdir_it_iternext;
|
iter->iternext = vfs_posix_ilistdir_it_iternext;
|
||||||
iter->is_str = mp_obj_get_type(path_in) == &mp_type_str;
|
iter->is_str = mp_obj_get_type(path_in) == &mp_type_str;
|
||||||
const char *path = vfs_posix_get_path_str(self, path_in);
|
const char *path = vfs_posix_get_path_str(self, path_in);
|
||||||
@ -233,7 +255,11 @@ STATIC mp_obj_t vfs_posix_mkdir(mp_obj_t self_in, mp_obj_t path_in) {
|
|||||||
mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in);
|
mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
const char *path = vfs_posix_get_path_str(self, path_in);
|
const char *path = vfs_posix_get_path_str(self, path_in);
|
||||||
MP_THREAD_GIL_EXIT();
|
MP_THREAD_GIL_EXIT();
|
||||||
|
#ifdef _WIN32
|
||||||
|
int ret = mkdir(path);
|
||||||
|
#else
|
||||||
int ret = mkdir(path, 0777);
|
int ret = mkdir(path, 0777);
|
||||||
|
#endif
|
||||||
MP_THREAD_GIL_ENTER();
|
MP_THREAD_GIL_ENTER();
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
mp_raise_OSError(errno);
|
mp_raise_OSError(errno);
|
||||||
@ -287,6 +313,8 @@ STATIC mp_obj_t vfs_posix_stat(mp_obj_t self_in, mp_obj_t path_in) {
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_stat_obj, vfs_posix_stat);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_stat_obj, vfs_posix_stat);
|
||||||
|
|
||||||
|
#if MICROPY_PY_UOS_STATVFS
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
#define USE_STATFS 1
|
#define USE_STATFS 1
|
||||||
#endif
|
#endif
|
||||||
@ -328,6 +356,8 @@ STATIC mp_obj_t vfs_posix_statvfs(mp_obj_t self_in, mp_obj_t path_in) {
|
|||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_statvfs_obj, vfs_posix_statvfs);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_statvfs_obj, vfs_posix_statvfs);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = {
|
STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&vfs_posix_mount_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&vfs_posix_mount_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&vfs_posix_umount_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&vfs_posix_umount_obj) },
|
||||||
@ -341,7 +371,9 @@ STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = {
|
|||||||
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&vfs_posix_rename_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&vfs_posix_rename_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&vfs_posix_rmdir_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&vfs_posix_rmdir_obj) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&vfs_posix_stat_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&vfs_posix_stat_obj) },
|
||||||
|
#if MICROPY_PY_UOS_STATVFS
|
||||||
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&vfs_posix_statvfs_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&vfs_posix_statvfs_obj) },
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
STATIC MP_DEFINE_CONST_DICT(vfs_posix_locals_dict, vfs_posix_locals_dict_table);
|
STATIC MP_DEFINE_CONST_DICT(vfs_posix_locals_dict, vfs_posix_locals_dict_table);
|
||||||
|
|
||||||
|
@ -1,8 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2018 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2018 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
#ifndef MICROPY_INCLUDED_EXTMOD_VFS_POSIX_H
|
#ifndef MICROPY_INCLUDED_EXTMOD_VFS_POSIX_H
|
||||||
#define MICROPY_INCLUDED_EXTMOD_VFS_POSIX_H
|
#define MICROPY_INCLUDED_EXTMOD_VFS_POSIX_H
|
||||||
|
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2013-2018 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2018 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
#include "py/mpthread.h"
|
#include "py/mpthread.h"
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
/*
|
||||||
// SPDX-FileCopyrightText: Copyright (c) 2013-2017 Damien P. George
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2017 Damien P. George
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -1,7 +1,28 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright (c) 2016 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "extmod/virtpin.h"
|
#include "extmod/virtpin.h"
|
||||||
#include "py/proto.h"
|
#include "py/proto.h"
|
||||||
|
@ -1,8 +1,28 @@
|
|||||||
// Copyright (c) 2016 Paul Sokolovsky
|
/*
|
||||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
* This file is part of the MicroPython project, http://micropython.org/
|
||||||
//
|
*
|
||||||
// SPDX-License-Identifier: MIT
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Paul Sokolovsky
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
#ifndef MICROPY_INCLUDED_EXTMOD_VIRTPIN_H
|
#ifndef MICROPY_INCLUDED_EXTMOD_VIRTPIN_H
|
||||||
#define MICROPY_INCLUDED_EXTMOD_VIRTPIN_H
|
#define MICROPY_INCLUDED_EXTMOD_VIRTPIN_H
|
||||||
|
|
||||||
|
1546
lib/littlefs/lfs2.c
1546
lib/littlefs/lfs2.c
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* The little filesystem
|
* The little filesystem
|
||||||
*
|
*
|
||||||
|
* Copyright (c) 2022, The littlefs authors.
|
||||||
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
@ -22,7 +23,7 @@ extern "C"
|
|||||||
// Software library version
|
// Software library version
|
||||||
// Major (top-nibble), incremented on backwards incompatible changes
|
// Major (top-nibble), incremented on backwards incompatible changes
|
||||||
// Minor (bottom-nibble), incremented on feature additions
|
// Minor (bottom-nibble), incremented on feature additions
|
||||||
#define LFS2_VERSION 0x00020003
|
#define LFS2_VERSION 0x00020005
|
||||||
#define LFS2_VERSION_MAJOR (0xffff & (LFS2_VERSION >> 16))
|
#define LFS2_VERSION_MAJOR (0xffff & (LFS2_VERSION >> 16))
|
||||||
#define LFS2_VERSION_MINOR (0xffff & (LFS2_VERSION >> 0))
|
#define LFS2_VERSION_MINOR (0xffff & (LFS2_VERSION >> 0))
|
||||||
|
|
||||||
@ -159,49 +160,49 @@ struct lfs2_config {
|
|||||||
// information to the block device operations
|
// information to the block device operations
|
||||||
void *context;
|
void *context;
|
||||||
|
|
||||||
// Read a region in a block. Negative error codes are propogated
|
// Read a region in a block. Negative error codes are propagated
|
||||||
// to the user.
|
// to the user.
|
||||||
int (*read)(const struct lfs2_config *c, lfs2_block_t block,
|
int (*read)(const struct lfs2_config *c, lfs2_block_t block,
|
||||||
lfs2_off_t off, void *buffer, lfs2_size_t size);
|
lfs2_off_t off, void *buffer, lfs2_size_t size);
|
||||||
|
|
||||||
// Program a region in a block. The block must have previously
|
// Program a region in a block. The block must have previously
|
||||||
// been erased. Negative error codes are propogated to the user.
|
// been erased. Negative error codes are propagated to the user.
|
||||||
// May return LFS2_ERR_CORRUPT if the block should be considered bad.
|
// May return LFS2_ERR_CORRUPT if the block should be considered bad.
|
||||||
int (*prog)(const struct lfs2_config *c, lfs2_block_t block,
|
int (*prog)(const struct lfs2_config *c, lfs2_block_t block,
|
||||||
lfs2_off_t off, const void *buffer, lfs2_size_t size);
|
lfs2_off_t off, const void *buffer, lfs2_size_t size);
|
||||||
|
|
||||||
// Erase a block. A block must be erased before being programmed.
|
// Erase a block. A block must be erased before being programmed.
|
||||||
// The state of an erased block is undefined. Negative error codes
|
// The state of an erased block is undefined. Negative error codes
|
||||||
// are propogated to the user.
|
// are propagated to the user.
|
||||||
// May return LFS2_ERR_CORRUPT if the block should be considered bad.
|
// May return LFS2_ERR_CORRUPT if the block should be considered bad.
|
||||||
int (*erase)(const struct lfs2_config *c, lfs2_block_t block);
|
int (*erase)(const struct lfs2_config *c, lfs2_block_t block);
|
||||||
|
|
||||||
// Sync the state of the underlying block device. Negative error codes
|
// Sync the state of the underlying block device. Negative error codes
|
||||||
// are propogated to the user.
|
// are propagated to the user.
|
||||||
int (*sync)(const struct lfs2_config *c);
|
int (*sync)(const struct lfs2_config *c);
|
||||||
|
|
||||||
#ifdef LFS2_THREADSAFE
|
#ifdef LFS2_THREADSAFE
|
||||||
// Lock the underlying block device. Negative error codes
|
// Lock the underlying block device. Negative error codes
|
||||||
// are propogated to the user.
|
// are propagated to the user.
|
||||||
int (*lock)(const struct lfs2_config *c);
|
int (*lock)(const struct lfs2_config *c);
|
||||||
|
|
||||||
// Unlock the underlying block device. Negative error codes
|
// Unlock the underlying block device. Negative error codes
|
||||||
// are propogated to the user.
|
// are propagated to the user.
|
||||||
int (*unlock)(const struct lfs2_config *c);
|
int (*unlock)(const struct lfs2_config *c);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Minimum size of a block read. All read operations will be a
|
// Minimum size of a block read in bytes. All read operations will be a
|
||||||
// multiple of this value.
|
// multiple of this value.
|
||||||
lfs2_size_t read_size;
|
lfs2_size_t read_size;
|
||||||
|
|
||||||
// Minimum size of a block program. All program operations will be a
|
// Minimum size of a block program in bytes. All program operations will be
|
||||||
// multiple of this value.
|
// a multiple of this value.
|
||||||
lfs2_size_t prog_size;
|
lfs2_size_t prog_size;
|
||||||
|
|
||||||
// Size of an erasable block. This does not impact ram consumption and
|
// Size of an erasable block in bytes. This does not impact ram consumption
|
||||||
// may be larger than the physical erase size. However, non-inlined files
|
// and may be larger than the physical erase size. However, non-inlined
|
||||||
// take up at minimum one block. Must be a multiple of the read
|
// files take up at minimum one block. Must be a multiple of the read and
|
||||||
// and program sizes.
|
// program sizes.
|
||||||
lfs2_size_t block_size;
|
lfs2_size_t block_size;
|
||||||
|
|
||||||
// Number of erasable blocks on the device.
|
// Number of erasable blocks on the device.
|
||||||
@ -215,11 +216,11 @@ struct lfs2_config {
|
|||||||
// Set to -1 to disable block-level wear-leveling.
|
// Set to -1 to disable block-level wear-leveling.
|
||||||
int32_t block_cycles;
|
int32_t block_cycles;
|
||||||
|
|
||||||
// Size of block caches. Each cache buffers a portion of a block in RAM.
|
// Size of block caches in bytes. Each cache buffers a portion of a block in
|
||||||
// The littlefs needs a read cache, a program cache, and one additional
|
// RAM. The littlefs needs a read cache, a program cache, and one additional
|
||||||
// cache per file. Larger caches can improve performance by storing more
|
// cache per file. Larger caches can improve performance by storing more
|
||||||
// data and reducing the number of disk accesses. Must be a multiple of
|
// data and reducing the number of disk accesses. Must be a multiple of the
|
||||||
// the read and program sizes, and a factor of the block size.
|
// read and program sizes, and a factor of the block size.
|
||||||
lfs2_size_t cache_size;
|
lfs2_size_t cache_size;
|
||||||
|
|
||||||
// Size of the lookahead buffer in bytes. A larger lookahead buffer
|
// Size of the lookahead buffer in bytes. A larger lookahead buffer
|
||||||
@ -256,6 +257,12 @@ struct lfs2_config {
|
|||||||
// larger attributes size but must be <= LFS2_ATTR_MAX. Defaults to
|
// larger attributes size but must be <= LFS2_ATTR_MAX. Defaults to
|
||||||
// LFS2_ATTR_MAX when zero.
|
// LFS2_ATTR_MAX when zero.
|
||||||
lfs2_size_t attr_max;
|
lfs2_size_t attr_max;
|
||||||
|
|
||||||
|
// Optional upper limit on total space given to metadata pairs in bytes. On
|
||||||
|
// devices with large blocks (e.g. 128kB) setting this to a low size (2-8kB)
|
||||||
|
// can help bound the metadata compaction time. Must be <= block_size.
|
||||||
|
// Defaults to block_size when zero.
|
||||||
|
lfs2_size_t metadata_max;
|
||||||
};
|
};
|
||||||
|
|
||||||
// File info structure
|
// File info structure
|
||||||
@ -479,7 +486,7 @@ int lfs2_stat(lfs2_t *lfs2, const char *path, struct lfs2_info *info);
|
|||||||
// Returns the size of the attribute, or a negative error code on failure.
|
// Returns the size of the attribute, or a negative error code on failure.
|
||||||
// Note, the returned size is the size of the attribute on disk, irrespective
|
// Note, the returned size is the size of the attribute on disk, irrespective
|
||||||
// of the size of the buffer. This can be used to dynamically allocate a buffer
|
// of the size of the buffer. This can be used to dynamically allocate a buffer
|
||||||
// or check for existance.
|
// or check for existence.
|
||||||
lfs2_ssize_t lfs2_getattr(lfs2_t *lfs2, const char *path,
|
lfs2_ssize_t lfs2_getattr(lfs2_t *lfs2, const char *path,
|
||||||
uint8_t type, void *buffer, lfs2_size_t size);
|
uint8_t type, void *buffer, lfs2_size_t size);
|
||||||
|
|
||||||
@ -507,6 +514,7 @@ int lfs2_removeattr(lfs2_t *lfs2, const char *path, uint8_t type);
|
|||||||
|
|
||||||
/// File operations ///
|
/// File operations ///
|
||||||
|
|
||||||
|
#ifndef LFS2_NO_MALLOC
|
||||||
// Open a file
|
// Open a file
|
||||||
//
|
//
|
||||||
// The mode that the file is opened in is determined by the flags, which
|
// The mode that the file is opened in is determined by the flags, which
|
||||||
@ -516,6 +524,10 @@ int lfs2_removeattr(lfs2_t *lfs2, const char *path, uint8_t type);
|
|||||||
int lfs2_file_open(lfs2_t *lfs2, lfs2_file_t *file,
|
int lfs2_file_open(lfs2_t *lfs2, lfs2_file_t *file,
|
||||||
const char *path, int flags);
|
const char *path, int flags);
|
||||||
|
|
||||||
|
// if LFS2_NO_MALLOC is defined, lfs2_file_open() will fail with LFS2_ERR_NOMEM
|
||||||
|
// thus use lfs2_file_opencfg() with config.buffer set.
|
||||||
|
#endif
|
||||||
|
|
||||||
// Open a file with extra configuration
|
// Open a file with extra configuration
|
||||||
//
|
//
|
||||||
// The mode that the file is opened in is determined by the flags, which
|
// The mode that the file is opened in is determined by the flags, which
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* lfs2 util functions
|
* lfs2 util functions
|
||||||
*
|
*
|
||||||
|
* Copyright (c) 2022, The littlefs authors.
|
||||||
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* lfs2 utility functions
|
* lfs2 utility functions
|
||||||
*
|
*
|
||||||
|
* Copyright (c) 2022, The littlefs authors.
|
||||||
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
@ -49,6 +50,7 @@ extern "C"
|
|||||||
// code footprint
|
// code footprint
|
||||||
|
|
||||||
// Logging functions
|
// Logging functions
|
||||||
|
#ifndef LFS2_TRACE
|
||||||
#ifdef LFS2_YES_TRACE
|
#ifdef LFS2_YES_TRACE
|
||||||
#define LFS2_TRACE_(fmt, ...) \
|
#define LFS2_TRACE_(fmt, ...) \
|
||||||
printf("%s:%d:trace: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
printf("%s:%d:trace: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||||
@ -56,7 +58,9 @@ extern "C"
|
|||||||
#else
|
#else
|
||||||
#define LFS2_TRACE(...)
|
#define LFS2_TRACE(...)
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS2_DEBUG
|
||||||
#ifndef LFS2_NO_DEBUG
|
#ifndef LFS2_NO_DEBUG
|
||||||
#define LFS2_DEBUG_(fmt, ...) \
|
#define LFS2_DEBUG_(fmt, ...) \
|
||||||
printf("%s:%d:debug: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
printf("%s:%d:debug: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||||
@ -64,7 +68,9 @@ extern "C"
|
|||||||
#else
|
#else
|
||||||
#define LFS2_DEBUG(...)
|
#define LFS2_DEBUG(...)
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS2_WARN
|
||||||
#ifndef LFS2_NO_WARN
|
#ifndef LFS2_NO_WARN
|
||||||
#define LFS2_WARN_(fmt, ...) \
|
#define LFS2_WARN_(fmt, ...) \
|
||||||
printf("%s:%d:warn: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
printf("%s:%d:warn: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||||
@ -72,7 +78,9 @@ extern "C"
|
|||||||
#else
|
#else
|
||||||
#define LFS2_WARN(...)
|
#define LFS2_WARN(...)
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS2_ERROR
|
||||||
#ifndef LFS2_NO_ERROR
|
#ifndef LFS2_NO_ERROR
|
||||||
#define LFS2_ERROR_(fmt, ...) \
|
#define LFS2_ERROR_(fmt, ...) \
|
||||||
printf("%s:%d:error: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
printf("%s:%d:error: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||||
@ -80,13 +88,16 @@ extern "C"
|
|||||||
#else
|
#else
|
||||||
#define LFS2_ERROR(...)
|
#define LFS2_ERROR(...)
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
// Runtime assertions
|
// Runtime assertions
|
||||||
|
#ifndef LFS2_ASSERT
|
||||||
#ifndef LFS2_NO_ASSERT
|
#ifndef LFS2_NO_ASSERT
|
||||||
#define LFS2_ASSERT(test) assert(test)
|
#define LFS2_ASSERT(test) assert(test)
|
||||||
#else
|
#else
|
||||||
#define LFS2_ASSERT(test)
|
#define LFS2_ASSERT(test)
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Builtin functions, these may be replaced by more efficient
|
// Builtin functions, these may be replaced by more efficient
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* The MIT License (MIT)
|
* The MIT License (MIT)
|
||||||
*
|
*
|
||||||
* SPDX-FileCopyrightText: Copyright (c) 2013-2019 Damien P. George
|
* Copyright (c) 2013-2019 Damien P. George
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user