Hi Kevin,
I have some thoughts, but I’m not sure they all directly address your
concerns :-)
More details on directory re-org and drivers below, but I wanted to
mention upfront: I really think its worth thinking through the sensor
api you mention in your PS, and then doing the directory org after that.
Because I would imagine that these drivers fit directly into that API,
which I think is crucially important. It would be really good to
understand whether that API was sufficient for 99% of use cases as well,
because if so, we would just want to have the implementations map into
that API.
Additionally, I wanted to mention, that a worthy goal here would be to
make these sensors discoverable, in a way that can be mapped into OIC.
One of the nice things about OIC is that it supports standardized
resource discovery, and I think it would be awesome, especially for
Maker applications, if you could connect to a device with a phone, and
automatically get a list of sensors available, and interact with them.
If we make sure that the sensor APIs are introspectable, this should be
easy to do.
I also want to point out how we’ve done certain drivers, like the ADC
driver. Essentially, we have a top-level package, “adc”, which
contains the interface for all ADC drivers, and then we have the
individual implementation of the driver itself. The following source
files point to this:
* high-level ADC API: hw/drivers/adc/include/adc/adc.h
- note: 2 interfaces defined here. The driver implementation
interface: adc_driver_funcs, and the user interface calls.
* implementation of ADC for NRF52:
hw/drivers/adc/adc_nrf52/src/adc_nrf52.c
- note: only exported call is int nrf52_adc_dev_init(struct os_dev *,
void *), which is passed as a function pointer to os_dev_create() in
hal_bsp.c, when the adc device is created.
So the idea is that there is an API for the driver, and then
sub-packages to that driver that can implement that API. You have
flexibility in the sub-packages, so you could do something like:
hw/drivers/sensors/src/sensors.c (*) main sensors driver
hw/drivers/sensors/pressure/bosch/bm32/src/bm32.c (*) bm32
implementation.
Users would then create the device, with the bm32 sensor:
os_dev_create(“my_sensor”, bm32_init_func);
But can then open and use the device with the generic sensor API,
without knowing the underlying implementation.
sensor = (struct sensor *) os_dev_open(“my_sensor”)
sensor_read(sensor, &val);
I assume you read most of this, but I just wanted to point this out.
As an aside: I certainly think we should use pkg.keywords extensively in
the drivers directory, and make it easy to search for drivers. We
should also make sure that “newt pkg search”: a) works, and b)
provides useful information about each of the drivers when there are
matches. There is going to be no _perfect_ way to organize this for
ease of discovery, but I think newt can help a lot.
On 10 Nov 2016, at 1:59, Kevin Townsend wrote:
There are no sensor drivers in the system at present, but now that the
HAL rework is complete I wanted to port a few drivers over to Mynewt
just to properly test the HW and HAL out. Existing sensor drivers is
one of the key factors to draw people into any embedded RTOS/system,
so I think it's important to get this right to pull people into the
Mynewt ecosystem.
+1 - I totally agree!
I'm curious what kind of organization would make the most sense moving
forward, though. Assuming some drivers are included in the core mynewt
repo instead of being in independent libraries, what would be an ideal
root location to place them in the file structure?
- hw/drivers/sensors ?
Do we think that 90% of sensors will have a unified interface. I.e.
sensors have discoverable channels, and those channels have value types.
sensor_discover(sensor, &sensor_chan_types);
assert(sensor_chan_types[0]->type == SENSOR_ACCEL_X);
sensor_read(sensor, 0, &accel_x);
And you can have unified interface to configure these (e.g.
sensor_config()), that might take an opaque blob, but is pretty
standard.
If so, I think you have a driver of type: sensor, that defines the
sensor API, and then you have subdirectories from there, which implement
the sensor API.
The problem is that hw/drivers already has things like adc and uart
implementations or nimble which is quite a different concept, though
it's not entirely inappropriate all the same.
Yeah. we’re going to have to be very disciplined about how we
organize this directory and break drivers into groups.. Irregardless of
where we put sensor, I think this is the case.
And inside sensors (or wherever) you'll have another problem: should
you have a single flat list of all drivers by device name, or do you
want to organize them by type/manufacturer/etc.:
* hw/drivers/sensors/bmp085/*
* hw/drivers/sensors/bmp280/*
* hw/drivers/sensors/tsl2651/*
* hw/drivers/sensors/lsm303dlhc/*
* hw/drivers/sensors/bno055/*
Or do you want to organize them by family (which is nice in some ways
but very awkward in others with certain SoCs):
* hw/drivers/sensors/pressure/bmp085/*
* hw/drivers/sensors/pressure/bmp280/*
* hw/drivers/sensors/light/tsl2561/*
* hw/drivers/sensors/accelerometers/lsm303dlhc/* <-- This is also a
magnetometer!
* hw/drivers/sensors/orientation???/bno055/* <-- this is an accel,
mag
and gyro with sensor fusion for orientation
Or does manufacturer make more sense:
* hw/drivers/sensors/bosch/bmp085/*
* hw/drivers/sensors/bosch/bmp280/*
* hw/drivers/sensors/bosch/bno055/*
* hw/drivers/sensors/taos/tsl2561/* <-- Complicated since Taos was
purchased and is now AMS, which is a recurring theme these days
* hw/drivers/sensors/st/lsm303dlhc/*
My preference would probably be by manufacturer. As you mention, often
sensors are multi-purpose. I also think that the collection of code
that is common is likely going to be by manufacturer (e.g. bosch.)
so you have hw/drivers/sensor as the API, and
hw/drivers/sensor/bosch/bmp085/src/bmp085.c as the implementation.
It would likely be useful to have some sort of basic meta-data as well
about the sensor types since some ICs can contain multiple sensors,
such as the bmp280 being a pressure sensor but also having temperature
data, or the lsm303dlhc being a 3 axis accelerometer and magnetometer.
This meta-data isn't critical, but could be useful as a filter at some
point using the newt tool or the newt 'newt vals' type functionality.
+1
I also think it would be great if this could be
introspectable/discoverable at runtime. I’m thinking it would make
things like a TI sensor tag really easy to implement from a phone
perspective.
Adding drivers to the core repo is problematic in that it creates a
maintenance burden, but I think drivers are also a huge pull for
people to use the system and an important reference to keep up to date
with changes in the HAL over time. There should at least be one
reference for each bus like I2C, SPI, ADC and UART (GPS etc.) that
makes use of the power management API, etc. Having a maintained
reference driver will reduce support requirements long term, and
ensure best practices are followed by people contributing other
drivers in the future.
I think this is a no-brainer. The value of an operating system is that
a community of people maintains this software, and for the type of
devices Mynewt goes into, sensors are a very common thing. Even if
writing each individual driver isn’t that hard, there are certainly
edge cases with this type of hardware, and having other people find and
maintain those for you is very valuable.
Sterling