I should also mention, another option that we could do is have drivers
for the individual sensors (just have them expose native APIs as
drivers, e.g. bmp2085_read_val()), but also map into a generic sensor
API, that we locate in hw/sensors, as an example.
I’m not sure to what extent people using these sensors want raw access
to them (i.e. this sensor has special features I care about), versus
just treating them as a generic sensor. If we think it will be common
to have special features per-sensor, i’d say it makes sense to have:
hw/sensors — generic sensor API
and then
hw/drivers/sensors/
contain individual sensor drivers organized by manufacturer, that create
their own device APIs, but also can register with the sensor API in
hw/sensors.
Sterling
On 10 Nov 2016, at 15:42, Sterling Hughes wrote:
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