Paul -
I think you make a number of good points here, but I'm not sure all of
them argue for re-organizing the HAL, but perhaps just improving the
existing structure.
The purpose of the HAL is to abstract MCU peripheral functions, and make
that portable across various MCU architectures. This is why the HAL
APIs are defined in the hw/hal package, but the implementation for the
HAL lives in the various mcu support packages in hw/mcu (*).
I think it makes sense to group the definition of MCU support functions
together. That way, as people use it, and contribute support back --
support for a given processor grows in a cohesive fashion. Now, of course:
- Not all MCUs will implement all HAL interfaces (e.g. DMA v non-DMA chips)
- Not all HAL implementations are going to be complete: if I don't use
the ADC on a chip, am I going to spend my time developing a MCU support
package for it?
I think, however, that this can be exposed both:
- At runtime, with HAL introspection APIs
- At package/compile time, using capabilities (MCU packages export more
fine grained hal capabilities, e.g. hal-adc, hal-adc-outc)
That way people who are searching for MCU support packages, can inspect
what aspects of the HAL are/aren't implemented (view capabilities.)
I think then, on top of the HAL there can be more complex drivers for
everything you want to do with it. As an example, hal-gpio would just
have on/off, and read state (abstracting peripherals): but you might
distribute a gpio-led package on top of that, which had common functions
for controlling LEDs through GPIO (PWM for color, etc.) This driver
would require that their be a hal-gpio capability present, but it
wouldn't need to specify the specific support package necessary.
Fundamentally, I think the question comes down to me: where do you want
the implementation of MCU specific functionality to live. Ideally MCU
support is in a single package/set of packages in hw/mcu that is being
constantly improved for all peripheral interfaces. The HAL then becomes
a glue to let all the higher layer drivers operate, without knowing
about the specifics of the underlying MCU implementation.
Thoughts?
Sterling
(*) hw/hal does take some definitions from the BSP. I'm more inclined
to move these out of the HAL, and have the HAL just be MCU support. But
that is a discussion for another day.
On 2/18/16 4:32 PM, p...@wrada.com wrote:
Just wanted to pass on some thoughts I had today about the hal ...
I was thinking about how much is in a hal, how it will grow over time and how to tell
"how complete" a given hal is. And more importantly how to provide simple
stuff that does basic HW (like polling GPIO) while allowing advanced features of chips
that support it.
Let's consider one example: ADC.
For now assume that the customer wants a simple way to poll ADC. So they go to newt and
look at possible packages with "*adc*".
The find
Libs/poll_adc
Libs/adc_periodic
Libs/adc_compare
And perhaps some custom ADC libraries that are not hardware agnostic written by
HW vendors that want to provide the best interfaces to their products (open
source is great)
Which is my trying to say that there is different functionality that they may
want from adc and generally folks don't want to learn anything more than they
have to especially with these frameworky things that are already hard to get
your head around.
The chose the simple one since they are not ready to do anything fancy and just
want to see it working. And add it to their project.yml file.
Now lets consider their Hardware platform they have. Suppose the customer has
the following different combinations of hardware
1. A board with an MCU with ADC channels built into the MCU
2. A board with an MCU with no ADC channels
3. A board with an external SPI ADC device (possibly to replace the
internal ADC that was not accurate enough).
They include libs/poll_adc into their project ... if it were me I'd want the
dependency system to say that "unresolved dependency, libs/poll_adc requires a
driver that implements hw/simple_adc_driver. The following packages implement
hw/simple_adc_driver:
* samd21/adc
* nr52/adc
* ..
* sim/adc
* stub/adc
* mcp3008/adc (This is an external SPI ADC)
The customer now knows what is available or what they need to write. This may
be an important step. For example suppose they have both #1 and #3 and have
internal and external ADC for different purposes (not accurate enough etc).
How to they select that they are binding the ADC to #3 or #1. Or do they get
to? Do we need to make sure its their choice, but we give them enough guidance
to make it easy? What if the customer wants both an internal and external ADC
through our simple API?
They just chose the one for their internal ADC and move on. Now they build and
get some unresolved external
Unersolved reference to bspProvideADCConfig()
They gather that they need to provide the info in this function and go fill it
out. This seemingly would have a different API for every device since the
different devices might have the need for different settings. For example, the
external one might be looking for a spi port while the internal ones may be
looking for pins. The sim version might be looking for a function pointer
that for a function that returns a fake A/D sample.
Either way they implement this using the prototype in the adc package they
selected and they are off and running. Done...
They might have the same experience for ADC, DAC, SPI, GPIO, PWM, I2C, CAN,
ZIGBEE, WIFI, Bluetooth, etc. I would think we would want all of these
peripheral components to work the same way. Given that, maybe the hal should
be reserved for OS critical functions only and the rest should be libraries.
Comments from folks. Do you think that this is too complicate. Do we want to
ensure that chip vendors making spi components can write drivers for mynewt
that have a dependency on an MCU SPI port without knowing which SPI port
implementation they are using. In other words, they provide hw/simple_adc and
that depends on hw/spi .
Just food for thought. Not sure whether this is doable or even worth it, just
trying to imagine when all hardware vendors just write a mynewt driver for
their sensor, MCU, etc as standard practice to sell them. Want to make sure
that is possible, easy and flexible enough to support non MCU parts.