Merge remote-tracking branch 'adafruit/main' into update_tinyusb_abort
This commit is contained in:
commit
f4dba86f1c
@ -20,3 +20,7 @@ deques
|
||||
extint
|
||||
shs
|
||||
pass-thru
|
||||
numer
|
||||
arithmetics
|
||||
ftbfs
|
||||
straightaway
|
||||
|
@ -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.
|
||||
0f78c36c5aa458a954eed39a46942209107a553e
|
||||
|
||||
|
4
.github/workflows/run-tests.yml
vendored
4
.github/workflows/run-tests.yml
vendored
@ -55,13 +55,11 @@ jobs:
|
||||
run: |
|
||||
make -C examples/natmod/features1
|
||||
make -C examples/natmod/features2
|
||||
make -C examples/natmod/btree
|
||||
make -C examples/natmod/framebuf
|
||||
make -C examples/natmod/uheapq
|
||||
make -C examples/natmod/urandom
|
||||
make -C examples/natmod/ure
|
||||
make -C examples/natmod/uzlib
|
||||
- name: Test native modules
|
||||
if: matrix.test == 'all'
|
||||
run: ./run-natmodtests.py extmod/{btree*,framebuf*,uheapq*,ure*,uzlib*}.py
|
||||
run: ./run-natmodtests.py extmod/{uheapq*,ure*,uzlib*}.py
|
||||
working-directory: tests
|
||||
|
@ -235,7 +235,7 @@ litex alpha
|
||||
mimxrt10xx alpha
|
||||
nrf stable
|
||||
raspberrypi stable
|
||||
efr32 alpha
|
||||
silabs (efr32) alpha
|
||||
stm ``F4`` stable | ``others`` beta
|
||||
unix alpha
|
||||
================ ============================================================
|
||||
|
19
conf.py
19
conf.py
@ -266,19 +266,9 @@ rst_epilog = """
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# on_rtd is whether we are on readthedocs.org
|
||||
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
|
||||
|
||||
if not on_rtd: # only import and set the theme if we're building docs locally
|
||||
try:
|
||||
import sphinx_rtd_theme
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.']
|
||||
except:
|
||||
html_theme = 'default'
|
||||
html_theme_path = ['.']
|
||||
else:
|
||||
html_theme_path = ['.']
|
||||
import sphinx_rtd_theme
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.']
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
@ -441,8 +431,9 @@ texinfo_documents = [
|
||||
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {"cpython": ('https://docs.python.org/3/', None),
|
||||
intersphinx_mapping = {"python": ('https://docs.python.org/3/', None),
|
||||
"register": ('https://circuitpython.readthedocs.io/projects/register/en/latest/', None),
|
||||
"mcp2515": ('https://circuitpython.readthedocs.io/projects/mcp2515/en/latest/', None),
|
||||
"typing": ('https://circuitpython.readthedocs.io/projects/adafruit-circuitpython-typing/en/latest/', None)}
|
||||
|
||||
# Adapted from sphinxcontrib-redirects
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 427cc923976229bcb981ca6f218ebe8efd636df6
|
||||
Subproject commit d17b999f46fd148ac192ad692b8a4639f81add38
|
@ -82,28 +82,23 @@ STATIC void add_generic_services(bleio_adapter_obj_t *adapter) {
|
||||
|
||||
// Generic Access Service setup.
|
||||
|
||||
bleio_uuid_obj_t *generic_access_service_uuid = m_new_obj(bleio_uuid_obj_t);
|
||||
generic_access_service_uuid->base.type = &bleio_uuid_type;
|
||||
bleio_uuid_obj_t *generic_access_service_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
|
||||
common_hal_bleio_uuid_construct(generic_access_service_uuid, 0x1800, NULL);
|
||||
|
||||
bleio_uuid_obj_t *device_name_characteristic_uuid = m_new_obj(bleio_uuid_obj_t);
|
||||
device_name_characteristic_uuid->base.type = &bleio_uuid_type;
|
||||
bleio_uuid_obj_t *device_name_characteristic_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
|
||||
common_hal_bleio_uuid_construct(device_name_characteristic_uuid, 0x2A00, NULL);
|
||||
|
||||
bleio_uuid_obj_t *appearance_characteristic_uuid = m_new_obj(bleio_uuid_obj_t);
|
||||
appearance_characteristic_uuid->base.type = &bleio_uuid_type;
|
||||
bleio_uuid_obj_t *appearance_characteristic_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
|
||||
common_hal_bleio_uuid_construct(appearance_characteristic_uuid, 0x2A01, NULL);
|
||||
|
||||
// Not implemented:
|
||||
// Peripheral Preferred Connection Parameters
|
||||
// Central Address Resolution
|
||||
|
||||
bleio_service_obj_t *generic_access_service = m_new_obj(bleio_service_obj_t);
|
||||
generic_access_service->base.type = &bleio_service_type;
|
||||
bleio_service_obj_t *generic_access_service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type);
|
||||
common_hal_bleio_service_construct(generic_access_service, generic_access_service_uuid, false);
|
||||
|
||||
adapter->device_name_characteristic = m_new_obj(bleio_characteristic_obj_t);
|
||||
adapter->device_name_characteristic->base.type = &bleio_characteristic_type;
|
||||
adapter->device_name_characteristic = mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type);
|
||||
|
||||
char generic_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 'n', 'n', 'n', 'n' };
|
||||
mp_buffer_info_t generic_name_bufinfo = {
|
||||
@ -132,8 +127,7 @@ STATIC void add_generic_services(bleio_adapter_obj_t *adapter) {
|
||||
.len = sizeof(zero_16),
|
||||
};
|
||||
|
||||
adapter->appearance_characteristic = m_new_obj(bleio_characteristic_obj_t);
|
||||
adapter->appearance_characteristic->base.type = &bleio_characteristic_type;
|
||||
adapter->appearance_characteristic = mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type);
|
||||
|
||||
common_hal_bleio_characteristic_construct(
|
||||
adapter->appearance_characteristic,
|
||||
@ -151,20 +145,16 @@ STATIC void add_generic_services(bleio_adapter_obj_t *adapter) {
|
||||
|
||||
// Generic Attribute Service setup.
|
||||
|
||||
bleio_uuid_obj_t *generic_attribute_service_uuid = m_new_obj(bleio_uuid_obj_t);
|
||||
generic_attribute_service_uuid->base.type = &bleio_uuid_type;
|
||||
bleio_uuid_obj_t *generic_attribute_service_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
|
||||
common_hal_bleio_uuid_construct(generic_attribute_service_uuid, 0x1801, NULL);
|
||||
|
||||
bleio_uuid_obj_t *service_changed_characteristic_uuid = m_new_obj(bleio_uuid_obj_t);
|
||||
service_changed_characteristic_uuid->base.type = &bleio_uuid_type;
|
||||
bleio_uuid_obj_t *service_changed_characteristic_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
|
||||
common_hal_bleio_uuid_construct(service_changed_characteristic_uuid, 0x2A05, NULL);
|
||||
|
||||
bleio_service_obj_t *generic_attribute_service = m_new_obj(bleio_service_obj_t);
|
||||
generic_attribute_service->base.type = &bleio_service_type;
|
||||
bleio_service_obj_t *generic_attribute_service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type);
|
||||
common_hal_bleio_service_construct(generic_attribute_service, generic_attribute_service_uuid, false);
|
||||
|
||||
adapter->service_changed_characteristic = m_new_obj(bleio_characteristic_obj_t);
|
||||
adapter->service_changed_characteristic->base.type = &bleio_characteristic_type;
|
||||
adapter->service_changed_characteristic = mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type);
|
||||
|
||||
uint32_t zero_32 = 0;
|
||||
mp_buffer_info_t zero_32_value = {
|
||||
@ -416,8 +406,7 @@ bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *s
|
||||
bt_addr_t addr;
|
||||
hci_check_error(hci_read_bd_addr(&addr));
|
||||
|
||||
bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t);
|
||||
address->base.type = &bleio_address_type;
|
||||
bleio_address_obj_t *address = mp_obj_malloc(bleio_address_obj_t, &bleio_address_type);
|
||||
|
||||
common_hal_bleio_address_construct(address, addr.val, BT_ADDR_LE_PUBLIC);
|
||||
return address;
|
||||
@ -490,7 +479,7 @@ mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t
|
||||
self->scan_results = shared_module_bleio_new_scanresults(buffer_size, prefixes, prefix_length, minimum_rssi);
|
||||
|
||||
// size_t max_packet_size = extended ? BLE_GAP_SCAN_BUFFER_EXTENDED_MAX_SUPPORTED : BLE_GAP_SCAN_BUFFER_MAX;
|
||||
// uint8_t *raw_data = m_malloc(sizeof(ble_data_t) + max_packet_size, false);
|
||||
// uint8_t *raw_data = m_malloc(sizeof(ble_data_t) + max_packet_size);
|
||||
// ble_data_t * sd_data = (ble_data_t *) raw_data;
|
||||
// self->scan_results->common_hal_data = sd_data;
|
||||
// sd_data->len = max_packet_size;
|
||||
|
@ -55,8 +55,7 @@ void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffe
|
||||
self->characteristic = characteristic;
|
||||
self->timeout_ms = timeout * 1000;
|
||||
// This is a macro.
|
||||
// true means long-lived, so it won't be moved.
|
||||
ringbuf_alloc(&self->ringbuf, buffer_size, true);
|
||||
ringbuf_alloc(&self->ringbuf, buffer_size);
|
||||
|
||||
bleio_characteristic_set_observer(characteristic, self);
|
||||
}
|
||||
|
@ -453,8 +453,7 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern
|
||||
// for (size_t i = 0; i < response->count; ++i) {
|
||||
// ble_gattc_service_t *gattc_service = &response->services[i];
|
||||
|
||||
// bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t);
|
||||
// service->base.type = &bleio_service_type;
|
||||
// bleio_service_obj_t *service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type);
|
||||
|
||||
// // Initialize several fields at once.
|
||||
// bleio_service_from_connection(service, bleio_connection_new_from_internal(connection));
|
||||
@ -466,8 +465,7 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern
|
||||
|
||||
// if (gattc_service->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
|
||||
// // Known service UUID.
|
||||
// bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t);
|
||||
// uuid->base.type = &bleio_uuid_type;
|
||||
// bleio_uuid_obj_t *uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
|
||||
// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid);
|
||||
// service->uuid = uuid;
|
||||
// } else {
|
||||
@ -491,15 +489,14 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern
|
||||
// for (size_t i = 0; i < response->count; ++i) {
|
||||
// ble_gattc_char_t *gattc_char = &response->chars[i];
|
||||
|
||||
// bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t);
|
||||
// characteristic->base.type = &bleio_characteristic_type;
|
||||
// bleio_characteristic_obj_t *characteristic =
|
||||
// mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type);
|
||||
|
||||
// bleio_uuid_obj_t *uuid = NULL;
|
||||
|
||||
// if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
|
||||
// // Known characteristic UUID.
|
||||
// uuid = m_new_obj(bleio_uuid_obj_t);
|
||||
// uuid->base.type = &bleio_uuid_type;
|
||||
// uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
|
||||
// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid);
|
||||
// } else {
|
||||
// // The discovery response contained a 128-bit UUID that has not yet been registered with the
|
||||
@ -557,15 +554,13 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern
|
||||
// break;
|
||||
// }
|
||||
|
||||
// bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t);
|
||||
// descriptor->base.type = &bleio_descriptor_type;
|
||||
// bleio_descriptor_obj_t *descriptor = mp_obj_malloc(bleio_descriptor_obj_t, &bleio_descriptor_type);
|
||||
|
||||
// bleio_uuid_obj_t *uuid = NULL;
|
||||
|
||||
// if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
|
||||
// // Known descriptor UUID.
|
||||
// uuid = m_new_obj(bleio_uuid_obj_t);
|
||||
// uuid->base.type = &bleio_uuid_type;
|
||||
// uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
|
||||
// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid);
|
||||
// } else {
|
||||
// // The discovery response contained a 128-bit UUID that has not yet been registered with the
|
||||
@ -750,8 +745,7 @@ mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t *interna
|
||||
if (internal->connection_obj != mp_const_none) {
|
||||
return internal->connection_obj;
|
||||
}
|
||||
bleio_connection_obj_t *connection = m_new_obj(bleio_connection_obj_t);
|
||||
connection->base.type = &bleio_connection_type;
|
||||
bleio_connection_obj_t *connection = mp_obj_malloc(bleio_connection_obj_t, &bleio_connection_type);
|
||||
connection->connection = internal;
|
||||
internal->connection_obj = connection;
|
||||
|
||||
|
@ -101,7 +101,7 @@ void common_hal_bleio_packet_buffer_construct(
|
||||
}
|
||||
|
||||
if (incoming) {
|
||||
if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + max_packet_size), false)) {
|
||||
if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + max_packet_size))) {
|
||||
mp_raise_ValueError(translate("Buffer too large and unable to allocate"));
|
||||
}
|
||||
}
|
||||
@ -110,8 +110,8 @@ void common_hal_bleio_packet_buffer_construct(
|
||||
self->packet_queued = false;
|
||||
self->pending_index = 0;
|
||||
self->pending_size = 0;
|
||||
self->outgoing[0] = m_malloc(max_packet_size, false);
|
||||
self->outgoing[1] = m_malloc(max_packet_size, false);
|
||||
self->outgoing[0] = m_malloc(max_packet_size);
|
||||
self->outgoing[1] = m_malloc(max_packet_size);
|
||||
} else {
|
||||
self->outgoing[0] = NULL;
|
||||
self->outgoing[1] = NULL;
|
||||
|
@ -101,8 +101,7 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self,
|
||||
|
||||
if (characteristic->props & (CHAR_PROP_NOTIFY | CHAR_PROP_INDICATE)) {
|
||||
// We need a CCCD if this characteristic is doing notify or indicate.
|
||||
bleio_descriptor_obj_t *cccd = m_new_obj(bleio_descriptor_obj_t);
|
||||
cccd->base.type = &bleio_descriptor_type;
|
||||
bleio_descriptor_obj_t *cccd = mp_obj_malloc(bleio_descriptor_obj_t, &bleio_descriptor_type);
|
||||
|
||||
uint16_t zero = 0;
|
||||
mp_buffer_info_t zero_cccd_value = {
|
||||
|
@ -19,6 +19,7 @@ Full Table of Contents
|
||||
:caption: API and Usage
|
||||
|
||||
../shared-bindings/index.rst
|
||||
library/index.rst
|
||||
supported_ports.rst
|
||||
troubleshooting.rst
|
||||
libraries.rst
|
||||
@ -32,13 +33,12 @@ Full Table of Contents
|
||||
design_guide
|
||||
porting
|
||||
common_hal
|
||||
reference/mpyfiles.rst
|
||||
reference/glossary.rst
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: MicroPython specific
|
||||
|
||||
library/index.rst
|
||||
reference/glossary.rst
|
||||
:caption: Python stand
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
@ -1,10 +1,10 @@
|
||||
:mod:`array` -- arrays of numeric data
|
||||
=======================================
|
||||
======================================
|
||||
|
||||
.. module:: array
|
||||
: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``,
|
||||
``L``, ``q``, ``Q``, ``f``, ``d`` (the latter 2 depending on the
|
||||
|
@ -1,10 +1,10 @@
|
||||
:mod:`binascii` -- binary/ASCII conversions
|
||||
============================================
|
||||
===========================================
|
||||
|
||||
.. module:: binascii
|
||||
: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
|
||||
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>`_.
|
||||
Returns a bytes object.
|
||||
|
||||
.. function:: b2a_base64(data)
|
||||
.. function:: b2a_base64(data, *, newline=True)
|
||||
|
||||
Encode binary data in base64 format, as in `RFC 3548
|
||||
<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, /)
|
||||
|
||||
|
@ -1,161 +0,0 @@
|
||||
:mod:`btree` -- simple BTree database
|
||||
=====================================
|
||||
|
||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
||||
|
||||
.. module:: btree
|
||||
:synopsis: simple BTree database
|
||||
|
||||
The ``btree`` module implements a simple key-value database using external
|
||||
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
|
||||
value, a database also supports efficient ordered range scans (retrieval
|
||||
of values with the keys in a given range). On the application interface
|
||||
side, BTree database work as close a possible to a way standard `dict`
|
||||
type works, one notable difference is that both keys and values must
|
||||
be `bytes` objects (so, if you want to store objects of other types, you
|
||||
need to serialize them to `bytes` first).
|
||||
|
||||
The module is based on the well-known BerkelyDB library, version 1.xx.
|
||||
|
||||
Example::
|
||||
|
||||
import btree
|
||||
|
||||
# First, we need to open a stream which holds a database
|
||||
# This is usually a file, but can be in-memory database
|
||||
# using io.BytesIO, a raw flash partition, etc.
|
||||
# Oftentimes, you want to create a database file if it doesn't
|
||||
# exist and open if it exists. Idiom below takes care of this.
|
||||
# DO NOT open database with "a+b" access mode.
|
||||
try:
|
||||
f = open("mydb", "r+b")
|
||||
except OSError:
|
||||
f = open("mydb", "w+b")
|
||||
|
||||
# Now open a database itself
|
||||
db = btree.open(f)
|
||||
|
||||
# The keys you add will be sorted internally in the database
|
||||
db[b"3"] = b"three"
|
||||
db[b"1"] = b"one"
|
||||
db[b"2"] = b"two"
|
||||
|
||||
# Assume that any changes are cached in memory unless
|
||||
# explicitly flushed (or database closed). Flush database
|
||||
# at the end of each "transaction".
|
||||
db.flush()
|
||||
|
||||
# Prints b'two'
|
||||
print(db[b"2"])
|
||||
|
||||
# Iterate over sorted keys in the database, starting from b"2"
|
||||
# until the end of the database, returning only values.
|
||||
# Mind that arguments passed to values() method are *key* values.
|
||||
# Prints:
|
||||
# b'two'
|
||||
# b'three'
|
||||
for word in db.values(b"2"):
|
||||
print(word)
|
||||
|
||||
del db[b"2"]
|
||||
|
||||
# No longer true, prints False
|
||||
print(b"2" in db)
|
||||
|
||||
# Prints:
|
||||
# b"1"
|
||||
# b"3"
|
||||
for key in db:
|
||||
print(key)
|
||||
|
||||
db.close()
|
||||
|
||||
# Don't forget to close the underlying stream!
|
||||
f.close()
|
||||
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. function:: open(stream, *, flags=0, pagesize=0, cachesize=0, minkeypage=0)
|
||||
|
||||
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
|
||||
parameters of the database operation (most users will not need them):
|
||||
|
||||
* *flags* - Currently unused.
|
||||
* *pagesize* - Page size used for the nodes in BTree. Acceptable range
|
||||
is 512-65536. If 0, a port-specific default will be used, optimized for
|
||||
port's memory usage and/or performance.
|
||||
* *cachesize* - Suggested memory cache size in bytes. For a
|
||||
board with enough memory using larger values may improve performance.
|
||||
Cache policy is as follows: entire cache is not allocated at once;
|
||||
instead, accessing a new page in database will allocate a memory buffer
|
||||
for it, until value specified by *cachesize* is reached. Then, these
|
||||
buffers will be managed using LRU (least recently used) policy. More
|
||||
buffers may still be allocated if needed (e.g., if a database contains
|
||||
big keys and/or values). Allocated cache buffers aren't reclaimed.
|
||||
* *minkeypage* - Minimum number of keys to store per page. Default value
|
||||
of 0 equivalent to 2.
|
||||
|
||||
Returns a BTree object, which implements a dictionary protocol (set
|
||||
of methods), and some additional methods described below.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
||||
.. method:: btree.close()
|
||||
|
||||
Close the database. It's mandatory to close the database at the end of
|
||||
processing, as some unwritten data may be still in the cache. Note that
|
||||
this does not close underlying stream with which the database was opened,
|
||||
it should be closed separately (which is also mandatory to make sure that
|
||||
data flushed from buffer to the underlying storage).
|
||||
|
||||
.. method:: btree.flush()
|
||||
|
||||
Flush any data in cache to the underlying stream.
|
||||
|
||||
.. method:: btree.__getitem__(key)
|
||||
btree.get(key, default=None, /)
|
||||
btree.__setitem__(key, val)
|
||||
btree.__delitem__(key)
|
||||
btree.__contains__(key)
|
||||
|
||||
Standard dictionary methods.
|
||||
|
||||
.. method:: btree.__iter__()
|
||||
|
||||
A BTree object can be iterated over directly (similar to a dictionary)
|
||||
to get access to all keys in order.
|
||||
|
||||
.. method:: btree.keys([start_key, [end_key, [flags]]])
|
||||
btree.values([start_key, [end_key, [flags]]])
|
||||
btree.items([start_key, [end_key, [flags]]])
|
||||
|
||||
These methods are similar to standard dictionary methods, but also can
|
||||
take optional parameters to iterate over a key sub-range, instead of
|
||||
the entire database. Note that for all 3 methods, *start_key* and
|
||||
*end_key* arguments represent key values. For example, `values()`
|
||||
method will iterate over values corresponding to they key range
|
||||
given. None values for *start_key* means "from the first key", no
|
||||
*end_key* or its value of None means "until the end of database".
|
||||
By default, range is inclusive of *start_key* and exclusive of
|
||||
*end_key*, you can include *end_key* in iteration by passing *flags*
|
||||
of `btree.INCL`. You can iterate in descending key direction
|
||||
by passing *flags* of `btree.DESC`. The flags values can be ORed
|
||||
together.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: INCL
|
||||
|
||||
A flag for `keys()`, `values()`, `items()` methods to specify that
|
||||
scanning should be inclusive of the end key.
|
||||
|
||||
.. data:: DESC
|
||||
|
||||
A flag for `keys()`, `values()`, `items()` methods to specify that
|
||||
scanning should be in descending direction of keys.
|
@ -33,7 +33,7 @@ Functions and types
|
||||
|
||||
.. class:: bytes()
|
||||
|
||||
|see_cpython| `bytes`.
|
||||
|see_cpython| `python:bytes`.
|
||||
|
||||
.. function:: callable()
|
||||
|
||||
@ -68,7 +68,7 @@ Functions and types
|
||||
|
||||
.. 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()
|
||||
|
||||
@ -88,12 +88,12 @@ Functions and types
|
||||
|
||||
.. 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).
|
||||
|
||||
.. 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).
|
||||
|
||||
.. function:: isinstance()
|
||||
@ -138,7 +138,7 @@ Functions and types
|
||||
|
||||
.. 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()
|
||||
|
||||
@ -224,10 +224,14 @@ Exceptions
|
||||
|
||||
.. exception:: SystemExit
|
||||
|
||||
|see_cpython| `python:SystemExit`.
|
||||
|
||||
.. exception:: TimeoutError
|
||||
|
||||
.. exception:: TypeError
|
||||
|
||||
|see_cpython| `python:TypeError`.
|
||||
|
||||
.. exception:: UnicodeError
|
||||
|
||||
.. exception:: ValueError
|
||||
|
@ -1,12 +1,12 @@
|
||||
: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
|
||||
: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
|
||||
hold/accumulate various objects.
|
||||
@ -14,7 +14,7 @@ hold/accumulate various objects.
|
||||
Classes
|
||||
-------
|
||||
|
||||
.. function:: deque(iterable, maxlen[, flags])
|
||||
.. class:: deque(iterable, maxlen[, flags])
|
||||
|
||||
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
|
||||
@ -59,7 +59,7 @@ Classes
|
||||
print(t1.name)
|
||||
assert t2.name == t2[1]
|
||||
|
||||
.. function:: OrderedDict(...)
|
||||
.. class:: OrderedDict(...)
|
||||
|
||||
``dict`` type subclass which remembers and preserves the order of keys
|
||||
added. When ordered dict is iterated over, keys/items are returned in
|
||||
|
@ -4,10 +4,10 @@
|
||||
.. module:: errno
|
||||
: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.
|
||||
A particular inventory of codes depends on :term:`MicroPython port`.
|
||||
The codes available may vary per CircuitPython build.
|
||||
|
||||
Constants
|
||||
---------
|
||||
@ -15,14 +15,13 @@ Constants
|
||||
.. data:: EEXIST, EAGAIN, etc.
|
||||
|
||||
Error codes, based on ANSI C/POSIX standard. All error codes start with
|
||||
"E". As mentioned above, inventory of the codes depends on
|
||||
:term:`MicroPython port`. Errors are usually accessible as ``exc.args[0]``
|
||||
"E". Errors are usually accessible as ``exc.errno``
|
||||
where ``exc`` is an instance of `OSError`. Usage example::
|
||||
|
||||
try:
|
||||
os.mkdir("my_dir")
|
||||
except OSError as exc:
|
||||
if exc.args[0] == errno.EEXIST:
|
||||
if exc.errno == errno.EEXIST:
|
||||
print("Directory already exists")
|
||||
|
||||
.. data:: errorcode
|
||||
|
@ -1,170 +0,0 @@
|
||||
:mod:`framebuf` --- frame buffer manipulation
|
||||
=============================================
|
||||
|
||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
||||
|
||||
.. module:: framebuf
|
||||
:synopsis: Frame buffer manipulation
|
||||
|
||||
This module provides a general frame buffer which can be used to create
|
||||
bitmap images, which can then be sent to a display.
|
||||
|
||||
class FrameBuffer
|
||||
-----------------
|
||||
|
||||
The FrameBuffer class provides a pixel buffer which can be drawn upon with
|
||||
pixels, lines, rectangles, text and even other FrameBuffer's. It is useful
|
||||
when generating output for displays.
|
||||
|
||||
For example::
|
||||
|
||||
import framebuf
|
||||
|
||||
# FrameBuffer needs 2 bytes for every RGB565 pixel
|
||||
fbuf = framebuf.FrameBuffer(bytearray(100 * 10 * 2), 100, 10, framebuf.RGB565)
|
||||
|
||||
fbuf.fill(0)
|
||||
fbuf.text('MicroPython!', 0, 0, 0xffff)
|
||||
fbuf.hline(0, 9, 96, 0xffff)
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
.. class:: FrameBuffer(buffer, width, height, format, stride=width, /)
|
||||
|
||||
Construct a FrameBuffer object. The parameters are:
|
||||
|
||||
- *buffer* is an object with a buffer protocol which must be large
|
||||
enough to contain every pixel defined by the width, height and
|
||||
format of the FrameBuffer.
|
||||
- *width* is the width of the FrameBuffer in pixels
|
||||
- *height* is the height of the FrameBuffer in pixels
|
||||
- *format* specifies the type of pixel used in the FrameBuffer;
|
||||
permissible values are listed under Constants below. These set the
|
||||
number of bits used to encode a color value and the layout of these
|
||||
bits in *buffer*.
|
||||
Where a color value c is passed to a method, c is a small integer
|
||||
with an encoding that is dependent on the format of the FrameBuffer.
|
||||
- *stride* is the number of pixels between each horizontal line
|
||||
of pixels in the FrameBuffer. This defaults to *width* but may
|
||||
need adjustments when implementing a FrameBuffer within another
|
||||
larger FrameBuffer or screen. The *buffer* size must accommodate
|
||||
an increased step size.
|
||||
|
||||
One must specify valid *buffer*, *width*, *height*, *format* and
|
||||
optionally *stride*. Invalid *buffer* size or dimensions may lead to
|
||||
unexpected errors.
|
||||
|
||||
Drawing primitive shapes
|
||||
------------------------
|
||||
|
||||
The following methods draw shapes onto the FrameBuffer.
|
||||
|
||||
.. method:: FrameBuffer.fill(c)
|
||||
|
||||
Fill the entire FrameBuffer with the specified color.
|
||||
|
||||
.. method:: FrameBuffer.pixel(x, y[, c])
|
||||
|
||||
If *c* is not given, get the color value of the specified pixel.
|
||||
If *c* is given, set the specified pixel to the given color.
|
||||
|
||||
.. method:: FrameBuffer.hline(x, y, w, c)
|
||||
.. method:: FrameBuffer.vline(x, y, h, c)
|
||||
.. method:: FrameBuffer.line(x1, y1, x2, y2, c)
|
||||
|
||||
Draw a line from a set of coordinates using the given color and
|
||||
a thickness of 1 pixel. The `line` method draws the line up to
|
||||
a second set of coordinates whereas the `hline` and `vline`
|
||||
methods draw horizontal and vertical lines respectively up to
|
||||
a given length.
|
||||
|
||||
.. method:: FrameBuffer.rect(x, y, w, h, c)
|
||||
.. method:: FrameBuffer.fill_rect(x, y, w, h, c)
|
||||
|
||||
Draw a rectangle at the given location, size and color. The `rect`
|
||||
method draws only a 1 pixel outline whereas the `fill_rect` method
|
||||
draws both the outline and interior.
|
||||
|
||||
Drawing text
|
||||
------------
|
||||
|
||||
.. method:: FrameBuffer.text(s, x, y[, c])
|
||||
|
||||
Write text to the FrameBuffer using the the coordinates as the upper-left
|
||||
corner of the text. The color of the text can be defined by the optional
|
||||
argument but is otherwise a default value of 1. All characters have
|
||||
dimensions of 8x8 pixels and there is currently no way to change the font.
|
||||
|
||||
|
||||
Other methods
|
||||
-------------
|
||||
|
||||
.. method:: FrameBuffer.scroll(xstep, ystep)
|
||||
|
||||
Shift the contents of the FrameBuffer by the given vector. This may
|
||||
leave a footprint of the previous colors in the FrameBuffer.
|
||||
|
||||
.. method:: FrameBuffer.blit(fbuf, x, y, key=-1, palette=None)
|
||||
|
||||
Draw another FrameBuffer on top of the current one at the given coordinates.
|
||||
If *key* is specified then it should be a color integer and the
|
||||
corresponding color will be considered transparent: all pixels with that
|
||||
color value will not be drawn.
|
||||
|
||||
The *palette* argument enables blitting between FrameBuffers with differing
|
||||
formats. Typical usage is to render a monochrome or grayscale glyph/icon to
|
||||
a color display. The *palette* is a FrameBuffer instance whose format is
|
||||
that of the current FrameBuffer. The *palette* height is one pixel and its
|
||||
pixel width is the number of colors in the source FrameBuffer. The *palette*
|
||||
for an N-bit source needs 2**N pixels; the *palette* for a monochrome source
|
||||
would have 2 pixels representing background and foreground colors. The
|
||||
application assigns a color to each pixel in the *palette*. The color of the
|
||||
current pixel will be that of that *palette* pixel whose x position is the
|
||||
color of the corresponding source pixel.
|
||||
|
||||
Constants
|
||||
---------
|
||||
|
||||
.. data:: framebuf.MONO_VLSB
|
||||
|
||||
Monochrome (1-bit) color format
|
||||
This defines a mapping where the bits in a byte are vertically mapped with
|
||||
bit 0 being nearest the top of the screen. Consequently each byte occupies
|
||||
8 vertical pixels. Subsequent bytes appear at successive horizontal
|
||||
locations until the rightmost edge is reached. Further bytes are rendered
|
||||
at locations starting at the leftmost edge, 8 pixels lower.
|
||||
|
||||
.. data:: framebuf.MONO_HLSB
|
||||
|
||||
Monochrome (1-bit) color format
|
||||
This defines a mapping where the bits in a byte are horizontally mapped.
|
||||
Each byte occupies 8 horizontal pixels with bit 7 being the leftmost.
|
||||
Subsequent bytes appear at successive horizontal locations until the
|
||||
rightmost edge is reached. Further bytes are rendered on the next row, one
|
||||
pixel lower.
|
||||
|
||||
.. data:: framebuf.MONO_HMSB
|
||||
|
||||
Monochrome (1-bit) color format
|
||||
This defines a mapping where the bits in a byte are horizontally mapped.
|
||||
Each byte occupies 8 horizontal pixels with bit 0 being the leftmost.
|
||||
Subsequent bytes appear at successive horizontal locations until the
|
||||
rightmost edge is reached. Further bytes are rendered on the next row, one
|
||||
pixel lower.
|
||||
|
||||
.. data:: framebuf.RGB565
|
||||
|
||||
Red Green Blue (16-bit, 5+6+5) color format
|
||||
|
||||
.. data:: framebuf.GS2_HMSB
|
||||
|
||||
Grayscale (2-bit) color format
|
||||
|
||||
.. data:: framebuf.GS4_HMSB
|
||||
|
||||
Grayscale (4-bit) color format
|
||||
|
||||
.. data:: framebuf.GS8
|
||||
|
||||
Grayscale (8-bit) color format
|
@ -1,12 +1,10 @@
|
||||
:mod:`gc` -- control the garbage collector
|
||||
==========================================
|
||||
|
||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
||||
|
||||
.. module:: gc
|
||||
:synopsis: control the garbage collector
|
||||
|
||||
|see_cpython_module| :mod:`cpython:gc`.
|
||||
|see_cpython_module| :mod:`python:gc`.
|
||||
|
||||
Functions
|
||||
---------
|
||||
@ -63,6 +61,6 @@ Functions
|
||||
.. admonition:: Difference to CPython
|
||||
: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
|
||||
implementations, its signature and semantics are different.
|
||||
|
@ -6,7 +6,7 @@
|
||||
.. module:: heapq
|
||||
:synopsis: heap queue algorithm
|
||||
|
||||
|see_cpython_module| :mod:`cpython:heapq`.
|
||||
|see_cpython_module| :mod:`python:heapq`.
|
||||
|
||||
This module implements the
|
||||
`min heap queue algorithm <https://en.wikipedia.org/wiki/Heap_%28data_structure%29>`_.
|
||||
|
@ -1,21 +1,19 @@
|
||||
.. _micropython_lib:
|
||||
|
||||
MicroPython libraries
|
||||
=====================
|
||||
Standard Libraries
|
||||
==================
|
||||
|
||||
Python standard libraries and micro-libraries
|
||||
---------------------------------------------
|
||||
Python standard libraries
|
||||
-------------------------
|
||||
|
||||
The libraries below are inherited from MicroPython.
|
||||
They are similar to the standard Python libraries with the same name.
|
||||
They implement a subset of or a variant of the corresponding
|
||||
standard Python library.
|
||||
The libraries below implement a subset of the corresponding
|
||||
standard Python (CPython) library. They are implemented in C, not Python.
|
||||
|
||||
CircuitPython's long-term goal is that code written in CircuitPython
|
||||
using Python standard libraries will be runnable on CPython without changes.
|
||||
|
||||
These libraries are not enabled on CircuitPython builds with
|
||||
limited flash memory, usually on non-Express builds:
|
||||
limited flash memory:
|
||||
``binascii``, ``errno``, ``json``, ``re``.
|
||||
|
||||
These libraries are not currently enabled in any CircuitPython build, but may be in the future:
|
||||
@ -38,11 +36,11 @@ These libraries are not currently enabled in any CircuitPython build, but may be
|
||||
ctypes.rst
|
||||
select.rst
|
||||
|
||||
Omitted functions in the ``string`` library
|
||||
-------------------------------------------
|
||||
Omitted ``string`` functions
|
||||
----------------------------
|
||||
|
||||
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.reversed()``.
|
||||
|
||||
@ -50,13 +48,10 @@ A few string operations are not enabled on small builds
|
||||
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.
|
||||
Functionality specific to the CircuitPython/MicroPython implementations is available in
|
||||
the following libraries.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
btree.rst
|
||||
framebuf.rst
|
||||
micropython.rst
|
||||
|
@ -1,10 +1,10 @@
|
||||
:mod:`io` -- input/output streams
|
||||
==================================
|
||||
=================================
|
||||
|
||||
.. module:: io
|
||||
: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
|
||||
and helper functions.
|
||||
@ -112,3 +112,20 @@ Classes
|
||||
.. method:: getvalue()
|
||||
|
||||
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
|
||||
==========================================
|
||||
=========================================
|
||||
|
||||
.. module:: json
|
||||
: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
|
||||
data format.
|
||||
@ -12,14 +12,20 @@ data format.
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. function:: dump(obj, stream)
|
||||
.. function:: dump(obj, stream, separators=None)
|
||||
|
||||
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.
|
||||
|
||||
The arguments have the same meaning as in `dump`.
|
||||
|
||||
.. function:: load(stream)
|
||||
|
||||
Parse the given ``stream``, interpreting it as a JSON string and
|
||||
|
@ -1,7 +1,5 @@
|
||||
:mod:`micropython` -- access and control MicroPython internals
|
||||
==============================================================
|
||||
|
||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
||||
:mod:`micropython` -- MicroPython extensions and internals
|
||||
==========================================================
|
||||
|
||||
.. module:: micropython
|
||||
:synopsis: access and control MicroPython internals
|
||||
@ -11,7 +9,7 @@ Functions
|
||||
|
||||
.. 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::
|
||||
|
||||
from micropython import const
|
||||
@ -28,111 +26,3 @@ Functions
|
||||
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
|
||||
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
|
||||
========================================
|
||||
=======================================
|
||||
|
||||
.. module:: re
|
||||
:synopsis: regular expressions
|
||||
|
||||
|see_cpython_module| :mod:`cpython:re`.
|
||||
|see_cpython_module| :mod:`python:re`.
|
||||
|
||||
This module implements regular expression operations. Regular expression
|
||||
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
|
||||
====================================================
|
||||
|
||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
||||
|
||||
.. module:: select
|
||||
:synopsis: wait for events on a set of streams
|
||||
|
||||
@ -86,7 +84,7 @@ Methods
|
||||
.. method:: poll.ipoll(timeout=-1, flags=0, /)
|
||||
|
||||
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.
|
||||
|
||||
If *flags* is 1, one-shot behaviour for events is employed: streams for
|
||||
|
@ -1,12 +1,10 @@
|
||||
:mod:`sys` -- system specific functions
|
||||
========================================
|
||||
|
||||
.. include:: ../templates/unsupported_in_circuitpython.inc
|
||||
=======================================
|
||||
|
||||
.. module:: sys
|
||||
:synopsis: system specific functions
|
||||
|
||||
|see_cpython_module| :mod:`cpython:sys`.
|
||||
|see_cpython_module| :mod:`python:sys`.
|
||||
|
||||
Functions
|
||||
---------
|
||||
@ -35,6 +33,7 @@ Constants
|
||||
|
||||
* *name* - string "circuitpython"
|
||||
* *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
|
||||
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
|
||||
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
|
||||
|
||||
Standard error ``stream``.
|
||||
@ -109,6 +114,14 @@ Constants
|
||||
|
||||
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
|
||||
|
||||
Python language version that this implementation conforms to, as a string.
|
||||
|
@ -159,7 +159,7 @@ Glossary
|
||||
typically accessible on a host PC via USB.
|
||||
|
||||
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
|
||||
implements a corresponding interface, which consists of methods like
|
||||
``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 'C' 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 0x43 (ASCII 'C')
|
||||
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.
|
@ -1,6 +1,13 @@
|
||||
# Derived from code on Eric Holscher's blog, found at:
|
||||
# https://www.ericholscher.com/blog/2016/jul/25/integrating-jinja-rst-sphinx/
|
||||
|
||||
import re
|
||||
|
||||
def render_with_jinja(docname, source):
|
||||
if re.search('^\s*.. jinja$', source[0], re.M):
|
||||
return True
|
||||
return False
|
||||
|
||||
def rstjinja(app, docname, source):
|
||||
"""
|
||||
Render our pages as a jinja template for fancy templating goodness.
|
||||
@ -9,12 +16,12 @@ def rstjinja(app, docname, source):
|
||||
if app.builder.format not in ("html", "latex"):
|
||||
return
|
||||
|
||||
# we only want our one jinja template to run through this func
|
||||
if "shared-bindings/support_matrix" not in docname:
|
||||
# we only want specific files to run through this func
|
||||
if not render_with_jinja(docname, source):
|
||||
return
|
||||
|
||||
src = rendered = source[0]
|
||||
print(docname)
|
||||
print(f"rendering {docname} as jinja templates")
|
||||
|
||||
if app.builder.format == "html":
|
||||
rendered = app.builder.templates.render_string(
|
||||
|
@ -69,28 +69,23 @@ ADDITIONAL_MODULES = {
|
||||
"array": "CIRCUITPY_ARRAY",
|
||||
# always available, so depend on something that's always 1.
|
||||
"builtins": "CIRCUITPY",
|
||||
"builtins.pow3": "CIRCUITPY_BUILTINS_POW3",
|
||||
"busio.SPI": "CIRCUITPY_BUSIO_SPI",
|
||||
"busio.UART": "CIRCUITPY_BUSIO_UART",
|
||||
"collections": "CIRCUITPY_COLLECTIONS",
|
||||
"fontio": "CIRCUITPY_DISPLAYIO",
|
||||
"io": "CIRCUITPY_IO",
|
||||
"keypad.KeyMatrix": "CIRCUITPY_KEYPAD_KEYMATRIX",
|
||||
"keypad.Keys": "CIRCUITPY_KEYPAD_KEYS",
|
||||
"keypad.ShiftRegisterKeys": "CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS",
|
||||
"os.getenv": "CIRCUITPY_OS_GETENV",
|
||||
"select": "MICROPY_PY_USELECT_SELECT",
|
||||
"terminalio": "CIRCUITPY_DISPLAYIO",
|
||||
"sys": "CIRCUITPY_SYS",
|
||||
"terminalio": "CIRCUITPY_DISPLAYIO",
|
||||
"usb": "CIRCUITPY_USB_HOST",
|
||||
}
|
||||
|
||||
MODULES_NOT_IN_BINDINGS = [
|
||||
"_asyncio",
|
||||
"array",
|
||||
"binascii",
|
||||
"builtins",
|
||||
"collections",
|
||||
"errno",
|
||||
"json",
|
||||
"re",
|
||||
"select",
|
||||
"sys",
|
||||
"ulab",
|
||||
]
|
||||
MODULES_NOT_IN_BINDINGS = [ "binascii", "errno", "json", "re", "ulab" ]
|
||||
|
||||
FROZEN_EXCLUDES = ["examples", "docs", "tests", "utils", "conf.py", "setup.py"]
|
||||
"""Files and dirs at the root of a frozen directory that should be ignored.
|
||||
@ -117,7 +112,7 @@ def get_bindings():
|
||||
bindings_modules = []
|
||||
for d in get_circuitpython_root_dir().glob("ports/*/bindings"):
|
||||
bindings_modules.extend(module.name for module in d.iterdir() if d.is_dir())
|
||||
return shared_bindings_modules + bindings_modules + MODULES_NOT_IN_BINDINGS
|
||||
return shared_bindings_modules + bindings_modules + MODULES_NOT_IN_BINDINGS + list(ADDITIONAL_MODULES.keys())
|
||||
|
||||
|
||||
def get_board_mapping():
|
||||
|
@ -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,13 +1,14 @@
|
||||
# Location of top-level MicroPython directory
|
||||
MPY_DIR = ../../..
|
||||
|
||||
# Name of module (different to built-in framebuf so it can coexist)
|
||||
MOD = framebuf_$(ARCH)
|
||||
# Name of module
|
||||
MOD = features3
|
||||
|
||||
# Source files (.c or .py)
|
||||
SRC = framebuf.c
|
||||
SRC = features3.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
|
60
examples/natmod/features3/features3.c
Normal file
60
examples/natmod/features3/features3.c
Normal file
@ -0,0 +1,60 @@
|
||||
/* This example demonstrates the following features in a native module:
|
||||
- using types
|
||||
- using constant objects
|
||||
- creating dictionaries
|
||||
*/
|
||||
|
||||
// Include the header file to get access to the MicroPython API.
|
||||
#include "py/dynruntime.h"
|
||||
|
||||
// A function that returns a tuple of object types.
|
||||
STATIC mp_obj_t get_types(void) {
|
||||
return mp_obj_new_tuple(9, ((mp_obj_t []) {
|
||||
MP_OBJ_FROM_PTR(&mp_type_type),
|
||||
MP_OBJ_FROM_PTR(&mp_type_NoneType),
|
||||
MP_OBJ_FROM_PTR(&mp_type_bool),
|
||||
MP_OBJ_FROM_PTR(&mp_type_int),
|
||||
MP_OBJ_FROM_PTR(&mp_type_str),
|
||||
MP_OBJ_FROM_PTR(&mp_type_bytes),
|
||||
MP_OBJ_FROM_PTR(&mp_type_tuple),
|
||||
MP_OBJ_FROM_PTR(&mp_type_list),
|
||||
MP_OBJ_FROM_PTR(&mp_type_dict),
|
||||
}));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(get_types_obj, get_types);
|
||||
|
||||
// A function that returns a tuple of constant objects.
|
||||
STATIC mp_obj_t get_const_objects(void) {
|
||||
return mp_obj_new_tuple(5, ((mp_obj_t []) {
|
||||
mp_const_none,
|
||||
mp_const_false,
|
||||
mp_const_true,
|
||||
mp_const_empty_bytes,
|
||||
mp_const_empty_tuple,
|
||||
}));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(get_const_objects_obj, get_const_objects);
|
||||
|
||||
// A function that creates a dictionary from the given arguments.
|
||||
STATIC mp_obj_t make_dict(size_t n_args, const mp_obj_t *args) {
|
||||
mp_obj_t dict = mp_obj_new_dict(n_args / 2);
|
||||
for (; n_args >= 2; n_args -= 2, args += 2) {
|
||||
mp_obj_dict_store(dict, args[0], args[1]);
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(make_dict_obj, 0, MP_OBJ_FUN_ARGS_MAX, make_dict);
|
||||
|
||||
// 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_make_dict, MP_OBJ_FROM_PTR(&make_dict_obj));
|
||||
mp_store_global(MP_QSTR_get_types, MP_OBJ_FROM_PTR(&get_types_obj));
|
||||
mp_store_global(MP_QSTR_get_const_objects, MP_OBJ_FROM_PTR(&get_const_objects_obj));
|
||||
|
||||
// This must be last, it restores the globals dict.
|
||||
MP_DYNRUNTIME_INIT_EXIT
|
||||
}
|
@ -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
|
||||
}
|
@ -31,7 +31,4 @@ const mp_obj_module_t example_user_cmodule = {
|
||||
};
|
||||
|
||||
// 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);
|
||||
MP_REGISTER_MODULE(MP_QSTR_cexample, example_user_cmodule);
|
||||
|
@ -22,7 +22,4 @@ const mp_obj_module_t cppexample_user_cmodule = {
|
||||
};
|
||||
|
||||
// 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);
|
||||
MP_REGISTER_MODULE(MP_QSTR_cppexample, cppexample_user_cmodule);
|
||||
|
@ -6,7 +6,7 @@ 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)
|
||||
CXXFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR) -std=c++11
|
||||
|
||||
# We use C++ features so have to link against the standard library.
|
||||
LDFLAGS_USERMOD += -lstdc++
|
||||
|
@ -26,7 +26,11 @@
|
||||
#ifndef AXTLS_OS_PORT_H
|
||||
#define AXTLS_OS_PORT_H
|
||||
|
||||
#ifndef __ets__
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include "py/stream.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_util.c \
|
||||
)
|
||||
else
|
||||
CFLAGS_MOD += -DMICROPY_VFS_LFS1=0
|
||||
endif
|
||||
|
||||
ifeq ($(MICROPY_VFS_LFS2),1)
|
||||
@ -39,8 +37,6 @@ SRC_MOD += $(addprefix $(LITTLEFS_DIR)/,\
|
||||
lfs2.c \
|
||||
lfs2_util.c \
|
||||
)
|
||||
else
|
||||
CFLAGS_MOD += -DMICROPY_VFS_LFS2=0
|
||||
|
||||
$(BUILD)/$(LITTLEFS_DIR)/lfs2.o: CFLAGS += -Wno-missing-field-initializers
|
||||
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
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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
|
||||
#define MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H
|
||||
|
||||
static const uint8_t font_petme128_8x8[] = {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 32=
|
||||
0x00,0x00,0x00,0x4f,0x4f,0x00,0x00,0x00, // 33=!
|
||||
0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, // 34="
|
||||
0x14,0x7f,0x7f,0x14,0x14,0x7f,0x7f,0x14, // 35=#
|
||||
0x00,0x24,0x2e,0x6b,0x6b,0x3a,0x12,0x00, // 36=$
|
||||
0x00,0x63,0x33,0x18,0x0c,0x66,0x63,0x00, // 37=%
|
||||
0x00,0x32,0x7f,0x4d,0x4d,0x77,0x72,0x50, // 38=&
|
||||
0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x00, // 39='
|
||||
0x00,0x00,0x1c,0x3e,0x63,0x41,0x00,0x00, // 40=(
|
||||
0x00,0x00,0x41,0x63,0x3e,0x1c,0x00,0x00, // 41=)
|
||||
0x08,0x2a,0x3e,0x1c,0x1c,0x3e,0x2a,0x08, // 42=*
|
||||
0x00,0x08,0x08,0x3e,0x3e,0x08,0x08,0x00, // 43=+
|
||||
0x00,0x00,0x80,0xe0,0x60,0x00,0x00,0x00, // 44=,
|
||||
0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, // 45=-
|
||||
0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, // 46=.
|
||||
0x00,0x40,0x60,0x30,0x18,0x0c,0x06,0x02, // 47=/
|
||||
0x00,0x3e,0x7f,0x49,0x45,0x7f,0x3e,0x00, // 48=0
|
||||
0x00,0x40,0x44,0x7f,0x7f,0x40,0x40,0x00, // 49=1
|
||||
0x00,0x62,0x73,0x51,0x49,0x4f,0x46,0x00, // 50=2
|
||||
0x00,0x22,0x63,0x49,0x49,0x7f,0x36,0x00, // 51=3
|
||||
0x00,0x18,0x18,0x14,0x16,0x7f,0x7f,0x10, // 52=4
|
||||
0x00,0x27,0x67,0x45,0x45,0x7d,0x39,0x00, // 53=5
|
||||
0x00,0x3e,0x7f,0x49,0x49,0x7b,0x32,0x00, // 54=6
|
||||
0x00,0x03,0x03,0x79,0x7d,0x07,0x03,0x00, // 55=7
|
||||
0x00,0x36,0x7f,0x49,0x49,0x7f,0x36,0x00, // 56=8
|
||||
0x00,0x26,0x6f,0x49,0x49,0x7f,0x3e,0x00, // 57=9
|
||||
0x00,0x00,0x00,0x24,0x24,0x00,0x00,0x00, // 58=:
|
||||
0x00,0x00,0x80,0xe4,0x64,0x00,0x00,0x00, // 59=;
|
||||
0x00,0x08,0x1c,0x36,0x63,0x41,0x41,0x00, // 60=<
|
||||
0x00,0x14,0x14,0x14,0x14,0x14,0x14,0x00, // 61==
|
||||
0x00,0x41,0x41,0x63,0x36,0x1c,0x08,0x00, // 62=>
|
||||
0x00,0x02,0x03,0x51,0x59,0x0f,0x06,0x00, // 63=?
|
||||
0x00,0x3e,0x7f,0x41,0x4d,0x4f,0x2e,0x00, // 64=@
|
||||
0x00,0x7c,0x7e,0x0b,0x0b,0x7e,0x7c,0x00, // 65=A
|
||||
0x00,0x7f,0x7f,0x49,0x49,0x7f,0x36,0x00, // 66=B
|
||||
0x00,0x3e,0x7f,0x41,0x41,0x63,0x22,0x00, // 67=C
|
||||
0x00,0x7f,0x7f,0x41,0x63,0x3e,0x1c,0x00, // 68=D
|
||||
0x00,0x7f,0x7f,0x49,0x49,0x41,0x41,0x00, // 69=E
|
||||
0x00,0x7f,0x7f,0x09,0x09,0x01,0x01,0x00, // 70=F
|
||||
0x00,0x3e,0x7f,0x41,0x49,0x7b,0x3a,0x00, // 71=G
|
||||
0x00,0x7f,0x7f,0x08,0x08,0x7f,0x7f,0x00, // 72=H
|
||||
0x00,0x00,0x41,0x7f,0x7f,0x41,0x00,0x00, // 73=I
|
||||
0x00,0x20,0x60,0x41,0x7f,0x3f,0x01,0x00, // 74=J
|
||||
0x00,0x7f,0x7f,0x1c,0x36,0x63,0x41,0x00, // 75=K
|
||||
0x00,0x7f,0x7f,0x40,0x40,0x40,0x40,0x00, // 76=L
|
||||
0x00,0x7f,0x7f,0x06,0x0c,0x06,0x7f,0x7f, // 77=M
|
||||
0x00,0x7f,0x7f,0x0e,0x1c,0x7f,0x7f,0x00, // 78=N
|
||||
0x00,0x3e,0x7f,0x41,0x41,0x7f,0x3e,0x00, // 79=O
|
||||
0x00,0x7f,0x7f,0x09,0x09,0x0f,0x06,0x00, // 80=P
|
||||
0x00,0x1e,0x3f,0x21,0x61,0x7f,0x5e,0x00, // 81=Q
|
||||
0x00,0x7f,0x7f,0x19,0x39,0x6f,0x46,0x00, // 82=R
|
||||
0x00,0x26,0x6f,0x49,0x49,0x7b,0x32,0x00, // 83=S
|
||||
0x00,0x01,0x01,0x7f,0x7f,0x01,0x01,0x00, // 84=T
|
||||
0x00,0x3f,0x7f,0x40,0x40,0x7f,0x3f,0x00, // 85=U
|
||||
0x00,0x1f,0x3f,0x60,0x60,0x3f,0x1f,0x00, // 86=V
|
||||
0x00,0x7f,0x7f,0x30,0x18,0x30,0x7f,0x7f, // 87=W
|
||||
0x00,0x63,0x77,0x1c,0x1c,0x77,0x63,0x00, // 88=X
|
||||
0x00,0x07,0x0f,0x78,0x78,0x0f,0x07,0x00, // 89=Y
|
||||
0x00,0x61,0x71,0x59,0x4d,0x47,0x43,0x00, // 90=Z
|
||||
0x00,0x00,0x7f,0x7f,0x41,0x41,0x00,0x00, // 91=[
|
||||
0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0x40, // 92='\'
|
||||
0x00,0x00,0x41,0x41,0x7f,0x7f,0x00,0x00, // 93=]
|
||||
0x00,0x08,0x0c,0x06,0x06,0x0c,0x08,0x00, // 94=^
|
||||
0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, // 95=_
|
||||
0x00,0x00,0x01,0x03,0x06,0x04,0x00,0x00, // 96=`
|
||||
0x00,0x20,0x74,0x54,0x54,0x7c,0x78,0x00, // 97=a
|
||||
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,0x7f,0x7f,0x00, // 100=d
|
||||
0x00,0x38,0x7c,0x54,0x54,0x5c,0x58,0x00, // 101=e
|
||||
0x00,0x08,0x7e,0x7f,0x09,0x03,0x02,0x00, // 102=f
|
||||
0x00,0x98,0xbc,0xa4,0xa4,0xfc,0x7c,0x00, // 103=g
|
||||
0x00,0x7f,0x7f,0x04,0x04,0x7c,0x78,0x00, // 104=h
|
||||
0x00,0x00,0x00,0x7d,0x7d,0x00,0x00,0x00, // 105=i
|
||||
0x00,0x40,0xc0,0x80,0x80,0xfd,0x7d,0x00, // 106=j
|
||||
0x00,0x7f,0x7f,0x30,0x38,0x6c,0x44,0x00, // 107=k
|
||||
0x00,0x00,0x41,0x7f,0x7f,0x40,0x00,0x00, // 108=l
|
||||
0x00,0x7c,0x7c,0x18,0x30,0x18,0x7c,0x7c, // 109=m
|
||||
0x00,0x7c,0x7c,0x04,0x04,0x7c,0x78,0x00, // 110=n
|
||||
0x00,0x38,0x7c,0x44,0x44,0x7c,0x38,0x00, // 111=o
|
||||
0x00,0xfc,0xfc,0x24,0x24,0x3c,0x18,0x00, // 112=p
|
||||
0x00,0x18,0x3c,0x24,0x24,0xfc,0xfc,0x00, // 113=q
|
||||
0x00,0x7c,0x7c,0x04,0x04,0x0c,0x08,0x00, // 114=r
|
||||
0x00,0x48,0x5c,0x54,0x54,0x74,0x20,0x00, // 115=s
|
||||
0x04,0x04,0x3f,0x7f,0x44,0x64,0x20,0x00, // 116=t
|
||||
0x00,0x3c,0x7c,0x40,0x40,0x7c,0x3c,0x00, // 117=u
|
||||
0x00,0x1c,0x3c,0x60,0x60,0x3c,0x1c,0x00, // 118=v
|
||||
0x00,0x1c,0x7c,0x30,0x18,0x30,0x7c,0x1c, // 119=w
|
||||
0x00,0x44,0x6c,0x38,0x38,0x6c,0x44,0x00, // 120=x
|
||||
0x00,0x9c,0xbc,0xa0,0xa0,0xfc,0x7c,0x00, // 121=y
|
||||
0x00,0x44,0x64,0x74,0x5c,0x4c,0x44,0x00, // 122=z
|
||||
0x00,0x08,0x08,0x3e,0x77,0x41,0x41,0x00, // 123={
|
||||
0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00, // 124=|
|
||||
0x00,0x41,0x41,0x77,0x3e,0x08,0x08,0x00, // 125=}
|
||||
0x00,0x02,0x03,0x01,0x03,0x02,0x03,0x01, // 126=~
|
||||
0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55, // 127
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 32=
|
||||
0x00, 0x00, 0x00, 0x4f, 0x4f, 0x00, 0x00, 0x00, // 33=!
|
||||
0x00, 0x07, 0x07, 0x00, 0x00, 0x07, 0x07, 0x00, // 34="
|
||||
0x14, 0x7f, 0x7f, 0x14, 0x14, 0x7f, 0x7f, 0x14, // 35=#
|
||||
0x00, 0x24, 0x2e, 0x6b, 0x6b, 0x3a, 0x12, 0x00, // 36=$
|
||||
0x00, 0x63, 0x33, 0x18, 0x0c, 0x66, 0x63, 0x00, // 37=%
|
||||
0x00, 0x32, 0x7f, 0x4d, 0x4d, 0x77, 0x72, 0x50, // 38=&
|
||||
0x00, 0x00, 0x00, 0x04, 0x06, 0x03, 0x01, 0x00, // 39='
|
||||
0x00, 0x00, 0x1c, 0x3e, 0x63, 0x41, 0x00, 0x00, // 40=(
|
||||
0x00, 0x00, 0x41, 0x63, 0x3e, 0x1c, 0x00, 0x00, // 41=)
|
||||
0x08, 0x2a, 0x3e, 0x1c, 0x1c, 0x3e, 0x2a, 0x08, // 42=*
|
||||
0x00, 0x08, 0x08, 0x3e, 0x3e, 0x08, 0x08, 0x00, // 43=+
|
||||
0x00, 0x00, 0x80, 0xe0, 0x60, 0x00, 0x00, 0x00, // 44=,
|
||||
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, // 45=-
|
||||
0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, // 46=.
|
||||
0x00, 0x40, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, // 47=/
|
||||
0x00, 0x3e, 0x7f, 0x49, 0x45, 0x7f, 0x3e, 0x00, // 48=0
|
||||
0x00, 0x40, 0x44, 0x7f, 0x7f, 0x40, 0x40, 0x00, // 49=1
|
||||
0x00, 0x62, 0x73, 0x51, 0x49, 0x4f, 0x46, 0x00, // 50=2
|
||||
0x00, 0x22, 0x63, 0x49, 0x49, 0x7f, 0x36, 0x00, // 51=3
|
||||
0x00, 0x18, 0x18, 0x14, 0x16, 0x7f, 0x7f, 0x10, // 52=4
|
||||
0x00, 0x27, 0x67, 0x45, 0x45, 0x7d, 0x39, 0x00, // 53=5
|
||||
0x00, 0x3e, 0x7f, 0x49, 0x49, 0x7b, 0x32, 0x00, // 54=6
|
||||
0x00, 0x03, 0x03, 0x79, 0x7d, 0x07, 0x03, 0x00, // 55=7
|
||||
0x00, 0x36, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00, // 56=8
|
||||
0x00, 0x26, 0x6f, 0x49, 0x49, 0x7f, 0x3e, 0x00, // 57=9
|
||||
0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x00, // 58=:
|
||||
0x00, 0x00, 0x80, 0xe4, 0x64, 0x00, 0x00, 0x00, // 59=;
|
||||
0x00, 0x08, 0x1c, 0x36, 0x63, 0x41, 0x41, 0x00, // 60=<
|
||||
0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, // 61==
|
||||
0x00, 0x41, 0x41, 0x63, 0x36, 0x1c, 0x08, 0x00, // 62=>
|
||||
0x00, 0x02, 0x03, 0x51, 0x59, 0x0f, 0x06, 0x00, // 63=?
|
||||
0x00, 0x3e, 0x7f, 0x41, 0x4d, 0x4f, 0x2e, 0x00, // 64=@
|
||||
0x00, 0x7c, 0x7e, 0x0b, 0x0b, 0x7e, 0x7c, 0x00, // 65=A
|
||||
0x00, 0x7f, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00, // 66=B
|
||||
0x00, 0x3e, 0x7f, 0x41, 0x41, 0x63, 0x22, 0x00, // 67=C
|
||||
0x00, 0x7f, 0x7f, 0x41, 0x63, 0x3e, 0x1c, 0x00, // 68=D
|
||||
0x00, 0x7f, 0x7f, 0x49, 0x49, 0x41, 0x41, 0x00, // 69=E
|
||||
0x00, 0x7f, 0x7f, 0x09, 0x09, 0x01, 0x01, 0x00, // 70=F
|
||||
0x00, 0x3e, 0x7f, 0x41, 0x49, 0x7b, 0x3a, 0x00, // 71=G
|
||||
0x00, 0x7f, 0x7f, 0x08, 0x08, 0x7f, 0x7f, 0x00, // 72=H
|
||||
0x00, 0x00, 0x41, 0x7f, 0x7f, 0x41, 0x00, 0x00, // 73=I
|
||||
0x00, 0x20, 0x60, 0x41, 0x7f, 0x3f, 0x01, 0x00, // 74=J
|
||||
0x00, 0x7f, 0x7f, 0x1c, 0x36, 0x63, 0x41, 0x00, // 75=K
|
||||
0x00, 0x7f, 0x7f, 0x40, 0x40, 0x40, 0x40, 0x00, // 76=L
|
||||
0x00, 0x7f, 0x7f, 0x06, 0x0c, 0x06, 0x7f, 0x7f, // 77=M
|
||||
0x00, 0x7f, 0x7f, 0x0e, 0x1c, 0x7f, 0x7f, 0x00, // 78=N
|
||||
0x00, 0x3e, 0x7f, 0x41, 0x41, 0x7f, 0x3e, 0x00, // 79=O
|
||||
0x00, 0x7f, 0x7f, 0x09, 0x09, 0x0f, 0x06, 0x00, // 80=P
|
||||
0x00, 0x1e, 0x3f, 0x21, 0x61, 0x7f, 0x5e, 0x00, // 81=Q
|
||||
0x00, 0x7f, 0x7f, 0x19, 0x39, 0x6f, 0x46, 0x00, // 82=R
|
||||
0x00, 0x26, 0x6f, 0x49, 0x49, 0x7b, 0x32, 0x00, // 83=S
|
||||
0x00, 0x01, 0x01, 0x7f, 0x7f, 0x01, 0x01, 0x00, // 84=T
|
||||
0x00, 0x3f, 0x7f, 0x40, 0x40, 0x7f, 0x3f, 0x00, // 85=U
|
||||
0x00, 0x1f, 0x3f, 0x60, 0x60, 0x3f, 0x1f, 0x00, // 86=V
|
||||
0x00, 0x7f, 0x7f, 0x30, 0x18, 0x30, 0x7f, 0x7f, // 87=W
|
||||
0x00, 0x63, 0x77, 0x1c, 0x1c, 0x77, 0x63, 0x00, // 88=X
|
||||
0x00, 0x07, 0x0f, 0x78, 0x78, 0x0f, 0x07, 0x00, // 89=Y
|
||||
0x00, 0x61, 0x71, 0x59, 0x4d, 0x47, 0x43, 0x00, // 90=Z
|
||||
0x00, 0x00, 0x7f, 0x7f, 0x41, 0x41, 0x00, 0x00, // 91=[
|
||||
0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x40, // 92='\'
|
||||
0x00, 0x00, 0x41, 0x41, 0x7f, 0x7f, 0x00, 0x00, // 93=]
|
||||
0x00, 0x08, 0x0c, 0x06, 0x06, 0x0c, 0x08, 0x00, // 94=^
|
||||
0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, // 95=_
|
||||
0x00, 0x00, 0x01, 0x03, 0x06, 0x04, 0x00, 0x00, // 96=`
|
||||
0x00, 0x20, 0x74, 0x54, 0x54, 0x7c, 0x78, 0x00, // 97=a
|
||||
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, 0x7f, 0x7f, 0x00, // 100=d
|
||||
0x00, 0x38, 0x7c, 0x54, 0x54, 0x5c, 0x58, 0x00, // 101=e
|
||||
0x00, 0x08, 0x7e, 0x7f, 0x09, 0x03, 0x02, 0x00, // 102=f
|
||||
0x00, 0x98, 0xbc, 0xa4, 0xa4, 0xfc, 0x7c, 0x00, // 103=g
|
||||
0x00, 0x7f, 0x7f, 0x04, 0x04, 0x7c, 0x78, 0x00, // 104=h
|
||||
0x00, 0x00, 0x00, 0x7d, 0x7d, 0x00, 0x00, 0x00, // 105=i
|
||||
0x00, 0x40, 0xc0, 0x80, 0x80, 0xfd, 0x7d, 0x00, // 106=j
|
||||
0x00, 0x7f, 0x7f, 0x30, 0x38, 0x6c, 0x44, 0x00, // 107=k
|
||||
0x00, 0x00, 0x41, 0x7f, 0x7f, 0x40, 0x00, 0x00, // 108=l
|
||||
0x00, 0x7c, 0x7c, 0x18, 0x30, 0x18, 0x7c, 0x7c, // 109=m
|
||||
0x00, 0x7c, 0x7c, 0x04, 0x04, 0x7c, 0x78, 0x00, // 110=n
|
||||
0x00, 0x38, 0x7c, 0x44, 0x44, 0x7c, 0x38, 0x00, // 111=o
|
||||
0x00, 0xfc, 0xfc, 0x24, 0x24, 0x3c, 0x18, 0x00, // 112=p
|
||||
0x00, 0x18, 0x3c, 0x24, 0x24, 0xfc, 0xfc, 0x00, // 113=q
|
||||
0x00, 0x7c, 0x7c, 0x04, 0x04, 0x0c, 0x08, 0x00, // 114=r
|
||||
0x00, 0x48, 0x5c, 0x54, 0x54, 0x74, 0x20, 0x00, // 115=s
|
||||
0x04, 0x04, 0x3f, 0x7f, 0x44, 0x64, 0x20, 0x00, // 116=t
|
||||
0x00, 0x3c, 0x7c, 0x40, 0x40, 0x7c, 0x3c, 0x00, // 117=u
|
||||
0x00, 0x1c, 0x3c, 0x60, 0x60, 0x3c, 0x1c, 0x00, // 118=v
|
||||
0x00, 0x1c, 0x7c, 0x30, 0x18, 0x30, 0x7c, 0x1c, // 119=w
|
||||
0x00, 0x44, 0x6c, 0x38, 0x38, 0x6c, 0x44, 0x00, // 120=x
|
||||
0x00, 0x9c, 0xbc, 0xa0, 0xa0, 0xfc, 0x7c, 0x00, // 121=y
|
||||
0x00, 0x44, 0x64, 0x74, 0x5c, 0x4c, 0x44, 0x00, // 122=z
|
||||
0x00, 0x08, 0x08, 0x3e, 0x77, 0x41, 0x41, 0x00, // 123={
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, // 124=|
|
||||
0x00, 0x41, 0x41, 0x77, 0x3e, 0x08, 0x08, 0x00, // 125=}
|
||||
0x00, 0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, // 126=~
|
||||
0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, // 127
|
||||
};
|
||||
|
||||
#endif // MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H
|
||||
|
@ -3,7 +3,8 @@
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC
|
||||
* Copyright (c) 2014-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
|
||||
@ -23,21 +24,25 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#ifndef MICROPY_INCLUDED_EXTMOD_MISC_H
|
||||
#define MICROPY_INCLUDED_EXTMOD_MISC_H
|
||||
|
||||
// These helpers move MicroPython objects and their sub-objects to the long lived portion of the
|
||||
// heap.
|
||||
// This file contains cumulative declarations for extmod/ .
|
||||
|
||||
#ifndef MICROPY_INCLUDED_PY_GC_LONG_LIVED_H
|
||||
#define MICROPY_INCLUDED_PY_GC_LONG_LIVED_H
|
||||
#include <stddef.h>
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "py/objfun.h"
|
||||
#include "py/objproperty.h"
|
||||
#include "py/objstr.h"
|
||||
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_dupterm_obj);
|
||||
|
||||
mp_obj_fun_bc_t *make_fun_bc_long_lived(mp_obj_fun_bc_t *fun_bc, uint8_t max_depth);
|
||||
mp_obj_property_t *make_property_long_lived(mp_obj_property_t *prop, uint8_t max_depth);
|
||||
mp_obj_dict_t *make_dict_long_lived(mp_obj_dict_t *dict, uint8_t max_depth);
|
||||
mp_obj_str_t *make_str_long_lived(mp_obj_str_t *str);
|
||||
mp_obj_t make_obj_long_lived(mp_obj_t obj, uint8_t max_depth);
|
||||
#if MICROPY_PY_OS_DUPTERM
|
||||
bool mp_uos_dupterm_is_builtin_stream(mp_const_obj_t stream);
|
||||
void mp_uos_dupterm_stream_detached_attached(mp_obj_t stream_detached, mp_obj_t stream_attached);
|
||||
uintptr_t mp_uos_dupterm_poll(uintptr_t poll_flags);
|
||||
int mp_uos_dupterm_rx_chr(void);
|
||||
void mp_uos_dupterm_tx_strn(const char *str, size_t len);
|
||||
void mp_uos_deactivate(size_t dupterm_idx, const char *msg, mp_obj_t exc);
|
||||
#else
|
||||
#define mp_uos_dupterm_tx_strn(s, l)
|
||||
#endif
|
||||
|
||||
#endif // MICROPY_INCLUDED_PY_GC_LONG_LIVED_H
|
||||
#endif // MICROPY_INCLUDED_EXTMOD_MISC_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
|
@ -29,14 +29,14 @@
|
||||
#include "py/pairheap.h"
|
||||
#include "py/mphal.h"
|
||||
|
||||
#if MICROPY_PY_UASYNCIO
|
||||
|
||||
#if CIRCUITPY && !(defined(__unix__) || defined(__APPLE__))
|
||||
#include "shared-bindings/supervisor/__init__.h"
|
||||
#endif
|
||||
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
|
||||
#if MICROPY_PY_UASYNCIO
|
||||
|
||||
// Used when task cannot be guaranteed to be non-NULL.
|
||||
#define TASK_PAIRHEAP(task) ((task) ? &(task)->pairheap : NULL)
|
||||
|
||||
@ -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
|
||||
|
||||
// CIRCUITPY-style ticks
|
||||
#define _TICKS_PERIOD (1lu << 29)
|
||||
#define _TICKS_MAX (_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) {
|
||||
(void)args;
|
||||
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);
|
||||
self->base.type = type;
|
||||
mp_obj_task_queue_t *self = mp_obj_malloc(mp_obj_task_queue_t, type);
|
||||
self->heap = (mp_obj_task_t *)mp_pairheap_new(task_lt);
|
||||
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_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_t *task = MP_OBJ_TO_PTR(args[1]);
|
||||
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));
|
||||
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_t *head = (mp_obj_task_t *)mp_pairheap_peek(task_lt, &self->heap->pairheap);
|
||||
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);
|
||||
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) {
|
||||
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
@ -157,10 +157,14 @@ 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[] = {
|
||||
{ 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_head), MP_ROM_PTR(&task_queue_push_sorted_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_pop_head), MP_ROM_PTR(&task_queue_pop_head_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_push), MP_ROM_PTR(&task_queue_push_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_pop), MP_ROM_PTR(&task_queue_pop_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&task_queue_remove_obj) },
|
||||
|
||||
// CIRCUITPYTHON: remove these after the bundle need not support 8.x
|
||||
{ MP_ROM_QSTR(MP_QSTR_push_head), MP_ROM_PTR(&task_queue_push_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_push_sorted), MP_ROM_PTR(&task_queue_push_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_pop_head), MP_ROM_PTR(&task_queue_pop_obj) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(task_queue_locals_dict, task_queue_locals_dict_table);
|
||||
|
||||
@ -223,18 +227,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.
|
||||
dest[2] = MP_OBJ_FROM_PTR(self);
|
||||
mp_call_method_n_kw(1, 0, dest);
|
||||
// _task_queue.push_head(self)
|
||||
// _task_queue.push(self)
|
||||
dest[0] = _task_queue;
|
||||
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) {
|
||||
// On the main running queue but scheduled in the future, so bring it forward to now.
|
||||
// _task_queue.remove(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[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));
|
||||
@ -243,6 +247,7 @@ STATIC mp_obj_t task_cancel(mp_obj_t self_in) {
|
||||
}
|
||||
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) {
|
||||
return task_getiter(self_in, NULL);
|
||||
}
|
||||
@ -266,6 +271,7 @@ STATIC void task_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||
dest[1] = self_in;
|
||||
} else if (attr == MP_QSTR_ph_key) {
|
||||
dest[0] = self->ph_key;
|
||||
// CIRCUITPY provides __await__().
|
||||
} else if (attr == MP_QSTR___await__) {
|
||||
dest[0] = MP_OBJ_FROM_PTR(&task_await_obj);
|
||||
dest[1] = self_in;
|
||||
@ -291,6 +297,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) {
|
||||
// Allocate the waiting queue.
|
||||
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;
|
||||
}
|
||||
@ -298,6 +307,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) {
|
||||
mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
if (TASK_IS_DONE(self)) {
|
||||
// CIRCUITPY
|
||||
if (self->data == mp_const_none) {
|
||||
// Task finished but has already been sent to the loop's exception handler.
|
||||
mp_raise_StopIteration(MP_OBJ_NULL);
|
||||
@ -309,7 +319,7 @@ STATIC mp_obj_t task_iternext(mp_obj_t self_in) {
|
||||
// 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 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.
|
||||
((mp_obj_task_t *)MP_OBJ_TO_PTR(cur_task))->data = self_in;
|
||||
}
|
||||
@ -347,6 +357,6 @@ const mp_obj_module_t mp_module_uasyncio = {
|
||||
.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__asyncio, mp_module_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)
|
||||
// SPDX-FileCopyrightText: 2022 Beat Ludin for Adafruit Industries
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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 <assert.h>
|
||||
@ -13,6 +33,8 @@
|
||||
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
|
||||
#if MICROPY_PY_UBINASCII
|
||||
|
||||
static void check_not_unicode(const mp_obj_t arg) {
|
||||
#if MICROPY_CPYTHON_COMPAT
|
||||
if (mp_obj_is_str(arg)) {
|
||||
@ -20,7 +42,6 @@ static void check_not_unicode(const mp_obj_t arg) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) {
|
||||
// First argument is the data to convert.
|
||||
// Second argument is an optional separator to be used between values.
|
||||
@ -154,13 +175,21 @@ 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_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
|
||||
check_not_unicode(data);
|
||||
STATIC mp_obj_t mod_binascii_b2a_base64(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
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;
|
||||
check_not_unicode(pos_args[0]);
|
||||
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_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
|
||||
byte *in = bufinfo.buf, *out = (byte *)vstr.buf;
|
||||
@ -186,7 +215,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
|
||||
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) {
|
||||
*out += 'A';
|
||||
} else if (*out < 52) {
|
||||
@ -202,10 +231,15 @@ STATIC mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
|
||||
}
|
||||
out++;
|
||||
}
|
||||
*out = '\n';
|
||||
if (newline) {
|
||||
*out = '\n';
|
||||
}
|
||||
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
|
||||
@ -296,4 +330,6 @@ const mp_obj_module_t mp_module_ubinascii = {
|
||||
.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_binascii, 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)
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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 <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) {
|
||||
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);
|
||||
o->base.type = type;
|
||||
mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, type);
|
||||
o->addr = (void *)(uintptr_t)mp_obj_int_get_truncated(args[0]);
|
||||
o->desc = args[1];
|
||||
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) {
|
||||
case STRUCT: {
|
||||
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
|
||||
o->base.type = &uctypes_struct_type;
|
||||
mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type);
|
||||
o->desc = sub->items[1];
|
||||
o->addr = self->addr + offset;
|
||||
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
|
||||
}
|
||||
case PTR: {
|
||||
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
|
||||
o->base.type = &uctypes_struct_type;
|
||||
mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type);
|
||||
o->desc = MP_OBJ_FROM_PTR(sub);
|
||||
o->addr = self->addr + offset;
|
||||
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) {
|
||||
mp_uint_t dummy = 0;
|
||||
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);
|
||||
o->base.type = &uctypes_struct_type;
|
||||
mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type);
|
||||
o->desc = t->items[2];
|
||||
o->addr = self->addr + size * index;
|
||||
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 {
|
||||
mp_uint_t dummy = 0;
|
||||
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);
|
||||
o->base.type = &uctypes_struct_type;
|
||||
mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type);
|
||||
o->desc = t->items[1];
|
||||
o->addr = p + size * index;
|
||||
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,
|
||||
};
|
||||
|
||||
MP_REGISTER_MODULE(MP_QSTR_uctypes, mp_module_uctypes);
|
||||
|
||||
#endif
|
||||
|
@ -1,7 +1,28 @@
|
||||
// Copyright (c) 2014 Paul Sokolovsky
|
||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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 <string.h>
|
||||
@ -39,7 +60,6 @@
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct _mp_obj_hash_t {
|
||||
mp_obj_base_t base;
|
||||
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) {
|
||||
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));
|
||||
o->base.type = type;
|
||||
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context), type);
|
||||
o->final = false;
|
||||
mbedtls_sha256_init((mbedtls_sha256_context *)&o->state);
|
||||
mbedtls_sha256_starts_ret((mbedtls_sha256_context *)&o->state, 0);
|
||||
@ -105,13 +124,11 @@ static void check_not_unicode(const mp_obj_t arg) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if MICROPY_PY_UHASHLIB_SHA256
|
||||
#include "lib/crypto-algorithms/sha256.c"
|
||||
|
||||
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_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX));
|
||||
o->base.type = type;
|
||||
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX), type);
|
||||
o->final = false;
|
||||
sha256_init((CRYAL_SHA256_CTX *)o->state);
|
||||
if (n_args == 1) {
|
||||
@ -159,16 +176,13 @@ STATIC const mp_obj_type_t uhashlib_sha256_type = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if MICROPY_PY_UHASHLIB_SHA1
|
||||
STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg);
|
||||
|
||||
#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) {
|
||||
mp_arg_check_num(n_args, kw_args, 0, 1, false);
|
||||
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(SHA1_CTX));
|
||||
o->base.type = type;
|
||||
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_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(SHA1_CTX), type);
|
||||
o->final = false;
|
||||
SHA1_Init((SHA1_CTX *)o->state);
|
||||
if (n_args == 1) {
|
||||
@ -178,7 +192,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) {
|
||||
check_not_unicode(arg);
|
||||
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
uhashlib_ensure_not_final(self);
|
||||
mp_buffer_info_t bufinfo;
|
||||
@ -208,8 +221,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) {
|
||||
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));
|
||||
o->base.type = type;
|
||||
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_sha1_context), type);
|
||||
o->final = false;
|
||||
mbedtls_sha1_init((mbedtls_sha1_context *)o->state);
|
||||
mbedtls_sha1_starts_ret((mbedtls_sha1_context *)o->state);
|
||||
@ -263,8 +275,7 @@ STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg);
|
||||
#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) {
|
||||
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));
|
||||
o->base.type = type;
|
||||
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(MD5_CTX), type);
|
||||
o->final = false;
|
||||
MD5_Init((MD5_CTX *)o->state);
|
||||
if (n_args == 1) {
|
||||
@ -303,8 +314,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) {
|
||||
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));
|
||||
o->base.type = type;
|
||||
mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_md5_context), type);
|
||||
o->final = false;
|
||||
mbedtls_md5_init((mbedtls_md5_context *)o->state);
|
||||
mbedtls_md5_starts_ret((mbedtls_md5_context *)o->state);
|
||||
@ -372,4 +382,6 @@ const mp_obj_module_t mp_module_uhashlib = {
|
||||
.globals = (mp_obj_dict_t *)&mp_module_uhashlib_globals,
|
||||
};
|
||||
|
||||
MP_REGISTER_MODULE(MP_QSTR_hashlib, mp_module_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
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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/runtime.h"
|
||||
@ -98,6 +119,8 @@ const mp_obj_module_t mp_module_uheapq = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&mp_module_uheapq_globals,
|
||||
};
|
||||
|
||||
MP_REGISTER_MODULE(MP_QSTR_heapq, mp_module_uheapq);
|
||||
#endif
|
||||
|
||||
#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
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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>
|
||||
|
||||
@ -112,6 +133,7 @@ typedef struct _ujson_stream_t {
|
||||
mp_obj_t stream_obj;
|
||||
mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode);
|
||||
int errcode;
|
||||
// CIRCUITPY
|
||||
mp_obj_t python_readinto[2 + 1];
|
||||
mp_obj_array_t bytearray_obj;
|
||||
size_t start;
|
||||
@ -136,6 +158,8 @@ STATIC byte ujson_stream_next(ujson_stream_t *s) {
|
||||
return s->cur;
|
||||
}
|
||||
|
||||
// CIRCUITPY
|
||||
|
||||
// We read from an object's `readinto` method in chunks larger than the json
|
||||
// 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:
|
||||
// CIRCUITPY
|
||||
|
||||
// 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
|
||||
// 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,
|
||||
};
|
||||
|
||||
MP_REGISTER_MODULE(MP_QSTR_json, mp_module_ujson, MICROPY_PY_UJSON);
|
||||
MP_REGISTER_MODULE(MP_QSTR_json, mp_module_ujson);
|
||||
|
||||
#endif // MICROPY_PY_UJSON
|
||||
|
186
extmod/moduos.c
Normal file
186
extmod/moduos.c
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* 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) },
|
||||
#if defined(MICROPY_UNIX_COVERAGE)
|
||||
{ MP_ROM_QSTR(MP_QSTR_getenv_int), MP_ROM_PTR(&mp_uos_getenv_int_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_getenv_str), MP_ROM_PTR(&mp_uos_getenv_str_obj) },
|
||||
#endif
|
||||
|
||||
{ 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_os, mp_module_uos);
|
||||
|
||||
#endif // MICROPY_PY_UOS
|
@ -29,87 +29,19 @@
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objstr.h"
|
||||
#include "py/mphal.h"
|
||||
#include "extmod/moduplatform.h"
|
||||
#include "genhdr/mpversion.h"
|
||||
|
||||
#if MICROPY_PY_UPLATFORM
|
||||
|
||||
// platform - Access to underlying platform's identifying data
|
||||
|
||||
// TODO: Add more architectures, compilers and libraries.
|
||||
// See: https://sourceforge.net/p/predef/wiki/Home/
|
||||
|
||||
#if defined(__ARM_ARCH)
|
||||
#define PLATFORM_ARCH "arm"
|
||||
#elif defined(__x86_64__) || defined(_WIN64)
|
||||
#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_DEFINE_STR_OBJ(info_platform_obj, MICROPY_PLATFORM_SYSTEM "-" \
|
||||
MICROPY_VERSION_STRING "-" MICROPY_PLATFORM_ARCH "-" MICROPY_PLATFORM_VERSION "-with-" \
|
||||
MICROPY_PLATFORM_LIBC_LIB "" MICROPY_PLATFORM_LIBC_VER);
|
||||
STATIC const MP_DEFINE_STR_OBJ(info_python_compiler_obj, MICROPY_PLATFORM_COMPILER);
|
||||
STATIC const MP_DEFINE_STR_OBJ(info_libc_lib_obj, MICROPY_PLATFORM_LIBC_LIB);
|
||||
STATIC const MP_DEFINE_STR_OBJ(info_libc_ver_obj, MICROPY_PLATFORM_LIBC_VER);
|
||||
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)}
|
||||
};
|
||||
@ -143,4 +75,6 @@ const mp_obj_module_t mp_module_uplatform = {
|
||||
.globals = (mp_obj_dict_t *)&modplatform_globals,
|
||||
};
|
||||
|
||||
MP_REGISTER_MODULE(MP_QSTR_platform, mp_module_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 identifying 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)
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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 <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
|
||||
|
||||
#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
|
||||
// that it's only ever seeded once.
|
||||
static bool seeded = false;
|
||||
@ -233,6 +254,8 @@ const mp_obj_module_t mp_module_urandom = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&mp_module_urandom_globals,
|
||||
};
|
||||
|
||||
MP_REGISTER_MODULE(MP_QSTR_random, mp_module_urandom);
|
||||
#endif
|
||||
|
||||
#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)
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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 <assert.h>
|
||||
@ -18,6 +39,7 @@
|
||||
|
||||
#include "lib/re1.5/re1.5.h"
|
||||
|
||||
// CIRCUITPY
|
||||
#if MICROPY_PY_URE_DEBUG
|
||||
#define FLAG_DEBUG 0x1000
|
||||
#endif
|
||||
@ -168,7 +190,7 @@ STATIC mp_obj_t ure_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
|
||||
}
|
||||
Subject subj;
|
||||
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;
|
||||
#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;
|
||||
size_t len;
|
||||
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;
|
||||
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;
|
||||
const char *where_str = mp_obj_str_get_data(where, &where_len);
|
||||
Subject subj;
|
||||
subj.begin = where_str;
|
||||
subj.begin_line = subj.begin = where_str;
|
||||
subj.end = subj.begin + where_len;
|
||||
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) {
|
||||
goto error;
|
||||
}
|
||||
mp_obj_re_t *o = m_new_obj_var(mp_obj_re_t, char, size);
|
||||
o->base.type = &re_type;
|
||||
mp_obj_re_t *o = mp_obj_malloc_var(mp_obj_re_t, char, size, &re_type);
|
||||
#if MICROPY_PY_URE_DEBUG
|
||||
int flags = 0;
|
||||
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,
|
||||
};
|
||||
|
||||
MP_REGISTER_MODULE(MP_QSTR_re, mp_module_ure, MICROPY_PY_URE);
|
||||
MP_REGISTER_MODULE(MP_QSTR_re, mp_module_ure);
|
||||
#endif
|
||||
|
||||
// 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
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2015-2017 Paul Sokolovsky
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (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"
|
||||
#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);
|
||||
return mp_obj_new_tuple(3, list_array);
|
||||
}
|
||||
// CIRCUITPY
|
||||
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)) {
|
||||
break;
|
||||
}
|
||||
// CIRCUITPY
|
||||
RUN_BACKGROUND_TASKS;
|
||||
if (mp_hal_is_interrupted()) {
|
||||
return 0;
|
||||
@ -333,8 +356,7 @@ STATIC const mp_obj_type_t mp_type_poll = {
|
||||
|
||||
// poll()
|
||||
STATIC mp_obj_t select_poll(void) {
|
||||
mp_obj_poll_t *poll = m_new_obj(mp_obj_poll_t);
|
||||
poll->base.type = &mp_type_poll;
|
||||
mp_obj_poll_t *poll = mp_obj_malloc(mp_obj_poll_t, &mp_type_poll);
|
||||
mp_map_init(&poll->poll_map, 0);
|
||||
poll->iter_cnt = 0;
|
||||
poll->ret_tuple = MP_OBJ_NULL;
|
||||
@ -361,6 +383,6 @@ const mp_obj_module_t mp_module_uselect = {
|
||||
.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_select, mp_module_uselect);
|
||||
|
||||
#endif // MICROPY_PY_USELECT
|
||||
|
@ -1,217 +0,0 @@
|
||||
// Copyright (c) 2016-2017 Paul Sokolovsky
|
||||
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "py/objlist.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/smallint.h"
|
||||
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
|
||||
#if MICROPY_PY_UTIMEQ
|
||||
|
||||
#define MODULO MICROPY_PY_UTIME_TICKS_PERIOD
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
// the algorithm here is modelled on CPython's heapq.py
|
||||
|
||||
struct qentry {
|
||||
mp_uint_t time;
|
||||
mp_uint_t id;
|
||||
mp_obj_t callback;
|
||||
mp_obj_t args;
|
||||
};
|
||||
|
||||
typedef struct _mp_obj_utimeq_t {
|
||||
mp_obj_base_t base;
|
||||
mp_uint_t alloc;
|
||||
mp_uint_t len;
|
||||
struct qentry items[];
|
||||
} mp_obj_utimeq_t;
|
||||
|
||||
STATIC mp_uint_t utimeq_id;
|
||||
|
||||
STATIC mp_obj_utimeq_t *utimeq_get_heap(mp_obj_t heap_in) {
|
||||
return MP_OBJ_TO_PTR(heap_in);
|
||||
}
|
||||
|
||||
STATIC bool time_less_than(struct qentry *item, struct qentry *parent) {
|
||||
mp_uint_t item_tm = item->time;
|
||||
mp_uint_t parent_tm = parent->time;
|
||||
mp_uint_t res = parent_tm - item_tm;
|
||||
if (res == 0) {
|
||||
// TODO: This actually should use the same "ring" logic
|
||||
// as for time, to avoid artifacts when id's overflow.
|
||||
return item->id < parent->id;
|
||||
}
|
||||
if ((mp_int_t)res < 0) {
|
||||
res += MODULO;
|
||||
}
|
||||
return res && res < (MODULO / 2);
|
||||
}
|
||||
|
||||
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_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);
|
||||
o->base.type = type;
|
||||
memset(o->items, 0, sizeof(*o->items) * alloc);
|
||||
o->alloc = alloc;
|
||||
o->len = 0;
|
||||
return MP_OBJ_FROM_PTR(o);
|
||||
}
|
||||
|
||||
STATIC void utimeq_heap_siftdown(mp_obj_utimeq_t *heap, mp_uint_t start_pos, mp_uint_t pos) {
|
||||
struct qentry item = heap->items[pos];
|
||||
while (pos > start_pos) {
|
||||
mp_uint_t parent_pos = (pos - 1) >> 1;
|
||||
struct qentry *parent = &heap->items[parent_pos];
|
||||
bool lessthan = time_less_than(&item, parent);
|
||||
if (lessthan) {
|
||||
heap->items[pos] = *parent;
|
||||
pos = parent_pos;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
heap->items[pos] = item;
|
||||
}
|
||||
|
||||
STATIC void utimeq_heap_siftup(mp_obj_utimeq_t *heap, mp_uint_t pos) {
|
||||
mp_uint_t start_pos = pos;
|
||||
mp_uint_t end_pos = heap->len;
|
||||
struct qentry item = heap->items[pos];
|
||||
for (mp_uint_t child_pos = 2 * pos + 1; child_pos < end_pos; child_pos = 2 * pos + 1) {
|
||||
// choose right child if it's <= left child
|
||||
if (child_pos + 1 < end_pos) {
|
||||
bool lessthan = time_less_than(&heap->items[child_pos], &heap->items[child_pos + 1]);
|
||||
if (!lessthan) {
|
||||
child_pos += 1;
|
||||
}
|
||||
}
|
||||
// bubble up the smaller child
|
||||
heap->items[pos] = heap->items[child_pos];
|
||||
pos = child_pos;
|
||||
}
|
||||
heap->items[pos] = item;
|
||||
utimeq_heap_siftdown(heap, start_pos, pos);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t mod_utimeq_heappush(size_t n_args, const mp_obj_t *args) {
|
||||
(void)n_args;
|
||||
mp_obj_t heap_in = args[0];
|
||||
mp_obj_utimeq_t *heap = utimeq_get_heap(heap_in);
|
||||
if (heap->len == heap->alloc) {
|
||||
mp_raise_IndexError(MP_ERROR_TEXT("queue overflow"));
|
||||
}
|
||||
mp_uint_t l = heap->len;
|
||||
heap->items[l].time = MP_OBJ_SMALL_INT_VALUE(args[1]);
|
||||
heap->items[l].id = utimeq_id++;
|
||||
heap->items[l].callback = args[2];
|
||||
heap->items[l].args = args[3];
|
||||
utimeq_heap_siftdown(heap, 0, heap->len);
|
||||
heap->len++;
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_utimeq_heappush_obj, 4, 4, mod_utimeq_heappush);
|
||||
|
||||
STATIC mp_obj_t mod_utimeq_heappop(mp_obj_t heap_in, mp_obj_t list_ref) {
|
||||
mp_obj_utimeq_t *heap = utimeq_get_heap(heap_in);
|
||||
if (heap->len == 0) {
|
||||
mp_raise_IndexError(MP_ERROR_TEXT("empty heap"));
|
||||
}
|
||||
mp_obj_list_t *ret = MP_OBJ_TO_PTR(list_ref);
|
||||
if (!mp_obj_is_type(list_ref, &mp_type_list) || ret->len < 3) {
|
||||
mp_raise_TypeError(NULL);
|
||||
}
|
||||
|
||||
struct qentry *item = &heap->items[0];
|
||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(item->time);
|
||||
ret->items[1] = item->callback;
|
||||
ret->items[2] = item->args;
|
||||
heap->len -= 1;
|
||||
heap->items[0] = heap->items[heap->len];
|
||||
heap->items[heap->len].callback = MP_OBJ_NULL; // so we don't retain a pointer
|
||||
heap->items[heap->len].args = MP_OBJ_NULL;
|
||||
if (heap->len) {
|
||||
utimeq_heap_siftup(heap, 0);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_utimeq_heappop_obj, mod_utimeq_heappop);
|
||||
|
||||
STATIC mp_obj_t mod_utimeq_peektime(mp_obj_t heap_in) {
|
||||
mp_obj_utimeq_t *heap = utimeq_get_heap(heap_in);
|
||||
if (heap->len == 0) {
|
||||
mp_raise_IndexError(MP_ERROR_TEXT("empty heap"));
|
||||
}
|
||||
|
||||
struct qentry *item = &heap->items[0];
|
||||
return MP_OBJ_NEW_SMALL_INT(item->time);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_utimeq_peektime_obj, mod_utimeq_peektime);
|
||||
|
||||
#if DEBUG
|
||||
STATIC mp_obj_t mod_utimeq_dump(mp_obj_t heap_in) {
|
||||
mp_obj_utimeq_t *heap = utimeq_get_heap(heap_in);
|
||||
for (int i = 0; i < heap->len; i++) {
|
||||
printf(UINT_FMT "\t%p\t%p\n", heap->items[i].time,
|
||||
MP_OBJ_TO_PTR(heap->items[i].callback), MP_OBJ_TO_PTR(heap->items[i].args));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_utimeq_dump_obj, mod_utimeq_dump);
|
||||
#endif
|
||||
|
||||
STATIC mp_obj_t utimeq_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
|
||||
mp_obj_utimeq_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
switch (op) {
|
||||
case MP_UNARY_OP_BOOL:
|
||||
return mp_obj_new_bool(self->len != 0);
|
||||
case MP_UNARY_OP_LEN:
|
||||
return MP_OBJ_NEW_SMALL_INT(self->len);
|
||||
default:
|
||||
return MP_OBJ_NULL; // op not supported
|
||||
}
|
||||
}
|
||||
|
||||
STATIC const mp_rom_map_elem_t utimeq_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_push), MP_ROM_PTR(&mod_utimeq_heappush_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_pop), MP_ROM_PTR(&mod_utimeq_heappop_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_peektime), MP_ROM_PTR(&mod_utimeq_peektime_obj) },
|
||||
#if DEBUG
|
||||
{ MP_ROM_QSTR(MP_QSTR_dump), MP_ROM_PTR(&mod_utimeq_dump_obj) },
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(utimeq_locals_dict, utimeq_locals_dict_table);
|
||||
|
||||
STATIC const mp_obj_type_t utimeq_type = {
|
||||
{ &mp_type_type },
|
||||
.flags = MP_TYPE_FLAG_EXTENDED,
|
||||
.name = MP_QSTR_utimeq,
|
||||
.make_new = utimeq_make_new,
|
||||
.locals_dict = (void *)&utimeq_locals_dict,
|
||||
MP_TYPE_EXTENDED_FIELDS(
|
||||
.unary_op = utimeq_unary_op,
|
||||
),
|
||||
};
|
||||
|
||||
STATIC const mp_rom_map_elem_t mp_module_utimeq_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_utimeq) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_utimeq), MP_ROM_PTR(&utimeq_type) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_utimeq_globals, mp_module_utimeq_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_utimeq = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&mp_module_utimeq_globals,
|
||||
};
|
||||
|
||||
#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)
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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 <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) {
|
||||
mp_arg_check_num(n_args, n_kw, 1, 2, false);
|
||||
mp_get_stream_raise(args[0], MP_STREAM_OP_READ);
|
||||
mp_obj_decompio_t *o = m_new_obj(mp_obj_decompio_t);
|
||||
o->base.type = type;
|
||||
mp_obj_decompio_t *o = mp_obj_malloc(mp_obj_decompio_t, type);
|
||||
memset(&o->decomp, 0, sizeof(o->decomp));
|
||||
o->decomp.readSource = read_src_stream;
|
||||
o->src_stream = args[0];
|
||||
o->eof = false;
|
||||
|
||||
mp_int_t dict_opt = 0;
|
||||
int dict_sz;
|
||||
uint dict_sz;
|
||||
if (n_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:
|
||||
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 {
|
||||
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_limit = (unsigned char *)buf + size;
|
||||
o->decomp.dest_limit = (byte *)buf + size;
|
||||
int st = uzlib_uncompress_chksum(&o->decomp);
|
||||
if (st == TINF_DONE) {
|
||||
o->eof = true;
|
||||
}
|
||||
if (st < 0) {
|
||||
DEBUG_printf("uncompress error=" INT_FMT "\n", st);
|
||||
*errcode = MP_EINVAL;
|
||||
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_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_limit = (unsigned char *)bufinfo.buf + bufinfo.len;
|
||||
decomp->source_limit = (byte *)bufinfo.buf + bufinfo.len;
|
||||
|
||||
int st;
|
||||
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_size += 256;
|
||||
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;
|
||||
@ -203,6 +228,9 @@ const mp_obj_module_t mp_module_uzlib = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t *)&mp_module_uzlib_globals,
|
||||
};
|
||||
|
||||
|
||||
MP_REGISTER_MODULE(MP_QSTR_zlib, mp_module_uzlib);
|
||||
#endif
|
||||
|
||||
// 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)
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2013-2016 Damien P. George
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (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"
|
||||
#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)
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2013-2016 Damien P. George
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (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
|
||||
#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
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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 <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) {
|
||||
// list the root directory
|
||||
mp_vfs_ilistdir_it_t *iter = m_new_obj(mp_vfs_ilistdir_it_t);
|
||||
iter->base.type = &mp_type_polymorph_iter;
|
||||
mp_vfs_ilistdir_it_t *iter = mp_obj_malloc(mp_vfs_ilistdir_it_t, &mp_type_polymorph_iter);
|
||||
iter->iternext = mp_vfs_ilistdir_it_iternext;
|
||||
iter->cur.vfs = MP_STATE_VM(vfs_mount_table);
|
||||
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
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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
|
||||
#define MICROPY_INCLUDED_EXTMOD_VFS_H
|
||||
|
||||
#include "py/lexer.h"
|
||||
#include "py/builtin.h"
|
||||
#include "py/obj.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)
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (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"
|
||||
#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);
|
||||
|
||||
// create new object
|
||||
fs_user_mount_t *vfs = m_new_obj(fs_user_mount_t);
|
||||
vfs->base.type = type;
|
||||
fs_user_mount_t *vfs = mp_obj_malloc(fs_user_mount_t, type);
|
||||
vfs->fatfs.drv = vfs;
|
||||
|
||||
// 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
|
||||
mp_vfs_fat_ilistdir_it_t *iter = m_new_obj(mp_vfs_fat_ilistdir_it_t);
|
||||
iter->base.type = &mp_type_polymorph_iter;
|
||||
mp_vfs_fat_ilistdir_it_t *iter = mp_obj_malloc(mp_vfs_fat_ilistdir_it_t, &mp_type_polymorph_iter);
|
||||
iter->iternext = mp_vfs_fat_ilistdir_it_iternext;
|
||||
iter->is_str = is_str_type;
|
||||
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
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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
|
||||
#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
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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"
|
||||
#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
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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"
|
||||
#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)
|
||||
|
||||
// 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) {
|
||||
int mode = 0;
|
||||
const char *mode_s = mp_obj_str_get_str(args[1].u_obj);
|
||||
@ -210,7 +232,7 @@ STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_ar
|
||||
DWORD size = (temp_table[0] + 1) * 2;
|
||||
|
||||
// Now allocate the size and construct the map.
|
||||
o->fp.cltbl = m_malloc_maybe(size * sizeof(DWORD), false);
|
||||
o->fp.cltbl = m_malloc_maybe(size * sizeof(DWORD));
|
||||
if (o->fp.cltbl != NULL) {
|
||||
o->fp.cltbl[0] = size;
|
||||
res = f_lseek(&o->fp, CREATE_LINKMAP);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
MP_VFS_LFSx(ilistdir_it_t) * iter = m_new_obj(MP_VFS_LFSx(ilistdir_it_t));
|
||||
iter->base.type = &mp_type_polymorph_iter;
|
||||
MP_VFS_LFSx(ilistdir_it_t) * iter = mp_obj_malloc(MP_VFS_LFSx(ilistdir_it_t), &mp_type_polymorph_iter);
|
||||
iter->iternext = MP_VFS_LFSx(ilistdir_it_iternext);
|
||||
iter->is_str = is_str_type;
|
||||
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
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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/mperrno.h"
|
||||
@ -16,6 +37,9 @@
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#ifdef _MSC_VER
|
||||
#include <direct.h> // For mkdir etc.
|
||||
#endif
|
||||
|
||||
typedef struct _mp_obj_vfs_posix_t {
|
||||
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) {
|
||||
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);
|
||||
vfs->base.type = type;
|
||||
mp_obj_vfs_posix_t *vfs = mp_obj_malloc(mp_obj_vfs_posix_t, type);
|
||||
vstr_init(&vfs->root, 0);
|
||||
if (n_args == 1) {
|
||||
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) {
|
||||
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);
|
||||
iter->base.type = &mp_type_polymorph_iter;
|
||||
vfs_posix_ilistdir_it_t *iter = mp_obj_malloc(vfs_posix_ilistdir_it_t, &mp_type_polymorph_iter);
|
||||
iter->iternext = vfs_posix_ilistdir_it_iternext;
|
||||
iter->is_str = mp_obj_get_type(path_in) == &mp_type_str;
|
||||
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);
|
||||
const char *path = vfs_posix_get_path_str(self, path_in);
|
||||
MP_THREAD_GIL_EXIT();
|
||||
#ifdef _WIN32
|
||||
int ret = mkdir(path);
|
||||
#else
|
||||
int ret = mkdir(path, 0777);
|
||||
#endif
|
||||
MP_THREAD_GIL_ENTER();
|
||||
if (ret != 0) {
|
||||
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);
|
||||
|
||||
#if MICROPY_PY_UOS_STATVFS
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#define USE_STATFS 1
|
||||
#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);
|
||||
|
||||
#endif
|
||||
|
||||
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_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_rmdir), MP_ROM_PTR(&vfs_posix_rmdir_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) },
|
||||
#endif
|
||||
};
|
||||
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
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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
|
||||
#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
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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/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
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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 <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)
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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 "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)
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* 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
|
||||
#define MICROPY_INCLUDED_EXTMOD_VIRTPIN_H
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 2582575b500547f26dae04c83e540367c121c7b4
|
||||
Subproject commit 9ddd59650598b7a0641d70aabcc8aab71799cb93
|
@ -1 +1 @@
|
||||
Subproject commit f32e7b953ec93f71fcb292074b6d25c7c4355a88
|
||||
Subproject commit e07e1853d7e995b9797a064c098bccc5c384632e
|
@ -1 +1 @@
|
||||
Subproject commit 8455eb0b1f5be39638a88df84c9ab360f50ecc90
|
||||
Subproject commit b06b47037aed97475b1676b104d1f4b05c3f5e86
|
@ -1 +1 @@
|
||||
Subproject commit 14f5a0b957a11814339f0e22896243fecc9a78f2
|
||||
Subproject commit 9ace770b048be9ab0da4a154af279dbb643bbdb0
|
@ -1 +1 @@
|
||||
Subproject commit bdf4373d734a5c000ef500f70c94b5b24d2663af
|
||||
Subproject commit 47f848f13f75d2f62d16407edaaf6dd0ec1fc3cc
|
@ -1 +1 @@
|
||||
Subproject commit a1f66529437232d85dbbd3ce7d9688357966cc26
|
||||
Subproject commit a37c7cc83685f2ff84a171a519207567a75d0947
|
@ -1 +1 @@
|
||||
Subproject commit 547a7d2a738eeee18e511d71505a645915094395
|
||||
Subproject commit ab0ffa938dfa7eb1fd7260353a7a4e28f55e537a
|
@ -1 +1 @@
|
||||
Subproject commit fc3a6a651ee6211b02903ec0bc6808b359bf6d4b
|
||||
Subproject commit e6a9a0140ed44ef5f15d8040fce35b5319c1f216
|
@ -1 +1 @@
|
||||
Subproject commit 12beb94e4758d6d0f4965b731b086a1bf8c3704e
|
||||
Subproject commit cf2b173d0fc3ac2cd961754c6adf8f614a1c7c39
|
@ -1 +1 @@
|
||||
Subproject commit c8bc5431f9ac20ca5b40d0760ac407368d640c4d
|
||||
Subproject commit 911201504a269dbfc49b04ca59bc54adabd4716a
|
@ -1 +1 @@
|
||||
Subproject commit 67f8c35e2ce4a8abc3cfb24ab5029b40a64857b8
|
||||
Subproject commit 187279a95e5cdd634d233af59352558cea4c1227
|
@ -1 +1 @@
|
||||
Subproject commit c8bb6258a0444c31ab5ae69e3af1fffbd7761a99
|
||||
Subproject commit ee6bfcf9e676eb435c8890db37f07719984a60a1
|
@ -1 +1 @@
|
||||
Subproject commit bf7763ef99ca00d1808a9aa47bb1d593a2cc0334
|
||||
Subproject commit 8eedf860beca0d32219189b72ea6fc8eea7e66db
|
@ -1 +1 @@
|
||||
Subproject commit 5e4d371d210bbe00e63f83ce698f5bfa8652fa51
|
||||
Subproject commit 3d7d404a1cafc02f6c3391b100157490132e5c5f
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user