Merge remote-tracking branch 'adafruit/main' into update_tinyusb_abort

This commit is contained in:
Scott Shawcroft 2023-08-29 11:11:36 -07:00
commit f4dba86f1c
No known key found for this signature in database
GPG Key ID: 0DFD512649C052DA
1114 changed files with 17433 additions and 15688 deletions

View File

@ -20,3 +20,7 @@ deques
extint extint
shs shs
pass-thru pass-thru
numer
arithmetics
ftbfs
straightaway

View File

@ -1,3 +1,15 @@
#all: Reformat remaining C code that doesn't have a space after a comma.
5b700b0af90591d6b1a2c087bb8de6b7f1bfdd2d
# ports: Reformat more C and Python source code.
5c32111fa0e31e451b0f1666bdf926be2fdfd82c
# all: Update Python formatting to latest Black version 22.1.0.
ab2923dfa1174dc177f0a90cb00a7e4ff87958d2
# all: Update Python formatting to latest Black version 21.12b0.
3770fab33449a5dadf8eb06edfae0767e75320a6
# tools/gen-cpydiff.py: Fix formatting of doc strings for new Black. # tools/gen-cpydiff.py: Fix formatting of doc strings for new Black.
0f78c36c5aa458a954eed39a46942209107a553e 0f78c36c5aa458a954eed39a46942209107a553e

View File

@ -55,13 +55,11 @@ jobs:
run: | run: |
make -C examples/natmod/features1 make -C examples/natmod/features1
make -C examples/natmod/features2 make -C examples/natmod/features2
make -C examples/natmod/btree
make -C examples/natmod/framebuf
make -C examples/natmod/uheapq make -C examples/natmod/uheapq
make -C examples/natmod/urandom make -C examples/natmod/urandom
make -C examples/natmod/ure make -C examples/natmod/ure
make -C examples/natmod/uzlib make -C examples/natmod/uzlib
- name: Test native modules - name: Test native modules
if: matrix.test == 'all' 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 working-directory: tests

View File

@ -235,7 +235,7 @@ litex alpha
mimxrt10xx alpha mimxrt10xx alpha
nrf stable nrf stable
raspberrypi stable raspberrypi stable
efr32 alpha silabs (efr32) alpha
stm ``F4`` stable | ``others`` beta stm ``F4`` stable | ``others`` beta
unix alpha unix alpha
================ ============================================================ ================ ============================================================

19
conf.py
View File

@ -266,19 +266,9 @@ rst_epilog = """
# -- Options for HTML output ---------------------------------------------- # -- Options for HTML output ----------------------------------------------
# on_rtd is whether we are on readthedocs.org import sphinx_rtd_theme
on_rtd = os.environ.get('READTHEDOCS', None) == 'True' html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.']
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 = ['.']
# Theme options are theme-specific and customize the look and feel of a theme # 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 # 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. # 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), "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)} "typing": ('https://circuitpython.readthedocs.io/projects/adafruit-circuitpython-typing/en/latest/', None)}
# Adapted from sphinxcontrib-redirects # Adapted from sphinxcontrib-redirects

@ -1 +1 @@
Subproject commit 427cc923976229bcb981ca6f218ebe8efd636df6 Subproject commit d17b999f46fd148ac192ad692b8a4639f81add38

View File

@ -82,28 +82,23 @@ STATIC void add_generic_services(bleio_adapter_obj_t *adapter) {
// Generic Access Service setup. // Generic Access Service setup.
bleio_uuid_obj_t *generic_access_service_uuid = m_new_obj(bleio_uuid_obj_t); bleio_uuid_obj_t *generic_access_service_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
generic_access_service_uuid->base.type = &bleio_uuid_type;
common_hal_bleio_uuid_construct(generic_access_service_uuid, 0x1800, NULL); 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); bleio_uuid_obj_t *device_name_characteristic_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
device_name_characteristic_uuid->base.type = &bleio_uuid_type;
common_hal_bleio_uuid_construct(device_name_characteristic_uuid, 0x2A00, NULL); 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); bleio_uuid_obj_t *appearance_characteristic_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
appearance_characteristic_uuid->base.type = &bleio_uuid_type;
common_hal_bleio_uuid_construct(appearance_characteristic_uuid, 0x2A01, NULL); common_hal_bleio_uuid_construct(appearance_characteristic_uuid, 0x2A01, NULL);
// Not implemented: // Not implemented:
// Peripheral Preferred Connection Parameters // Peripheral Preferred Connection Parameters
// Central Address Resolution // Central Address Resolution
bleio_service_obj_t *generic_access_service = m_new_obj(bleio_service_obj_t); bleio_service_obj_t *generic_access_service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type);
generic_access_service->base.type = &bleio_service_type;
common_hal_bleio_service_construct(generic_access_service, generic_access_service_uuid, false); 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 = mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type);
adapter->device_name_characteristic->base.type = &bleio_characteristic_type;
char generic_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 'n', 'n', 'n', 'n' }; char generic_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 'n', 'n', 'n', 'n' };
mp_buffer_info_t generic_name_bufinfo = { 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), .len = sizeof(zero_16),
}; };
adapter->appearance_characteristic = m_new_obj(bleio_characteristic_obj_t); adapter->appearance_characteristic = mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type);
adapter->appearance_characteristic->base.type = &bleio_characteristic_type;
common_hal_bleio_characteristic_construct( common_hal_bleio_characteristic_construct(
adapter->appearance_characteristic, adapter->appearance_characteristic,
@ -151,20 +145,16 @@ STATIC void add_generic_services(bleio_adapter_obj_t *adapter) {
// Generic Attribute Service setup. // Generic Attribute Service setup.
bleio_uuid_obj_t *generic_attribute_service_uuid = m_new_obj(bleio_uuid_obj_t); bleio_uuid_obj_t *generic_attribute_service_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
generic_attribute_service_uuid->base.type = &bleio_uuid_type;
common_hal_bleio_uuid_construct(generic_attribute_service_uuid, 0x1801, NULL); 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); bleio_uuid_obj_t *service_changed_characteristic_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
service_changed_characteristic_uuid->base.type = &bleio_uuid_type;
common_hal_bleio_uuid_construct(service_changed_characteristic_uuid, 0x2A05, NULL); 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); bleio_service_obj_t *generic_attribute_service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type);
generic_attribute_service->base.type = &bleio_service_type;
common_hal_bleio_service_construct(generic_attribute_service, generic_attribute_service_uuid, false); 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 = mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type);
adapter->service_changed_characteristic->base.type = &bleio_characteristic_type;
uint32_t zero_32 = 0; uint32_t zero_32 = 0;
mp_buffer_info_t zero_32_value = { 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; bt_addr_t addr;
hci_check_error(hci_read_bd_addr(&addr)); hci_check_error(hci_read_bd_addr(&addr));
bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t); bleio_address_obj_t *address = mp_obj_malloc(bleio_address_obj_t, &bleio_address_type);
address->base.type = &bleio_address_type;
common_hal_bleio_address_construct(address, addr.val, BT_ADDR_LE_PUBLIC); common_hal_bleio_address_construct(address, addr.val, BT_ADDR_LE_PUBLIC);
return address; 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); 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; // 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; // ble_data_t * sd_data = (ble_data_t *) raw_data;
// self->scan_results->common_hal_data = sd_data; // self->scan_results->common_hal_data = sd_data;
// sd_data->len = max_packet_size; // sd_data->len = max_packet_size;

View File

@ -55,8 +55,7 @@ void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffe
self->characteristic = characteristic; self->characteristic = characteristic;
self->timeout_ms = timeout * 1000; self->timeout_ms = timeout * 1000;
// This is a macro. // This is a macro.
// true means long-lived, so it won't be moved. ringbuf_alloc(&self->ringbuf, buffer_size);
ringbuf_alloc(&self->ringbuf, buffer_size, true);
bleio_characteristic_set_observer(characteristic, self); bleio_characteristic_set_observer(characteristic, self);
} }

View File

@ -453,8 +453,7 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern
// for (size_t i = 0; i < response->count; ++i) { // for (size_t i = 0; i < response->count; ++i) {
// ble_gattc_service_t *gattc_service = &response->services[i]; // ble_gattc_service_t *gattc_service = &response->services[i];
// bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t); // bleio_service_obj_t *service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type);
// service->base.type = &bleio_service_type;
// // Initialize several fields at once. // // Initialize several fields at once.
// bleio_service_from_connection(service, bleio_connection_new_from_internal(connection)); // 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) { // if (gattc_service->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
// // Known service UUID. // // Known service UUID.
// bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); // bleio_uuid_obj_t *uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
// uuid->base.type = &bleio_uuid_type;
// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid); // bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid);
// service->uuid = uuid; // service->uuid = uuid;
// } else { // } 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) { // for (size_t i = 0; i < response->count; ++i) {
// ble_gattc_char_t *gattc_char = &response->chars[i]; // ble_gattc_char_t *gattc_char = &response->chars[i];
// bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t); // bleio_characteristic_obj_t *characteristic =
// characteristic->base.type = &bleio_characteristic_type; // mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type);
// bleio_uuid_obj_t *uuid = NULL; // bleio_uuid_obj_t *uuid = NULL;
// if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) { // if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
// // Known characteristic UUID. // // Known characteristic UUID.
// uuid = m_new_obj(bleio_uuid_obj_t); // uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
// uuid->base.type = &bleio_uuid_type;
// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid); // bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid);
// } else { // } else {
// // The discovery response contained a 128-bit UUID that has not yet been registered with the // // 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; // break;
// } // }
// bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t); // bleio_descriptor_obj_t *descriptor = mp_obj_malloc(bleio_descriptor_obj_t, &bleio_descriptor_type);
// descriptor->base.type = &bleio_descriptor_type;
// bleio_uuid_obj_t *uuid = NULL; // bleio_uuid_obj_t *uuid = NULL;
// if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) { // if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
// // Known descriptor UUID. // // Known descriptor UUID.
// uuid = m_new_obj(bleio_uuid_obj_t); // uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type);
// uuid->base.type = &bleio_uuid_type;
// bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid); // bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid);
// } else { // } else {
// // The discovery response contained a 128-bit UUID that has not yet been registered with the // // 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) { if (internal->connection_obj != mp_const_none) {
return internal->connection_obj; return internal->connection_obj;
} }
bleio_connection_obj_t *connection = m_new_obj(bleio_connection_obj_t); bleio_connection_obj_t *connection = mp_obj_malloc(bleio_connection_obj_t, &bleio_connection_type);
connection->base.type = &bleio_connection_type;
connection->connection = internal; connection->connection = internal;
internal->connection_obj = connection; internal->connection_obj = connection;

View File

@ -101,7 +101,7 @@ void common_hal_bleio_packet_buffer_construct(
} }
if (incoming) { 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")); 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->packet_queued = false;
self->pending_index = 0; self->pending_index = 0;
self->pending_size = 0; self->pending_size = 0;
self->outgoing[0] = m_malloc(max_packet_size, false); self->outgoing[0] = m_malloc(max_packet_size);
self->outgoing[1] = m_malloc(max_packet_size, false); self->outgoing[1] = m_malloc(max_packet_size);
} else { } else {
self->outgoing[0] = NULL; self->outgoing[0] = NULL;
self->outgoing[1] = NULL; self->outgoing[1] = NULL;

View File

@ -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)) { if (characteristic->props & (CHAR_PROP_NOTIFY | CHAR_PROP_INDICATE)) {
// We need a CCCD if this characteristic is doing notify or 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); bleio_descriptor_obj_t *cccd = mp_obj_malloc(bleio_descriptor_obj_t, &bleio_descriptor_type);
cccd->base.type = &bleio_descriptor_type;
uint16_t zero = 0; uint16_t zero = 0;
mp_buffer_info_t zero_cccd_value = { mp_buffer_info_t zero_cccd_value = {

View File

@ -19,6 +19,7 @@ Full Table of Contents
:caption: API and Usage :caption: API and Usage
../shared-bindings/index.rst ../shared-bindings/index.rst
library/index.rst
supported_ports.rst supported_ports.rst
troubleshooting.rst troubleshooting.rst
libraries.rst libraries.rst
@ -32,13 +33,12 @@ Full Table of Contents
design_guide design_guide
porting porting
common_hal common_hal
reference/mpyfiles.rst
reference/glossary.rst
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
:caption: MicroPython specific :caption: Python stand
library/index.rst
reference/glossary.rst
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1

View File

@ -1,10 +1,10 @@
:mod:`array` -- arrays of numeric data :mod:`array` -- arrays of numeric data
======================================= ======================================
.. module:: array .. module:: array
:synopsis: efficient arrays of numeric data :synopsis: efficient arrays of numeric data
|see_cpython_module| :mod:`cpython:array`. |see_cpython_module| :mod:`python:array`.
Supported format codes: ``b``, ``B``, ``h``, ``H``, ``i``, ``I``, ``l``, Supported format codes: ``b``, ``B``, ``h``, ``H``, ``i``, ``I``, ``l``,
``L``, ``q``, ``Q``, ``f``, ``d`` (the latter 2 depending on the ``L``, ``q``, ``Q``, ``f``, ``d`` (the latter 2 depending on the

View File

@ -1,10 +1,10 @@
:mod:`binascii` -- binary/ASCII conversions :mod:`binascii` -- binary/ASCII conversions
============================================ ===========================================
.. module:: binascii .. module:: binascii
:synopsis: binary/ASCII conversions :synopsis: binary/ASCII conversions
|see_cpython_module| :mod:`cpython:binascii`. |see_cpython_module| :mod:`python:binascii`.
This module implements conversions between binary data and various This module implements conversions between binary data and various
encodings of it in ASCII form (in both directions). encodings of it in ASCII form (in both directions).
@ -31,11 +31,11 @@ Functions
Conforms to `RFC 2045 s.6.8 <https://tools.ietf.org/html/rfc2045#section-6.8>`_. Conforms to `RFC 2045 s.6.8 <https://tools.ietf.org/html/rfc2045#section-6.8>`_.
Returns a bytes object. Returns a bytes object.
.. function:: b2a_base64(data) .. function:: b2a_base64(data, *, newline=True)
Encode binary data in base64 format, as in `RFC 3548 Encode binary data in base64 format, as in `RFC 3548
<https://tools.ietf.org/html/rfc3548.html>`_. Returns the encoded data <https://tools.ietf.org/html/rfc3548.html>`_. Returns the encoded data
followed by a newline character, as a bytes object. followed by a newline character if ``newline`` is true, as a bytes object.
.. function:: crc32(data, value=0, /) .. function:: crc32(data, value=0, /)

View File

@ -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.

View File

@ -33,7 +33,7 @@ Functions and types
.. class:: bytes() .. class:: bytes()
|see_cpython| `bytes`. |see_cpython| `python:bytes`.
.. function:: callable() .. function:: callable()
@ -68,7 +68,7 @@ Functions and types
.. class:: frozenset() .. class:: frozenset()
`frozenset()` is not enabled on non-Express CircuitPython boards. `frozenset()` is not enabled on the smallest CircuitPython boards for space reasons.
.. function:: getattr() .. function:: getattr()
@ -88,12 +88,12 @@ Functions and types
.. classmethod:: from_bytes(bytes, byteorder) .. classmethod:: from_bytes(bytes, byteorder)
In CircuitPython, ``byteorder`` parameter must be positional (this is In CircuitPython, the ``byteorder`` parameter must be positional (this is
compatible with CPython). compatible with CPython).
.. method:: to_bytes(size, byteorder) .. method:: to_bytes(size, byteorder)
In CircuitPython, ``byteorder`` parameter must be positional (this is In CircuitPython, the ``byteorder`` parameter must be positional (this is
compatible with CPython). compatible with CPython).
.. function:: isinstance() .. function:: isinstance()
@ -138,7 +138,7 @@ Functions and types
.. function:: reversed() .. function:: reversed()
`reversed()` is not enabled on non-Express CircuitPython boards. `reversed()` is not enabled on the smallest CircuitPython boards for space reasons.
.. function:: round() .. function:: round()
@ -224,10 +224,14 @@ Exceptions
.. exception:: SystemExit .. exception:: SystemExit
|see_cpython| `python:SystemExit`.
.. exception:: TimeoutError .. exception:: TimeoutError
.. exception:: TypeError .. exception:: TypeError
|see_cpython| `python:TypeError`.
.. exception:: UnicodeError .. exception:: UnicodeError
.. exception:: ValueError .. exception:: ValueError

View File

@ -1,12 +1,12 @@
:mod:`collections` -- collection and container types :mod:`collections` -- collection and container types
===================================================== ====================================================
.. include:: ../templates/unsupported_in_circuitpython.inc **Limitations:** Not implemented on the smallest CircuitPython boards for space reasons.
.. module:: collections .. module:: collections
:synopsis: collection and container types :synopsis: collection and container types
|see_cpython_module| :mod:`cpython:collections`. |see_cpython_module| :mod:`python:collections`.
This module implements advanced collection and container types to This module implements advanced collection and container types to
hold/accumulate various objects. hold/accumulate various objects.
@ -14,7 +14,7 @@ hold/accumulate various objects.
Classes Classes
------- -------
.. function:: deque(iterable, maxlen[, flags]) .. class:: deque(iterable, maxlen[, flags])
Deques (double-ended queues) are a list-like container that support O(1) Deques (double-ended queues) are a list-like container that support O(1)
appends and pops from either side of the deque. New deques are created appends and pops from either side of the deque. New deques are created
@ -59,7 +59,7 @@ Classes
print(t1.name) print(t1.name)
assert t2.name == t2[1] assert t2.name == t2[1]
.. function:: OrderedDict(...) .. class:: OrderedDict(...)
``dict`` type subclass which remembers and preserves the order of keys ``dict`` type subclass which remembers and preserves the order of keys
added. When ordered dict is iterated over, keys/items are returned in added. When ordered dict is iterated over, keys/items are returned in

View File

@ -4,10 +4,10 @@
.. module:: errno .. module:: errno
:synopsis: system error codes :synopsis: system error codes
|see_cpython_module| :mod:`cpython:errno`. |see_cpython_module| :mod:`python:errno`.
This module provides access to symbolic error codes for `OSError` exception. This module provides access to symbolic error codes for `OSError` exception.
A particular inventory of codes depends on :term:`MicroPython port`. The codes available may vary per CircuitPython build.
Constants Constants
--------- ---------
@ -15,14 +15,13 @@ Constants
.. data:: EEXIST, EAGAIN, etc. .. data:: EEXIST, EAGAIN, etc.
Error codes, based on ANSI C/POSIX standard. All error codes start with Error codes, based on ANSI C/POSIX standard. All error codes start with
"E". As mentioned above, inventory of the codes depends on "E". Errors are usually accessible as ``exc.errno``
:term:`MicroPython port`. Errors are usually accessible as ``exc.args[0]``
where ``exc`` is an instance of `OSError`. Usage example:: where ``exc`` is an instance of `OSError`. Usage example::
try: try:
os.mkdir("my_dir") os.mkdir("my_dir")
except OSError as exc: except OSError as exc:
if exc.args[0] == errno.EEXIST: if exc.errno == errno.EEXIST:
print("Directory already exists") print("Directory already exists")
.. data:: errorcode .. data:: errorcode

View File

@ -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

View File

@ -1,12 +1,10 @@
:mod:`gc` -- control the garbage collector :mod:`gc` -- control the garbage collector
========================================== ==========================================
.. include:: ../templates/unsupported_in_circuitpython.inc
.. module:: gc .. module:: gc
:synopsis: control the garbage collector :synopsis: control the garbage collector
|see_cpython_module| :mod:`cpython:gc`. |see_cpython_module| :mod:`python:gc`.
Functions Functions
--------- ---------
@ -63,6 +61,6 @@ Functions
.. admonition:: Difference to CPython .. admonition:: Difference to CPython
:class: attention :class: attention
This function is a a MicroPython extension. CPython has a similar This function is a MicroPython extension. CPython has a similar
function - ``set_threshold()``, but due to different GC function - ``set_threshold()``, but due to different GC
implementations, its signature and semantics are different. implementations, its signature and semantics are different.

View File

@ -6,7 +6,7 @@
.. module:: heapq .. module:: heapq
:synopsis: heap queue algorithm :synopsis: heap queue algorithm
|see_cpython_module| :mod:`cpython:heapq`. |see_cpython_module| :mod:`python:heapq`.
This module implements the This module implements the
`min heap queue algorithm <https://en.wikipedia.org/wiki/Heap_%28data_structure%29>`_. `min heap queue algorithm <https://en.wikipedia.org/wiki/Heap_%28data_structure%29>`_.

View File

@ -1,21 +1,19 @@
.. _micropython_lib: .. _micropython_lib:
MicroPython libraries Standard Libraries
===================== ==================
Python standard libraries and micro-libraries Python standard libraries
--------------------------------------------- -------------------------
The libraries below are inherited from MicroPython. The libraries below implement a subset of the corresponding
They are similar to the standard Python libraries with the same name. standard Python (CPython) library. They are implemented in C, not Python.
They implement a subset of or a variant of the corresponding
standard Python library.
CircuitPython's long-term goal is that code written in CircuitPython CircuitPython's long-term goal is that code written in CircuitPython
using Python standard libraries will be runnable on CPython without changes. using Python standard libraries will be runnable on CPython without changes.
These libraries are not enabled on CircuitPython builds with These libraries are not enabled on CircuitPython builds with
limited flash memory, usually on non-Express builds: limited flash memory:
``binascii``, ``errno``, ``json``, ``re``. ``binascii``, ``errno``, ``json``, ``re``.
These libraries are not currently enabled in any CircuitPython build, but may be in the future: These libraries are not currently enabled in any CircuitPython build, but may be in the future:
@ -38,11 +36,11 @@ These libraries are not currently enabled in any CircuitPython build, but may be
ctypes.rst ctypes.rst
select.rst select.rst
Omitted functions in the ``string`` library Omitted ``string`` functions
------------------------------------------- ----------------------------
A few string operations are not enabled on small builds A few string operations are not enabled on small builds
(usually non-Express), due to limited flash memory: due to limited flash memory:
``string.center()``, ``string.partition()``, ``string.splitlines()``, ``string.center()``, ``string.partition()``, ``string.splitlines()``,
``string.reversed()``. ``string.reversed()``.
@ -50,13 +48,10 @@ A few string operations are not enabled on small builds
CircuitPython/MicroPython-specific libraries CircuitPython/MicroPython-specific libraries
-------------------------------------------- --------------------------------------------
Functionality specific to the CircuitPython/MicroPython implementation is available in Functionality specific to the CircuitPython/MicroPython implementations is available in
the following libraries. These libraries may change significantly or be removed in future the following libraries.
versions of CircuitPython.
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
btree.rst
framebuf.rst
micropython.rst micropython.rst

View File

@ -1,10 +1,10 @@
:mod:`io` -- input/output streams :mod:`io` -- input/output streams
================================== =================================
.. module:: io .. module:: io
:synopsis: input/output streams :synopsis: input/output streams
|see_cpython_module| :mod:`cpython:io`. |see_cpython_module| :mod:`python:io`.
This module contains additional types of ``stream`` (file-like) objects This module contains additional types of ``stream`` (file-like) objects
and helper functions. and helper functions.
@ -112,3 +112,20 @@ Classes
.. method:: getvalue() .. method:: getvalue()
Get the current contents of the underlying buffer which holds data. Get the current contents of the underlying buffer which holds data.
.. class:: StringIO(alloc_size)
:noindex:
.. class:: BytesIO(alloc_size)
:noindex:
Create an empty `StringIO`/`BytesIO` object, preallocated to hold up
to *alloc_size* number of bytes. That means that writing that amount
of bytes won't lead to reallocation of the buffer, and thus won't hit
out-of-memory situation or lead to memory fragmentation. These constructors
are a MicroPython extension and are recommended for usage only in special
cases and in system-level libraries, not for end-user applications.
.. admonition:: Difference to CPython
:class: attention
These constructors are a MicroPython extension.

View File

@ -1,10 +1,10 @@
:mod:`json` -- JSON encoding and decoding :mod:`json` -- JSON encoding and decoding
========================================== =========================================
.. module:: json .. module:: json
:synopsis: JSON encoding and decoding :synopsis: JSON encoding and decoding
|see_cpython_module| :mod:`cpython:json`. |see_cpython_module| :mod:`python:json`.
This modules allows to convert between Python objects and the JSON This modules allows to convert between Python objects and the JSON
data format. data format.
@ -12,14 +12,20 @@ data format.
Functions Functions
--------- ---------
.. function:: dump(obj, stream) .. function:: dump(obj, stream, separators=None)
Serialise ``obj`` to a JSON string, writing it to the given *stream*. Serialise ``obj`` to a JSON string, writing it to the given *stream*.
.. function:: dumps(obj) If specified, separators should be an ``(item_separator, key_separator)``
tuple. The default is ``(', ', ': ')``. To get the most compact JSON
representation, you should specify ``(',', ':')`` to eliminate whitespace.
.. function:: dumps(obj, separators=None)
Return ``obj`` represented as a JSON string. Return ``obj`` represented as a JSON string.
The arguments have the same meaning as in `dump`.
.. function:: load(stream) .. function:: load(stream)
Parse the given ``stream``, interpreting it as a JSON string and Parse the given ``stream``, interpreting it as a JSON string and

View File

@ -1,7 +1,5 @@
:mod:`micropython` -- access and control MicroPython internals :mod:`micropython` -- MicroPython extensions and internals
============================================================== ==========================================================
.. include:: ../templates/unsupported_in_circuitpython.inc
.. module:: micropython .. module:: micropython
:synopsis: access and control MicroPython internals :synopsis: access and control MicroPython internals
@ -11,7 +9,7 @@ Functions
.. function:: const(expr) .. function:: const(expr)
Used to declare that the expression is a constant so that the compile can Used to declare that the expression is a constant so that the compiler can
optimise it. The use of this function should be as follows:: optimise it. The use of this function should be as follows::
from micropython import const from micropython import const
@ -28,111 +26,3 @@ Functions
provided as part of the :mod:`micropython` module mainly so that scripts can be provided as part of the :mod:`micropython` module mainly so that scripts can be
written which run under both CPython and MicroPython, by following the above written which run under both CPython and MicroPython, by following the above
pattern. pattern.
.. function:: opt_level([level])
If *level* is given then this function sets the optimisation level for subsequent
compilation of scripts, and returns ``None``. Otherwise it returns the current
optimisation level.
The optimisation level controls the following compilation features:
- Assertions: at level 0 assertion statements are enabled and compiled into the
bytecode; at levels 1 and higher assertions are not compiled.
- Built-in ``__debug__`` variable: at level 0 this variable expands to ``True``;
at levels 1 and higher it expands to ``False``.
- Source-code line numbers: at levels 0, 1 and 2 source-code line number are
stored along with the bytecode so that exceptions can report the line number
they occurred at; at levels 3 and higher line numbers are not stored.
The default optimisation level is usually level 0.
.. function:: mem_info([verbose])
Print information about currently used memory. If the *verbose* argument
is given then extra information is printed.
The information that is printed is implementation dependent, but currently
includes the amount of stack and heap used. In verbose mode it prints out
the entire heap indicating which blocks are used and which are free.
.. function:: qstr_info([verbose])
Print information about currently interned strings. If the *verbose*
argument is given then extra information is printed.
The information that is printed is implementation dependent, but currently
includes the number of interned strings and the amount of RAM they use. In
verbose mode it prints out the names of all RAM-interned strings.
.. function:: stack_use()
Return an integer representing the current amount of stack that is being
used. The absolute value of this is not particularly useful, rather it
should be used to compute differences in stack usage at different points.
.. function:: heap_lock()
.. function:: heap_unlock()
.. function:: heap_locked()
Lock or unlock the heap. When locked no memory allocation can occur and a
``MemoryError`` will be raised if any heap allocation is attempted.
`heap_locked()` returns a true value if the heap is currently locked.
These functions can be nested, ie `heap_lock()` can be called multiple times
in a row and the lock-depth will increase, and then `heap_unlock()` must be
called the same number of times to make the heap available again.
Both `heap_unlock()` and `heap_locked()` return the current lock depth
(after unlocking for the former) as a non-negative integer, with 0 meaning
the heap is not locked.
If the REPL becomes active with the heap locked then it will be forcefully
unlocked.
Note: `heap_locked()` is not enabled on most ports by default,
requires ``MICROPY_PY_MICROPYTHON_HEAP_LOCKED``.
.. function:: kbd_intr(chr)
Set the character that will raise a `KeyboardInterrupt` exception. By
default this is set to 3 during script execution, corresponding to Ctrl-C.
Passing -1 to this function will disable capture of Ctrl-C, and passing 3
will restore it.
This function can be used to prevent the capturing of Ctrl-C on the
incoming stream of characters that is usually used for the REPL, in case
that stream is used for other purposes.
.. function:: schedule(func, arg)
Schedule the function *func* to be executed "very soon". The function
is passed the value *arg* as its single argument. "Very soon" means that
the MicroPython runtime will do its best to execute the function at the
earliest possible time, given that it is also trying to be efficient, and
that the following conditions hold:
- A scheduled function will never preempt another scheduled function.
- Scheduled functions are always executed "between opcodes" which means
that all fundamental Python operations (such as appending to a list)
are guaranteed to be atomic.
- A given port may define "critical regions" within which scheduled
functions will never be executed. Functions may be scheduled within
a critical region but they will not be executed until that region
is exited. An example of a critical region is a preempting interrupt
handler (an IRQ).
A use for this function is to schedule a callback from a preempting IRQ.
Such an IRQ puts restrictions on the code that runs in the IRQ (for example
the heap may be locked) and scheduling a function to call later will lift
those restrictions.
Note: If `schedule()` is called from a preempting IRQ, when memory
allocation is not allowed and the callback to be passed to `schedule()` is
a bound method, passing this directly will fail. This is because creating a
reference to a bound method causes memory allocation. A solution is to
create a reference to the method in the class constructor and to pass that
reference to `schedule()`.
There is a finite queue to hold the scheduled functions and `schedule()`
will raise a `RuntimeError` if the queue is full.

View File

@ -1,10 +1,10 @@
:mod:`re` -- simple regular expressions :mod:`re` -- simple regular expressions
======================================== =======================================
.. module:: re .. module:: re
:synopsis: regular expressions :synopsis: regular expressions
|see_cpython_module| :mod:`cpython:re`. |see_cpython_module| :mod:`python:re`.
This module implements regular expression operations. Regular expression This module implements regular expression operations. Regular expression
syntax supported is a subset of CPython ``re`` module (and actually is syntax supported is a subset of CPython ``re`` module (and actually is

View File

@ -1,8 +1,6 @@
:mod:`select` -- wait for events on a set of streams :mod:`select` -- wait for events on a set of streams
==================================================== ====================================================
.. include:: ../templates/unsupported_in_circuitpython.inc
.. module:: select .. module:: select
:synopsis: wait for events on a set of streams :synopsis: wait for events on a set of streams
@ -86,7 +84,7 @@ Methods
.. method:: poll.ipoll(timeout=-1, flags=0, /) .. method:: poll.ipoll(timeout=-1, flags=0, /)
Like :meth:`poll.poll`, but instead returns an iterator which yields a Like :meth:`poll.poll`, but instead returns an iterator which yields a
``callee-owned tuples``. This function provides efficient, allocation-free "callee-owned tuple". This function provides an efficient, allocation-free
way to poll on streams. way to poll on streams.
If *flags* is 1, one-shot behaviour for events is employed: streams for If *flags* is 1, one-shot behaviour for events is employed: streams for

View File

@ -1,12 +1,10 @@
:mod:`sys` -- system specific functions :mod:`sys` -- system specific functions
======================================== =======================================
.. include:: ../templates/unsupported_in_circuitpython.inc
.. module:: sys .. module:: sys
:synopsis: system specific functions :synopsis: system specific functions
|see_cpython_module| :mod:`cpython:sys`. |see_cpython_module| :mod:`python:sys`.
Functions Functions
--------- ---------
@ -35,6 +33,7 @@ Constants
* *name* - string "circuitpython" * *name* - string "circuitpython"
* *version* - tuple (major, minor, micro), e.g. (1, 7, 0) * *version* - tuple (major, minor, micro), e.g. (1, 7, 0)
* *_mpy* - supported mpy file-format version (optional attribute)
This object is the recommended way to distinguish CircuitPython from other This object is the recommended way to distinguish CircuitPython from other
Python implementations (note that it still may not exist in the very Python implementations (note that it still may not exist in the very
@ -97,6 +96,12 @@ Constants
If you need to check whether your program runs on CircuitPython (vs other If you need to check whether your program runs on CircuitPython (vs other
Python implementation), use `sys.implementation` instead. Python implementation), use `sys.implementation` instead.
.. data:: ps1
ps2
Mutable attributes holding strings, which are used for the REPL prompt. The defaults
give the standard Python prompt of ``>>>`` and ``...``.
.. data:: stderr .. data:: stderr
Standard error ``stream``. Standard error ``stream``.
@ -109,6 +114,14 @@ Constants
Standard output ``stream``. Standard output ``stream``.
.. data:: tracebacklimit
A mutable attribute holding an integer value which is the maximum number of traceback
entries to store in an exception. Set to 0 to disable adding tracebacks. Defaults
to 1000.
Note: this is not available on all ports.
.. data:: version .. data:: version
Python language version that this implementation conforms to, as a string. Python language version that this implementation conforms to, as a string.

View File

@ -159,7 +159,7 @@ Glossary
typically accessible on a host PC via USB. typically accessible on a host PC via USB.
stream stream
Also known as a "file-like object". An Python object which provides Also known as a "file-like object". A Python object which provides
sequential read-write access to the underlying data. A stream object sequential read-write access to the underlying data. A stream object
implements a corresponding interface, which consists of methods like implements a corresponding interface, which consists of methods like
``read()``, ``write()``, ``readinto()``, ``seek()``, ``flush()``, ``read()``, ``write()``, ``readinto()``, ``seek()``, ``flush()``,

199
docs/reference/mpyfiles.rst Normal file
View 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.

View File

@ -1,6 +1,13 @@
# Derived from code on Eric Holscher's blog, found at: # Derived from code on Eric Holscher's blog, found at:
# https://www.ericholscher.com/blog/2016/jul/25/integrating-jinja-rst-sphinx/ # 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): def rstjinja(app, docname, source):
""" """
Render our pages as a jinja template for fancy templating goodness. 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"): if app.builder.format not in ("html", "latex"):
return return
# we only want our one jinja template to run through this func # we only want specific files to run through this func
if "shared-bindings/support_matrix" not in docname: if not render_with_jinja(docname, source):
return return
src = rendered = source[0] src = rendered = source[0]
print(docname) print(f"rendering {docname} as jinja templates")
if app.builder.format == "html": if app.builder.format == "html":
rendered = app.builder.templates.render_string( rendered = app.builder.templates.render_string(

View File

@ -69,28 +69,23 @@ ADDITIONAL_MODULES = {
"array": "CIRCUITPY_ARRAY", "array": "CIRCUITPY_ARRAY",
# always available, so depend on something that's always 1. # always available, so depend on something that's always 1.
"builtins": "CIRCUITPY", "builtins": "CIRCUITPY",
"builtins.pow3": "CIRCUITPY_BUILTINS_POW3",
"busio.SPI": "CIRCUITPY_BUSIO_SPI",
"busio.UART": "CIRCUITPY_BUSIO_UART",
"collections": "CIRCUITPY_COLLECTIONS", "collections": "CIRCUITPY_COLLECTIONS",
"fontio": "CIRCUITPY_DISPLAYIO", "fontio": "CIRCUITPY_DISPLAYIO",
"io": "CIRCUITPY_IO", "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", "select": "MICROPY_PY_USELECT_SELECT",
"terminalio": "CIRCUITPY_DISPLAYIO",
"sys": "CIRCUITPY_SYS", "sys": "CIRCUITPY_SYS",
"terminalio": "CIRCUITPY_DISPLAYIO",
"usb": "CIRCUITPY_USB_HOST", "usb": "CIRCUITPY_USB_HOST",
} }
MODULES_NOT_IN_BINDINGS = [ MODULES_NOT_IN_BINDINGS = [ "binascii", "errno", "json", "re", "ulab" ]
"_asyncio",
"array",
"binascii",
"builtins",
"collections",
"errno",
"json",
"re",
"select",
"sys",
"ulab",
]
FROZEN_EXCLUDES = ["examples", "docs", "tests", "utils", "conf.py", "setup.py"] FROZEN_EXCLUDES = ["examples", "docs", "tests", "utils", "conf.py", "setup.py"]
"""Files and dirs at the root of a frozen directory that should be ignored. """Files and dirs at the root of a frozen directory that should be ignored.
@ -117,7 +112,7 @@ def get_bindings():
bindings_modules = [] bindings_modules = []
for d in get_circuitpython_root_dir().glob("ports/*/bindings"): for d in get_circuitpython_root_dir().glob("ports/*/bindings"):
bindings_modules.extend(module.name for module in d.iterdir() if d.is_dir()) 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(): def get_board_mapping():

View File

@ -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

View File

@ -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
}

View File

@ -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)

View File

@ -1,13 +1,14 @@
# Location of top-level MicroPython directory # Location of top-level MicroPython directory
MPY_DIR = ../../.. MPY_DIR = ../../..
# Name of module (different to built-in framebuf so it can coexist) # Name of module
MOD = framebuf_$(ARCH) MOD = features3
# Source files (.c or .py) # Source files (.c or .py)
SRC = framebuf.c SRC = features3.c
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) # Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
ARCH = x64 ARCH = x64
# Include to get the rules for compiling and linking the module
include $(MPY_DIR)/py/dynruntime.mk include $(MPY_DIR)/py/dynruntime.mk

View 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
}

View File

@ -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
}

View File

@ -31,7 +31,4 @@ const mp_obj_module_t example_user_cmodule = {
}; };
// Register the module to make it available in Python. // Register the module to make it available in Python.
// Note: the "1" in the third argument means this module is always enabled. MP_REGISTER_MODULE(MP_QSTR_cexample, example_user_cmodule);
// 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);

View File

@ -22,7 +22,4 @@ const mp_obj_module_t cppexample_user_cmodule = {
}; };
// Register the module to make it available in Python. // Register the module to make it available in Python.
// Note: the "1" in the third argument means this module is always enabled. MP_REGISTER_MODULE(MP_QSTR_cppexample, cppexample_user_cmodule);
// 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);

View File

@ -6,7 +6,7 @@ SRC_USERMOD_CXX += $(CPPEXAMPLE_MOD_DIR)/example.cpp
# Add our module directory to the include path. # Add our module directory to the include path.
CFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR) 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. # We use C++ features so have to link against the standard library.
LDFLAGS_USERMOD += -lstdc++ LDFLAGS_USERMOD += -lstdc++

View File

@ -26,7 +26,11 @@
#ifndef AXTLS_OS_PORT_H #ifndef AXTLS_OS_PORT_H
#define AXTLS_OS_PORT_H #define AXTLS_OS_PORT_H
#ifndef __ets__
#include <arpa/inet.h>
#endif
#include <errno.h> #include <errno.h>
#include <sys/time.h>
#include "py/stream.h" #include "py/stream.h"
#include "lib/crypto-algorithms/sha256.h" #include "lib/crypto-algorithms/sha256.h"

View File

@ -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()

View File

@ -28,8 +28,6 @@ SRC_MOD += $(addprefix $(LITTLEFS_DIR)/,\
lfs1.c \ lfs1.c \
lfs1_util.c \ lfs1_util.c \
) )
else
CFLAGS_MOD += -DMICROPY_VFS_LFS1=0
endif endif
ifeq ($(MICROPY_VFS_LFS2),1) ifeq ($(MICROPY_VFS_LFS2),1)
@ -39,8 +37,6 @@ SRC_MOD += $(addprefix $(LITTLEFS_DIR)/,\
lfs2.c \ lfs2.c \
lfs2_util.c \ lfs2_util.c \
) )
else
CFLAGS_MOD += -DMICROPY_VFS_LFS2=0
$(BUILD)/$(LITTLEFS_DIR)/lfs2.o: CFLAGS += -Wno-missing-field-initializers $(BUILD)/$(LITTLEFS_DIR)/lfs2.o: CFLAGS += -Wno-missing-field-initializers
endif endif

View File

@ -1,108 +1,128 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) /*
// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H #ifndef MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H
#define MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H #define MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H
static const uint8_t font_petme128_8x8[] = { static const uint8_t font_petme128_8x8[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 32= 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 32=
0x00,0x00,0x00,0x4f,0x4f,0x00,0x00,0x00, // 33=! 0x00, 0x00, 0x00, 0x4f, 0x4f, 0x00, 0x00, 0x00, // 33=!
0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, // 34=" 0x00, 0x07, 0x07, 0x00, 0x00, 0x07, 0x07, 0x00, // 34="
0x14,0x7f,0x7f,0x14,0x14,0x7f,0x7f,0x14, // 35=# 0x14, 0x7f, 0x7f, 0x14, 0x14, 0x7f, 0x7f, 0x14, // 35=#
0x00,0x24,0x2e,0x6b,0x6b,0x3a,0x12,0x00, // 36=$ 0x00, 0x24, 0x2e, 0x6b, 0x6b, 0x3a, 0x12, 0x00, // 36=$
0x00,0x63,0x33,0x18,0x0c,0x66,0x63,0x00, // 37=% 0x00, 0x63, 0x33, 0x18, 0x0c, 0x66, 0x63, 0x00, // 37=%
0x00,0x32,0x7f,0x4d,0x4d,0x77,0x72,0x50, // 38=& 0x00, 0x32, 0x7f, 0x4d, 0x4d, 0x77, 0x72, 0x50, // 38=&
0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x00, // 39=' 0x00, 0x00, 0x00, 0x04, 0x06, 0x03, 0x01, 0x00, // 39='
0x00,0x00,0x1c,0x3e,0x63,0x41,0x00,0x00, // 40=( 0x00, 0x00, 0x1c, 0x3e, 0x63, 0x41, 0x00, 0x00, // 40=(
0x00,0x00,0x41,0x63,0x3e,0x1c,0x00,0x00, // 41=) 0x00, 0x00, 0x41, 0x63, 0x3e, 0x1c, 0x00, 0x00, // 41=)
0x08,0x2a,0x3e,0x1c,0x1c,0x3e,0x2a,0x08, // 42=* 0x08, 0x2a, 0x3e, 0x1c, 0x1c, 0x3e, 0x2a, 0x08, // 42=*
0x00,0x08,0x08,0x3e,0x3e,0x08,0x08,0x00, // 43=+ 0x00, 0x08, 0x08, 0x3e, 0x3e, 0x08, 0x08, 0x00, // 43=+
0x00,0x00,0x80,0xe0,0x60,0x00,0x00,0x00, // 44=, 0x00, 0x00, 0x80, 0xe0, 0x60, 0x00, 0x00, 0x00, // 44=,
0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, // 45=- 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, // 45=-
0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, // 46=. 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, // 46=.
0x00,0x40,0x60,0x30,0x18,0x0c,0x06,0x02, // 47=/ 0x00, 0x40, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, // 47=/
0x00,0x3e,0x7f,0x49,0x45,0x7f,0x3e,0x00, // 48=0 0x00, 0x3e, 0x7f, 0x49, 0x45, 0x7f, 0x3e, 0x00, // 48=0
0x00,0x40,0x44,0x7f,0x7f,0x40,0x40,0x00, // 49=1 0x00, 0x40, 0x44, 0x7f, 0x7f, 0x40, 0x40, 0x00, // 49=1
0x00,0x62,0x73,0x51,0x49,0x4f,0x46,0x00, // 50=2 0x00, 0x62, 0x73, 0x51, 0x49, 0x4f, 0x46, 0x00, // 50=2
0x00,0x22,0x63,0x49,0x49,0x7f,0x36,0x00, // 51=3 0x00, 0x22, 0x63, 0x49, 0x49, 0x7f, 0x36, 0x00, // 51=3
0x00,0x18,0x18,0x14,0x16,0x7f,0x7f,0x10, // 52=4 0x00, 0x18, 0x18, 0x14, 0x16, 0x7f, 0x7f, 0x10, // 52=4
0x00,0x27,0x67,0x45,0x45,0x7d,0x39,0x00, // 53=5 0x00, 0x27, 0x67, 0x45, 0x45, 0x7d, 0x39, 0x00, // 53=5
0x00,0x3e,0x7f,0x49,0x49,0x7b,0x32,0x00, // 54=6 0x00, 0x3e, 0x7f, 0x49, 0x49, 0x7b, 0x32, 0x00, // 54=6
0x00,0x03,0x03,0x79,0x7d,0x07,0x03,0x00, // 55=7 0x00, 0x03, 0x03, 0x79, 0x7d, 0x07, 0x03, 0x00, // 55=7
0x00,0x36,0x7f,0x49,0x49,0x7f,0x36,0x00, // 56=8 0x00, 0x36, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00, // 56=8
0x00,0x26,0x6f,0x49,0x49,0x7f,0x3e,0x00, // 57=9 0x00, 0x26, 0x6f, 0x49, 0x49, 0x7f, 0x3e, 0x00, // 57=9
0x00,0x00,0x00,0x24,0x24,0x00,0x00,0x00, // 58=: 0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x00, // 58=:
0x00,0x00,0x80,0xe4,0x64,0x00,0x00,0x00, // 59=; 0x00, 0x00, 0x80, 0xe4, 0x64, 0x00, 0x00, 0x00, // 59=;
0x00,0x08,0x1c,0x36,0x63,0x41,0x41,0x00, // 60=< 0x00, 0x08, 0x1c, 0x36, 0x63, 0x41, 0x41, 0x00, // 60=<
0x00,0x14,0x14,0x14,0x14,0x14,0x14,0x00, // 61== 0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, // 61==
0x00,0x41,0x41,0x63,0x36,0x1c,0x08,0x00, // 62=> 0x00, 0x41, 0x41, 0x63, 0x36, 0x1c, 0x08, 0x00, // 62=>
0x00,0x02,0x03,0x51,0x59,0x0f,0x06,0x00, // 63=? 0x00, 0x02, 0x03, 0x51, 0x59, 0x0f, 0x06, 0x00, // 63=?
0x00,0x3e,0x7f,0x41,0x4d,0x4f,0x2e,0x00, // 64=@ 0x00, 0x3e, 0x7f, 0x41, 0x4d, 0x4f, 0x2e, 0x00, // 64=@
0x00,0x7c,0x7e,0x0b,0x0b,0x7e,0x7c,0x00, // 65=A 0x00, 0x7c, 0x7e, 0x0b, 0x0b, 0x7e, 0x7c, 0x00, // 65=A
0x00,0x7f,0x7f,0x49,0x49,0x7f,0x36,0x00, // 66=B 0x00, 0x7f, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00, // 66=B
0x00,0x3e,0x7f,0x41,0x41,0x63,0x22,0x00, // 67=C 0x00, 0x3e, 0x7f, 0x41, 0x41, 0x63, 0x22, 0x00, // 67=C
0x00,0x7f,0x7f,0x41,0x63,0x3e,0x1c,0x00, // 68=D 0x00, 0x7f, 0x7f, 0x41, 0x63, 0x3e, 0x1c, 0x00, // 68=D
0x00,0x7f,0x7f,0x49,0x49,0x41,0x41,0x00, // 69=E 0x00, 0x7f, 0x7f, 0x49, 0x49, 0x41, 0x41, 0x00, // 69=E
0x00,0x7f,0x7f,0x09,0x09,0x01,0x01,0x00, // 70=F 0x00, 0x7f, 0x7f, 0x09, 0x09, 0x01, 0x01, 0x00, // 70=F
0x00,0x3e,0x7f,0x41,0x49,0x7b,0x3a,0x00, // 71=G 0x00, 0x3e, 0x7f, 0x41, 0x49, 0x7b, 0x3a, 0x00, // 71=G
0x00,0x7f,0x7f,0x08,0x08,0x7f,0x7f,0x00, // 72=H 0x00, 0x7f, 0x7f, 0x08, 0x08, 0x7f, 0x7f, 0x00, // 72=H
0x00,0x00,0x41,0x7f,0x7f,0x41,0x00,0x00, // 73=I 0x00, 0x00, 0x41, 0x7f, 0x7f, 0x41, 0x00, 0x00, // 73=I
0x00,0x20,0x60,0x41,0x7f,0x3f,0x01,0x00, // 74=J 0x00, 0x20, 0x60, 0x41, 0x7f, 0x3f, 0x01, 0x00, // 74=J
0x00,0x7f,0x7f,0x1c,0x36,0x63,0x41,0x00, // 75=K 0x00, 0x7f, 0x7f, 0x1c, 0x36, 0x63, 0x41, 0x00, // 75=K
0x00,0x7f,0x7f,0x40,0x40,0x40,0x40,0x00, // 76=L 0x00, 0x7f, 0x7f, 0x40, 0x40, 0x40, 0x40, 0x00, // 76=L
0x00,0x7f,0x7f,0x06,0x0c,0x06,0x7f,0x7f, // 77=M 0x00, 0x7f, 0x7f, 0x06, 0x0c, 0x06, 0x7f, 0x7f, // 77=M
0x00,0x7f,0x7f,0x0e,0x1c,0x7f,0x7f,0x00, // 78=N 0x00, 0x7f, 0x7f, 0x0e, 0x1c, 0x7f, 0x7f, 0x00, // 78=N
0x00,0x3e,0x7f,0x41,0x41,0x7f,0x3e,0x00, // 79=O 0x00, 0x3e, 0x7f, 0x41, 0x41, 0x7f, 0x3e, 0x00, // 79=O
0x00,0x7f,0x7f,0x09,0x09,0x0f,0x06,0x00, // 80=P 0x00, 0x7f, 0x7f, 0x09, 0x09, 0x0f, 0x06, 0x00, // 80=P
0x00,0x1e,0x3f,0x21,0x61,0x7f,0x5e,0x00, // 81=Q 0x00, 0x1e, 0x3f, 0x21, 0x61, 0x7f, 0x5e, 0x00, // 81=Q
0x00,0x7f,0x7f,0x19,0x39,0x6f,0x46,0x00, // 82=R 0x00, 0x7f, 0x7f, 0x19, 0x39, 0x6f, 0x46, 0x00, // 82=R
0x00,0x26,0x6f,0x49,0x49,0x7b,0x32,0x00, // 83=S 0x00, 0x26, 0x6f, 0x49, 0x49, 0x7b, 0x32, 0x00, // 83=S
0x00,0x01,0x01,0x7f,0x7f,0x01,0x01,0x00, // 84=T 0x00, 0x01, 0x01, 0x7f, 0x7f, 0x01, 0x01, 0x00, // 84=T
0x00,0x3f,0x7f,0x40,0x40,0x7f,0x3f,0x00, // 85=U 0x00, 0x3f, 0x7f, 0x40, 0x40, 0x7f, 0x3f, 0x00, // 85=U
0x00,0x1f,0x3f,0x60,0x60,0x3f,0x1f,0x00, // 86=V 0x00, 0x1f, 0x3f, 0x60, 0x60, 0x3f, 0x1f, 0x00, // 86=V
0x00,0x7f,0x7f,0x30,0x18,0x30,0x7f,0x7f, // 87=W 0x00, 0x7f, 0x7f, 0x30, 0x18, 0x30, 0x7f, 0x7f, // 87=W
0x00,0x63,0x77,0x1c,0x1c,0x77,0x63,0x00, // 88=X 0x00, 0x63, 0x77, 0x1c, 0x1c, 0x77, 0x63, 0x00, // 88=X
0x00,0x07,0x0f,0x78,0x78,0x0f,0x07,0x00, // 89=Y 0x00, 0x07, 0x0f, 0x78, 0x78, 0x0f, 0x07, 0x00, // 89=Y
0x00,0x61,0x71,0x59,0x4d,0x47,0x43,0x00, // 90=Z 0x00, 0x61, 0x71, 0x59, 0x4d, 0x47, 0x43, 0x00, // 90=Z
0x00,0x00,0x7f,0x7f,0x41,0x41,0x00,0x00, // 91=[ 0x00, 0x00, 0x7f, 0x7f, 0x41, 0x41, 0x00, 0x00, // 91=[
0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0x40, // 92='\' 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x40, // 92='\'
0x00,0x00,0x41,0x41,0x7f,0x7f,0x00,0x00, // 93=] 0x00, 0x00, 0x41, 0x41, 0x7f, 0x7f, 0x00, 0x00, // 93=]
0x00,0x08,0x0c,0x06,0x06,0x0c,0x08,0x00, // 94=^ 0x00, 0x08, 0x0c, 0x06, 0x06, 0x0c, 0x08, 0x00, // 94=^
0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, // 95=_ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, // 95=_
0x00,0x00,0x01,0x03,0x06,0x04,0x00,0x00, // 96=` 0x00, 0x00, 0x01, 0x03, 0x06, 0x04, 0x00, 0x00, // 96=`
0x00,0x20,0x74,0x54,0x54,0x7c,0x78,0x00, // 97=a 0x00, 0x20, 0x74, 0x54, 0x54, 0x7c, 0x78, 0x00, // 97=a
0x00,0x7f,0x7f,0x44,0x44,0x7c,0x38,0x00, // 98=b 0x00, 0x7f, 0x7f, 0x44, 0x44, 0x7c, 0x38, 0x00, // 98=b
0x00,0x38,0x7c,0x44,0x44,0x6c,0x28,0x00, // 99=c 0x00, 0x38, 0x7c, 0x44, 0x44, 0x6c, 0x28, 0x00, // 99=c
0x00,0x38,0x7c,0x44,0x44,0x7f,0x7f,0x00, // 100=d 0x00, 0x38, 0x7c, 0x44, 0x44, 0x7f, 0x7f, 0x00, // 100=d
0x00,0x38,0x7c,0x54,0x54,0x5c,0x58,0x00, // 101=e 0x00, 0x38, 0x7c, 0x54, 0x54, 0x5c, 0x58, 0x00, // 101=e
0x00,0x08,0x7e,0x7f,0x09,0x03,0x02,0x00, // 102=f 0x00, 0x08, 0x7e, 0x7f, 0x09, 0x03, 0x02, 0x00, // 102=f
0x00,0x98,0xbc,0xa4,0xa4,0xfc,0x7c,0x00, // 103=g 0x00, 0x98, 0xbc, 0xa4, 0xa4, 0xfc, 0x7c, 0x00, // 103=g
0x00,0x7f,0x7f,0x04,0x04,0x7c,0x78,0x00, // 104=h 0x00, 0x7f, 0x7f, 0x04, 0x04, 0x7c, 0x78, 0x00, // 104=h
0x00,0x00,0x00,0x7d,0x7d,0x00,0x00,0x00, // 105=i 0x00, 0x00, 0x00, 0x7d, 0x7d, 0x00, 0x00, 0x00, // 105=i
0x00,0x40,0xc0,0x80,0x80,0xfd,0x7d,0x00, // 106=j 0x00, 0x40, 0xc0, 0x80, 0x80, 0xfd, 0x7d, 0x00, // 106=j
0x00,0x7f,0x7f,0x30,0x38,0x6c,0x44,0x00, // 107=k 0x00, 0x7f, 0x7f, 0x30, 0x38, 0x6c, 0x44, 0x00, // 107=k
0x00,0x00,0x41,0x7f,0x7f,0x40,0x00,0x00, // 108=l 0x00, 0x00, 0x41, 0x7f, 0x7f, 0x40, 0x00, 0x00, // 108=l
0x00,0x7c,0x7c,0x18,0x30,0x18,0x7c,0x7c, // 109=m 0x00, 0x7c, 0x7c, 0x18, 0x30, 0x18, 0x7c, 0x7c, // 109=m
0x00,0x7c,0x7c,0x04,0x04,0x7c,0x78,0x00, // 110=n 0x00, 0x7c, 0x7c, 0x04, 0x04, 0x7c, 0x78, 0x00, // 110=n
0x00,0x38,0x7c,0x44,0x44,0x7c,0x38,0x00, // 111=o 0x00, 0x38, 0x7c, 0x44, 0x44, 0x7c, 0x38, 0x00, // 111=o
0x00,0xfc,0xfc,0x24,0x24,0x3c,0x18,0x00, // 112=p 0x00, 0xfc, 0xfc, 0x24, 0x24, 0x3c, 0x18, 0x00, // 112=p
0x00,0x18,0x3c,0x24,0x24,0xfc,0xfc,0x00, // 113=q 0x00, 0x18, 0x3c, 0x24, 0x24, 0xfc, 0xfc, 0x00, // 113=q
0x00,0x7c,0x7c,0x04,0x04,0x0c,0x08,0x00, // 114=r 0x00, 0x7c, 0x7c, 0x04, 0x04, 0x0c, 0x08, 0x00, // 114=r
0x00,0x48,0x5c,0x54,0x54,0x74,0x20,0x00, // 115=s 0x00, 0x48, 0x5c, 0x54, 0x54, 0x74, 0x20, 0x00, // 115=s
0x04,0x04,0x3f,0x7f,0x44,0x64,0x20,0x00, // 116=t 0x04, 0x04, 0x3f, 0x7f, 0x44, 0x64, 0x20, 0x00, // 116=t
0x00,0x3c,0x7c,0x40,0x40,0x7c,0x3c,0x00, // 117=u 0x00, 0x3c, 0x7c, 0x40, 0x40, 0x7c, 0x3c, 0x00, // 117=u
0x00,0x1c,0x3c,0x60,0x60,0x3c,0x1c,0x00, // 118=v 0x00, 0x1c, 0x3c, 0x60, 0x60, 0x3c, 0x1c, 0x00, // 118=v
0x00,0x1c,0x7c,0x30,0x18,0x30,0x7c,0x1c, // 119=w 0x00, 0x1c, 0x7c, 0x30, 0x18, 0x30, 0x7c, 0x1c, // 119=w
0x00,0x44,0x6c,0x38,0x38,0x6c,0x44,0x00, // 120=x 0x00, 0x44, 0x6c, 0x38, 0x38, 0x6c, 0x44, 0x00, // 120=x
0x00,0x9c,0xbc,0xa0,0xa0,0xfc,0x7c,0x00, // 121=y 0x00, 0x9c, 0xbc, 0xa0, 0xa0, 0xfc, 0x7c, 0x00, // 121=y
0x00,0x44,0x64,0x74,0x5c,0x4c,0x44,0x00, // 122=z 0x00, 0x44, 0x64, 0x74, 0x5c, 0x4c, 0x44, 0x00, // 122=z
0x00,0x08,0x08,0x3e,0x77,0x41,0x41,0x00, // 123={ 0x00, 0x08, 0x08, 0x3e, 0x77, 0x41, 0x41, 0x00, // 123={
0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00, // 124=| 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, // 124=|
0x00,0x41,0x41,0x77,0x3e,0x08,0x08,0x00, // 125=} 0x00, 0x41, 0x41, 0x77, 0x3e, 0x08, 0x08, 0x00, // 125=}
0x00,0x02,0x03,0x01,0x03,0x02,0x03,0x01, // 126=~ 0x00, 0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, // 126=~
0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55, // 127 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, // 127
}; };
#endif // MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H #endif // MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H

View File

@ -3,7 +3,8 @@
* *
* The MIT License (MIT) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -23,21 +24,25 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * 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 // This file contains cumulative declarations for extmod/ .
// heap.
#ifndef MICROPY_INCLUDED_PY_GC_LONG_LIVED_H #include <stddef.h>
#define MICROPY_INCLUDED_PY_GC_LONG_LIVED_H #include "py/runtime.h"
#include "py/objfun.h" MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_dupterm_obj);
#include "py/objproperty.h"
#include "py/objstr.h"
mp_obj_fun_bc_t *make_fun_bc_long_lived(mp_obj_fun_bc_t *fun_bc, uint8_t max_depth); #if MICROPY_PY_OS_DUPTERM
mp_obj_property_t *make_property_long_lived(mp_obj_property_t *prop, uint8_t max_depth); bool mp_uos_dupterm_is_builtin_stream(mp_const_obj_t stream);
mp_obj_dict_t *make_dict_long_lived(mp_obj_dict_t *dict, uint8_t max_depth); void mp_uos_dupterm_stream_detached_attached(mp_obj_t stream_detached, mp_obj_t stream_attached);
mp_obj_str_t *make_str_long_lived(mp_obj_str_t *str); uintptr_t mp_uos_dupterm_poll(uintptr_t poll_flags);
mp_obj_t make_obj_long_lived(mp_obj_t obj, uint8_t max_depth); 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -29,14 +29,14 @@
#include "py/pairheap.h" #include "py/pairheap.h"
#include "py/mphal.h" #include "py/mphal.h"
#if MICROPY_PY_UASYNCIO
#if CIRCUITPY && !(defined(__unix__) || defined(__APPLE__)) #if CIRCUITPY && !(defined(__unix__) || defined(__APPLE__))
#include "shared-bindings/supervisor/__init__.h" #include "shared-bindings/supervisor/__init__.h"
#endif #endif
#include "supervisor/shared/translate/translate.h" #include "supervisor/shared/translate/translate.h"
#if MICROPY_PY_UASYNCIO
// Used when task cannot be guaranteed to be non-NULL. // Used when task cannot be guaranteed to be non-NULL.
#define TASK_PAIRHEAP(task) ((task) ? &(task)->pairheap : 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 // Ticks for task ordering in pairing heap
// CIRCUITPY-style ticks
#define _TICKS_PERIOD (1lu << 29) #define _TICKS_PERIOD (1lu << 29)
#define _TICKS_MAX (_TICKS_PERIOD - 1) #define _TICKS_MAX (_TICKS_PERIOD - 1)
#define _TICKS_HALFPERIOD (_TICKS_PERIOD >> 1) #define _TICKS_HALFPERIOD (_TICKS_PERIOD >> 1)
@ -105,8 +106,7 @@ STATIC int task_lt(mp_pairheap_t *n1, mp_pairheap_t *n2) {
STATIC mp_obj_t task_queue_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { STATIC mp_obj_t task_queue_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
(void)args; (void)args;
mp_arg_check_num(n_args, n_kw, 0, 0, false); mp_arg_check_num(n_args, n_kw, 0, 0, false);
mp_obj_task_queue_t *self = m_new_obj(mp_obj_task_queue_t); mp_obj_task_queue_t *self = mp_obj_malloc(mp_obj_task_queue_t, type);
self->base.type = type;
self->heap = (mp_obj_task_t *)mp_pairheap_new(task_lt); self->heap = (mp_obj_task_t *)mp_pairheap_new(task_lt);
return MP_OBJ_FROM_PTR(self); return MP_OBJ_FROM_PTR(self);
} }
@ -121,7 +121,7 @@ STATIC mp_obj_t task_queue_peek(mp_obj_t self_in) {
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_peek_obj, task_queue_peek); STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_peek_obj, task_queue_peek);
STATIC mp_obj_t task_queue_push_sorted(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t task_queue_push(size_t n_args, const mp_obj_t *args) {
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(args[0]); mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(args[0]);
mp_obj_task_t *task = MP_OBJ_TO_PTR(args[1]); mp_obj_task_t *task = MP_OBJ_TO_PTR(args[1]);
task->data = mp_const_none; task->data = mp_const_none;
@ -134,9 +134,9 @@ STATIC mp_obj_t task_queue_push_sorted(size_t n_args, const mp_obj_t *args) {
self->heap = (mp_obj_task_t *)mp_pairheap_push(task_lt, TASK_PAIRHEAP(self->heap), TASK_PAIRHEAP(task)); self->heap = (mp_obj_task_t *)mp_pairheap_push(task_lt, TASK_PAIRHEAP(self->heap), TASK_PAIRHEAP(task));
return mp_const_none; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(task_queue_push_sorted_obj, 2, 3, task_queue_push_sorted); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(task_queue_push_obj, 2, 3, task_queue_push);
STATIC mp_obj_t task_queue_pop_head(mp_obj_t self_in) { STATIC mp_obj_t task_queue_pop(mp_obj_t self_in) {
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in);
mp_obj_task_t *head = (mp_obj_task_t *)mp_pairheap_peek(task_lt, &self->heap->pairheap); mp_obj_task_t *head = (mp_obj_task_t *)mp_pairheap_peek(task_lt, &self->heap->pairheap);
if (head == NULL) { if (head == NULL) {
@ -145,7 +145,7 @@ STATIC mp_obj_t task_queue_pop_head(mp_obj_t self_in) {
self->heap = (mp_obj_task_t *)mp_pairheap_pop(task_lt, &self->heap->pairheap); self->heap = (mp_obj_task_t *)mp_pairheap_pop(task_lt, &self->heap->pairheap);
return MP_OBJ_FROM_PTR(head); return MP_OBJ_FROM_PTR(head);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_pop_head_obj, task_queue_pop_head); STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_pop_obj, task_queue_pop);
STATIC mp_obj_t task_queue_remove(mp_obj_t self_in, mp_obj_t task_in) { STATIC mp_obj_t task_queue_remove(mp_obj_t self_in, mp_obj_t task_in) {
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in);
@ -157,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[] = { STATIC const mp_rom_map_elem_t task_queue_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_peek), MP_ROM_PTR(&task_queue_peek_obj) }, { MP_ROM_QSTR(MP_QSTR_peek), MP_ROM_PTR(&task_queue_peek_obj) },
{ MP_ROM_QSTR(MP_QSTR_push_sorted), MP_ROM_PTR(&task_queue_push_sorted_obj) }, { MP_ROM_QSTR(MP_QSTR_push), MP_ROM_PTR(&task_queue_push_obj) },
{ MP_ROM_QSTR(MP_QSTR_push_head), MP_ROM_PTR(&task_queue_push_sorted_obj) }, { MP_ROM_QSTR(MP_QSTR_pop), MP_ROM_PTR(&task_queue_pop_obj) },
{ MP_ROM_QSTR(MP_QSTR_pop_head), MP_ROM_PTR(&task_queue_pop_head_obj) },
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&task_queue_remove_obj) }, { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&task_queue_remove_obj) },
// 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); 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. // Not on the main running queue, remove the task from the queue it's on.
dest[2] = MP_OBJ_FROM_PTR(self); dest[2] = MP_OBJ_FROM_PTR(self);
mp_call_method_n_kw(1, 0, dest); mp_call_method_n_kw(1, 0, dest);
// _task_queue.push_head(self) // _task_queue.push(self)
dest[0] = _task_queue; dest[0] = _task_queue;
dest[1] = MP_OBJ_FROM_PTR(self); dest[1] = MP_OBJ_FROM_PTR(self);
task_queue_push_sorted(2, dest); task_queue_push(2, dest);
} else if (ticks_diff(self->ph_key, ticks()) > 0) { } else if (ticks_diff(self->ph_key, ticks()) > 0) {
// On the main running queue but scheduled in the future, so bring it forward to now. // On the main running queue but scheduled in the future, so bring it forward to now.
// _task_queue.remove(self) // _task_queue.remove(self)
task_queue_remove(_task_queue, MP_OBJ_FROM_PTR(self)); task_queue_remove(_task_queue, MP_OBJ_FROM_PTR(self));
// _task_queue.push_head(self) // _task_queue.push(self)
dest[0] = _task_queue; dest[0] = _task_queue;
dest[1] = MP_OBJ_FROM_PTR(self); dest[1] = MP_OBJ_FROM_PTR(self);
task_queue_push_sorted(2, dest); task_queue_push(2, dest);
} }
self->data = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_CancelledError)); self->data = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_CancelledError));
@ -243,6 +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); STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_cancel_obj, task_cancel);
// CIRCUITPY provides __await__().
STATIC mp_obj_t task_await(mp_obj_t self_in) { STATIC mp_obj_t task_await(mp_obj_t self_in) {
return task_getiter(self_in, NULL); return task_getiter(self_in, NULL);
} }
@ -266,6 +271,7 @@ STATIC void task_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
dest[1] = self_in; dest[1] = self_in;
} else if (attr == MP_QSTR_ph_key) { } else if (attr == MP_QSTR_ph_key) {
dest[0] = self->ph_key; dest[0] = self->ph_key;
// CIRCUITPY provides __await__().
} else if (attr == MP_QSTR___await__) { } else if (attr == MP_QSTR___await__) {
dest[0] = MP_OBJ_FROM_PTR(&task_await_obj); dest[0] = MP_OBJ_FROM_PTR(&task_await_obj);
dest[1] = self_in; dest[1] = self_in;
@ -291,6 +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) { } else if (self->state == TASK_STATE_RUNNING_NOT_WAITED_ON) {
// Allocate the waiting queue. // Allocate the waiting queue.
self->state = task_queue_make_new(&task_queue_type, 0, 0, NULL); self->state = task_queue_make_new(&task_queue_type, 0, 0, NULL);
} else if (mp_obj_get_type(self->state) != &task_queue_type) {
// Task has state used for another purpose, so can't also wait on it.
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("can't wait"));
} }
return self_in; return self_in;
} }
@ -298,6 +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) { STATIC mp_obj_t task_iternext(mp_obj_t self_in) {
mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in);
if (TASK_IS_DONE(self)) { if (TASK_IS_DONE(self)) {
// CIRCUITPY
if (self->data == mp_const_none) { if (self->data == mp_const_none) {
// Task finished but has already been sent to the loop's exception handler. // Task finished but has already been sent to the loop's exception handler.
mp_raise_StopIteration(MP_OBJ_NULL); mp_raise_StopIteration(MP_OBJ_NULL);
@ -309,7 +319,7 @@ STATIC mp_obj_t task_iternext(mp_obj_t self_in) {
// Put calling task on waiting queue. // Put calling task on waiting queue.
mp_obj_t cur_task = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task)); mp_obj_t cur_task = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task));
mp_obj_t args[2] = { self->state, cur_task }; mp_obj_t args[2] = { self->state, cur_task };
task_queue_push_sorted(2, args); task_queue_push(2, args);
// Set calling task's data to this task that it waits on, to double-link it. // Set calling task's data to this task that it waits on, to double-link it.
((mp_obj_task_t *)MP_OBJ_TO_PTR(cur_task))->data = self_in; ((mp_obj_task_t *)MP_OBJ_TO_PTR(cur_task))->data = self_in;
} }
@ -347,6 +357,6 @@ const mp_obj_module_t mp_module_uasyncio = {
.globals = (mp_obj_dict_t *)&mp_module_uasyncio_globals, .globals = (mp_obj_dict_t *)&mp_module_uasyncio_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR__asyncio, mp_module_uasyncio, MICROPY_PY_UASYNCIO); MP_REGISTER_MODULE(MP_QSTR__asyncio, mp_module_uasyncio);
#endif // MICROPY_PY_UASYNCIO #endif // MICROPY_PY_UASYNCIO

View File

@ -1,8 +1,28 @@
// Copyright (c) 2014 Paul Sokolovsky /*
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) * This file is part of the MicroPython project, http://micropython.org/
// SPDX-FileCopyrightText: 2022 Beat Ludin for Adafruit Industries *
// * The MIT License (MIT)
// SPDX-License-Identifier: MIT *
* Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
@ -13,6 +33,8 @@
#include "supervisor/shared/translate/translate.h" #include "supervisor/shared/translate/translate.h"
#if MICROPY_PY_UBINASCII
static void check_not_unicode(const mp_obj_t arg) { static void check_not_unicode(const mp_obj_t arg) {
#if MICROPY_CPYTHON_COMPAT #if MICROPY_CPYTHON_COMPAT
if (mp_obj_is_str(arg)) { if (mp_obj_is_str(arg)) {
@ -20,7 +42,6 @@ static void check_not_unicode(const mp_obj_t arg) {
} }
#endif #endif
} }
STATIC mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) {
// First argument is the data to convert. // First argument is the data to convert.
// Second argument is an optional separator to be used between values. // 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_DEFINE_CONST_FUN_OBJ_1(mod_binascii_a2b_base64_obj, mod_binascii_a2b_base64);
STATIC mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) { STATIC mp_obj_t mod_binascii_b2a_base64(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
check_not_unicode(data); enum { ARG_newline };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_newline, MP_ARG_BOOL, {.u_bool = true} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
uint8_t newline = args[ARG_newline].u_bool;
check_not_unicode(pos_args[0]);
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(pos_args[0], &bufinfo, MP_BUFFER_READ);
vstr_t vstr; vstr_t vstr;
vstr_init_len(&vstr, ((bufinfo.len != 0) ? (((bufinfo.len - 1) / 3) + 1) * 4 : 0) + 1); vstr_init_len(&vstr, ((bufinfo.len != 0) ? (((bufinfo.len - 1) / 3) + 1) * 4 : 0) + newline);
// First pass, we convert input buffer to numeric base 64 values // First pass, we convert input buffer to numeric base 64 values
byte *in = bufinfo.buf, *out = (byte *)vstr.buf; byte *in = bufinfo.buf, *out = (byte *)vstr.buf;
@ -186,7 +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 // Second pass, we convert number base 64 values to actual base64 ascii encoding
out = (byte *)vstr.buf; out = (byte *)vstr.buf;
for (mp_uint_t j = vstr.len - 1; j--;) { for (mp_uint_t j = vstr.len - newline; j--;) {
if (*out < 26) { if (*out < 26) {
*out += 'A'; *out += 'A';
} else if (*out < 52) { } else if (*out < 52) {
@ -202,10 +231,15 @@ STATIC mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
} }
out++; out++;
} }
*out = '\n'; if (newline) {
*out = '\n';
}
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_b2a_base64_obj, mod_binascii_b2a_base64); STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_binascii_b2a_base64_obj, 1, mod_binascii_b2a_base64);
// CIRCUITPY uses a self-contained implementation of CRC32,
// instead of depending on uzlib, like MicroPython.
/* /*
* CRC32 checksum * CRC32 checksum
@ -296,4 +330,6 @@ const mp_obj_module_t mp_module_ubinascii = {
.globals = (mp_obj_dict_t *)&mp_module_binascii_globals, .globals = (mp_obj_dict_t *)&mp_module_binascii_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_binascii, mp_module_ubinascii, MICROPY_PY_UBINASCII); MP_REGISTER_MODULE(MP_QSTR_binascii, mp_module_ubinascii);
#endif // MICROPY_PY_UBINASCII

View File

@ -1,7 +1,28 @@
// Copyright (c) 2014-2018 Paul Sokolovsky /*
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2014-2018 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -76,8 +97,7 @@ STATIC NORETURN void syntax_error(void) {
STATIC mp_obj_t uctypes_struct_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { STATIC mp_obj_t uctypes_struct_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 2, 3, false); mp_arg_check_num(n_args, n_kw, 2, 3, false);
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t); mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, type);
o->base.type = type;
o->addr = (void *)(uintptr_t)mp_obj_int_get_truncated(args[0]); o->addr = (void *)(uintptr_t)mp_obj_int_get_truncated(args[0]);
o->desc = args[1]; o->desc = args[1];
o->flags = LAYOUT_NATIVE; o->flags = LAYOUT_NATIVE;
@ -444,8 +464,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set
switch (agg_type) { switch (agg_type) {
case STRUCT: { case STRUCT: {
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t); mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type);
o->base.type = &uctypes_struct_type;
o->desc = sub->items[1]; o->desc = sub->items[1];
o->addr = self->addr + offset; o->addr = self->addr + offset;
o->flags = self->flags; o->flags = self->flags;
@ -460,8 +479,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set
MP_FALLTHROUGH MP_FALLTHROUGH
} }
case PTR: { case PTR: {
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t); mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type);
o->base.type = &uctypes_struct_type;
o->desc = MP_OBJ_FROM_PTR(sub); o->desc = MP_OBJ_FROM_PTR(sub);
o->addr = self->addr + offset; o->addr = self->addr + offset;
o->flags = self->flags; o->flags = self->flags;
@ -533,8 +551,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_ob
} else if (value == MP_OBJ_SENTINEL) { } else if (value == MP_OBJ_SENTINEL) {
mp_uint_t dummy = 0; mp_uint_t dummy = 0;
mp_uint_t size = uctypes_struct_size(t->items[2], self->flags, &dummy); mp_uint_t size = uctypes_struct_size(t->items[2], self->flags, &dummy);
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t); mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type);
o->base.type = &uctypes_struct_type;
o->desc = t->items[2]; o->desc = t->items[2];
o->addr = self->addr + size * index; o->addr = self->addr + size * index;
o->flags = self->flags; o->flags = self->flags;
@ -551,8 +568,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_ob
} else { } else {
mp_uint_t dummy = 0; mp_uint_t dummy = 0;
mp_uint_t size = uctypes_struct_size(t->items[1], self->flags, &dummy); mp_uint_t size = uctypes_struct_size(t->items[1], self->flags, &dummy);
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t); mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type);
o->base.type = &uctypes_struct_type;
o->desc = t->items[1]; o->desc = t->items[1];
o->addr = p + size * index; o->addr = p + size * index;
o->flags = self->flags; o->flags = self->flags;
@ -706,4 +722,6 @@ const mp_obj_module_t mp_module_uctypes = {
.globals = (mp_obj_dict_t *)&mp_module_uctypes_globals, .globals = (mp_obj_dict_t *)&mp_module_uctypes_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_uctypes, mp_module_uctypes);
#endif #endif

View File

@ -1,7 +1,28 @@
// Copyright (c) 2014 Paul Sokolovsky /*
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -39,7 +60,6 @@
#endif #endif
typedef struct _mp_obj_hash_t { typedef struct _mp_obj_hash_t {
mp_obj_base_t base; mp_obj_base_t base;
bool final; // if set, update and digest raise an exception bool final; // if set, update and digest raise an exception
@ -65,8 +85,7 @@ STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg);
STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context)); mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context), type);
o->base.type = type;
o->final = false; o->final = false;
mbedtls_sha256_init((mbedtls_sha256_context *)&o->state); mbedtls_sha256_init((mbedtls_sha256_context *)&o->state);
mbedtls_sha256_starts_ret((mbedtls_sha256_context *)&o->state, 0); mbedtls_sha256_starts_ret((mbedtls_sha256_context *)&o->state, 0);
@ -105,13 +124,11 @@ static void check_not_unicode(const mp_obj_t arg) {
#endif #endif
} }
#if MICROPY_PY_UHASHLIB_SHA256
#include "lib/crypto-algorithms/sha256.c" #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) { STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX)); mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX), type);
o->base.type = type;
o->final = false; o->final = false;
sha256_init((CRYAL_SHA256_CTX *)o->state); sha256_init((CRYAL_SHA256_CTX *)o->state);
if (n_args == 1) { if (n_args == 1) {
@ -159,16 +176,13 @@ STATIC const mp_obj_type_t uhashlib_sha256_type = {
}; };
#endif #endif
#endif
#if MICROPY_PY_UHASHLIB_SHA1 #if MICROPY_PY_UHASHLIB_SHA1
STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg); STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg);
#if MICROPY_SSL_AXTLS #if MICROPY_SSL_AXTLS
STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, kw_args, 0, 1, false); mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(SHA1_CTX)); mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(SHA1_CTX), type);
o->base.type = type;
o->final = false; o->final = false;
SHA1_Init((SHA1_CTX *)o->state); SHA1_Init((SHA1_CTX *)o->state);
if (n_args == 1) { if (n_args == 1) {
@ -178,7 +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) { STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) {
check_not_unicode(arg);
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self); uhashlib_ensure_not_final(self);
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
@ -208,8 +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) { STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha1_context)); mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_sha1_context), type);
o->base.type = type;
o->final = false; o->final = false;
mbedtls_sha1_init((mbedtls_sha1_context *)o->state); mbedtls_sha1_init((mbedtls_sha1_context *)o->state);
mbedtls_sha1_starts_ret((mbedtls_sha1_context *)o->state); mbedtls_sha1_starts_ret((mbedtls_sha1_context *)o->state);
@ -263,8 +275,7 @@ STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg);
#if MICROPY_SSL_AXTLS #if MICROPY_SSL_AXTLS
STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(MD5_CTX)); mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(MD5_CTX), type);
o->base.type = type;
o->final = false; o->final = false;
MD5_Init((MD5_CTX *)o->state); MD5_Init((MD5_CTX *)o->state);
if (n_args == 1) { if (n_args == 1) {
@ -303,8 +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) { STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_md5_context)); mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_md5_context), type);
o->base.type = type;
o->final = false; o->final = false;
mbedtls_md5_init((mbedtls_md5_context *)o->state); mbedtls_md5_init((mbedtls_md5_context *)o->state);
mbedtls_md5_starts_ret((mbedtls_md5_context *)o->state); mbedtls_md5_starts_ret((mbedtls_md5_context *)o->state);
@ -372,4 +382,6 @@ const mp_obj_module_t mp_module_uhashlib = {
.globals = (mp_obj_dict_t *)&mp_module_uhashlib_globals, .globals = (mp_obj_dict_t *)&mp_module_uhashlib_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_hashlib, mp_module_uhashlib);
#endif // MICROPY_PY_UHASHLIB #endif // MICROPY_PY_UHASHLIB

View File

@ -1,7 +1,28 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) /*
// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2014 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/objlist.h" #include "py/objlist.h"
#include "py/runtime.h" #include "py/runtime.h"
@ -98,6 +119,8 @@ const mp_obj_module_t mp_module_uheapq = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_uheapq_globals, .globals = (mp_obj_dict_t *)&mp_module_uheapq_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_heapq, mp_module_uheapq);
#endif #endif
#endif // MICROPY_PY_UHEAPQ #endif // MICROPY_PY_UHEAPQ

View File

@ -1,7 +1,28 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) /*
// SPDX-FileCopyrightText: Copyright (c) 2014-2019 Damien P. George * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2014-2019 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h> #include <stdio.h>
@ -112,6 +133,7 @@ typedef struct _ujson_stream_t {
mp_obj_t stream_obj; mp_obj_t stream_obj;
mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode); mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode);
int errcode; int errcode;
// CIRCUITPY
mp_obj_t python_readinto[2 + 1]; mp_obj_t python_readinto[2 + 1];
mp_obj_array_t bytearray_obj; mp_obj_array_t bytearray_obj;
size_t start; size_t start;
@ -136,6 +158,8 @@ STATIC byte ujson_stream_next(ujson_stream_t *s) {
return s->cur; return s->cur;
} }
// CIRCUITPY
// We read from an object's `readinto` method in chunks larger than the json // We read from an object's `readinto` method in chunks larger than the json
// parser needs to reduce the number of function calls done. // parser needs to reduce the number of function calls done.
@ -375,6 +399,8 @@ STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) {
} }
} }
success: success:
// CIRCUITPY
// It is legal for a stream to have contents after JSON. // It is legal for a stream to have contents after JSON.
// E.g., A UART is not closed after receiving an object; in load() we will // E.g., A UART is not closed after receiving an object; in load() we will
// return the first complete JSON object, while in loads() we will retain // return the first complete JSON object, while in loads() we will retain
@ -432,6 +458,6 @@ const mp_obj_module_t mp_module_ujson = {
.globals = (mp_obj_dict_t *)&mp_module_ujson_globals, .globals = (mp_obj_dict_t *)&mp_module_ujson_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_json, mp_module_ujson, MICROPY_PY_UJSON); MP_REGISTER_MODULE(MP_QSTR_json, mp_module_ujson);
#endif // MICROPY_PY_UJSON #endif // MICROPY_PY_UJSON

186
extmod/moduos.c Normal file
View 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

View File

@ -29,87 +29,19 @@
#include "py/objtuple.h" #include "py/objtuple.h"
#include "py/objstr.h" #include "py/objstr.h"
#include "py/mphal.h" #include "py/mphal.h"
#include "extmod/moduplatform.h"
#include "genhdr/mpversion.h" #include "genhdr/mpversion.h"
#if MICROPY_PY_UPLATFORM #if MICROPY_PY_UPLATFORM
// platform - Access to underlying platform's identifying data // platform - Access to underlying platform's identifying data
// TODO: Add more architectures, compilers and libraries. STATIC const MP_DEFINE_STR_OBJ(info_platform_obj, MICROPY_PLATFORM_SYSTEM "-" \
// See: https://sourceforge.net/p/predef/wiki/Home/ MICROPY_VERSION_STRING "-" MICROPY_PLATFORM_ARCH "-" MICROPY_PLATFORM_VERSION "-with-" \
MICROPY_PLATFORM_LIBC_LIB "" MICROPY_PLATFORM_LIBC_VER);
#if defined(__ARM_ARCH) STATIC const MP_DEFINE_STR_OBJ(info_python_compiler_obj, MICROPY_PLATFORM_COMPILER);
#define PLATFORM_ARCH "arm" STATIC const MP_DEFINE_STR_OBJ(info_libc_lib_obj, MICROPY_PLATFORM_LIBC_LIB);
#elif defined(__x86_64__) || defined(_WIN64) STATIC const MP_DEFINE_STR_OBJ(info_libc_ver_obj, MICROPY_PLATFORM_LIBC_VER);
#define PLATFORM_ARCH "x86_64"
#elif defined(__i386__) || defined(_M_IX86)
#define PLATFORM_ARCH "x86"
#elif defined(__xtensa__) || defined(_M_IX86)
#define PLATFORM_ARCH "xtensa"
#else
#define PLATFORM_ARCH ""
#endif
#if defined(__GNUC__)
#define PLATFORM_COMPILER \
"GCC " \
MP_STRINGIFY(__GNUC__) "." \
MP_STRINGIFY(__GNUC_MINOR__) "." \
MP_STRINGIFY(__GNUC_PATCHLEVEL__)
#elif defined(__ARMCC_VERSION)
#define PLATFORM_COMPILER \
"ARMCC " \
MP_STRINGIFY((__ARMCC_VERSION / 1000000)) "." \
MP_STRINGIFY((__ARMCC_VERSION / 10000 % 100)) "." \
MP_STRINGIFY((__ARMCC_VERSION % 10000))
#elif defined(_MSC_VER)
#if defined(_WIN64)
#define COMPILER_BITS "64 bit"
#elif defined(_M_IX86)
#define COMPILER_BITS "32 bit"
#else
#define COMPILER_BITS ""
#endif
#define PLATFORM_COMPILER \
"MSC v." MP_STRINGIFY(_MSC_VER) " " COMPILER_BITS
#else
#define PLATFORM_COMPILER ""
#endif
#if defined(__GLIBC__)
#define PLATFORM_LIBC_LIB "glibc"
#define PLATFORM_LIBC_VER \
MP_STRINGIFY(__GLIBC__) "." \
MP_STRINGIFY(__GLIBC_MINOR__)
#elif defined(__NEWLIB__)
#define PLATFORM_LIBC_LIB "newlib"
#define PLATFORM_LIBC_VER _NEWLIB_VERSION
#else
#define PLATFORM_LIBC_LIB ""
#define PLATFORM_LIBC_VER ""
#endif
#if defined(__linux)
#define PLATFORM_SYSTEM "Linux"
#elif defined(__unix__)
#define PLATFORM_SYSTEM "Unix"
#elif defined(__CYGWIN__)
#define PLATFORM_SYSTEM "Cygwin"
#elif defined(_WIN32)
#define PLATFORM_SYSTEM "Windows"
#else
#define PLATFORM_SYSTEM "MicroPython"
#endif
#ifndef MICROPY_PLATFORM_VERSION
#define MICROPY_PLATFORM_VERSION ""
#endif
STATIC const MP_DEFINE_STR_OBJ(info_platform_obj, PLATFORM_SYSTEM "-" MICROPY_VERSION_STRING "-" \
PLATFORM_ARCH "-" MICROPY_PLATFORM_VERSION "-with-" PLATFORM_LIBC_LIB "" PLATFORM_LIBC_VER);
STATIC const MP_DEFINE_STR_OBJ(info_python_compiler_obj, PLATFORM_COMPILER);
STATIC const MP_DEFINE_STR_OBJ(info_libc_lib_obj, PLATFORM_LIBC_LIB);
STATIC const MP_DEFINE_STR_OBJ(info_libc_ver_obj, PLATFORM_LIBC_VER);
STATIC const mp_rom_obj_tuple_t info_libc_tuple_obj = { STATIC const mp_rom_obj_tuple_t info_libc_tuple_obj = {
{&mp_type_tuple}, 2, {MP_ROM_PTR(&info_libc_lib_obj), MP_ROM_PTR(&info_libc_ver_obj)} {&mp_type_tuple}, 2, {MP_ROM_PTR(&info_libc_lib_obj), MP_ROM_PTR(&info_libc_ver_obj)}
}; };
@ -143,4 +75,6 @@ const mp_obj_module_t mp_module_uplatform = {
.globals = (mp_obj_dict_t *)&modplatform_globals, .globals = (mp_obj_dict_t *)&modplatform_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_platform, mp_module_uplatform);
#endif // MICROPY_PY_UPLATFORM #endif // MICROPY_PY_UPLATFORM

105
extmod/moduplatform.h Normal file
View 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

View File

@ -1,7 +1,28 @@
// Copyright (c) 2016 Paul Sokolovsky /*
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2016 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -195,7 +216,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_urandom_uniform_obj, mod_urandom_uniform);
#endif // MICROPY_PY_URANDOM_EXTRA_FUNCS #endif // MICROPY_PY_URANDOM_EXTRA_FUNCS
#if SEED_ON_IMPORT #if SEED_ON_IMPORT
STATIC mp_obj_t mod_urandom___init__() { STATIC mp_obj_t mod_urandom___init__(void) {
// This module may be imported by more than one name so need to ensure // This module may be imported by more than one name so need to ensure
// that it's only ever seeded once. // that it's only ever seeded once.
static bool seeded = false; static bool seeded = false;
@ -233,6 +254,8 @@ const mp_obj_module_t mp_module_urandom = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_urandom_globals, .globals = (mp_obj_dict_t *)&mp_module_urandom_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_random, mp_module_urandom);
#endif #endif
#endif // MICROPY_PY_URANDOM #endif // MICROPY_PY_URANDOM

View File

@ -1,7 +1,28 @@
// Copyright (c) 2014 Paul Sokolovsky /*
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2014 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
@ -18,6 +39,7 @@
#include "lib/re1.5/re1.5.h" #include "lib/re1.5/re1.5.h"
// CIRCUITPY
#if MICROPY_PY_URE_DEBUG #if MICROPY_PY_URE_DEBUG
#define FLAG_DEBUG 0x1000 #define FLAG_DEBUG 0x1000
#endif #endif
@ -168,7 +190,7 @@ STATIC mp_obj_t ure_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
} }
Subject subj; Subject subj;
size_t len; size_t len;
subj.begin = mp_obj_str_get_data(args[1], &len); subj.begin_line = subj.begin = mp_obj_str_get_data(args[1], &len);
subj.end = subj.begin + len; subj.end = subj.begin + len;
#if MICROPY_PY_URE_MATCH_SPAN_START_END && !(defined(MICROPY_ENABLE_DYNRUNTIME) && MICROPY_ENABLE_DYNRUNTIME) #if MICROPY_PY_URE_MATCH_SPAN_START_END && !(defined(MICROPY_ENABLE_DYNRUNTIME) && MICROPY_ENABLE_DYNRUNTIME)
@ -231,7 +253,7 @@ STATIC mp_obj_t re_split(size_t n_args, const mp_obj_t *args) {
Subject subj; Subject subj;
size_t len; size_t len;
const mp_obj_type_t *str_type = mp_obj_get_type(args[1]); const mp_obj_type_t *str_type = mp_obj_get_type(args[1]);
subj.begin = mp_obj_str_get_data(args[1], &len); subj.begin_line = subj.begin = mp_obj_str_get_data(args[1], &len);
subj.end = subj.begin + len; subj.end = subj.begin + len;
int caps_num = (self->re.sub + 1) * 2; int caps_num = (self->re.sub + 1) * 2;
@ -291,7 +313,7 @@ STATIC mp_obj_t re_sub_helper(size_t n_args, const mp_obj_t *args) {
size_t where_len; size_t where_len;
const char *where_str = mp_obj_str_get_data(where, &where_len); const char *where_str = mp_obj_str_get_data(where, &where_len);
Subject subj; Subject subj;
subj.begin = where_str; subj.begin_line = subj.begin = where_str;
subj.end = subj.begin + where_len; subj.end = subj.begin + where_len;
int caps_num = (self->re.sub + 1) * 2; int caps_num = (self->re.sub + 1) * 2;
@ -421,8 +443,7 @@ STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) {
if (size == -1) { if (size == -1) {
goto error; goto error;
} }
mp_obj_re_t *o = m_new_obj_var(mp_obj_re_t, char, size); mp_obj_re_t *o = mp_obj_malloc_var(mp_obj_re_t, char, size, &re_type);
o->base.type = &re_type;
#if MICROPY_PY_URE_DEBUG #if MICROPY_PY_URE_DEBUG
int flags = 0; int flags = 0;
if (n_args > 1) { if (n_args > 1) {
@ -470,7 +491,7 @@ const mp_obj_module_t mp_module_ure = {
.globals = (mp_obj_dict_t *)&mp_module_re_globals, .globals = (mp_obj_dict_t *)&mp_module_re_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_re, mp_module_ure, MICROPY_PY_URE); MP_REGISTER_MODULE(MP_QSTR_re, mp_module_ure);
#endif #endif
// Source files #include'd here to make sure they're compiled in // Source files #include'd here to make sure they're compiled in

View File

@ -1,8 +1,29 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) /*
// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George * This file is part of the MicroPython project, http://micropython.org/
// SPDX-FileCopyrightText: Copyright (c) 2015-2017 Paul Sokolovsky *
// * The MIT License (MIT)
// SPDX-License-Identifier: MIT *
* Copyright (c) 2014 Damien P. George
* Copyright (c) 2015-2017 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/mpconfig.h" #include "py/mpconfig.h"
#if MICROPY_PY_USELECT #if MICROPY_PY_USELECT
@ -151,6 +172,7 @@ STATIC mp_obj_t select_select(size_t n_args, const mp_obj_t *args) {
mp_map_deinit(&poll_map); mp_map_deinit(&poll_map);
return mp_obj_new_tuple(3, list_array); return mp_obj_new_tuple(3, list_array);
} }
// CIRCUITPY
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
} }
} }
@ -230,6 +252,7 @@ STATIC mp_uint_t poll_poll_internal(uint n_args, const mp_obj_t *args) {
if (n_ready > 0 || (timeout != (mp_uint_t)-1 && mp_hal_ticks_ms() - start_tick >= timeout)) { if (n_ready > 0 || (timeout != (mp_uint_t)-1 && mp_hal_ticks_ms() - start_tick >= timeout)) {
break; break;
} }
// CIRCUITPY
RUN_BACKGROUND_TASKS; RUN_BACKGROUND_TASKS;
if (mp_hal_is_interrupted()) { if (mp_hal_is_interrupted()) {
return 0; return 0;
@ -333,8 +356,7 @@ STATIC const mp_obj_type_t mp_type_poll = {
// poll() // poll()
STATIC mp_obj_t select_poll(void) { STATIC mp_obj_t select_poll(void) {
mp_obj_poll_t *poll = m_new_obj(mp_obj_poll_t); mp_obj_poll_t *poll = mp_obj_malloc(mp_obj_poll_t, &mp_type_poll);
poll->base.type = &mp_type_poll;
mp_map_init(&poll->poll_map, 0); mp_map_init(&poll->poll_map, 0);
poll->iter_cnt = 0; poll->iter_cnt = 0;
poll->ret_tuple = MP_OBJ_NULL; poll->ret_tuple = MP_OBJ_NULL;
@ -361,6 +383,6 @@ const mp_obj_module_t mp_module_uselect = {
.globals = (mp_obj_dict_t *)&mp_module_select_globals, .globals = (mp_obj_dict_t *)&mp_module_select_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_select, mp_module_uselect, MICROPY_PY_USELECT); MP_REGISTER_MODULE(MP_QSTR_select, mp_module_uselect);
#endif // MICROPY_PY_USELECT #endif // MICROPY_PY_USELECT

View File

@ -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

View File

@ -1,7 +1,28 @@
// Copyright (c) 2014-2016 Paul Sokolovsky /*
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2014-2016 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -51,15 +72,14 @@ STATIC int read_src_stream(TINF_DATA *data) {
STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, 2, false); mp_arg_check_num(n_args, n_kw, 1, 2, false);
mp_get_stream_raise(args[0], MP_STREAM_OP_READ); mp_get_stream_raise(args[0], MP_STREAM_OP_READ);
mp_obj_decompio_t *o = m_new_obj(mp_obj_decompio_t); mp_obj_decompio_t *o = mp_obj_malloc(mp_obj_decompio_t, type);
o->base.type = type;
memset(&o->decomp, 0, sizeof(o->decomp)); memset(&o->decomp, 0, sizeof(o->decomp));
o->decomp.readSource = read_src_stream; o->decomp.readSource = read_src_stream;
o->src_stream = args[0]; o->src_stream = args[0];
o->eof = false; o->eof = false;
mp_int_t dict_opt = 0; mp_int_t dict_opt = 0;
int dict_sz; uint dict_sz;
if (n_args > 1) { if (n_args > 1) {
dict_opt = mp_obj_get_int(args[1]); dict_opt = mp_obj_get_int(args[1]);
} }
@ -76,7 +96,10 @@ STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size
header_error: header_error:
mp_raise_ValueError(MP_ERROR_TEXT("compression header")); mp_raise_ValueError(MP_ERROR_TEXT("compression header"));
} }
dict_sz = 1 << dict_opt; // RFC 1950 section 2.2:
// CINFO is the base-2 logarithm of the LZ77 window size,
// minus eight (CINFO=7 indicates a 32K window size)
dict_sz = 1 << (dict_opt + 8);
} else { } else {
dict_sz = 1 << -dict_opt; dict_sz = 1 << -dict_opt;
} }
@ -92,12 +115,13 @@ STATIC mp_uint_t decompio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *er
} }
o->decomp.dest = buf; o->decomp.dest = buf;
o->decomp.dest_limit = (unsigned char *)buf + size; o->decomp.dest_limit = (byte *)buf + size;
int st = uzlib_uncompress_chksum(&o->decomp); int st = uzlib_uncompress_chksum(&o->decomp);
if (st == TINF_DONE) { if (st == TINF_DONE) {
o->eof = true; o->eof = true;
} }
if (st < 0) { if (st < 0) {
DEBUG_printf("uncompress error=" INT_FMT "\n", st);
*errcode = MP_EINVAL; *errcode = MP_EINVAL;
return MP_STREAM_ERROR; return MP_STREAM_ERROR;
} }
@ -146,9 +170,10 @@ STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) {
decomp->dest = dest_buf; decomp->dest = dest_buf;
decomp->dest_limit = dest_buf + dest_buf_size; decomp->dest_limit = dest_buf + dest_buf_size;
DEBUG_printf("uzlib: Initial out buffer: " UINT_FMT " bytes\n", decomp->destSize); DEBUG_printf("uzlib: Initial out buffer: " UINT_FMT " bytes\n", dest_buf_size);
decomp->source = bufinfo.buf; decomp->source = bufinfo.buf;
decomp->source_limit = (unsigned char *)bufinfo.buf + bufinfo.len; decomp->source_limit = (byte *)bufinfo.buf + bufinfo.len;
int st; int st;
bool is_zlib = true; bool is_zlib = true;
@ -175,7 +200,7 @@ STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) {
dest_buf = m_renew(byte, dest_buf, dest_buf_size, dest_buf_size + 256); dest_buf = m_renew(byte, dest_buf, dest_buf_size, dest_buf_size + 256);
dest_buf_size += 256; dest_buf_size += 256;
decomp->dest = dest_buf + offset; decomp->dest = dest_buf + offset;
decomp->dest_limit = dest_buf + offset + 256; decomp->dest_limit = decomp->dest + 256;
} }
mp_uint_t final_sz = decomp->dest - dest_buf; mp_uint_t final_sz = decomp->dest - dest_buf;
@ -203,6 +228,9 @@ const mp_obj_module_t mp_module_uzlib = {
.base = { &mp_type_module }, .base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_uzlib_globals, .globals = (mp_obj_dict_t *)&mp_module_uzlib_globals,
}; };
MP_REGISTER_MODULE(MP_QSTR_zlib, mp_module_uzlib);
#endif #endif
// Source files #include'd here to make sure they're compiled in // Source files #include'd here to make sure they're compiled in

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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,
)

View File

@ -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?

View File

@ -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

View File

@ -1,8 +1,29 @@
// Copyright (c) 2016 Paul Sokolovsky /*
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) * This file is part of the MicroPython project, http://micropython.org/
// SPDX-FileCopyrightText: Copyright (c) 2013-2016 Damien P. George *
// * The MIT License (MIT)
// SPDX-License-Identifier: MIT *
* Copyright (c) 2013-2016 Damien P. George
* Copyright (c) 2016 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/mpconfig.h" #include "py/mpconfig.h"
#if MICROPY_PY_UTIME_MP_HAL #if MICROPY_PY_UTIME_MP_HAL

View File

@ -1,9 +1,29 @@
// Copyright (c) 2016 Paul Sokolovsky /*
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) * This file is part of the MicroPython project, http://micropython.org/
// SPDX-FileCopyrightText: Copyright (c) 2013-2016 Damien P. George *
// * The MIT License (MIT)
// SPDX-License-Identifier: MIT *
* Copyright (c) 2013-2016 Damien P. George
* Copyright (c) 2016 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H #ifndef MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H
#define MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H #define MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H

View File

@ -1,7 +1,28 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) /*
// SPDX-FileCopyrightText: Copyright (c) 2017 Damien P. George * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2017 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@ -386,8 +407,7 @@ mp_obj_t mp_vfs_ilistdir(size_t n_args, const mp_obj_t *args) {
if (vfs == MP_VFS_ROOT) { if (vfs == MP_VFS_ROOT) {
// list the root directory // list the root directory
mp_vfs_ilistdir_it_t *iter = m_new_obj(mp_vfs_ilistdir_it_t); mp_vfs_ilistdir_it_t *iter = mp_obj_malloc(mp_vfs_ilistdir_it_t, &mp_type_polymorph_iter);
iter->base.type = &mp_type_polymorph_iter;
iter->iternext = mp_vfs_ilistdir_it_iternext; iter->iternext = mp_vfs_ilistdir_it_iternext;
iter->cur.vfs = MP_STATE_VM(vfs_mount_table); iter->cur.vfs = MP_STATE_VM(vfs_mount_table);
iter->is_str = mp_obj_get_type(path_in) == &mp_type_str; iter->is_str = mp_obj_get_type(path_in) == &mp_type_str;

View File

@ -1,12 +1,32 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) /*
// SPDX-FileCopyrightText: Copyright (c) 2017 Damien P. George * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2017 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_EXTMOD_VFS_H #ifndef MICROPY_INCLUDED_EXTMOD_VFS_H
#define MICROPY_INCLUDED_EXTMOD_VFS_H #define MICROPY_INCLUDED_EXTMOD_VFS_H
#include "py/lexer.h" #include "py/builtin.h"
#include "py/obj.h" #include "py/obj.h"
#include "py/proto.h" #include "py/proto.h"

View File

@ -1,8 +1,29 @@
// Copyright (c) 2016 Paul Sokolovsky /*
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) * This file is part of the MicroPython project, http://micropython.org/
// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George *
// * The MIT License (MIT)
// SPDX-License-Identifier: MIT *
* Copyright (c) 2014 Damien P. George
* Copyright (c) 2016 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/mpconfig.h" #include "py/mpconfig.h"
#if MICROPY_VFS_FAT #if MICROPY_VFS_FAT
@ -54,8 +75,7 @@ STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, size_
mp_arg_check_num(n_args, n_kw, 1, 1, false); mp_arg_check_num(n_args, n_kw, 1, 1, false);
// create new object // create new object
fs_user_mount_t *vfs = m_new_obj(fs_user_mount_t); fs_user_mount_t *vfs = mp_obj_malloc(fs_user_mount_t, type);
vfs->base.type = type;
vfs->fatfs.drv = vfs; vfs->fatfs.drv = vfs;
// Initialise underlying block device // Initialise underlying block device
@ -171,8 +191,7 @@ STATIC mp_obj_t fat_vfs_ilistdir_func(size_t n_args, const mp_obj_t *args) {
} }
// Create a new iterator object to list the dir // Create a new iterator object to list the dir
mp_vfs_fat_ilistdir_it_t *iter = m_new_obj(mp_vfs_fat_ilistdir_it_t); mp_vfs_fat_ilistdir_it_t *iter = mp_obj_malloc(mp_vfs_fat_ilistdir_it_t, &mp_type_polymorph_iter);
iter->base.type = &mp_type_polymorph_iter;
iter->iternext = mp_vfs_fat_ilistdir_it_iternext; iter->iternext = mp_vfs_fat_ilistdir_it_iternext;
iter->is_str = is_str_type; iter->is_str = is_str_type;
FRESULT res = f_opendir(&self->fatfs, &iter->dir, path); FRESULT res = f_opendir(&self->fatfs, &iter->dir, path);

View File

@ -1,8 +1,28 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) /*
// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_EXTMOD_VFS_FAT_H #ifndef MICROPY_INCLUDED_EXTMOD_VFS_FAT_H
#define MICROPY_INCLUDED_EXTMOD_VFS_FAT_H #define MICROPY_INCLUDED_EXTMOD_VFS_FAT_H

View File

@ -1,7 +1,31 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) /*
// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * Original template for this file comes from:
* Low level disk I/O module skeleton for FatFs, (C)ChaN, 2013
*
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/mpconfig.h" #include "py/mpconfig.h"
#if MICROPY_VFS && MICROPY_VFS_FAT #if MICROPY_VFS && MICROPY_VFS_FAT

View File

@ -1,7 +1,28 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) /*
// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/mpconfig.h" #include "py/mpconfig.h"
#if MICROPY_VFS && MICROPY_VFS_FAT #if MICROPY_VFS && MICROPY_VFS_FAT
@ -136,6 +157,7 @@ STATIC const mp_arg_t file_open_args[] = {
}; };
#define FILE_OPEN_NUM_ARGS MP_ARRAY_SIZE(file_open_args) #define FILE_OPEN_NUM_ARGS MP_ARRAY_SIZE(file_open_args)
// CIRCUITPY is more careful about validating the open mode.
STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_arg_val_t *args) { STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_arg_val_t *args) {
int mode = 0; int mode = 0;
const char *mode_s = mp_obj_str_get_str(args[1].u_obj); const char *mode_s = mp_obj_str_get_str(args[1].u_obj);
@ -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; DWORD size = (temp_table[0] + 1) * 2;
// Now allocate the size and construct the map. // 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) { if (o->fp.cltbl != NULL) {
o->fp.cltbl[0] = size; o->fp.cltbl[0] = size;
res = f_lseek(&o->fp, CREATE_LINKMAP); res = f_lseek(&o->fp, CREATE_LINKMAP);

View File

@ -203,8 +203,7 @@ STATIC mp_obj_t MP_VFS_LFSx(ilistdir_func)(size_t n_args, const mp_obj_t *args)
path = vstr_null_terminated_str(&self->cur_dir); path = vstr_null_terminated_str(&self->cur_dir);
} }
MP_VFS_LFSx(ilistdir_it_t) * iter = m_new_obj(MP_VFS_LFSx(ilistdir_it_t)); MP_VFS_LFSx(ilistdir_it_t) * iter = mp_obj_malloc(MP_VFS_LFSx(ilistdir_it_t), &mp_type_polymorph_iter);
iter->base.type = &mp_type_polymorph_iter;
iter->iternext = MP_VFS_LFSx(ilistdir_it_iternext); iter->iternext = MP_VFS_LFSx(ilistdir_it_iternext);
iter->is_str = is_str_type; iter->is_str = is_str_type;
iter->vfs = self; iter->vfs = self;

View File

@ -1,7 +1,28 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) /*
// SPDX-FileCopyrightText: Copyright (c) 2017-2018 Damien P. George * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2017-2018 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/runtime.h" #include "py/runtime.h"
#include "py/mperrno.h" #include "py/mperrno.h"
@ -16,6 +37,9 @@
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <dirent.h> #include <dirent.h>
#ifdef _MSC_VER
#include <direct.h> // For mkdir etc.
#endif
typedef struct _mp_obj_vfs_posix_t { typedef struct _mp_obj_vfs_posix_t {
mp_obj_base_t base; mp_obj_base_t base;
@ -74,8 +98,7 @@ STATIC mp_import_stat_t mp_vfs_posix_import_stat(void *self_in, const char *path
STATIC mp_obj_t vfs_posix_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { STATIC mp_obj_t vfs_posix_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false); mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_vfs_posix_t *vfs = m_new_obj(mp_obj_vfs_posix_t); mp_obj_vfs_posix_t *vfs = mp_obj_malloc(mp_obj_vfs_posix_t, type);
vfs->base.type = type;
vstr_init(&vfs->root, 0); vstr_init(&vfs->root, 0);
if (n_args == 1) { if (n_args == 1) {
vstr_add_str(&vfs->root, mp_obj_str_get_str(args[0])); vstr_add_str(&vfs->root, mp_obj_str_get_str(args[0]));
@ -205,8 +228,7 @@ STATIC mp_obj_t vfs_posix_ilistdir_it_iternext(mp_obj_t self_in) {
STATIC mp_obj_t vfs_posix_ilistdir(mp_obj_t self_in, mp_obj_t path_in) { STATIC mp_obj_t vfs_posix_ilistdir(mp_obj_t self_in, mp_obj_t path_in) {
mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in);
vfs_posix_ilistdir_it_t *iter = m_new_obj(vfs_posix_ilistdir_it_t); vfs_posix_ilistdir_it_t *iter = mp_obj_malloc(vfs_posix_ilistdir_it_t, &mp_type_polymorph_iter);
iter->base.type = &mp_type_polymorph_iter;
iter->iternext = vfs_posix_ilistdir_it_iternext; iter->iternext = vfs_posix_ilistdir_it_iternext;
iter->is_str = mp_obj_get_type(path_in) == &mp_type_str; iter->is_str = mp_obj_get_type(path_in) == &mp_type_str;
const char *path = vfs_posix_get_path_str(self, path_in); const char *path = vfs_posix_get_path_str(self, path_in);
@ -233,7 +255,11 @@ STATIC mp_obj_t vfs_posix_mkdir(mp_obj_t self_in, mp_obj_t path_in) {
mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in);
const char *path = vfs_posix_get_path_str(self, path_in); const char *path = vfs_posix_get_path_str(self, path_in);
MP_THREAD_GIL_EXIT(); MP_THREAD_GIL_EXIT();
#ifdef _WIN32
int ret = mkdir(path);
#else
int ret = mkdir(path, 0777); int ret = mkdir(path, 0777);
#endif
MP_THREAD_GIL_ENTER(); MP_THREAD_GIL_ENTER();
if (ret != 0) { if (ret != 0) {
mp_raise_OSError(errno); mp_raise_OSError(errno);
@ -287,6 +313,8 @@ STATIC mp_obj_t vfs_posix_stat(mp_obj_t self_in, mp_obj_t path_in) {
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_stat_obj, vfs_posix_stat); STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_stat_obj, vfs_posix_stat);
#if MICROPY_PY_UOS_STATVFS
#ifdef __ANDROID__ #ifdef __ANDROID__
#define USE_STATFS 1 #define USE_STATFS 1
#endif #endif
@ -328,6 +356,8 @@ STATIC mp_obj_t vfs_posix_statvfs(mp_obj_t self_in, mp_obj_t path_in) {
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_statvfs_obj, vfs_posix_statvfs); STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_statvfs_obj, vfs_posix_statvfs);
#endif
STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = { STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&vfs_posix_mount_obj) }, { MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&vfs_posix_mount_obj) },
{ MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&vfs_posix_umount_obj) }, { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&vfs_posix_umount_obj) },
@ -341,7 +371,9 @@ STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&vfs_posix_rename_obj) }, { MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&vfs_posix_rename_obj) },
{ MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&vfs_posix_rmdir_obj) }, { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&vfs_posix_rmdir_obj) },
{ MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&vfs_posix_stat_obj) }, { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&vfs_posix_stat_obj) },
#if MICROPY_PY_UOS_STATVFS
{ MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&vfs_posix_statvfs_obj) }, { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&vfs_posix_statvfs_obj) },
#endif
}; };
STATIC MP_DEFINE_CONST_DICT(vfs_posix_locals_dict, vfs_posix_locals_dict_table); STATIC MP_DEFINE_CONST_DICT(vfs_posix_locals_dict, vfs_posix_locals_dict_table);

View File

@ -1,8 +1,28 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) /*
// SPDX-FileCopyrightText: Copyright (c) 2018 Damien P. George * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2018 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_EXTMOD_VFS_POSIX_H #ifndef MICROPY_INCLUDED_EXTMOD_VFS_POSIX_H
#define MICROPY_INCLUDED_EXTMOD_VFS_POSIX_H #define MICROPY_INCLUDED_EXTMOD_VFS_POSIX_H

View File

@ -1,7 +1,28 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) /*
// SPDX-FileCopyrightText: Copyright (c) 2013-2018 Damien P. George * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2013-2018 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "py/mphal.h" #include "py/mphal.h"
#include "py/mpthread.h" #include "py/mpthread.h"

View File

@ -1,7 +1,28 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) /*
// SPDX-FileCopyrightText: Copyright (c) 2013-2017 Damien P. George * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2013-2017 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>

View File

@ -1,7 +1,28 @@
// SPDX-FileCopyrightText: Copyright (c) 2016 Paul Sokolovsky /*
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2016 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "extmod/virtpin.h" #include "extmod/virtpin.h"
#include "py/proto.h" #include "py/proto.h"

View File

@ -1,8 +1,28 @@
// Copyright (c) 2016 Paul Sokolovsky /*
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) * This file is part of the MicroPython project, http://micropython.org/
// *
// SPDX-License-Identifier: MIT * The MIT License (MIT)
*
* Copyright (c) 2016 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_EXTMOD_VIRTPIN_H #ifndef MICROPY_INCLUDED_EXTMOD_VIRTPIN_H
#define MICROPY_INCLUDED_EXTMOD_VIRTPIN_H #define MICROPY_INCLUDED_EXTMOD_VIRTPIN_H

@ -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