CAN driver message structure

Pavel Pisa ppisa4lists at pikron.com
Tue Apr 12 08:30:44 UTC 2022


Hello Prashanth, Karel and Gedare,

On Tuesday 12 of April 2022 08:50:04 Karel Gardas wrote:
> not sure about others but Pavel Pisa is CAN expert here. CCing him
> directly as I've not seen him active recently.

Thanks for poke. I am subscribed on RTEMS devel (and many more lists)
but I am not capable to read all the messages so they are automatically
routed to the related folder.

As for the actual project proposal, I have already got notice
from Gedare and I have read it.

I have been driving force behind attempt to provide common
CAN drivers API for the Linux kernel

  http://ortcan.sourceforge.net/lincan/

but then thanks to cooperation of Volswagen and Pengutronix
SocketCAN API has been developed and only small remnants
of LinCAN has been reused.

As for the APIs, SocketCAN API is much more rich and user
friendly than characted driver LinCAN and others APIs.

On the other hand SocketCAN API is based on SKB infrastructure
and complete networking stack of Linux the kernel and this
stack is still not real-time/low latency capable even on
fully-preemptive Linux kernel variant.

We have done more analyses in cooperation with Oliver Hartkopp
from Volswagen

  https://static.lwn.net/images/conf/rtlws11/papers/proc/p30.pdf
  https://static.lwn.net/images/conf/rtlws-2011/proc/Sojka.pdf

The Linux kernel situation is better now but still not optimal
for demanding real-time CAN bus use.

In the case of RTEMS, using socket interface would even bind
driver to actually used external TCP/IP stack and BSD one
is problematic for smaller MCUs where CAN is really appropriate
choice.

I have proposed to port LinCAN to RTEMS many years ago.
But because no common testing environment has been found,
it has been decided that such tool has to be provided the first
and RTEMS donated GSoC slot to QEMU

  https://devel.rtems.org/wiki/Developer/Simulators/QEMU/CANEmulation
  https://www.qemu.org/docs/master/system/devices/can.html

After years of my further investments, the GSoC result has been
accepted into QEMU mainline and one of my bachelor studnets
implemented even CAN FD extension and support for our open source
CTU CAN FD IP core

  https://canbus.pages.fel.cvut.cz/

Xilinx used this base to include emulation of their CAN FD controllers
into QEMU.

We have invested into CAN bus support in NuttX in the last years.
NuttX provided character device API. See struct can_hdr_s
and struct can_msg_s

  https://github.com/apache/incubator-nuttx/blob/master/include/nuttx/can/can.h

It has options for finegrained tuning of its size according to the required
capabilities. It has sense for memory really constrained MCUs,
but RTEMS targets little bigger ones and variability is a problem
on the user and driver codes which as to put too many lines
under different ifdefs. So I would chose single head format
for all variants. Differentiate CAN_MAXDATALEN worth because
24 unused bytes overhead for each CAN message is large for
really small MCUs with CAN only support of application.

There was attempt to provide even SocketCAN API on NuttX
which would be attractive to build portable applications
for both GNU/Linux and NuttX. The initial attempt has been
done for S32 by Peter van der Perk from NXP. When we
looked for MCU for Elektroline.cz applications we have choosen
imxRT the first and my student Michal Lenc has ported and extended
SocketCAN NuttX driver to imxRT 

https://github.com/apache/incubator-nuttx/blob/master/arch/arm/src/imxrt/imxrt_flexcan.c

May problems has been corrected and it is running for year on
non safety NuttX based monitoring part of the resonant track circuit
electronic unit prototype. But I do not have good feeling about
mapping of this driver into NuttX TCP/IP stack infrastructure
and it makes driver quite complex... Later we proposed Elektroline.cz
to move focus on SAMV7/SAME70 MCUs due to total incapability of NXP
representants to provide their suggested S32 chip in shorter than years
frame. In this case we have used  Gregory Nut's already provided
MCAN CAN driver and enhanced it for CAN FD and new core revision.
The most CAN drivers n NuttX are based on this character driver
API and at least in the NuttX case and actual development status
I have much better feeling about robustness and RT capabilities
of this solution.

> If you are going to write CAN driver, then you first need to interface
> with the physical hardware which may expect data push to it and pulled
> from it in a certain format. That is probably the reason why you see
> different CAN message formats spread over RTEMS tree.

Yes and it is bad from application point of view. Unfortunately,
there exists more integrated CAN drivers for RTEMS with many different
origins. Probably GRlib is the one really used and tested.

But situation is really suboptimal. I have proposed for RTEMS
to try use and unify support on many years ago (may it be even
before SocketCAN existence), but have never RTEMS project
which could pay at least some my student on this topic.
The internal LinCAN concepts are documented there and I have
considered simplification of BSD MBUFs and TCP/IP stack as
a a model for limited number of priorities etc..

  https://cmp.felk.cvut.cz/~pisa/can/doc/lincandoc-0.3.5.pdf

The LinCAN message structure is defined there

  https://sourceforge.net/p/ortcan/lincan/ci/master/tree/lincan/include/canmsg.h

For sure canmsg_id_t is defined incorrectly for use of LinCAN
from 32-bit application running on 64-bit Linux kernel.

  typedef unsigned long canmsg_id_t;

It should be

  typedef uint32_t canmsg_id_t;

As for SoketCAN, I consider as discutable if the message fields
format should be i chosen host native endianing and alignemnt
or fixed little endian

  https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/can.h

The second approach would have a little higher overhead but would
allow direct wrapping of the messages into UDP or other protocols
and sending them over UDP or other protocol. Ability of SocketCAN
to provide direct higher level CAN miltiframe protocols in kernel
has advantage.

> But your approach or intuition of providing generic CAN message format
> is of course right here. The problem is, such messsage format then needs
> to be part of some CAN-related API which is used by user application.
> There are several ways how to design such API, but if we like to stay
> more generic, it's probably better to look around and see what people
> are already using.
>
> - in Linux world, there is a push to SocketCAN:
> https://en.wikipedia.org/wiki/SocketCAN and
> https://www.kernel.org/doc/html/latest/networking/can.html
> The API is also considered to be implemented or already implemented on
> top of some RTOSes like NuttX and Zephyr:
> https://forum.opencyphal.org/t/socketcan-api-on-a-rtos/750
> https://docs.zephyrproject.org/2.6.0/samples/net/sockets/can/README.html
>
> - the other crowd is pushing CANopen which not only provides whole
> layered architecture, but also its own API:
> https://en.wikipedia.org/wiki/CANopen
> https://canopen-stack.org/v4.2/api/node/
>
> I would definitely wait for Pavel message to know where the wind is
> blowing in industry these days and which API is most probably to be used
> in the future.

Oliver Hartkopp input would be really valuable too. 

> On 4/12/22 02:40, Prashanth S wrote:
> > Hi All,
> >
> > This is to query on CAN message format for CAN drivers.
> >
> > I want to implement a CAN driver for BeagleBone Black in RTEMS(GSoC).
> >
> > As I looked through the RTEMS Source Tree, found
> > https://devel.rtems.org/browser/rtems/bsps/arm/lpc176x/can
> > <https://www.google.com/url?q=https://devel.rtems.org/browser/rtems/bsps/
> >arm/lpc176x/can&sa=D&source=docs&ust=1649726382869937&usg=AOvVaw3vJP6V_BiC
> >CjzC3q-F4AH1> ,
> > https://devel.rtems.org/browser/rtems/bsps/powerpc/gen5200/mscan
> > <https://www.google.com/url?q=https://devel.rtems.org/browser/rtems/bsps/
> >powerpc/gen5200/mscan&sa=D&source=docs&ust=1649726382870043&usg=AOvVaw3i4_
> >IK73l4WoZ7u64ab0yB> CAN drivers, which have driver specific CAN message
> > structure.
> >
> > https://devel.rtems.org/browser/rtems/bsps/powerpc/gen5200/include/bsp/ms
> >can.h struct can_message {
> >    /* uint16_t mess_len; */
> >    uint16_t mess_id;
for sure no go, it has to be at least unit32_t
> >    uint16_t mess_time_stamp;
Should be probably longer
> >    uint8_t  mess_data[MSCAN_MAX_DATA_BYTES];
I would put data as the last element to keep format stable or even extensible
for CAN and CAN FD
> >    uint8_t  mess_len;
it is necessary to decide if it is encoded length or real data length
in further CAN FD case. I would suggest real length and at lest unit16_t
because CAN XL is comming with up to 2kB frames and byte length granularity.
> >    uint8_t  mess_rtr;
I would suggest old school unsigned or uint16/32_t for flags
then the extension is easy without breaking compatibility.
For sure you have to have space for EXTended flag, BRS flag
and FD message flag there
> >    uint32_t toucan_tx_idx;
I am not sure what is this. There could be reason to have possibility
to route message into selected controller message buffer.
But I think that it is better to select priority for gven queue
and left driver to take care about message buffers allocation.
 
> > };
> >
> > https://devel.rtems.org/browser/rtems/bsps/arm/lpc176x/include/bsp/can.h
> > typedef union {
> >    low_level_can_message low_level;
> >    registers_can_message registers;
> >   } can_message;

No, no no propagation of single controller tuned view to the API.

> > I would like to know if I should define a driver dependent CAN message
> > structure or use one of the existing ones.
> >
> > Ideally, I think a generic (driver independent) CAN message structure
> > will help applications to be portable.

Portable solution, please.

I have interrest in the RTEMS CAN support but my can cannot promise
much time. I can take role of the GSoC project co-mentor.
I have real interrest. Foe example, we are pushing CAN driver
for ESP32C3 into NuttiX mainline and I hope that our CTU CAN FD
core gets into Linux after years of effort. It would be great
to have QEMU Beagle Bone C-CAN emulation in the QEMU.
But I have done more wok for Elektroline.cz and have some
Beagle Bone HW there so I can test on it.

I have interrest in RTEMS CAN support on TMS570 and generally
extension of TMS570 BSP provided by us to RTEMS to integrate
full support for tms570lc4357 in addition to tms570ls3137.
But other project and teaching have higher priority for me

  https://cw.fel.cvut.cz/wiki/courses/b35apo/en/start
  https://github.com/cvut/qtrvsim

We will present it on Embedded World Conference 2022
so we can meet in Nuremberg in face and discuss more
as well. I plan to speak and coordinate our CAN
activities with Reiner Zitzmann from CiA....

Please, CC to me and if I do not response in week,
poke again to pisa at cmp.felk.cvut.cz, many tasks are
been buried under another incoming flood.

Best wishes,

                Pavel Pisa
    phone:      +420 603531357
    e-mail:     pisa at cmp.felk.cvut.cz
    Department of Control Engineering FEE CVUT
    Karlovo namesti 13, 121 35, Prague 2
    university: http://dce.fel.cvut.cz/
    company:    https://www.pikron.com/
    personal:   http://cmp.felk.cvut.cz/~pisa
    projects:   https://www.openhub.net/accounts/ppisa
    CAN related:http://canbus.pages.fel.cvut.cz/
    Open Technologies Research Education and Exchange Services
    https://gitlab.fel.cvut.cz/otrees/org/-/wikis/home


More information about the devel mailing list