Add `machine_i2s_deinit_all` to teardown any active I2S instances on soft
reset. Prior to this fix, code using I2S required a try/finally in order
to avoid a hard fault on soft reset.
Fixes issue #14339.
Signed-off-by: Phil Howard <phil@gadgetoid.com>
This change has no impact on vanilla MicroPython builds, but is intended to
avoid RP2's PIO implementation from trampling PIO usage in USER_C_MODULES.
This is consistent with PIOs tracking of used state machines and managed
programs, and makes working with PIO in USER_C_MODULES much less of an
uphill battle.
Since PIO deinit runs before gc_sweep_all it's impossible to work around
this wrinkle otherwise. A module finalizer does not get the opportunity to
put the PIOs back into a state which wont crash rp2_pio_deinit.
Changes are:
- init: Avoid exclusive handlers being added to all PIOs and add them only
when needed.
- deinit: Only remove handlers we have set.
- rp2_pio_irq: Add the exlusive handler if needed.
- rp2_state_machine_irq: Add the exclusive handler if needed.
Signed-off-by: Phil Howard <phil@gadgetoid.com>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>