← index #2093Issue #1504
Related · high · value 0.825
QUERY · ISSUE

RFC: Sensor driver interface

openby pfalconopened 2016-05-21updated 2025-10-01
rfc

As one of the latest KS stretch goals, we need to implement suite of drivers for number of sensors, and it would be nice to come up with a general sensor driver model to follow.

Requirements:

  1. A general, baseline interface (userstory: "I have a hundred of sensors, how do I use them in similar manner of any MicroPython port", not: "My project is centered around capabilities of a particular sensor, how do I expose them?")
  2. The general requirement is avoiding memory allocations to perform sensor reading
  3. One of the biggest contention points is usage of floating-point vs fixed points numbers, and if the latter, then how. Given that floating-point support is optional, and may lead to memory allocation, would be strongly nice to support (allocation-free) fixed point.
  4. Should be general enough for any sensor (including sensors which measure several values).
  5. There should be balance between efficiency tricks and pythonic ease of use.
CANDIDATE · ISSUE

RFC: configurablility of object representation, especially with respect to floats

closedby dpgeorgeopened 2015-10-12updated 2018-08-27
rfc

There is a need to make a more comprehensive selection of object models (ie how uPy objects are represented in a machine word). They would be configurable at compile time. In particular there is a need to have more flexibility with floating point representation so floats can be used without the heap. There are 3 driving use-cases: ESA, microbit, and floats in interrupts on pyboard.

I foresee the following:

  1. Floats always stuffed in an object word.
  2. Floats stuffed and on the heap.
  3. 64-bit NaN boxing.

Float stuffing is similar to int stuffing, except that we need to truncate the mantissa to fit. It depends on whether the word size is 32-bit or 64-bit, and what precision float you have. To keep it simple for now, here is the scheme I came up with for single precision float stuffing on a 32-bit machine:

iiiiiiii iiiiiiii iiiiiiii iiiiiii1 small int, i's are the 31-bit signed value
01111111 11qqqqqq qqqqqqqq qqqqqq10 str object with 20-bit qstr value
11111111 11qqqqqq qqqqqqqq qqqqqq10 bytes object with 20-bit qstr value (optional)
s1111111 10000000 00000000 00000010 +/- inf (lower 2 bits -> 0)
x1111111 101xxxxx xxxxxxxx xxxxxx10 nan (ok as-is, but could put lower 2 bits -> 0)
seeeeeee efffffff ffffffff ffffff10 30-bit fp, e != 0xff (lower 2 bits -> 0)
pppppppp pppppppp pppppppp pppppp00 ptr (4 byte alignment)

The trick is to truncate the last 2 bits of the single precision float (so it's stored as 30-bits) and then use 30-bit nan boxing within that 30-bit float to store qstr strings.

With float stuffing like this, no heap is needed for floating point objects. Downside is that all floats are stored in 30-bit precision. This is a loss in precision of about 1 part per million so not a great loss, and would be a good option for some ports that are low on RAM.

Of course, the big advantage of no heap for floats is that you can do floating point operations within an interrupt.

And we can actually keep 32-bit precision outside interrupts by the following trick: we allow 2 different float objects, one is stuffed and the other is the existing heap version. When extracting a float value from an object you just need to check if it's stuffed or a pointer, it's pretty easy and relatively efficient. When creating a float object, if the heap is locked then return a stuff float, otherwise allocate on the heap. So that's option 2 above, stuffed + heap.

The 64-bit NaN boxing option, option 3, is just standard boxing (see eg JavaScript, Lua). On a 32-bit machine the object size becomes 64-bit.

We could support 64-bit stuffing (ie truncate to 62-bit on a 64-bit machine) and that might be useful for testing etc.

Implementation of stuff floats is relatively easy (I already have a working patch). 64-bit NaN boxing is a bit harder.

One issue will be configuring all this and providing clear config options. At the moment we just use MICROPY_OBJ_REPR with current options being MICROPY_OBJ_REPR_A and MICROPY_OBJ_REPR_B (latter is for 16-bit systems, but works on 32-bit as well). Maybe we need more descriptive names?

Comments welcome!

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied