16229 Commits

Author SHA1 Message Date
Phil Howard
e7ff0b8a31 rp2/memmap_mp.ld: Lower the minimum GC heap to 32K.
Reduce mimimum heap requirement.  This value allows more room for large,
static buffers in user C modules (such as graphics buffers or otherwise)
which might be allocated outside of MicroPython's heap to guarantee
alignment or avoid fragmentation.

Signed-off-by: Phil Howard <phil@gadgetoid.com>
2024-08-02 16:21:36 +10:00
Phil Howard
1557014ea4 rp2/boards/PIMORONI_TINY2040: Add an 8MB variant to Tiny 2040.
Add an 8MB "PIMORONI_TINY2040" variant.

Signed-off-by: Phil Howard <phil@gadgetoid.com>
2024-08-02 16:17:48 +10:00
Phil Howard
cd1ab7645e rp2/boards/PIMORONI_PICOLIPO: Refactor Pico LiPo to use board variants.
Combine the 4MB and 16MB "PIMORONI_PICOLIPO" variants into a single board.

Signed-off-by: Phil Howard <phil@gadgetoid.com>
2024-08-02 16:17:24 +10:00
Phil Howard
11becbe223 rp2/CMakeLists.txt: Add MICROPY_DEF_BOARD to compile definitions.
Add MICROPY_DEF_BOARD as per esp32 port, allows board variants to override
the board name with:

    list(APPEND MICROPY_DEF_BOARD
        MICROPY_HW_BOARD_NAME="New Board Name"
    )

Signed-off-by: Phil Howard <phil@gadgetoid.com>
2024-08-02 16:16:23 +10:00
Angus Gratton
6d05424754 tests/extmod: Add esp32 support to the machine_i2s_rate test.
This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-08-02 10:31:19 +10:00
Angus Gratton
0d00d72b76 esp32/machine_i2s: Ensure 2 DMA buffers and improve I2S error handling.
ESP-IDF driver always requires at least two DMA buffers, so ensure that's
the case.

Failures during initialisation were being lost because ESP_ERROR_CHECK is
configured as a no-op, so the failure was deferred until read() or write()
was called on the port.  Raise an error from init, instead.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-08-02 10:30:14 +10:00
Angus Gratton
9ba04cc756 tests/extmod: Skip soft machine.Timer test on esp32 port.
Also rename the test to reflect that it's a soft timer test.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-08-02 10:27:53 +10:00
Tim Weber
d1685a3f5f docs/library/neopixel: Mention bitstream timing tuple.
Signed-off-by: Tim Weber <scy@scy.name>
2024-08-01 12:04:58 +10:00
George Hopkins
066243ea74 py/py.mk: Add SRC_USERMOD_LIB_ASM to include assembly files.
Introduce SRC_USERMOD_LIB_ASM to allow users to include assembly files as
part of their user modules.  It could be used to include optimized
functions or outputs of other programming languages.

Signed-off-by: George Hopkins <george-hopkins@null.net>
2024-08-01 12:01:18 +10:00
Angus Gratton
1754c587f9 esp32: Fix heap corruption triggered by bluetooth.active(0).
It seems like at some point Espressif NimBLE team changed
nimble_port_init and nimble_port_deinit to manage HCI init
internally:
https://github.com/espressif/esp-nimble/commit/f8a79b04c9743543b8959727d7

This change is included in all the IDF versions that MicroPython supports.

As a result, existing code that called esp_nimble_hci_deinit() explicitly
would trigger a use-after-free bug and heap corruption (specifically this
calls through to ble_transport_deinit() which calls os_mempool_free(). The
second time this writes out to a bunch of memory pools where the backing
buffers have already been freed.)

Symptoms were intermittent random crashes after de-activating Bluetooth
(running multi_bluetooth/ble_gatt_data_transfer.py could sometimes
reproduce). Setting Heap Poisoning to Comprehensive in menuconfig caused
the bug to be detected every time.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-08-01 11:01:05 +10:00
iabdalkader
6f27e1c968 lib/arduino-lib: Update submodule to the latest.
Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
2024-07-31 16:51:13 +10:00
iabdalkader
a3100be4b2 stm32/boards: Swap FMC banks on ARDUINO_GIGA and ARDUINO_PORTENTA_H7.
Swap FMC banks to remap the SDRAM bank1 address to 0x60000000.  Arduino's
M4 firmware uses address 0x60000000 by default.  When the elf loader tries
to load that it will fail because by default NOR/PSRAM is mapped at that
address, not SDRAM bank1.  (Note that the region at 0xC0000000 has an XN
attribute by default, so switching the M4 firmware address will not work.)

Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
2024-07-31 16:47:32 +10:00
Andrew Leech
70a7e0ff2f nrf/Makefile: Fix GCC_VERSION check.
Previously it was truncating the first digit of the version if the major
number had more than one digit.

Signed-off-by: Andrew Leech <andrew@alelec.net>
2024-07-31 12:44:16 +10:00
Alessandro Gatti
6007f3e206 esp32/mpconfigport: Enable the RV32 emitter for ESP32C3 targets.
The RV32 code emitter assumed that the arch-specific NLR was used
instead of the setjmp/longjmp based NLR code.  If the latter NLR
provider was chosen, the emitter would allocate space on the stack
for the NLR buffer but would not fill it in.

This change turns off setjmp()-based NLR and GCREGS for the ESP32C3
target, in favour of more platform-tailored alternatives.  As setjmp()
NLR is now disabled by default, the RV32 emitter can be safely enabled
by default as well for the target in question.

Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
2024-07-26 12:13:03 +10:00
robert-hh
4a134d212e nrf/modules/machine/pin: Disable IRQ with pin.irq(handler=None).
Before, the input was still set to `pin.irq()` mode, only the handler was
disabled.  That prevented switching the pin between input and output mode.

Signed-off-by: robert-hh <robert@hammelrath.com>
2024-07-26 11:32:49 +10:00
Andrew Leech
5e80416e6d nrf/modules/machine/soft_pwm: Ensure duty_width is always valid.
Signed-off-by: Andrew Leech <andrew@alelec.net>
2024-07-26 11:14:19 +10:00
Andrew Leech
62e0fa04a7 nrf/Makefile: Enable LTO by default only on newer gcc.
Older gcc/binutils linker does not support lto with wrap.

Signed-off-by: Andrew Leech <andrew@alelec.net>
2024-07-26 11:13:11 +10:00
Andrew Leech
56c1617384 nrf/modules/machine/uart: Support sending data stored in flash.
Signed-off-by: Andrew Leech <andrew@alelec.net>
2024-07-26 11:12:46 +10:00
Andrew Leech
19075695da nrf: Consolidate all stdio functions.
Consolidate CDC, UART and NUS stdio interfaces into the one handler.
Allows any/all of them to be enabled separately.

Updates UART REPL to use similar define to other platforms:
`MICROPY_HW_ENABLE_UART_REPL`.

USB now uses the shared/tinyusb CDC implementation.

Signed-off-by: Andrew Leech <andrew@alelec.net>
2024-07-26 11:10:32 +10:00
Damien George
e1fe62f4fc tests/multi_net: Fix skipping of SSLContext tests when .der don't exist.
The `sslcontext_server_client_ciphers.py` test was using stat to test for
the .der files after it already tried to open them for reading.  That is
now fixed.  And `sslcontext_server_client.py` is adjusted to use the same
pattern for skipping the test.

Signed-off-by: Damien George <damien@micropython.org>
2024-07-25 18:14:52 +10:00
Alessandro Gatti
17f254df35 github/workflows: Add RISC-V 64 bits Unix port to CI.
Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
2024-07-25 16:45:04 +10:00
stijn
1f907a2f5c tests/run-tests.py: Make Windows test skipping more granular.
Signed-off-by: stijn <stijn@ignitron.net>
2024-07-25 16:24:04 +10:00
stijn
a0c7bf12d2 github/workflows: Improve MSYS2-based CI builds.
Install the mingw variant of Python since it behaves more like a 'real'
Windows CPython than the msys2 variant: os.name == 'nt', not 'posix'.  Note
that os.sep is still '/' though so we don't actually need to skip the
import_file test.  This way one single Python version can be used both for
running run-tests.py and getting the expected test output.

Signed-off-by: stijn <stijn@ignitron.net>
2024-07-25 16:22:21 +10:00
Damien George
233f5ce661 py/runtime: Fix self arg passed to classmethod when accessed via super.
Thanks to @AJMansfield for the original test case.

Signed-off-by: Damien George <damien@micropython.org>
2024-07-25 13:07:42 +10:00
stijn
07bf3179f6 py/misc: Fix msvc and C++ compatibility.
Use explicit casts to suppress warnings about implicit conversions, add a
workaround for constant expression conditional, and make functions static
inline (as is done in the rest of the codebase) to suppress 'warning C4505:
unreferenced function with internal linkage has been removed'.

(Follow up to fix commit 908ab1ceca15ee6fd0ef82ca4cba770a3ec41894)

Signed-off-by: stijn <stijn@ignitron.net>
2024-07-25 12:55:23 +10:00
stijn
093d0c0a17 py/objtype: Validate super() arguments.
This fixes various null dereferencing and out-of-bounds access because
super_attr assumes the held obj is effectively an object of the held type,
which is now verified.

Fixes issue #12830.

Signed-off-by: stijn <stijn@ignitron.net>
2024-07-25 12:27:33 +10:00
David Lechner
d1bf0eeb0f tests/cpydiff: Add diff for overriding __init__.
This adds a CPython diff that explains why calling `super().__init__()` is
required in MicroPython when subclassing a native type (because `__new__`
and `__init__` are not separate functions).

Signed-off-by: David Lechner <david@pybricks.com>
2024-07-25 12:01:43 +10:00
Laurens Valk
9ca668f881 py/objtype: Avoid crash on calling members of uninitialized native type.
When subclassing a native type, calling native members in `__init__` before
`super().__init__()` has been called could cause a crash.  In this
situation, `self` in `mp_convert_member_lookup` is the
`native_base_init_wrapper_obj`.  The check added in this commit ensures
that an `AttributeError` is raised before this happens, which is consistent
with other failed lookups.

Also fix a typo in a related comment.

Signed-off-by: Laurens Valk <laurens@pybricks.com>
2024-07-25 12:01:43 +10:00
Laurens Valk
19b1333cb1 examples/usercmodule/cexample: Add more advanced native class.
This adds a separate `AdvancedTimer` class that demonstrates a few more
advanced concepts usch as custom handlers for printing and attributes.

Signed-off-by: Laurens Valk <laurens@pybricks.com>
2024-07-25 11:57:13 +10:00
Felix Dörre
7fe8f030ee rp2/lwip_inc: Enable IPv6 per default on rp2 port.
Having IPv6 support is important, especially for IoT-Devices which might be
many, requiring individual IP-addresses. In particular direct access via
link-local addresses and having deterministic SLAAC-addresses can be quite
convenient. Also in IPv6-only networks or for connecting to IPv6-only
services, this is very useful.

For the Pico W, there is enough flash and RAM that enabling IPv6 by default
is the right choice.

Should IPv6 support in a network exist (i.e. there are Router
Advertisements), but not provide connectivity, connecting by domain name
should not be a problem as DNS will default to return the IPv4-address (if
that exists), unless reconfigured at runtime to prefer IPv6.

In any case a user can disable obtaining SLAAC-addresses with:

    <nic>.ipconfig(autoconf6=False)

Signed-off-by: Felix Dörre <felix@dogcraft.de>
2024-07-24 14:59:01 +10:00
Angus Gratton
ba98533454 rp2: Stop machine.idle() blocking indefinitely.
Updates rp2 port to always resume from idle within 1ms max.

When rp2 port went tickless the behaviour of machine.idle() changed as
there is no longer a tick interrupt to wake it up every millisecond. On a
quiet system it would now block indefinitely. No other port does this.

See parent commit for justification of why this change is useful.

Also adds a test case that fails without this change.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-07-23 16:46:27 +10:00
Angus Gratton
81daba31c5 docs: Specify that machine.idle() returns at least every 1ms.
A lot of existing code (i.e. micropython-lib lps22h, lcd160cr sensor
drivers, lora sync_modem driver, usb-device-hid) calls machine.idle()
inside a tight loop that is polling some condition. This reduces the power
usage compared to constantly looping, but can be faster than calling a
sleep function. However on a tickless port there's not always an interrupt
before the condition they are polling for, so it's difficult to restructure
this code if machine.idle() doesn't have any upper limit on execution time.

This commit specifies an upper limit of 1ms before machine.idle() resumes
execution. This is already the case for all ports except rp2.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-07-23 16:42:42 +10:00
Phil Howard
e1ecc232dc rp2/rp2_pio: Disable correct IRQ for PIO1.
Fix a typo that was disabling PIO0_IRQ_1 instead of PIO1_IRQ_0.

Signed-off-by: Phil Howard <phil@gadgetoid.com>
2024-07-23 16:15:40 +10:00
Angus Gratton
9db16cfe31 rp2: Fix wakeup from WFE on core1.
If core1 executes `mp_wfe_or_timeout()` then it needs to receive an
interrupt or a SEV to resume execution, but the soft timer interrupt only
fires on core 0.  This fix adds a SEV to the soft timer interrupt handler.

This issue was masked by the issue fixed in the previous commit, as WFE
previously wasn't suspending properly.

Verified via the existing thread_sleep2 test.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-07-23 16:02:59 +10:00
Angus Gratton
eced9d86a7 rp2: Fix power consumption when sleeping with a timeout.
Fixes a regression introduced in 3af006efb39ad0b7aa7c0401c93329b654bca617
where WFE never blocked in `mp_wfe_or_timeout()` function and would
busy-wait instead.  This increases power consumption measurably.

Root cause is that `mp_wfe_or_timeout()` calls soft timer functions that
(after the regression) call `recursive_mutex_enter()` and
`recursive_mutex_exit()`.  The exit calls
`lock_internal_spin_unlock_with_notify()` and the default pico-sdk
implementation of this macro issues a SEV which negates the WFE that
follows it, meaning the CPU never suspends.

See https://forums.raspberrypi.com/viewtopic.php?p=2233908 for more
details.

The fix in this comment adds a custom "nowait" variant mutex that doesn't
do WFE/SEV, and uses this one for PendSV.  This will use more power when
there's contention for the PendSV mutex as the other core will spin, but
this shouldn't happen very often.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-07-23 16:01:42 +10:00
Alessandro Gatti
44527ada5f unix/main: Fix GCC builds for RISC-V 64 bits.
This contains a workaround to silence a possibly incorrect warning when
building the Unix port with GCC targeting RISC-V 64 bits.

Fixes issue #12838.

Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
2024-07-23 15:51:50 +10:00
robert-hh
594c4229b7 esp32/machine_timer: Limit timer numbers for ESP32C3.
The ESP32C3 has only two timers in one group.  In the code this is
reflected as two groups with one timer.

Signed-off-by: robert-hh <robert@hammelrath.com>
2024-07-23 14:55:35 +10:00
Angus Gratton
46c3df0229 tests/run-tests.py: Enable thread tests on esp32.
Before the fix in parent commit, some of these tests hung indefinitely.

After, they seem to consistently pass.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-07-23 12:34:14 +10:00
Angus Gratton
337742f6c7 esp32/mpthreadport: Fix uneven GIL allocation between Python threads.
Explicitly yield each time a thread mutex is unlocked.

Key to understanding this bug is that Python threads run at equal RTOS
priority, and although ESP-IDF FreeRTOS (and I think vanilla FreeRTOS)
scheduler will round-robin equal priority tasks in the ready state it does
not make a similar guarantee for tasks moving between ready and waiting.

The pathological case of this bug is when one Python thread task is busy
(i.e. never blocks) it will hog the CPU more than expected, sometimes for
an unbounded amount of time. This happens even though it periodically
unlocks the GIL to allow another task to run.

Assume T1 is busy and T2 is blocked waiting for the GIL. T1 is executing
and hits a condition to yield execution:

1. T1 calls MP_THREAD_GIL_EXIT
2. FreeRTOS sees T2 is waiting for the GIL and moves it to the Ready list
   (but does not preempt, as T2 is same priority, so T1 keeps running).
3. T1 immediately calls MP_THREAD_GIL_ENTER and re-takes the GIL.
4. Pre-emptive context switch happens, T2 wakes up, sees GIL is not
   available, and goes on the waiting list for the GIL again.

To break this cycle step 4 must happen before step 3, but this may be a
very narrow window of time so it may not happen regularly - and
quantisation of the timing of the tick interrupt to trigger a context
switch may mean it never happens.

Yielding at the end of step 2 maximises the chance for another task to run.

Adds a test that fails on esp32 before this fix and passes afterwards.

Fixes issue #15423.

This work was funded through GitHub Sponsors.

Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-07-23 12:33:19 +10:00
Junwha
2994354634 extmod/vfs: Fix buffer overflow of string comparison in umount.
The comparison between the given unmount string and existing mount strings
were made by the given string, which leads to buffer overflow.

Fixes issue #13006.

Signed-off-by: Junwha <qbit@unist.ac.kr>
2024-07-23 12:13:49 +10:00
Terence Stenvold
390390ec37 extmod/vfs_fat: Set default volume label on mkfs if it's defined.
Using mkfs doesn't set a volume label for FAT filesystems.  This commit
will set the volume label if `MICROPY_HW_FLASH_FS_LABEL` is defined.
2024-07-23 11:39:17 +10:00
stijn
444d7bacbe extmod/moductypes: Validate the descriptor tuple.
Fixes various null dereferencing, out-of-bounds memory accesses and
`assert(0)` failures in the case of an invalid `uctypes` descriptor.

By design `uctypes` can crash because it accesses arbitrary memory, but at
least describing the descriptor layout should be forced to be correct and
not crash.

Fixes issue #12702.

Signed-off-by: stijn <stijn@ignitron.net>
2024-07-22 14:40:45 +10:00
Michael Vornovitsky
6db91dfefb extmod/modbtree: Add checks for already-closed database.
Fixes use-after-free when accessing the database after it is closed with
`btree_close`.  `btree_close` always succeeds when called with an
already-closed database.

The new test checks that operations that access the underlying database
(get, set, flush, seq) fail with a `ValueError` when the btree is already
closed.  It also checks that closing and printing the btree succeed when
the btree is already closed.

Fixes issue #12543.

Signed-off-by: Michael Vornovitsky <michaelvornovitskiy@outlook.com>
2024-07-22 10:42:29 +10:00
Damien George
8159dcc276 extmod/modos: Include os.sep entry if MICROPY_VFS is enabled.
This simplifies configuration by removing the `MICROPY_PY_OS_SEP` option
and instead including `os.sep` if `MICROPY_VFS` is enabled.  That matches
the configuration of all existing ports that enabled `os.sep` (they also
had `MICROPY_VFS` enabled), and brings consistency to other ports.

Fixes issue #15116.

Signed-off-by: Damien George <damien@micropython.org>
2024-07-20 12:32:31 +10:00
Damien George
5f3ecc29f8 extmod/modmachine: Use sys.exit as implementation of machine.soft_reset.
It does the same thing, raising `SystemExit`.

Signed-off-by: Damien George <damien@micropython.org>
2024-07-20 12:18:07 +10:00
Damien George
69c25ea865 shared/runtime/pyexec: Make a raised SystemExit always do a forced exit.
The current situation with SystemExit and soft reset is the following:
- `sys.exit()` follows CPython and just raises `SystemExit`.
- On the unix port, raising `SystemExit` quits the application/MicroPython,
  whether at the REPL or in code (this follows CPython behaviour).
- On bare-metal ports, raising `SystemExit` at the REPL does nothing,
  raising it in code will stop the code and drop into the REPL.
- `machine.soft_reset()` raises `SystemExit` but with a special flag set,
  and bare-metal targets check this flag when it propagates to the
  top-level and do a soft reset when they receive it.

The original idea here was that a bare-metal target can't "quit" like the
unix port can, and so dropping to the REPL was considered the same as
"quit".  But this bare-metal behaviour is arguably inconsistent with unix,
and "quit" should mean terminate everything, including REPL access.

This commit changes the behaviour to the following, which is more
consistent:
- Raising `SystemExit` on a bare-metal port will do a soft reset (unless
  the exception is caught by the application).
- `machine.soft_reset()` is now equivalent to `sys.exit()`.
- unix port behaviour remains unchanged.

Tested running the test suite on an stm32 board and everything still
passes, in particular tests that skip by raising `SystemExit` still
correctly skip.

Signed-off-by: Damien George <damien@micropython.org>
2024-07-20 12:13:14 +10:00
robert-hh
a734ee9057 shared/tinyusb/mp_usbd_cdc: Skip writing to an uninitialized USB device.
During execution of `boot.py` the USB device is not yet initialized.  Any
attempt to write to the CDC (eg calling `print()`) would lock up the
device.  This commit skips writing when the USB device is not initialized.
Any output from `boot.py` is lost, but the device does not lock up.

Also removed unnecessary declaration of `tusb_init()`.

Signed-off-by: robert-hh <robert@hammelrath.com>
2024-07-20 00:27:58 +10:00
Damien George
847ee20d9b tests/multi_bluetooth/perf_gatt_notify.py: Reduce connection interval.
To test that the notification ping-pong can be low latency.

Signed-off-by: Damien George <damien@micropython.org>
2024-07-19 22:28:31 +10:00
Damien George
77bd8fe5b8 webassembly: Reuse PyProxy objects when they are the same Python object.
This commit makes it so that PyProxy objects are reused (on the JavaScript
side) when they correspond to an existing Python object that is the same
object.

For example, proxying the same Python function to JavaScript, the same
PyProxy instance is now used.  This means that if `foo` is a Python
function then accessing it on the JavaScript side such as
`api.globals().get("foo")` has the property that:

    api.globals().get("foo") === api.globals().get("foo")

Prior to this commit the above was not true because new PyProxy instances
were created each time `foo` was accessed.

Signed-off-by: Damien George <damien@micropython.org>
2024-07-19 11:55:24 +10:00
Damien George
5147dc5de5 py/gc: Remove commented-out functions.
These are old, unused, and most of them no longer compile.  The `gc_test()`
function is superseded by the test suite.

Signed-off-by: Damien George <damien@micropython.org>
2024-07-19 10:36:30 +10:00