Compare the full absolute path instead of relying on the path form
passed by the user.
For instance, this will make
python3 run-tests.py -d basics
python3 run-tests.py -d ./basics
python3 run-tests.py -d ../tests/basics
python3 run-tests.py -d /full/path/to/basics
all behave the same by correctly treating the bytes_compare3 and
builtin_help tests as special, whereas previously only the first
invocation would do that and hence result in these tests to fail
when called with a different path form.
Signed-off-by: stijn <stijn@ignitron.net>
Increases firmware size by +140 bytes and uses +4 extra bytes of RAM, but
allows the test suite to run without crashing.
Signed-off-by: Damien George <damien@micropython.org>
Flash sectors should start counting at 0 for each bank. This commit makes
sure that is the case on all H5 and H7 MCUs, by using `get_page()` instead
of `flash_get_sector_info()`.
Signed-off-by: Damien George <damien@micropython.org>
This commit removes the need for a separate `flash_cache_sector_id`
variable, instead using `flash_cache_sector_start` to indicate which sector
is curretly cached (and -1 indicates no sector).
Signed-off-by: Damien George <damien@micropython.org>
An erase sector sits in a given flash bank and some MCUs have two flash
banks. If trying to erase a range of sectors and that range crosses from
one flash bank into the next, the original implementation of
`flash_erase()` would not handle this case and would do the wrong thing.
This commit changes `flash_erase()` to only erase a single sector, which
sidesteps the need to handle flash-bank-crossing. Most callers of this
function only need to erase a single sector anyway.
Signed-off-by: Damien George <damien@micropython.org>
Newer STM32 parts have homogeneous flash layout, and in this case the MCU
configuration and page/sector calculation can be simplified. The affected
functions are `flash_is_valid_addr()` and `flash_get_sector_info()`, which
are now simpler for homogeneous flash.
Signed-off-by: Damien George <damien@micropython.org>
This commit replaces the linker symbol `_mboot_writable_flash_start` with
`_mboot_protected_flash_start` and `_mboot_protected_flash_end_exclusive`,
to provide better configuration of the protected flash area.
Signed-off-by: Damien George <damien@micropython.org>
Following ad806df857 where the
MICROPY_PY_PENDSV_ENTER/REENTER/EXIT macro definitions were moved to
mphalport.h.
Signed-off-by: Damien George <damien@micropython.org>
Codespell doesn't pick up "re-used" or "re-uses", and ignores the tests/
directory, so fix these manually.
Signed-off-by: Damien George <damien@micropython.org>
Implement the typical 're-run the failed tests' most test runners have, for
convenience. Accessible via the new --run-failures argument, and
implemented using a json file containing a list of the failed tests.
Signed-off-by: stijn <stijn@ignitron.net>
Otherwise running the tests can take a long time when the server is a slow
target (RP2040 takes 23 seconds for a handshake when using 4096-bit RSA).
Also add instructions on how to generate elliptic curve key/certs.
Signed-off-by: Damien George <damien@micropython.org>
This matches the behaviour of run-tests.py, which sets cwd to the directory
containing the test script, which helps to isolate the filesystem.
It means that the SSL tests no longer need to know the name of their
containing directory to find the certificate files, and helps to run these
tests on bare-metal.
Signed-off-by: Damien George <damien@micropython.org>
The existing thread_sleep1.py test only tests execution, not accuracy, of
time.sleep. Also the existing test only tests sleep(0) on targets like rp2
that can only create a single thread.
The new test in this commit checks for timing accuracy on the main thread
and one other thread when they run at the same time.
Signed-off-by: Damien George <damien@micropython.org>
The aim of this commit is to make it so that the existing thread tests can
be used to test the _thread module on the rp2 port. The rp2 port only
allows up to one thread to be created at a time, and does not have the GIL
enabled.
The following changes have been made:
- run-tests.py skips mutation tests on rp2, because there's no GIL.
- run-tests.py skips other tests on rp2 that require more than one thread.
- The tests stop trying to start a new thread after there is an OSError,
which indicates that the system cannot create more threads.
- Some of these tests also now run the test function on the main thread,
not just the spawned threads.
- In some tests the output printing is adjusted so it's the same regardless
of how many threads were spawned.
- Some time.sleep(1) are replaced with time.sleep(0) to make the tests run
a little faster (finish sooner when the work is done).
For the most part the tests are unchanged for existing platforms like esp32
and unix.
Signed-off-by: Damien George <damien@micropython.org>
Prior to this commit there is a potential deadlock in
mp_thread_begin_atomic_section(), when obtaining the atomic_mutex, in the
following situation:
- main thread calls mp_thread_begin_atomic_section() (for whatever reason,
doesn't matter)
- the second core is running so the main thread grabs the mutex via the
call mp_thread_mutex_lock(&atomic_mutex, 1), and this succeeds
- before the main thread has a chance to run save_and_disable_interrupts()
a USB IRQ comes in and the main thread jumps off to process this IRQ
- that USB processing triggers a call to the dcd_event_handler() wrapper
from commit bcbdee2357
- that then calls mp_sched_schedule_node()
- that then attempts to obtain the atomic section, calling
mp_thread_begin_atomic_section()
- that call then blocks trying to obtain atomic_mutex
- core0 is now deadlocked on itself, because the main thread has the mutex
but the IRQ handler (which preempted the main thread) is blocked waiting
for the mutex, which will never be free
The solution in this commit is to use mutex enter/exit functions that also
atomically disable/restore interrupts.
Fixes issues #12980 and #13288.
Signed-off-by: Damien George <damien@micropython.org>
Using the multicore lockout feature in the general atomic section makes it
much more difficult to get correct.
Signed-off-by: Damien George <damien@micropython.org>
This commit enables additional features for SAMD21 with external flash:
- Viper and native code support. On a relatively slow devices, viper and
native code can be helpful.
- Freeze the asyncio scripts and add the select module.
- Enable Framebuffer support.
- Enable UART flow control.
- Enable a few more features from the extra features set.
Drop onewire and asyncio support from SAMD21 firmware without external
flash, leaving a little bit more room for future extensions. Asyncio was
anyhow incomplete.
Signed-off-by: robert-hh <robert@hammelrath.com>
RTC is enabled on all boards. Therefore the conditional compile is not
needed. Removing it simplifies the source code a little bit.
Signed-off-by: robert-hh <robert@hammelrath.com>
Fixes a wrong assignment for Sparkfun SAMD51 Thing Plus, and updates the
sample script for printing the pin info table.
Signed-off-by: robert-hh <robert@hammelrath.com>
Instead, configure the default once at compile-time. This means the GAP
name will no longer be set to default after re-initializing Bluetooth.
Signed-off-by: Daniël van de Giessen <daniel@dvdgiessen.nl>
This commit implements fairly complete support for the DMA controller in
the rp2 series of microcontrollers. It provides a class for accessing the
DMA channels through a high-level, Pythonic interface, and functions for
setting and manipulating the DMA channel configurations.
Creating an instance of the rp2.DMA class claims one of the processor's DMA
channels. A sensible, per-channel default value for the ctrl register can
be fetched from the DMA.pack_ctrl() function, and the components of this
register can be set via keyword arguments to pack_ctrl().
The read, write, count and ctrl attributes of the DMA class provide
read/write access to the respective registers of the DMA controller. The
config() method allows any or all of these values to be set simultaneously
and adds a trigger keyword argument to allow the setup to immediately be
triggered. The read and write attributes (or keywords in config()) accept
either actual addresses or any object that supports the buffer interface.
The active() method provides read/write control of the channel's activity,
allowing the user to start and stop the channel and test if it is running.
Standard MicroPython interrupt handlers are supported through the irq()
method and the channel can be released either by deleting it and allowing
it to be garbage-collected or with the explicit close() method.
Direct, unfettered access to the DMA controllers registers is provided
through a proxy memoryview() object returned by the DMA.registers attribute
that maps directly onto the memory-mapped registers. This is necessary for
more fine-grained control and is helpful for allowing chaining of DMA
channels.
As a simple example, using DMA to do a fast memory copy just needs:
src = bytearray(32*1024)
dest = bytearray(32*1024)
dma = rp2.DMA()
dma.config(read=src, write=dest, count=len(src) // 4,
ctrl=dma.pack_ctrl(), trigger=True)
# Wait for completion
while dma.active():
pass
This API aims to strike a balance between simplicity and comprehensiveness.
Signed-off-by: Nicko van Someren <nicko@nicko.org>
Signed-off-by: Damien George <damien@micropython.org>
This allows to follow good practice and have libraries live in the lib
folder which means they will be found by the runtime without adding this
path manually at runtime.
Signed-off-by: Sebastian Romero <s.romero@arduino.cc>
When compiling with distcc, it does not understand the -MD flag on its own.
This fixes the interaction by explicitly adding the -MF option.
The error in distcc is described here under "Problems with gcc -MD":
https://www.distcc.org/faq.html
Signed-off-by: Peter Züger <zueger.peter@icloud.com>
The calculation of the lfs2 cache_size was incorrect, the maximum allowed
size is block_size.
The cache size must be: "a multiple of the read and program sizes, and a
factor of the block size".
Signed-off-by: Peter Züger <zueger.peter@icloud.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>
In case of multiple outputs, the minimum successful write length is
returned. In line with this, in case any output has a write error, zero is
returned.
In case of no outputs, -1 is returned.
The return value can be used to assess whether writes were attempted, and
if so, whether they succeeded.
Signed-off-by: Maarten van der Schrieck <maarten@thingsconnected.nl>
This adds a `add_library(name, path)` method for use in manifest.py that
allows registering an external path (e.g. to another repo) by name.
This name can then be passed to `require("package", library="name")` to
reference packages in that repo/library rather than micropython-lib.
Within the external library, `require()` continues to work as normal
(referencing micropython-lib) by default, but they can also specify the
library name to require another package from that repo/library.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>