Topics

HALs in Zephyr (was Re: STM32Cube SDK in Zephyr)


Amit Kucheria
 

Hi Erwan,

On Thu, Nov 3, 2016 at 8:07 PM, Erwan Gouriou <erwan.gouriou(a)linaro.org> wrote:
Hi all,


There are growing number of STM32 based boards being ported in Zephyr
by the community. As part of ST, I can say that we are pleased to contribute
this way to Zephyr impact in IoT world.

In order to ease porting of STM32 devices, we'd like to introduce STM32Cube
SDK into Zephyr. Aim is to make porting fast and easy thanks to ST CSMIS
files, reduce code duplication and provide mature software with STM32Cube
adaptation layers (HAL and LL).
I'm all for allowing Zephyr to quickly add support for as much
hardware as possible and if HALs are the way to do it, then so be it.

However, I'd like to hear from Zephyr maintainers on whether this is
just a short-term strategy to get broad hardware support or the long
term goal because HALs do make for hard-to-read code[1] and each
vendor's HAL is different leading to further maintenance issues.

I ask this coming from a Linux development mindset where HALs are
actively discouraged.

About STM32Cube CMSIS files:
Proposition for now is to move progressively towards the support of
STM32Cube
on available STM32 based boards and that new boards include STM32Cube CMSIS
files from start.
Shouldn't you import all possible HALs _today_ in order to enforce
that? Otherwise it'll lead to unnecessary churn when people are doing
platform/SoC ports.

Regards,
Amit
[1] What is it with vendor code and camel-case and excessive use of
typedefs? :-)


Mirza Krak
 

2016-11-08 8:51 GMT+01:00 Amit Kucheria <amit.kucheria(a)verdurent.com>:
Hi Erwan,

On Thu, Nov 3, 2016 at 8:07 PM, Erwan Gouriou <erwan.gouriou(a)linaro.org> wrote:
Hi all,


There are growing number of STM32 based boards being ported in Zephyr
by the community. As part of ST, I can say that we are pleased to contribute
this way to Zephyr impact in IoT world.

In order to ease porting of STM32 devices, we'd like to introduce STM32Cube
SDK into Zephyr. Aim is to make porting fast and easy thanks to ST CSMIS
files, reduce code duplication and provide mature software with STM32Cube
adaptation layers (HAL and LL).
I'm all for allowing Zephyr to quickly add support for as much
hardware as possible and if HALs are the way to do it, then so be it.

However, I'd like to hear from Zephyr maintainers on whether this is
just a short-term strategy to get broad hardware support or the long
term goal because HALs do make for hard-to-read code[1] and each
vendor's HAL is different leading to further maintenance issues.

I ask this coming from a Linux development mindset where HALs are
actively discouraged.

About STM32Cube CMSIS files:
Proposition for now is to move progressively towards the support of
STM32Cube
on available STM32 based boards and that new boards include STM32Cube CMSIS
files from start.
Shouldn't you import all possible HALs _today_ in order to enforce
that? Otherwise it'll lead to unnecessary churn when people are doing
platform/SoC ports.

Regards,
Amit
[1] What is it with vendor code and camel-case and excessive use of
typedefs? :-)
+1 on that comment :).

Interesting topic and I will follow this with interest.

Best Regards
Mirza


Erwan Gouriou
 

Hi Amit,


About STM32Cube CMSIS files:
Proposition for now is to move progressively towards the support of
STM32Cube
on available STM32 based boards and that new boards include STM32Cube
CMSIS
files from start.
Shouldn't you import all possible HALs _today_ in order to enforce
that? Otherwise it'll lead to unnecessary churn when people are doing
platform/SoC ports.
Good point, I had the request to push stm32f7xx as there was some work
going on
with this series. Pushing the whole family on the same change.

Erwan


Fabien Parent <fparent@...>
 

Hi Amit,

On Tue, Nov 8, 2016 at 8:51 AM, Amit Kucheria
<amit.kucheria(a)verdurent.com> wrote:
Hi Erwan,

On Thu, Nov 3, 2016 at 8:07 PM, Erwan Gouriou <erwan.gouriou(a)linaro.org> wrote:
Hi all,


There are growing number of STM32 based boards being ported in Zephyr
by the community. As part of ST, I can say that we are pleased to contribute
this way to Zephyr impact in IoT world.

In order to ease porting of STM32 devices, we'd like to introduce STM32Cube
SDK into Zephyr. Aim is to make porting fast and easy thanks to ST CSMIS
files, reduce code duplication and provide mature software with STM32Cube
adaptation layers (HAL and LL).
I'm all for allowing Zephyr to quickly add support for as much
hardware as possible and if HALs are the way to do it, then so be it.

However, I'd like to hear from Zephyr maintainers on whether this is
just a short-term strategy to get broad hardware support or the long
term goal because HALs do make for hard-to-read code[1] and each
vendor's HAL is different leading to further maintenance issues.

I ask this coming from a Linux development mindset where HALs are
actively discouraged.
I'm also interested in this topic. I posted several weeks ago on
gerrit some patches to add support for the STM32L4 family. The
reviewers wanted me to import the ST headers (they were not there at
the time) to reuse the peripheral's base register addresses, I do not
fully agree with it but this is just a few defines from ST headers
that follow the same coding convention as Zephyr so that's fine. Now
the reviewers also want me to start using the structure that defines
the peripherals registers from the ST headers, but here that's where
it starts to bothering me: this code does *NOT* follow the Zephyr
coding style at all.

Example:

typedef struct
{
__IO uint32_t MODER; /*!< GPIO port mode register,
Address offset: 0x00 */
__IO uint32_t OTYPER; /*!< GPIO port output type register,
Address offset: 0x04 */
__IO uint32_t OSPEEDR; /*!< GPIO port output speed register,
Address offset: 0x08 */
__IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down
register, Address offset: 0x0C */
__IO uint32_t IDR; /*!< GPIO port input data register,
Address offset: 0x10 */
__IO uint32_t ODR; /*!< GPIO port output data register,
Address offset: 0x14 */
__IO uint32_t BSRR; /*!< GPIO port bit set/reset register,
Address offset: 0x18 */
__IO uint32_t LCKR; /*!< GPIO port configuration lock
register, Address offset: 0x1C */
__IO uint32_t AFR[2]; /*!< GPIO alternate function registers,
Address offset: 0x20-0x24 */
__IO uint32_t BRR; /*!< GPIO Bit Reset register,
Address offset: 0x28 */
__IO uint32_t ASCR; /*!< GPIO analog switch control register,
Address offset: 0x2C */

} GPIO_TypeDef;

I feel that if I have something that works, that does not duplicate
existing code, and that follow the existing coding style, my code
should be merged as-is. But right now we are asking me the opposite:
to start using symbols that do not follow the coding style.

If that's what maintainers want, I will follow even if I don't like
it, but at least I would love to see an official guideline from the
maintainers of what is the preferred approach here.


About STM32Cube CMSIS files:
Proposition for now is to move progressively towards the support of
STM32Cube
on available STM32 based boards and that new boards include STM32Cube CMSIS
files from start.
Shouldn't you import all possible HALs _today_ in order to enforce
that? Otherwise it'll lead to unnecessary churn when people are doing
platform/SoC ports.

Regards,
Amit
[1] What is it with vendor code and camel-case and excessive use of
typedefs? :-)


Daniel Thompson <daniel.thompson@...>
 

On 14/11/16 10:04, Fabien Parent wrote:
Hi Amit,

On Tue, Nov 8, 2016 at 8:51 AM, Amit Kucheria
<amit.kucheria(a)verdurent.com> wrote:
Hi Erwan,

On Thu, Nov 3, 2016 at 8:07 PM, Erwan Gouriou <erwan.gouriou(a)linaro.org> wrote:
Hi all,


There are growing number of STM32 based boards being ported in Zephyr
by the community. As part of ST, I can say that we are pleased to contribute
this way to Zephyr impact in IoT world.

In order to ease porting of STM32 devices, we'd like to introduce STM32Cube
SDK into Zephyr. Aim is to make porting fast and easy thanks to ST CSMIS
files, reduce code duplication and provide mature software with STM32Cube
adaptation layers (HAL and LL).
I'm all for allowing Zephyr to quickly add support for as much
hardware as possible and if HALs are the way to do it, then so be it.

However, I'd like to hear from Zephyr maintainers on whether this is
just a short-term strategy to get broad hardware support or the long
term goal because HALs do make for hard-to-read code[1] and each
vendor's HAL is different leading to further maintenance issues.

I ask this coming from a Linux development mindset where HALs are
actively discouraged.
I'm also interested in this topic.
You can count me as interested here as well.

On the one hand, with the advent of OS projects like Zephyr the MCU
vendors are starting to release their HALs as open source (i.e. they are
no longer adding a "don't port this driver to anyone else's silicon"
clause). For me this is a great step forward for small open source OSs
which, in turn, makes working on MCU projects much more comfortable for me.

On the other hand, like others, I've internalized the Linux project's
strong distaste for non-native drivers due to the long term maintenance
challenges it presents. From a Zephyr project PoV I think that having a
"good" driver set is what really drives the choice between one OS and
another, where "good" is a function both driver breadth (how many
drivers there are) and driver quality (how painful it is to enhance
drivers).

Hence the question about whether HALs are a short term means to get
driver breadth quickly (i.e. similar to the contiki network stack) or a
long term means to avoid Zephyr becoming a "driver project".


Daniel.


Maureen Helm
 

Hi Fabien,

I'm also interested in this topic. I posted several weeks ago on gerrit some
patches to add support for the STM32L4 family. The reviewers wanted me to
import the ST headers (they were not there at the time) to reuse the
peripheral's base register addresses, I do not fully agree with it but this is just a
few defines from ST headers that follow the same coding convention as Zephyr
so that's fine. Now the reviewers also want me to start using the structure that
defines the peripherals registers from the ST headers, but here that's where it
starts to bothering me: this code does *NOT* follow the Zephyr coding style at
all.
You're right, it doesn't follow the Zephyr coding style, which is why we are importing these headers into ext/ and not into arch/arm/. Their style is defined by the ARM Cortex Microcontroller Software Interface Standard (CMSIS), specifically the CMSIS-CORE component of the standard, and has been widely adopted by ARM Cortex-M SoC vendors.
http://www.keil.com/pack/doc/CMSIS/Core/html/index.html

By reusing existing CMSIS peripheral register definitions from the SoC vendors as-is, there is a lot less custom code we need to write, test, and maintain for Zephyr. By importing them into ext/, we're keeping non-conformant code imported from other sources separate from the rest of the tree; everything else is expected to follow the Zephyr coding style.

As for vendor driver SDKs that are built on top of CMSIS register definitions, we are still in a bit of a learning period. For NXP SoCs, I would like to leverage the Kinetis SDK (ksdk) drivers with shims as much as possible for the same reasons as the CMSIS peripheral register definitions - less custom code to write, test, and maintain. For ST SoCs, Erwan recently started a similar exercise with STM32Cube. We've only done this for a handful of drivers, though, so it's possible we will find issues or incompatibilities as we fan out. When that happens, we should try to address them upstream with the vendors whenever possible.


I feel that if I have something that works, that does not duplicate existing code,
and that follow the existing coding style, my code should be merged as-is. But
right now we are asking me the opposite:
to start using symbols that do not follow the coding style.

If that's what maintainers want, I will follow even if I don't like it, but at least I
would love to see an official guideline from the maintainers of what is the
preferred approach here.
I agree that we need to publish some guidelines. I'll work on writing an ARM SoC porting guide over the next few weeks, and hope you'll be willing to provide some feedback on it when I have a draft ready.


About STM32Cube CMSIS files:
Proposition for now is to move progressively towards the support of
STM32Cube on available STM32 based boards and that new boards include
STM32Cube CMSIS files from start.
Shouldn't you import all possible HALs _today_ in order to enforce
that? Otherwise it'll lead to unnecessary churn when people are doing
platform/SoC ports.
I disagree with preemptively importing all the HALs today as that would clutter the tree with a lot of unused code. We also don't know which SoCs people will want to port to. I'll make sure to include a section about importing HALs in the above-mentioned ARM SoC porting guide.


Amit Kucheria
 

On Tue, Nov 15, 2016 at 2:18 AM, Maureen Helm <maureen.helm(a)nxp.com> wrote:
Hi Fabien,

I'm also interested in this topic. I posted several weeks ago on gerrit some
patches to add support for the STM32L4 family. The reviewers wanted me to
import the ST headers (they were not there at the time) to reuse the
peripheral's base register addresses, I do not fully agree with it but this is just a
few defines from ST headers that follow the same coding convention as Zephyr
so that's fine. Now the reviewers also want me to start using the structure that
defines the peripherals registers from the ST headers, but here that's where it
starts to bothering me: this code does *NOT* follow the Zephyr coding style at
all.
You're right, it doesn't follow the Zephyr coding style, which is why we are importing these headers into ext/ and not into arch/arm/. Their style is defined by the ARM Cortex Microcontroller Software Interface Standard (CMSIS), specifically the CMSIS-CORE component of the standard, and has been widely adopted by ARM Cortex-M SoC vendors.
http://www.keil.com/pack/doc/CMSIS/Core/html/index.html

By reusing existing CMSIS peripheral register definitions from the SoC vendors as-is, there is a lot less custom code we need to write, test, and maintain for Zephyr. By importing them into ext/, we're keeping non-conformant code imported from other sources separate from the rest of the tree; everything else is expected to follow the Zephyr coding style.

As for vendor driver SDKs that are built on top of CMSIS register definitions, we are still in a bit of a learning period. For NXP SoCs, I would like to leverage the Kinetis SDK (ksdk) drivers with shims as much as possible for the same reasons as the CMSIS peripheral register definitions - less custom code to write, test, and maintain. For ST SoCs, Erwan recently started a similar exercise with STM32Cube. We've only done this for a handful of drivers, though, so it's possible we will find issues or incompatibilities as we fan out. When that happens, we should try to address them upstream with the vendors whenever possible.
I'm skeptical about how this'll work because all the vendor SDK
definitions will leak into drivers (I'm currently refactoring my SPI
driver for nRF to work with hal files in ext/, because the build
system includes them by default, though I have no real use for them).
Since there isn't a standard way for vendors to do SDKs, every driver
will end up looking different within the same subsystem. When there
are no easy patterns, there will be less code reuse in the subsystem.

I feel that if I have something that works, that does not duplicate existing code,
and that follow the existing coding style, my code should be merged as-is. But
right now we are asking me the opposite:
to start using symbols that do not follow the coding style.

If that's what maintainers want, I will follow even if I don't like it, but at least I
would love to see an official guideline from the maintainers of what is the
preferred approach here.

Shouldn't you import all possible HALs _today_ in order to enforce
that? Otherwise it'll lead to unnecessary churn when people are doing
platform/SoC ports.
I disagree with preemptively importing all the HALs today as that would clutter the tree with a lot of unused code. We also don't know which SoCs people will want to port to. I'll make sure to include a section about importing HALs in the above-mentioned ARM SoC porting guide.
That would be appreciated if that is the official position. Then we
won't have SoC and platform ports starting with clean, native code
that then needs to be converted over to use the HAL after submission.
It is a waste of everyone's time.

Cheers,
Amit


Tomasz Bursztyka
 

Hi guys,


I'm also interested in this topic. I posted several weeks ago on gerrit some
patches to add support for the STM32L4 family. The reviewers wanted me to
import the ST headers (they were not there at the time) to reuse the
peripheral's base register addresses, I do not fully agree with it but this is just a
few defines from ST headers that follow the same coding convention as Zephyr
so that's fine. Now the reviewers also want me to start using the structure that
defines the peripherals registers from the ST headers, but here that's where it
starts to bothering me: this code does *NOT* follow the Zephyr coding style at
all.
You're right, it doesn't follow the Zephyr coding style, which is why we are importing these headers into ext/ and not into arch/arm/. Their style is defined by the ARM Cortex Microcontroller Software Interface Standard (CMSIS), specifically the CMSIS-CORE component of the standard, and has been widely adopted by ARM Cortex-M SoC vendors.
http://www.keil.com/pack/doc/CMSIS/Core/html/index.html

By reusing existing CMSIS peripheral register definitions from the SoC vendors as-is, there is a lot less custom code we need to write, test, and maintain for Zephyr. By importing them into ext/, we're keeping non-conformant code imported from other sources separate from the rest of the tree; everything else is expected to follow the Zephyr coding style.

As for vendor driver SDKs that are built on top of CMSIS register definitions, we are still in a bit of a learning period. For NXP SoCs, I would like to leverage the Kinetis SDK (ksdk) drivers with shims as much as possible for the same reasons as the CMSIS peripheral register definitions - less custom code to write, test, and maintain. For ST SoCs, Erwan recently started a similar exercise with STM32Cube. We've only done this for a handful of drivers, though, so it's possible we will find issues or incompatibilities as we fan out. When that happens, we should try to address them upstream with the vendors whenever possible.
I'm skeptical about how this'll work because all the vendor SDK
definitions will leak into drivers (I'm currently refactoring my SPI
driver for nRF to work with hal files in ext/, because the build
system includes them by default, though I have no real use for them).
Since there isn't a standard way for vendors to do SDKs, every driver
will end up looking different within the same subsystem. When there
are no easy patterns, there will be less code reuse in the subsystem.
Not to mention style issue is the least of the problem here. Though I fully
agree, it will grow uglier with time.

The much bigger problem is all about memory consumption and latency.
Exactly the kind of thing we try to lower as much as possible in such OS.

Take for instance the ethernet driver eth_ksdk.c, in net branch, where
vendor's API does not
enable the possibility to feed the chip with our way to hold data (our
net buf),
but instead needs a full frame buffer to be filled in first, which in
turn - inside vendor's
API - will be finally fed to the chip. It bloats everything up.

It's one example among others. It's just confusing to make so much
effort on kernel
and various sub-system, to loose quite much of it on driver side due to
vendor's API.

Technically, it makes sense to hurry things up using existing code from
vendors, to get
a quick prototype and all. But if one has time to provide native code,
this will imo be better.

Tomasz


Amit Kucheria
 

On Tue, Nov 15, 2016 at 5:46 PM, Tomasz Bursztyka
<tomasz.bursztyka(a)linux.intel.com> wrote:
Hi guys,


I'm also interested in this topic. I posted several weeks ago on gerrit
some
patches to add support for the STM32L4 family. The reviewers wanted me
to
import the ST headers (they were not there at the time) to reuse the
peripheral's base register addresses, I do not fully agree with it but
this is just a
few defines from ST headers that follow the same coding convention as
Zephyr
so that's fine. Now the reviewers also want me to start using the
structure that
defines the peripherals registers from the ST headers, but here that's
where it
starts to bothering me: this code does *NOT* follow the Zephyr coding
style at
all.
You're right, it doesn't follow the Zephyr coding style, which is why we
are importing these headers into ext/ and not into arch/arm/. Their style is
defined by the ARM Cortex Microcontroller Software Interface Standard
(CMSIS), specifically the CMSIS-CORE component of the standard, and has been
widely adopted by ARM Cortex-M SoC vendors.
http://www.keil.com/pack/doc/CMSIS/Core/html/index.html

By reusing existing CMSIS peripheral register definitions from the SoC
vendors as-is, there is a lot less custom code we need to write, test, and
maintain for Zephyr. By importing them into ext/, we're keeping
non-conformant code imported from other sources separate from the rest of
the tree; everything else is expected to follow the Zephyr coding style.

As for vendor driver SDKs that are built on top of CMSIS register
definitions, we are still in a bit of a learning period. For NXP SoCs, I
would like to leverage the Kinetis SDK (ksdk) drivers with shims as much as
possible for the same reasons as the CMSIS peripheral register definitions -
less custom code to write, test, and maintain. For ST SoCs, Erwan recently
started a similar exercise with STM32Cube. We've only done this for a
handful of drivers, though, so it's possible we will find issues or
incompatibilities as we fan out. When that happens, we should try to address
them upstream with the vendors whenever possible.
I'm skeptical about how this'll work because all the vendor SDK
definitions will leak into drivers (I'm currently refactoring my SPI
driver for nRF to work with hal files in ext/, because the build
system includes them by default, though I have no real use for them).
Since there isn't a standard way for vendors to do SDKs, every driver
will end up looking different within the same subsystem. When there
are no easy patterns, there will be less code reuse in the subsystem.

Not to mention style issue is the least of the problem here. Though I fully
agree, it will grow uglier with time.

The much bigger problem is all about memory consumption and latency.
Exactly the kind of thing we try to lower as much as possible in such OS.
Yeah I didn't want to bring this up (binary size, memory consumption)
until I'd actually done some comparative studies which is hard since
you basically have to write two different drivers - one with HAL and
one without. I'll take the porting opportunity to do some
measurements.


Marcus Shawcroft <marcus.shawcroft@...>
 

On 15 November 2016 at 13:22, Amit Kucheria <amit.kucheria(a)verdurent.com> wrote:

Yeah I didn't want to bring this up (binary size, memory consumption)
until I'd actually done some comparative studies which is hard since
you basically have to write two different drivers - one with HAL and
one without. I'll take the porting opportunity to do some
measurements.
We have one data point already in the ksdk ethernet driver that Tomasz
referred to. Due to the architectural difference in buffer handling
between zephyr and the underlying HAL abstraction the shim needs a
spare ethernet packet sized buffer available in order to copy data
from the network stack to the driver and likewise in the opposite
direction. Further, the HAL driver itself has one set of buffers
sufficient to hold at least one frame, while the network stack has its
own buffers. Hence we are wasting order of 3k RAM above what a
bespoke driver might be expected to need.

The ksdk driver could be adjusted to provide a scatter/gather
interface which would remove the need for at least one set of buffers,
but a proper solution, one that allowed the third set of duplicate
buffers to be removed, would require the ksdk implementation be
adapted such that we could plumb in the host os's buffer abstraction.
This would be a much more invasive change.

The other point worth mentioning is that these HAL abstractions
generally provide at least two features.
1) Definitions, consts, #defines, structs etc that define the register
interface to a bit of hardware
2) Functions that provide pre-canned functionality (sometimes quite elaborate).

The former are generally useful but don't impose architecture on the
user, the latter are more problematic if the pre-canned architecture
clashes with the host os architecture.

The issue mentioned above w.r.t the ksdk ethernet driver is due to the
architecture of the pre-canned functions provided in KSDK. One could
imagine a version of the ksdk ethernet shim driver that used the ksdk
register definitions (and some of the low level plumbing) while
providing its own higher level functions.

It isn't clear to me that this is an either/or discussion. I don't see
a compelling technical, stability, quality or maintenance reason why
we should not have co-existing native and hal/shim based drivers. The
HAL/shim route providing rapid scale out of device coverage with
bespoke drivers written and dropped in where the hal/shim driver
characteristics are unpalatable.

Given that we have the HALs in the tree along with their low level
definitions, it would be pragmatic that we use those definitions where
possible even if we choose not to use (some of the) pre-canned higher
level functionality. Since doing so should have no impact on
footprint, performance etc, minimises code duplication in the tree,
and minimises overall effort in moving zephyr forward.

Cheers
/Marcus


Chuck Jordan <Chuck.Jordan@...>
 

I would only that add that a HALL or SHIM layer should be implemented two different ways, depending on whether the user wants a size optimization or a speed optimization. For size, commonly called functions are good for smaller size, but bad for performance.
If speed is wanted, macros and/or inline functions are wanted.
Further, if speed is wanted, any argument checking or PARANOID code checks should be STRIPPED.

Some targets have large amounts of memory for code, and so size is not an issue, but speed is the issue.
Some targets have tiny memories, and thus size is the only optimization that matters.

-Chuck

-----Original Message-----
From: Marcus Shawcroft [mailto:marcus.shawcroft(a)gmail.com]
Sent: Tuesday, November 15, 2016 7:14 AM
To: Amit Kucheria <amit.kucheria(a)verdurent.com>
Cc: Tomasz Bursztyka <tomasz.bursztyka(a)linux.intel.com>; devel <devel(a)lists.zephyrproject.org>
Subject: [devel] Re: Re: Re: Re: Re: HALs in Zephyr (was Re: STM32Cube SDK in Zephyr)

On 15 November 2016 at 13:22, Amit Kucheria <amit.kucheria(a)verdurent.com> wrote:

Yeah I didn't want to bring this up (binary size, memory consumption)
until I'd actually done some comparative studies which is hard since
you basically have to write two different drivers - one with HAL and
one without. I'll take the porting opportunity to do some
measurements.
We have one data point already in the ksdk ethernet driver that Tomasz referred to. Due to the architectural difference in buffer handling between zephyr and the underlying HAL abstraction the shim needs a spare ethernet packet sized buffer available in order to copy data from the network stack to the driver and likewise in the opposite direction. Further, the HAL driver itself has one set of buffers sufficient to hold at least one frame, while the network stack has its own buffers. Hence we are wasting order of 3k RAM above what a bespoke driver might be expected to need.

The ksdk driver could be adjusted to provide a scatter/gather interface which would remove the need for at least one set of buffers, but a proper solution, one that allowed the third set of duplicate buffers to be removed, would require the ksdk implementation be adapted such that we could plumb in the host os's buffer abstraction.
This would be a much more invasive change.

The other point worth mentioning is that these HAL abstractions generally provide at least two features.
1) Definitions, consts, #defines, structs etc that define the register interface to a bit of hardware
2) Functions that provide pre-canned functionality (sometimes quite elaborate).

The former are generally useful but don't impose architecture on the user, the latter are more problematic if the pre-canned architecture clashes with the host os architecture.

The issue mentioned above w.r.t the ksdk ethernet driver is due to the architecture of the pre-canned functions provided in KSDK. One could imagine a version of the ksdk ethernet shim driver that used the ksdk register definitions (and some of the low level plumbing) while providing its own higher level functions.

It isn't clear to me that this is an either/or discussion. I don't see a compelling technical, stability, quality or maintenance reason why we should not have co-existing native and hal/shim based drivers. The HAL/shim route providing rapid scale out of device coverage with bespoke drivers written and dropped in where the hal/shim driver characteristics are unpalatable.

Given that we have the HALs in the tree along with their low level definitions, it would be pragmatic that we use those definitions where possible even if we choose not to use (some of the) pre-canned higher level functionality. Since doing so should have no impact on footprint, performance etc, minimises code duplication in the tree, and minimises overall effort in moving zephyr forward.

Cheers
/Marcus