Version 3.0.0 is
released!
This is a breaking changes major version bump, refactoring many APIs based on
the learnings made in the past year, acquired hindsight by fine tuning drivers
and feedback from users.
We do not take breaking users lightly!
Every single breaking change was done thoughtfully. We consider users have the
right for an explanation why their time is spent on this, so this document lists
the rationale for every single breaking change.
Highlight
The refactorings enabled:
The rationale is that host provides resources
that devices drivers in package devices
can leverage. Having host/… depend on
devices creates a import loop.
This is now a very clean design.
Breaking changes
You will likely be affected by the following changes. They are described along
the rationale, expected symptom and what you have to do to update your client
code:
- conn/gpio: Merged PinDefaultPull into
PinIn, PinPWM into PinOut.
- Rationale: The PinDefaultPull and PinPWM were added in v2 to not expand
PinIn and PinOut, which we considered a breaking change. Merging the
interfaces simplifies utilisation.
- Symptom: Compile error.
- Required work: Simplify references by removing the cast to PinDefaultPull or
PinPWM, they are now unnecessary.
- conn/i2c and
conn/spi: Change all the
hz
parameters to use physic.Frequency. This affects the functions Connect(),
LimitSpeed() and SetSpeed().
- Rationale: This enables a 0.000001 Hertz resolution consistently across the
package, and enables methods like Duration() to convert to time.Duration.
This enables using constants like MegaHertz, which makes easier to read
expressions like
10 * physic.MegaHertz
versus 10000000
. A
ParseFrequency() ala
ParseDuration() is planned but
I ran out of time.
- Symptom: Runtime error, either the driver refuses the specified frequency or
everything runs at a one millionth the desired speed (or 0).
- Required work: Multiply the value with Hertz, KiloHertz or MegaHertz.
- conn/physic: Increase
RelativeHumidity precision by 10x.
- Rationale: the BME280 has an higher precision that what RelativeHumidity was
providing.
- Symptom: humidity value is 10x larger than expected.
- Required work: Use the RH constants in package physic.
- devices: Was stripped of most of its
types into physic.
- Rationale: This required drivers in host (like sysfs) to import package
devices, which was a layering violation.
- Symptom: Compile error.
- Required work: Replace imports of package devices with physic.
- devices: most types were renamed while
moved into physic, and many had
their base type changed.
- Rationale: Separate the what (e.g. Temperature) from the unit (e.g.
MilliKelvin, MilliFahrenheit). This is largely inspired by
time.Duration, which has constants
for MicroSecond, Second, Minute, etc. We decided to stick with fixed point
instead of floating point as this enables deterministic calculation across
platforms. We are open to revisiting this decision in v4 based on the
feedback.
- Symptom: Compile error, invalid runtime behavior due to incorrect constants.
- Required work: Update references like devices.Celsius, KPascal,
Environment to their physic counter parts: Temperature, Pressure, Env. Use
the constants (Kelvin, Pascal, MicroRH) in physic to convert the units,
similar to how one would do with time.MicroSecond.
- devices: Moved the interface
devices.Display as Drawer in a new
conn/display package.
- Rationale: the package devices is only a container for device drivers, not a
location to define interfaces.
- Symptom: Compile error.
- Required work: Update references of devices.Display to display.Drawer,
devices/devicetest
: Moved to
conn/display/displaytest
- Rationale: coherency with the mode of devices.Display.
- conn/display: changed Drawer.Draw()
to return an error. We also clarified that the device driver is expected to
support incremental update, which requires a full frame buffer.
- Rationale: Draw() didn’t return an error to lookalike the draw.Drawer
interface but that was irrelevant.
- Symptom: Compile error for device drivers. User code not checking for error.
- Required work: Update device drivers, check error value.
Driver specific changes
This changes will affect you if you use this device driver:
- devices/apa102,
devices/bmxx80,
devices/ds248x,
devices/ssd136: Use Opts pattern
instead of individual arguments in the New() function.
- Rationale: This is extensible. This permits to consider adding more members
to Opts a non breaking change, which opens the door to add more
functionality to a device driver without having to wait for v4. Use a
DefaultOpts struct instance instead of a function to use more data instead
of code.
- Symptom: Compile error.
- Required work: Update the New() call to pass an Opts instance, likely using
DefaultOpts. Initialize the Opts member via their name, never by order. Use
bmxx80.Opts{Temperature: bmxx80.O4x, Pressure: bmxx80.O1x, Humidity: bmxx80.O1x, Filter: bmxx80.NoFilter}
, not the short form
bmxx80.Opts{bmxx80.O4x, bmxx80.O1x, bmxx80.O1x, bmxx80.NoFilter}
.
- devices/ds18b20: Replaced
Temperature() method with physic.SenseEnv implementation.
- Rationale: This makes this sensor behaves like any other temperature sensor,
so that
physic.SenseEnv
can be passed around.
- Symptom: Compile error.
- Required work: Update the dev.Temperature() call to use dev.SenseEnv().
- devices/ds248x: Remove I²C
address from the options, to NewI2C() as an explicit argument.
- Rationale: Coherency with all the other device drivers, which pass the I²C
address to NewI2C(). The rationale is that many devices support both SPI and
I²C, so putting the I²C device address in Opts results in an ambiguous
option.
- Symptom: Compile error.
- Required work: update call to New().
- devices/lepton: Remove cs
argument from New().
- Rationale: This was a hack trying to work around issues in the Raspberry Pi
driver, but this was incorrect. The driver now use the SPI’s connection CS
pin normally.
- Symptom: Compile error.
- Required work: Update call to New().
- devices/lepton: Frame uses
image14bit.Gray14 instead of image.Gray16.
- Rationale: A perf test determined that using []byte to store uint16 values
is significantly slower than using []uint16. It is also clunky to use. This
permits using Intensity14 as the ColorModel, which uses 8191 as full
intensity.
- Symptom: Compile error.
- Required work: Update client code to use
image14bit.
- devices/lepton: Replaced
ReadImg() with NextFrame().
- Rationale: ReadImg() required doing a memory allocation at every call,
NextFrame() permits reusing Frame instances, reducing heap churn.
- Symptom: Compile error.
- Required work: Update client code to preallocate the frame with
f := Frame{Gray14: image14bit.NewGray14(dev.Bounds())}
.
Lesser changes
These changes have no required work unless you wrote a device driver:
- cmd/apa102: Default intensity
increased from 127 to 255.
- conn: Add String() to Resource.
- Rationale: This permits to have a clear naming convention to help explain
the user what is being used. This enables removing a lot of dependency on
fmt.
- conn/gpio: Changed DutyMax from
1«16-1 to 1«24.
- Rationale: The fact that it was 1«16-1 was to keep it under 16 bits but
caused usability issues, as half wasn’t an exact number.
- Symptom: Invalid runtime behavior due to incorrect constants.
- Required work: Use values in referece to DutyMax.
- conn/gpio: PWM() now accepts a
physic.Frequency instead of time.Duration period.
- Rationale: While clock period is logical, it is really hard to relate. Users
will have a much easier time to understand 10kHz than 100µs.
- Symptom: Compile error.
- Required work: Use frequency instead of clock period.
- conn/gpio: Pull constants changed,
PullNoChange is now 0, instead of Float.
- Rationale: It is default value, which is more useful (and expected) than
Float.
- Symptom: Invalid runtime behavior due to incorrect constants.
- Required work: Explicitly specify Float where it was assumed to be the
default.
- conn/gpio/gpioreg: Remove
prefered argument to Register().
- Rationale: The reason that led to this argument were not needed anymore.
This was due to parallelism between sysfs-gpio and CPU GPIO drivers.
- conn/gpio/gpiostream:
Rewrote.
- Rationale: Its implementation proved to be suboptimal. Since this package
wasn’t used much yet, now was the right time to refactor it.
- conn/gpio/gpiotest: PinPWM
was merged into Pin.
- Rationale: This follows that gpio.PinPWM was merged into gpio.PinOut.
- conn/pin: pin.Pin is now a
conn.Resource, so it implements Halt().
- Rationale: Make everything a Resource, so they can be enumerated (via
String()) and halted on shutdown if desired.
- conn/physic: Added
SenseEnv.Precision(), implemented in all drivers.
- Rationale: It is useful for the application to know at which precision the
sensor is making its measurement.
- host/sysfs: Renamed SetSpeedHook to
I2CSetSpeedHook.
- Rationale: This function is I²C specific, but it was not clear from the
name.
- periph: Added After() to interface Driver.
- Rationale: Was needed to untangle the sysfs-gpio and CPU drivers, and host
pin headers. This enabled automatic fallback to sysfs GPIO driver when sysfs
loaded but the CPU GPIO driver failed to load, which may require running as
root.
Additional improvements
These are not breaking changes:
- cci: implements SenseEnv to
be used as a temperature sensor. This returns the housing temperature.
- Rationale: This permits to use all the temperature sensors connected to a
host in the same way.
- experimental: Many drivers were
improved towards being moved into non-experimental. These are not considered
breaking changes.
- The code is now tested on go1.5.4. This makes it easier for users to just
apt install golang
and immediately get going.
- conn: Removed all dependencies on /devices
or /host, by moving the smoketests under /cmd/periph-smoketest. Added travis
checks to verify.
Going forward
Some of the changes here are to enable new drivers like the FT232H and FT232R,
which enables a less Linux-focused driver support.
Thanks
I’d like to thanks for all the folks on the slack channel for the feedback and
code reviews. The project would be much less awesome without them!
Found bugs? Have questions?
Follow twitter.com/periphio for news and
updates!