GIL behaviour should be handled by the port. And ports probably want to
define sleep_us so that it doesn't release the GIL, to improve timing
accuracy.
This patch refactors the error handling in the lexer, to simplify it (ie
reduce code size).
A long time ago, when the lexer/parser/compiler were first written, the
lexer and parser were designed so they didn't use exceptions (ie nlr) to
report errors but rather returned an error code. Over time that has
gradually changed, the parser in particular has more and more ways of
raising exceptions. Also, the lexer never really handled all errors without
raising, eg there were some memory errors which could raise an exception
(and in these rare cases one would get a fatal nlr-not-handled fault).
This patch accepts the fact that the lexer can raise exceptions in some
cases and allows it to raise exceptions to handle all its errors, which are
for the most part just out-of-memory errors during construction of the
lexer. This makes the lexer a bit simpler, and also the persistent code
stuff is simplified.
What this means for users of the lexer is that calls to it must be wrapped
in a nlr handler. But all uses of the lexer already have such an nlr
handler for the parser (and compiler) so that doesn't put any extra burden
on the callers.
For example, if the current directory is the root dir then this patch
allows one to do uos.listdir('mnt'), where 'mnt' is a valid mount point.
Previous to this patch such a thing would not work, on needed to do
uos.listdir('/mnt') instead.
By adding back monotonically increasing field in addition to time field.
As heapsort is not stable, without this, among entried added and readded
at the same time instant, some might be always selected, and some might
never be selected, leading to scheduling starvation.
Allows to iterate over the following without allocating on the heap:
- tuple
- list
- string, bytes
- bytearray, array
- dict (not dict.keys, dict.values, dict.items)
- set, frozenset
Allows to call the following without heap memory:
- all, any, min, max, sum
TODO: still need to allocate stack memory in bytecode for iter_buf.
If the mounted object doesn't have a "mount" method then assume it's a
block device and try to detect the filesystem. Since we currently only
support FAT filesystems, the behaviour is to just try and create a VfsFat
object automatically, using the given block device.
Each method asserts and deasserts signal respectively. They are equivalent
to .value(1) and .value(0) but conceptually simpler (and may help to avoid
confusion with inverted signals, where "asserted" state means logical 0
output).
SPI needs to be fast, and calling the EVENT_POLL_HOOK every byte makes it
unusable for ports that need to do non-trivial work in the EVENT_POLL_HOOK
call. And individual SPI transfers should be short enough in time that
EVENT_POLL_HOOK doesn't need to be called.
If something like this proves to be needed in practice then we will need
to introduce separate event hook macros, one for "slow" loops (eg
select/poll) and one for "fast" loops (eg software I2C, SPI).
machine.time_pulse_us() is intended to provide very fine timing, including
while working with signal bursts, where each transition is tracked in row.
Throwing and handling an exception may take too much time and "signal loss".
So instead, in case of a timeout, just return negative value. Cases of
timeout while waiting for initial signal stabilization, and during actual
timing, are recognized.
The documentation is updated accordingly, and rewritten somewhat to clarify
the function behavior.
A signal is like a pin, but ca also be inverted (active low). As such, it
abstracts properties of various physical devices, like LEDs, buttons,
relays, buzzers, etc. To instantiate a Signal:
pin = machine.Pin(...)
signal = machine.Signal(pin, inverted=True)
signal has the same .value() and __call__() methods as a pin.
This provides mp_vfs_XXX functions (eg mount, open, listdir) which are
agnostic to the underlying filesystem type, and just require an object with
the relevant filesystem-like methods (eg .mount, .open, .listidr) which can
then be mounted.
These mp_vfs_XXX functions would typically be used by a port to implement
the "uos" module, and mp_vfs_open would be the builtin open function.
This feature is controlled by MICROPY_VFS, disabled by default.
If MICROPY_VFS_FAT is enabled by a port then the port must switch to using
MICROPY_FATFS_OO. Otherwise a port can continue to use the FatFs code
without any changes.
import utimeq, utime
# Max queue size, the queue allocated statically on creation
q = utimeq.utimeq(10)
q.push(utime.ticks_ms(), data1, data2)
res = [0, 0, 0]
# Items in res are filled up with results
q.pop(res)
So long as a port defines relevant mp_hal_pin_xxx functions (and delay) it
can make use of this software SPI class without the need for additional
code.
These are basic drawing primitives. They work in a generic way on all
framebuf formats by calling the underlying setpixel or fill_rect C-level
primitives.