SocketCAN and CAN char diver merge

2022-04-25 Thread Petro Karashchenko
Hello,

Recently I've been working on LIN bus support with SAME70 based device. In
general the integration was done smoothly and I would like to contribute my
work to the community. The LIN is pretty similar to CAN and in Linux is
abstracted as a SocketCAN device. During my integration I chose a more
traditional character driver "/dev/linX", but with CAN driver interface.

Currently I see that "old" CAN character driver and new SocketCAN live in
parallel with a decent amount of duplicated definitions that are already
out of sync. I see a room for improvement here and want to share my
thoughts.

I think that it should be possible to adapt CAN lower interface "struct
can_ops_s" so that it can be used by both CAN char and CAN netdev devices
upper drive logic. Taking into account that upper layer driver may operate
with messages of a different structure (might have padding fields, etc) the
minimum common logic should be defined as well.

I will express what should be done in a list:
1. All CAN char drivers use "cd_priv" field from "struct can_dev_s" while
lower driver interface require pointer to "struct can_dev_s" to be passed.
Here we need to define an intermediate type "struct can_updev_s" that will
have first two members of "cd_ops" and "cd_priv" so "struct can_dev_s" and
"struct can_netdev_s" can be inherited from "struct can_updev_s".
2. "co_send" interface in "struct can_ops_s" should be changed from "CODE
int (*co_send)(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg);" to
"CODE int (*co_send)(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr,
FAR uint8_t *data);" -- so we can get away from "struct can_msg_s" that is
specific to CAN char driver.
3. The CAN upper logic is already decoupled from "struct can_msg_s" because
of "int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr,
FAR uint8_t *data);" already contain separation, so we need just change
"struct can_dev_s" to "struct can_updev_s" here and char dev or netdev will
register a proper input callback that will handle RX data or a proper input
callback can be added into "struct can_updev_s"
4. "struct can_hdr_s" should be reworked so it can have maximum in common
with SocketCAN. SocketCAN expects that lower layer can operate either with
standard or extended CAN IDs, so SocketCAN will be available only if
CONFIG_CAN_EXTID=y
  a) In case of CONFIG_CAN_EXTID=y the ch_id in "struct can_hdr_s" is
uint32_t, so 3 upper bits are unused. SocketCAN stores supplementary
information in those 3 bits like "std vs ext CAN-ID", "RTR vs non-RTR
request" and "Error bit". I think we can adopt the same approach and
eliminate "ch_rtr", "ch_extid" and "ch_error" bit fields from "struct
can_hdr_s" with zero memory or performance hit.
  b) With "ch_dlc" and "ch_edl" / "ch_brs" / "ch_esi" it will be not so
easy because SocketCAN defines two uint8_t fields for this "len" and
"flags" while char driver packs everything using bit-fields. Here I need an
advice. We can keep bit-fields in the header and then split into two
uint8_t in the "can_receive()" variant of SocketCAN or we can extend
"struct can_hdr_s" to have 2 uint8_t. The second will not give any memory
overhead compared to what we have now because existing bit fields occupy
exactly 2 uint8_t variables (but using bit-fields will allow us to save 1
byte of course).

I would appreciate your feedback if above makes sense.

Thank you in advance,
Petro


Re: SocketCAN and CAN char diver merge

2022-04-25 Thread Peter van der Perk
Hi Petro,

I understand having 2 upper separate layers for CAN isn't welcomed.
However I don't see any real particular gains for a generic can_ops_s 
for both the SocketCAN and CAN Char driver.

For example SocketCAN net_driver_s interface uses the dev->d_buf 
interface to transfer data and then invokes a callback to the actual driver.
Whereas CAN Char uses the following prototype to call the driver directly
int (*co_send)(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg);
If we would manage to unify this we would probably have to rewrite the 
net/can upper driver to facilitate this.

Furthermore modifying the CAN Char can_hdr_s and can_msg_s data
structure would break backwards compatibility with all applications using 
the existing CAN char driver.

I'm not aware on the usage of the current CAN char driver is in general.
Another option instead of breaking the backwards compatibility for the
existing systems would be deprecating CAN Char and try to encourage 
the use of the SocketCAN driver and maybe migrate some platforms over as well.

I've made a quick overview of all NuttX architectures implementing a CAN
driver using both upper layers.

+-+--+---+
| | Char CAN | SocketCAN |
+-+--+---+
| AM335X  |Yes   | No|
+-+--+---+
| IXMRT   |No|Yes|
+-+--+---+
|  SAMA5  |Yes   | No|
+-+--+---+
|  SAMV7  |Yes   | No|
+-+--+---+
| STM32L4 |Yes   | No|
+-+--+---+
|  LPC43  |Yes   | No|
+-+--+---+
|  STM32  |Yes   |Yes|
+-+--+---+
| Kinetis |No|Yes|
+-+--+---+
| S32K1XX |No|Yes|
+-+--+---+
| STM32F7 |Yes   | No|
+-+--+---+
| STM32H7 |No|Yes|
+-+--+---+
| STM32L4 |Yes   | No|
+-+--+---+
| ESP32C3 |Yes   | No|
+-+--+---+
| |   9/13   |5/13   |
+-+--+---+



Re: SocketCAN and CAN char diver merge

2022-04-25 Thread Petro Karashchenko
The main reason why I'm raising this topic is that I think that the CAN
lower part should be a standard way the upper layer talks to CAN HW and the
upper half should perform the translation to a char or netdev interface.
Now that is not true. Basically I'm looking into the minimal set of
functions that I need to implement for LIN without knowing what is
"stilling" on top of it. I believe that it should be the right way of doing
things. From a user perspective I do not see any reason in deprecation of
CAN char driver. I'm not sure how it is done for Linux, I mean is SocketCAN
the only interface to CAN bus in Linux?

The deprecation of the CAN char driver could probably solve the issue, but
I see that there are many good things in CAN char driver that are not fully
integrated with SocketCAN in NuttX. Like HW message filtering (that is
currently managed by the SW SocketCAN layer).

Best regards,
Petro

вт, 26 квіт. 2022 р. о 00:06 Peter van der Perk 
пише:

> Hi Petro,
>
> I understand having 2 upper separate layers for CAN isn't welcomed.
> However I don't see any real particular gains for a generic can_ops_s
> for both the SocketCAN and CAN Char driver.
>
> For example SocketCAN net_driver_s interface uses the dev->d_buf
> interface to transfer data and then invokes a callback to the actual
> driver.
> Whereas CAN Char uses the following prototype to call the driver directly
> int (*co_send)(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg);
> If we would manage to unify this we would probably have to rewrite the
> net/can upper driver to facilitate this.
>
> Furthermore modifying the CAN Char can_hdr_s and can_msg_s data
> structure would break backwards compatibility with all applications using
> the existing CAN char driver.
>
> I'm not aware on the usage of the current CAN char driver is in general.
> Another option instead of breaking the backwards compatibility for the
> existing systems would be deprecating CAN Char and try to encourage
> the use of the SocketCAN driver and maybe migrate some platforms over as
> well.
>
> I've made a quick overview of all NuttX architectures implementing a CAN
> driver using both upper layers.
>
> +-+--+---+
> | | Char CAN | SocketCAN |
> +-+--+---+
> | AM335X  |Yes   | No|
> +-+--+---+
> | IXMRT   |No|Yes|
> +-+--+---+
> |  SAMA5  |Yes   | No|
> +-+--+---+
> |  SAMV7  |Yes   | No|
> +-+--+---+
> | STM32L4 |Yes   | No|
> +-+--+---+
> |  LPC43  |Yes   | No|
> +-+--+---+
> |  STM32  |Yes   |Yes|
> +-+--+---+
> | Kinetis |No|Yes|
> +-+--+---+
> | S32K1XX |No|Yes|
> +-+--+---+
> | STM32F7 |Yes   | No|
> +-+--+---+
> | STM32H7 |No|Yes|
> +-+--+---+
> | STM32L4 |Yes   | No|
> +-+--+---+
> | ESP32C3 |Yes   | No|
> +-+--+---+
> | |   9/13   |5/13   |
> +-+--+---+
>
>


Re: SocketCAN and CAN char diver merge

2022-04-25 Thread Gregory Nutt
There is another precedent here: nuttx/wireless/ieee802154.  For that radio
family, there are 3 applications interfaces:  There is a  dumb serial
driver and a network driver.  The network driver supports both a simple raw
interface and also an IPv6 LoPAN interface.

There is nothing that can be done with the serial driver that cannot be
done with the network raw packet interface.  IOCTL commands, for example,
are handled by the same logic.  They are totally redundant.  The serial
driver is a remnant of an older architectural concept that evolved over
time as documented here:
https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=139629397
(focuses on WiFI and Bluetooth as well as 802.15.4 radios).

I think that same policy on CAN networking should apply here.
Architectural consistency is an important property of a well-designed
operating system.

Removing the IEEE802.15.4 serial driver at this point would be a difficult
thing since it is entangled with the i8sak application so intimately.
However, I doubt there is such entanglement with the CAN serial driver
other than a few examples and perhaps some utilities.  So one option would
be to replace the CAN serial driver with a network raw socket type.

How does Linux deal with the CAN low level interface? My bet would be
through a raw socket.  Commonality with Linux in at least naming would be a
good thing too.




On Mon, Apr 25, 2022 at 3:49 PM Petro Karashchenko <
petro.karashche...@gmail.com> wrote:

> The main reason why I'm raising this topic is that I think that the CAN
> lower part should be a standard way the upper layer talks to CAN HW and the
> upper half should perform the translation to a char or netdev interface.
> Now that is not true. Basically I'm looking into the minimal set of
> functions that I need to implement for LIN without knowing what is
> "stilling" on top of it. I believe that it should be the right way of doing
> things. From a user perspective I do not see any reason in deprecation of
> CAN char driver. I'm not sure how it is done for Linux, I mean is SocketCAN
> the only interface to CAN bus in Linux?
>
> The deprecation of the CAN char driver could probably solve the issue, but
> I see that there are many good things in CAN char driver that are not fully
> integrated with SocketCAN in NuttX. Like HW message filtering (that is
> currently managed by the SW SocketCAN layer).
>
> Best regards,
> Petro
>
> вт, 26 квіт. 2022 р. о 00:06 Peter van der Perk 
> пише:
>
> > Hi Petro,
> >
> > I understand having 2 upper separate layers for CAN isn't welcomed.
> > However I don't see any real particular gains for a generic can_ops_s
> > for both the SocketCAN and CAN Char driver.
> >
> > For example SocketCAN net_driver_s interface uses the dev->d_buf
> > interface to transfer data and then invokes a callback to the actual
> > driver.
> > Whereas CAN Char uses the following prototype to call the driver directly
> > int (*co_send)(FAR struct can_dev_s *dev, FAR struct can_msg_s *msg);
> > If we would manage to unify this we would probably have to rewrite the
> > net/can upper driver to facilitate this.
> >
> > Furthermore modifying the CAN Char can_hdr_s and can_msg_s data
> > structure would break backwards compatibility with all applications using
> > the existing CAN char driver.
> >
> > I'm not aware on the usage of the current CAN char driver is in general.
> > Another option instead of breaking the backwards compatibility for the
> > existing systems would be deprecating CAN Char and try to encourage
> > the use of the SocketCAN driver and maybe migrate some platforms over as
> > well.
> >
> > I've made a quick overview of all NuttX architectures implementing a CAN
> > driver using both upper layers.
> >
> > +-+--+---+
> > | | Char CAN | SocketCAN |
> > +-+--+---+
> > | AM335X  |Yes   | No|
> > +-+--+---+
> > | IXMRT   |No|Yes|
> > +-+--+---+
> > |  SAMA5  |Yes   | No|
> > +-+--+---+
> > |  SAMV7  |Yes   | No|
> > +-+--+---+
> > | STM32L4 |Yes   | No|
> > +-+--+---+
> > |  LPC43  |Yes   | No|
> > +-+--+---+
> > |  STM32  |Yes   |Yes|
> > +-+--+---+
> > | Kinetis |No|Yes|
> > +-+--+---+
> > | S32K1XX |No|Yes|
> > +-+--+---+
> > | STM32F7 |Yes   | No|
> > +-+--+---+
> > | STM32H7 |No|Yes|
> > +-+--+---+
> > | STM32L4 |Yes   | No|
> > +-+--+---+
> > | ESP32C3 |Yes   | No|
> > +-+--+---+
> > | |   9/13   |5/13   |
> > +-+--+---+
> >
> >
>


Is there a standard way to build e.g. a nshlib.a static library from the apps repository?

2022-04-25 Thread Michael Jung
Hello everybody,

I am currently experimenting with buildroot to create a NuttX SDK, which
includes a GCC toolchain build using NuttX as the C library and basically a
sysroot environment that contains static libraries (for e.g. libwebsockets,
sqlite, etc...), which can optionally be linked by users of the SDK into
their application images.

I would like to include some of the great pieces of software from the apps
repository as static libraries in such an SDK. E.g. a nshlib.a or a
netlib.a.  Is there a 'standard way' of doing this?  Sorry if I missed some
obvious documentation.

As always, thanks for your help!
Michael


Re: Is there a standard way to build e.g. a nshlib.a static library from the apps repository?

2022-04-25 Thread Xiang Xiao
You may try to overwrite BIN in nshlib/Makefile to libnsh.a.

On Tue, Apr 26, 2022 at 2:38 PM Michael Jung  wrote:

> Hello everybody,
>
> I am currently experimenting with buildroot to create a NuttX SDK, which
> includes a GCC toolchain build using NuttX as the C library and basically a
> sysroot environment that contains static libraries (for e.g. libwebsockets,
> sqlite, etc...), which can optionally be linked by users of the SDK into
> their application images.
>
> I would like to include some of the great pieces of software from the apps
> repository as static libraries in such an SDK. E.g. a nshlib.a or a
> netlib.a.  Is there a 'standard way' of doing this?  Sorry if I missed some
> obvious documentation.
>
> As always, thanks for your help!
> Michael
>