Enables support for the ESP standard DTR/RTS based reboot to bootloader.
Switches from OTG to Serial/Jtag mode to workaround issue discussed
in: https://github.com/espressif/arduino-esp32/issues/6762
Signed-off-by: Andrew Leech <andrew@alelec.net>
The version of the assembly code for the GC helper that was committed
ended up being a version that had an opcode typo in.
The code was tested and working, but an undo operation too many when
cleaning up the file before committing checked in the wrong version.
Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
With the recent qemu (d9a0fdda9a and
0426934969) and zephyr
(05cad7b56f) changes to how their tests are
run, two things became unused:
- The tinytest framework, which embedded a set of tests and their expected
output within firmware, so these tests could be run stand-alone.
- The `--write-exp` and `--list-tests` options to `tests/run-tests.py`,
which were needed primarily to generated the expected test output for
tinytest (also the associated `tests/run-tests-exp.py/.sh` scripts are
now unused).
This commit removes the tinytest component and all its helper code. This
eliminates a maintenance burden.
Signed-off-by: Damien George <damien@micropython.org>
If GIL is disabled then there's threat of a race condition if some other
code specifically requests USB processing (i.e. to unblock stdio), while
a scheduled TinyUSB callback is already running on another thread.
Relies on the change in the parent commit, where scheduler is restricted
to main thread if GIL is disabled.
Fixes#15390 - "TinyUSB callback can't recurse" exceptions on rp2 when
using _thread module and USB serial I/O.
Adds a unit test for stdin functioning correctly in threads (fails on rp2
port without this fix).
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
The printed type for stdio streams indicates "FileIO", which is a binary IO
stream. Stdio is not binary by design, and its printed type should
indicate a text stream. "TextIOWrapper" suits that purpose, and is used
by VfsPosix files.
Signed-off-by: timdechant <timdechant.git@gmail.com>
Add native gchelper support for 64 bits RISC-V RV64I targets.
Now that RV64 is under CI, this also enables platform-specific ghelper
in the Unix port.
Also changes the data type holding the register contents to something more
appropriate, so in the remote eventuality somebody wants to use this with
RV128 all they have to do is update the `__riscv_xlen` check.
Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
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>
The `mp_event_wait_ms()` function may return earlier than the requested
timeout, and if that happens repeatedly (eg due to lots of USB data and
IRQs) then the loop waiting for CDC TX FIFO space to become available may
exit much earlier than MICROPY_HW_USB_CDC_TX_TIMEOUT, even when there is
no space.
Fix this by using `mp_hal_ticks_ms()` to compute a more accurate timeout.
The `basics/int_big_mul.py` test fails on RPI_PICO without this fix.
Signed-off-by: Damien George <damien@micropython.org>
This adds a RISC-V RV32 semihosting implementation, with all defined
system calls exposed to the user.
Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
Make room for RISC-V semihosting code, by renaming the existing
`semihosting.[ch]` files into `semihosting_arm.[ch]`.
Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
At startup, buffer initial stdout / MicroyPthon banner so that it can be
sent to the host on initial connection of the USB serial port. This
buffering also works for when the CDC becomes disconnected and the device
is still printing to stdout, and when CDC is reconnected the most recent
part of stdout (depending on how big the internal USB FIFO is) is flushed
to the host.
This change is most obvious when you've first plugged in a MicroPython
device (or hit reset), when it's a board that uses USB (CDC) serial in the
chip itself for the REPL interface. This doesn't apply to UART going via a
separate USB-serial chip.
The stm32 port already has this buffering behaviour (it doesn't use
TinyUSB) and this commit extends such behaviour to rp2, mimxrt, samd and
renesas-ra ports, which do use TinyUSB.
Signed-off-by: Andrew Leech <andrew@alelec.net>
This implements network.ipconfig() and network.WLAN.ipconfig() when the
ninaw10 driver is used for WLAN.
Due to a omission in the ninaw10 driver stack, setting the DNS address has
no effect. But the interface is kept here just in case it's fixed
eventually.
dhcp4 and has_dhcp4 are dummy arguments. Ninaw10 seems to always use DHCP.
Signed-off-by: robert-hh <robert@hammelrath.com>
This fixes the build for some esp32 and nrf boards (for example
`ARDUINO_NANO_33_BLE_SENSE` and `ARDUINO_NANO_ESP32`) due to commit
c98789a6d8. Changes are:
- Allow the CDC TX/RX functions in `mp_usbd_cdc.c` to be enabled
separately to those needed for `MICROPY_HW_USB_CDC_1200BPS_TOUCH`.
- Add `MICROPY_EXCLUDE_SHARED_TINYUSB_USBD_CDC` option as a temporary
workaround for the nrf port to use.
- Declare `mp_usbd_line_state_cb()` in a header as a public function.
- Fix warning with type cast of `.callback_line_state_changed`.
Signed-off-by: Damien George <damien@micropython.org>
There are a few TinyUSB CDC functions used for stdio that are currently
replicated across a number of ports. Not surprisingly in a couple of cases
these have started to diverge slightly, with additional features added to
one of them.
This commit consolidates a couple of key shared functions used directly by
TinyUSB based ports, and makes those functions available to all.
Signed-off-by: Andrew Leech <andrew@alelec.net>
The best_effort_wfe_or_timeout() and sleep_us() pico-sdk functions use the
pico-sdk alarm pool internally, and that has a bug.
Some usages inside pico-sdk (notably multicore_lockout_start_blocking())
will still end up calling best_effort_wfe_or_timeout(), although usually
with "end_of_time" as the timeout value so it should avoid any alarm pool
race conditions.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
Progress towards removing pico-sdk alarm pool, due to a known issue.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
Only when dynamic USB devices are enabled.
The issue here is that when the USB reset triggers, the dynamic USB device
reset callback is called from inside the TinyUSB task.
If that callback tries to print something then it'll call through to
tud_cdc_write_flush(), but TinyUSB hasn't finished updating state yet to
know it's no longer configured. Subsequently it may try to queue a transfer
and then the low-level DCD layer panics.
By explicitly stalling the endpoint first, usbd_edpt_claim() will fail and
tud_cdc_write_flush() returns immediately.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
In the case where an OUT control transfer triggers with wLength==0 (i.e.
all data sent in the SETUP phase, and no additional data phase) the
callbacks were previously implemented to return b"" (i.e. an empty buffer
for the data phase).
However this didn't actually work as intended because b"" can't provide a
RW buffer (needed for OUT transfers with a data phase to write data into),
so actually the endpoint would stall.
The symptom was often that the device process the request (if processing
it in the SETUP phase when all information was already available), but the
host sees the endpoint stall and eventually returns an error.
This commit changes the behaviour so returning True from the SETUP phase of
a control transfer queues a zero length status response.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
When defining custom USB devices, longer strings may be needed. Eventually
the memory for string descriptors can be allocated on demand, but for now
this bigger value should be reasonable.
Signed-off-by: Damien George <damien@micropython.org>
Updates a few code comments that were out of date or poorly worded. No code
changes.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
Previously, constructing the singleton USBDevice object was enough to
trigger a USB disconnect on soft reset. Now it also has to be active.
The only case where this changes the behaviour is if the USBDevice object
has been constructed but never set to active (no more disconnect in this
case). Otherwise, behaviour is the same.
This change was requested by hippy on the raspberrypi forums.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
This new machine-module driver provides a "USBDevice" singleton object and
a shim TinyUSB "runtime" driver that delegates the descriptors and all of
the TinyUSB callbacks to Python functions. This allows writing arbitrary
USB devices in pure Python. It's also possible to have a base built-in
USB device implemented in C (eg CDC, or CDC+MSC) and a Python USB device
added on top of that.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
The STATIC macro was introduced a very long time ago in commit
d5df6cd44a. The original reason for this was
to have the option to define it to nothing so that all static functions
become global functions and therefore visible to certain debug tools, so
one could do function size comparison and other things.
This STATIC feature is rarely (if ever) used. And with the use of LTO and
heavy inline optimisation, analysing the size of individual functions when
they are not static is not a good representation of the size of code when
fully optimised.
So the macro does not have much use and it's simpler to just remove it.
Then you know exactly what it's doing. For example, newcomers don't have
to learn what the STATIC macro is and why it exists. Reading the code is
also less "loud" with a lowercase static.
One other minor point in favour of removing it, is that it stops bugs with
`STATIC inline`, which should always be `static inline`.
Methodology for this commit was:
1) git ls-files | egrep '\.[ch]$' | \
xargs sed -Ei "s/(^| )STATIC($| )/\1static\2/"
2) Do some manual cleanup in the diff by searching for the word STATIC in
comments and changing those back.
3) "git-grep STATIC docs/", manually fixed those cases.
4) "rg -t python STATIC", manually fixed codegen lines that used STATIC.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
Allows bytecode itself to be used instead of an mp_raw_code_t in the simple
and common cases of a bytecode function without any children.
This can be used to further reduce frozen code size, and has the potential
to optimise other areas like importing.
Signed-off-by: Damien George <damien@micropython.org>
With these changes IPv6 works on the rp2 port (and possibly others that use
the lwIP socket implementation).
Things that have been tested and work:
- Neighbour solicitation for v6 link local address.
- Ping of v6 link-local address.
- Receiving a SLAAC address via router advertisement.
- Ping a v6 address allocated via SLAAC.
- Perform an outgoing connection to a routed v6-address (via default
gateway).
- Create a listening IPv6 wildcard socked bound to ::, and trying to access
it via link-local, SLAAC, and IPv4 (to ensure the dual-stack binding
works).
Things that could be improved:
- socket.socket().getaddrinfo only returns the v4 address. It could also
return v6 addresses (getaddrinfo is actively programmed to only return a
single address, and this is the v4-address by default, with fallback to
the v6 address if both are enabled).
Signed-off-by: Felix Dörre <felix@dogcraft.de>
For mimxrt, nrf, renesas-ra, rp2 and samd ports, this commit implements
similar behaviour to the stm32 port, where USB is only brought up after
boot.py completes execution.
Currently this doesn't add any useful functionality (and may break
workflows that depend on USB-CDC being live in boot.py), however it's a
precondition for more usable workflows with USB devices defined in
Python (allows setting up USB interfaces in boot.py before the device
enumerates for the first time).
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
The C99 standard states:
6.8.6.4 The return statement Constraints
A return statement with an expression shall not appear in a function
whose return type is void. A return statement without an expression
shall only appear in a function whose return type is void.
And when `-pedantic` is enabled the compiler gives an error.
Signed-off-by: Yoctopuce <dev@yoctopuce.com>
MicroPython code may rely on the return value of sys.stdout.buffer.write()
to reflect the number of bytes actually written. While in most scenarios a
write() operation is successful, there are cases where it fails, leading to
data loss. This problem arises because, currently, write() merely returns
the number of bytes it was supposed to write, without indication of
failure.
One scenario where write() might fail, is where USB is used and the
receiving end doesn't read quickly enough to empty the receive buffer. In
that case, write() on the MicroPython side can timeout, resulting in the
loss of data without any indication, a behavior observed notably in
communication between a Pi Pico as a client and a Linux host using the ACM
driver.
A complex issue arises with mp_hal_stdout_tx_strn() when it involves
multiple outputs, such as USB, dupterm and hardware UART. The challenge is
in handling cases where writing to one output is successful, but another
fails, either fully or partially. This patch implements the following
solution:
mp_hal_stdout_tx_strn() attempts to write len bytes to all of the possible
destinations for that data, and returns the minimum successful write
length.
The implementation of this is complicated by several factors:
- multiple outputs may be enabled or disabled at compiled time
- multiple outputs may be enabled or disabled at runtime
- mp_os_dupterm_tx_strn() is one such output, optionally containing
multiple additional outputs
- each of these outputs may or may not be able to report success
- each of these outputs may or may not be able to report partial writes
As a result, there's no single strategy that fits all ports, necessitating
unique logic for each instance of mp_hal_stdout_tx_strn().
Note that addressing sys.stdout.write() is more complex due to its data
modification process ("cooked" output), and it remains unchanged in this
patch. Developers who are concerned about accurate return values from
write operations should use sys.stdout.buffer.write().
This patch might disrupt some existing code, but it's also expected to
resolve issues, considering that the peculiar return value behavior of
sys.stdout.buffer.write() is not well-documented and likely not widely
known. Therefore, it's improbable that much existing code relies on the
previous behavior.
Signed-off-by: Maarten van der Schrieck <maarten@thingsconnected.nl>
If a port defines MICROPY_SOFT_TIMER_TICKS_MS then soft_timer assumes a
SysTick back end, and provides a soft_timer_next variable that sets when
the next call to soft_timer_handler() should occur.
Otherwise, a port should provide soft_timer_get_ms() and
soft_timer_schedule_at_ms() with appropriate semantics (see comments).
Existing users of soft_timer should continue to work as they did.
Signed-off-by: Damien George <damien@micropython.org>
Change the rp2 and renesas-ra ports to use the helper function.
Saves copy-pasta, at the small cost of one more function call in the
firmware (if not using LTO).
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
dcd_event_handler() is called from the IRQ when a new DCD event is queued
for processing by the TinyUSB thread mode task. This lets us queue the
handler to run immediately when MicroPython resumes.
Currently this relies on a linker --wrap hack to work, but a PR has been
submitted to TinyUSB to allow the function to be called inline from
dcd_event_handler() itself.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
C99 says that strncmp has UB for either string being NULL, so the
current behavior is technically correct, but it's an easy fix to handle
this case correctly.
7.1.4: "unless explicitly stated otherwise in the detailed
description... if an argument to a function has ...null pointer.. the
behavior is undefined".
7.21.1: "Unless explicitly stated otherwise in the description of a
particular function in this subclause, pointer arguments on such a call
shall still have valid values, as described in 7.1.4".
Also make the same change for the minimal version in bare-arm/lib.c.
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This prevents each port Makefile from having to add an explicit rule for
`build-BOARD/pins_BOARD.c`.
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This updates a small number of files that change with ruff-format's (vs
black's) rules.
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
If a non-string buffer was passed to execfile, then it would be passed
as a non-null-terminated char* to mp_lexer_new_from_file.
This changes mp_lexer_new_from_file to take a qstr instead (as in almost
all cases a qstr will be created from this input anyway to set the
`__file__` attribute on the module).
This now makes execfile require a string (not generic buffer) argument,
which is probably a good fix to make anyway.
Fixes issue #12522.
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This was previously hard-coded to "Micropy" / "Mass Storage" / "1.0".
Now allow it to be overridden by a board.
Also change "Micropy" to "MicroPy" and "1.0" to "1.00" to match stm32.
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
The DHCP server broadcasts messages. They are being sent via the default
netif which might be completely the wrong network. We want to send
messages to the netif we got the original message from.
Original author: [Peter Harper](https://github.com/peterharperuk)
Source: https://github.com/raspberrypi/pico-examples/pull/392
Signed-off-by: Samveen <samveen@samveen.in>