All of lore.kernel.org
 help / color / mirror / Atom feed
* Standard CAN over IP
@ 2015-02-04 20:27 Mike Purvis
  2015-02-04 20:44 ` Armin Burchardt
                   ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: Mike Purvis @ 2015-02-04 20:27 UTC (permalink / raw)
  To: linux-can

Hi all,

I'm interested in providing low-cost CAN connectivity to a standard
Mini-ITX PC— so USB, Ethernet, RS232, PCIe connectivity is available,
but not I2C or SPI (at least easily).

I'm interested in any proposals for how to achieve this, though the
idea I have in mind is basically a simple microcontroller which
provides a CAN-over-UDP bridge. But I'd like to stay away from writing
a kernel module to actually present the UDP traffic to the linux
system as a socketcan can0 device. Is there some standard component
which already does this, or at least some tooling around serializing
CAN messages to a bytestream?

I noticed an interesting past discussion on this topic:
http://socket-can.996257.n3.nabble.com/Socketcan-over-ethernet-td1203.html

Have anything changed significantly on this front since 2009?

Thanks,

Mike

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
  2015-02-04 20:27 Standard CAN over IP Mike Purvis
@ 2015-02-04 20:44 ` Armin Burchardt
  2015-02-04 21:38   ` Mike Purvis
  2015-02-04 23:43 ` Tom Evans
  2015-02-18 17:57 ` Maximilian Güntner
  2 siblings, 1 reply; 23+ messages in thread
From: Armin Burchardt @ 2015-02-04 20:44 UTC (permalink / raw)
  To: Mike Purvis, linux-can

Hi Mike,

On 04.02.2015 21:27, Mike Purvis wrote:
> system as a socketcan can0 device. Is there some standard component
> which already does this, or at least some tooling around serializing
> CAN messages to a bytestream?

there is slcand (UART to socketcan from the can-utils package) to use
serial CAN adapters with socketcan. Implementing the (line based)
protocol in the mcu should not be too hard.

Armin (switching back to read-only mode)


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
  2015-02-04 20:44 ` Armin Burchardt
@ 2015-02-04 21:38   ` Mike Purvis
  2015-02-04 22:42     ` Gerhard Bertelsmann
  2015-02-05  0:50     ` Tom Evans
  0 siblings, 2 replies; 23+ messages in thread
From: Mike Purvis @ 2015-02-04 21:38 UTC (permalink / raw)
  To: Armin Burchardt; +Cc: linux-can

Armin—

Fantastic, thanks for the pointer, this is just what I was looking
for. I've given it a quick try, and the binary in Ubuntu 14.04's
can-utils package appears to do what I want in terms of creating a net
device.

For future travellers, the protocol is documented in the slcan.c
source file, from the kernel tree:

https://github.com/torvalds/linux/blob/master/drivers/net/can/slcan.c#L103

The slcand program is a very thin setup utility that ultimately just
busy-waits, while the N_SLCAN line discipline on the TTY does all the
work.

Thanks again,

Mike

On 4 February 2015 at 15:44, Armin Burchardt <armin@uni-bremen.de> wrote:
> Hi Mike,
>
> On 04.02.2015 21:27, Mike Purvis wrote:
>> system as a socketcan can0 device. Is there some standard component
>> which already does this, or at least some tooling around serializing
>> CAN messages to a bytestream?
>
> there is slcand (UART to socketcan from the can-utils package) to use
> serial CAN adapters with socketcan. Implementing the (line based)
> protocol in the mcu should not be too hard.
>
> Armin (switching back to read-only mode)
>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
  2015-02-04 21:38   ` Mike Purvis
@ 2015-02-04 22:42     ` Gerhard Bertelsmann
  2015-02-05  0:50     ` Tom Evans
  1 sibling, 0 replies; 23+ messages in thread
From: Gerhard Bertelsmann @ 2015-02-04 22:42 UTC (permalink / raw)
  To: Mike Purvis; +Cc: linux-can

Hi Mike,

I've already created IMHO the cheapest CAN2ETH ever:

http://lnxpps.de/openwrt/wr841/indexe.html

The red little board uses the cheapest CAN capable PIC micro.
It's firmware is highly optimized ASM code which outperforms
all know diy boards and even some commercial CAN interfaces.

The only drawback it's not doing fancy error reporting - it's
just ignoring errors and try to recover. As of today you need
to setup the baud rate into the source. This will be fixed in the
near future.

Regards

Gerd

Am Mi, 4.02.2015, 22:38, schrieb Mike Purvis:
> Armin—
>
> Fantastic, thanks for the pointer, this is just what I was looking
> for. I've given it a quick try, and the binary in Ubuntu 14.04's
> can-utils package appears to do what I want in terms of creating a net
> device.
>
> For future travellers, the protocol is documented in the slcan.c
> source file, from the kernel tree:
>
> https://github.com/torvalds/linux/blob/master/drivers/net/can/slcan.c#L103
>
> The slcand program is a very thin setup utility that ultimately just
> busy-waits, while the N_SLCAN line discipline on the TTY does all the
> work.
>
> Thanks again,
>
> Mike
>
> On 4 February 2015 at 15:44, Armin Burchardt <armin@uni-bremen.de> wrote:
>> Hi Mike,
>>
>> On 04.02.2015 21:27, Mike Purvis wrote:
>>> system as a socketcan can0 device. Is there some standard component
>>> which already does this, or at least some tooling around serializing
>>> CAN messages to a bytestream?
>>
>> there is slcand (UART to socketcan from the can-utils package) to use
>> serial CAN adapters with socketcan. Implementing the (line based)
>> protocol in the mcu should not be too hard.
>>
>> Armin (switching back to read-only mode)
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-can" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
  2015-02-04 20:27 Standard CAN over IP Mike Purvis
  2015-02-04 20:44 ` Armin Burchardt
@ 2015-02-04 23:43 ` Tom Evans
  2015-02-18 17:57 ` Maximilian Güntner
  2 siblings, 0 replies; 23+ messages in thread
From: Tom Evans @ 2015-02-04 23:43 UTC (permalink / raw)
  To: Mike Purvis, linux-can

On 05/02/15 07:27, Mike Purvis wrote:
> Hi all,
>
> I'm interested in providing low-cost CAN connectivity to a standard
> Mini-ITX PC— so USB, Ethernet, RS232, PCIe connectivity is available,
> but not I2C or SPI (at least easily).

The obvious approach is to use a PCAN-USB. I guess you want something cheaper 
(these are 195 Euros each). Effectively you're making one of these:

http://www.peak-system.com/PCAN-Ethernet-Gateway-DR.330.0.html?&L=1

So you have the "Mini-ITX" presumably running Linux, and you want to bridge 
CAN over Ethernet to a Microcontroller that has one or more physical CAN ports 
on it. I would guess the latter doesn't have to run Linux.

I've implemented that sort of thing, but the other way around. We have a micro 
not running Linux with two CAN ports on it. It communicates over UDP with a 
small embedded Linux system. The latter provides three CAN ports that are 
bridged over Ethernet to appear to be "physical" ports on the first one. Two 
of those ports are physical ones on the Linux micro, and the third is a 
virtual VCAN port.

So the first micro thinks it has 5 CAN ports. The VCAN bus on the Linux micro 
allows us to run multiple Linux user programs which can each be configured to 
either run on a physical CAN port (for some product configurations) or on the 
VCAN bus when they need to be controlled by the other micro over Ethernet.

So then you have the question - which device is now in charge of setting the 
baud rate and the time quanta for these bridged ports? In our case we let the 
first micro set this up, so there has to be an "Open port and configure it 
this way" message in the UDP packets together with the Receive and Transmit 
framing of CAN messages.

We also signal CAN error states back over UDP, so we have Open, Close, 
Configure, Receive, Transmit and Status messages (and "Transmit Multiple").

You can open one UDP port for all the available CAN buses on a unit, one UDP 
port for each separate CAN port or a separate UDP port for each CAN ID on each 
bus (which requires setting filters). It all depends on how and where (in 
software) you want to demultiplex the CAN IDs to the relevant programs, and 
whether you want to pack multiple CAN frames in one UDP packet.

We found it easiest to let VCAN do the demultiplexing, as that's what the 
SocketCAN interface is very good at.

So we have a user "Bridge" program that receives the UDP frames, interprets 
them and simply receives and sends to the two physical CAN ports and the VCAN 
port. The user application programs on the Linux box open connections to the 
VCAN bus with the appropriate ID filters.

We open one UDP connection with a "port selector" field in each encapsulated 
CAN message in the UDP packet. That allows us to pack multiple CAN messages 
for multiple ports in the one UDP packet. It creates too much overhead for 
both CPUs to put one 8-bytes-of-data CAN message in a 
1500-bytes-available-with-60-bytes-overhead UDP packet.

Another consideration is that at the hardware level, CAN is a reliable 
protocol. The message got through or it didn't (unless a software bug or 
buffer overflow dropped the packet in the receiving device). UDP is the 
UNRELIABLE Datagram Protocol. If this is a problem for your usage you might 
want CAN over TCP or you might want to add some error handling or packet retry 
layer (in other words, try to reinvent TCP all over again).

Another problem is that transmission and reception on physical CAN ports can 
often be timestamped to the microsecond. Some uses of CAN rely on this. When 
you bridge over Ethernet (and with all the Linux non-real-time problems) you 
get some pretty bad latencies, or at least worse ones than the physical ports 
provide.

If you have a very busy 1MBit/sec physical CAN bus and you want to connect 
your PC to it over the Ethernet bridge, and the PC program is only sending or 
receiving messages at a low rate, then you probably don't want everything on 
that busy bus to be dumped onto a VCAN bus inside the PC. In that case you 
would want a connection that allows CAN filters on the physical port. How 
would you configure that if you needed to?

We're finding that a single 43% busy bridged CAN bus can take up 13% of the 
total CPU time on our 800MHz ARM CPU.

 > I noticed an interesting past discussion on this topic:

That suggested a user program receiving all packets on VCAN and sending them 
over UDP and vice versa. That's pretty much what we have.

Tom


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
  2015-02-04 21:38   ` Mike Purvis
  2015-02-04 22:42     ` Gerhard Bertelsmann
@ 2015-02-05  0:50     ` Tom Evans
  2015-02-05 13:15       ` Mike Purvis
  1 sibling, 1 reply; 23+ messages in thread
From: Tom Evans @ 2015-02-05  0:50 UTC (permalink / raw)
  To: Mike Purvis, Armin Burchardt; +Cc: linux-can

On 05/02/15 08:38, Mike Purvis wrote:
> Armin—
>
> Fantastic, thanks for the pointer, this is just what I was looking
> for. I've given it a quick try, and the binary in Ubuntu 14.04's
> can-utils package appears to do what I want in terms of creating a net
> device.
>
> For future travellers, the protocol is documented in the slcan.c
> source file, from the kernel tree:

That Kconfig in drivers/net/can also has the following in it:

       config CAN_SLCAN
       As only the sending and receiving of CAN frames is implemented,
       this driver should work with the (serial/USB) CAN hardware from:
       www.canusb.com / www.can232.com / www.mictronics.de /
       www.canhack.de

If your PC has spare serial ports, or if you want to buy some reliable 
USB-to-serial converters, then you might want to consider the above-mentioned 
serial-to-can devices:

http://www.can232.com/?page_id=14

Or the normal USB ones on the above site. They might be cheap enough for you. 
Or you could start here:

http://www.mictronics.de/projects/usb-can-bus/

Tom


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
  2015-02-05  0:50     ` Tom Evans
@ 2015-02-05 13:15       ` Mike Purvis
  2015-02-06  8:33         ` Michal Sojka
  0 siblings, 1 reply; 23+ messages in thread
From: Mike Purvis @ 2015-02-05 13:15 UTC (permalink / raw)
  To: tom_usenet; +Cc: Armin Burchardt, linux-can

Hi Tom,

Yes, thanks— in the short term, I'm going to prototype using an off
the shelf USB-based device. In the fullness of time, I'll probably
either implement the protocol myself as part of a larger MCU also
doing some other stuff, or bring a BSD-licensed implementation of the
protocol, if such a thing exists.

Looks like you might be able to get CAN over TCP/UDP in two steps, by
using socat to link a pty to the network socket, and then running
slcand (or the guts of it) against the pty. Does anyone know what the
efficiency story is with socat? Does it copy back and forth between
between userspace and kernelspace, or is it able to operate fully in
kernel-land the way slcand does?

On 4 February 2015 at 19:50, Tom Evans <tom_usenet@optusnet.com.au> wrote:
> On 05/02/15 08:38, Mike Purvis wrote:
>>
>> Armin—
>>
>> Fantastic, thanks for the pointer, this is just what I was looking
>> for. I've given it a quick try, and the binary in Ubuntu 14.04's
>> can-utils package appears to do what I want in terms of creating a net
>> device.
>>
>> For future travellers, the protocol is documented in the slcan.c
>> source file, from the kernel tree:
>
>
> That Kconfig in drivers/net/can also has the following in it:
>
>       config CAN_SLCAN
>       As only the sending and receiving of CAN frames is implemented,
>       this driver should work with the (serial/USB) CAN hardware from:
>       www.canusb.com / www.can232.com / www.mictronics.de /
>       www.canhack.de
>
> If your PC has spare serial ports, or if you want to buy some reliable
> USB-to-serial converters, then you might want to consider the
> above-mentioned serial-to-can devices:
>
> http://www.can232.com/?page_id=14
>
> Or the normal USB ones on the above site. They might be cheap enough for
> you. Or you could start here:
>
> http://www.mictronics.de/projects/usb-can-bus/
>
> Tom
>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
  2015-02-05 13:15       ` Mike Purvis
@ 2015-02-06  8:33         ` Michal Sojka
  2015-02-09 16:00           ` Mike Purvis
  0 siblings, 1 reply; 23+ messages in thread
From: Michal Sojka @ 2015-02-06  8:33 UTC (permalink / raw)
  To: Mike Purvis, tom_usenet
  Cc: Armin Burchardt, linux-can, 'Pavel Píša'

Hi Mike,

On Thu, Feb 05 2015, Mike Purvis wrote:
> Hi Tom,
>
> Yes, thanks— in the short term, I'm going to prototype using an off
> the shelf USB-based device. In the fullness of time, I'll probably
> either implement the protocol myself as part of a larger MCU also
> doing some other stuff, or bring a BSD-licensed implementation of the
> protocol, if such a thing exists.
>
> Looks like you might be able to get CAN over TCP/UDP in two steps, by
> using socat to link a pty to the network socket, and then running
> slcand (or the guts of it) against the pty. Does anyone know what the
> efficiency story is with socat? Does it copy back and forth between
> between userspace and kernelspace, or is it able to operate fully in
> kernel-land the way slcand does?

Socat definitely copies everything over the user space.

In the past, we developed a kernel-based CAN-to-Ethernet gateway. See
http://rtime.felk.cvut.cz/can/can-eth-gw.pdf (the documentation is not
perfect). The kernel part is at
https://rtime.felk.cvut.cz/gitweb/can-eth-gw-linux.git/blob/HEAD:/net/can/canethgw.c.
It would probably need minor updates for current kernels. The user space
part, which just configures the kernel to do its job, is at
https://rtime.felk.cvut.cz/gitweb/can-utils.git/blob/refs/heads/cegw:/cegw.c.

The kernel part was measured to be about 10% faster (on x86), but this
number depends on the architecture. System calls on modern x86 have less
overhead than, for example, on PPC32.

Cheers,
-Michal

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
  2015-02-06  8:33         ` Michal Sojka
@ 2015-02-09 16:00           ` Mike Purvis
  2015-02-09 18:32             ` Oliver Hartkopp
  0 siblings, 1 reply; 23+ messages in thread
From: Mike Purvis @ 2015-02-09 16:00 UTC (permalink / raw)
  To: Michal Sojka; +Cc: tom_usenet, Armin Burchardt, linux-can, Pavel Píša

It's a bummer that N_SLCAN has no checksumming or validation built in
at all. Definitely suggests that SLCAN devices are meant more for
diagnostic/observational use than actual control. (And perhaps another
argument for wrapping the SLCAN tty stream in TCP or UDP).

Michal— this work looks interesting. However, I'm probably not
interested in taking on an abandonware project. Was this ever
maintained/deployed anywhere, or was it purely an academic exercise?

Mike

On 6 February 2015 at 03:33, Michal Sojka <sojkam1@fel.cvut.cz> wrote:
> Hi Mike,
>
> On Thu, Feb 05 2015, Mike Purvis wrote:
>> Hi Tom,
>>
>> Yes, thanks— in the short term, I'm going to prototype using an off
>> the shelf USB-based device. In the fullness of time, I'll probably
>> either implement the protocol myself as part of a larger MCU also
>> doing some other stuff, or bring a BSD-licensed implementation of the
>> protocol, if such a thing exists.
>>
>> Looks like you might be able to get CAN over TCP/UDP in two steps, by
>> using socat to link a pty to the network socket, and then running
>> slcand (or the guts of it) against the pty. Does anyone know what the
>> efficiency story is with socat? Does it copy back and forth between
>> between userspace and kernelspace, or is it able to operate fully in
>> kernel-land the way slcand does?
>
> Socat definitely copies everything over the user space.
>
> In the past, we developed a kernel-based CAN-to-Ethernet gateway. See
> http://rtime.felk.cvut.cz/can/can-eth-gw.pdf (the documentation is not
> perfect). The kernel part is at
> https://rtime.felk.cvut.cz/gitweb/can-eth-gw-linux.git/blob/HEAD:/net/can/canethgw.c.
> It would probably need minor updates for current kernels. The user space
> part, which just configures the kernel to do its job, is at
> https://rtime.felk.cvut.cz/gitweb/can-utils.git/blob/refs/heads/cegw:/cegw.c.
>
> The kernel part was measured to be about 10% faster (on x86), but this
> number depends on the architecture. System calls on modern x86 have less
> overhead than, for example, on PPC32.
>
> Cheers,
> -Michal

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
  2015-02-09 16:00           ` Mike Purvis
@ 2015-02-09 18:32             ` Oliver Hartkopp
  0 siblings, 0 replies; 23+ messages in thread
From: Oliver Hartkopp @ 2015-02-09 18:32 UTC (permalink / raw)
  To: Mike Purvis, Michal Sojka
  Cc: tom_usenet, Armin Burchardt, linux-can, Pavel Píša

Hi all,

yes it was an academic approach to check how to route CAN frames via UDP 
inside the kernel (and do some performance measurements too).

The main problem was the missing 'standard' configuration possibility of UDP 
connections to establish the UDP/IP link without an user space application.

So I wonder if it would make sense to add some (small) CAN specific code to be 
able to use the new 'Foo over UDP' support which has been added to the 3.18 
Kernel recently:

http://lwn.net/Articles/614348/

Tom Herbert created some pretty generic configuration interface to establish 
UDP sockets inside the kernel.

Regards,
Oliver

On 09.02.2015 17:00, Mike Purvis wrote:
> It's a bummer that N_SLCAN has no checksumming or validation built in
> at all. Definitely suggests that SLCAN devices are meant more for
> diagnostic/observational use than actual control. (And perhaps another
> argument for wrapping the SLCAN tty stream in TCP or UDP).
>
> Michal— this work looks interesting. However, I'm probably not
> interested in taking on an abandonware project. Was this ever
> maintained/deployed anywhere, or was it purely an academic exercise?
>
> Mike
>
> On 6 February 2015 at 03:33, Michal Sojka <sojkam1@fel.cvut.cz> wrote:
>> Hi Mike,
>>
>> On Thu, Feb 05 2015, Mike Purvis wrote:
>>> Hi Tom,
>>>
>>> Yes, thanks— in the short term, I'm going to prototype using an off
>>> the shelf USB-based device. In the fullness of time, I'll probably
>>> either implement the protocol myself as part of a larger MCU also
>>> doing some other stuff, or bring a BSD-licensed implementation of the
>>> protocol, if such a thing exists.
>>>
>>> Looks like you might be able to get CAN over TCP/UDP in two steps, by
>>> using socat to link a pty to the network socket, and then running
>>> slcand (or the guts of it) against the pty. Does anyone know what the
>>> efficiency story is with socat? Does it copy back and forth between
>>> between userspace and kernelspace, or is it able to operate fully in
>>> kernel-land the way slcand does?
>>
>> Socat definitely copies everything over the user space.
>>
>> In the past, we developed a kernel-based CAN-to-Ethernet gateway. See
>> http://rtime.felk.cvut.cz/can/can-eth-gw.pdf (the documentation is not
>> perfect). The kernel part is at
>> https://rtime.felk.cvut.cz/gitweb/can-eth-gw-linux.git/blob/HEAD:/net/can/canethgw.c.
>> It would probably need minor updates for current kernels. The user space
>> part, which just configures the kernel to do its job, is at
>> https://rtime.felk.cvut.cz/gitweb/can-utils.git/blob/refs/heads/cegw:/cegw.c.
>>
>> The kernel part was measured to be about 10% faster (on x86), but this
>> number depends on the architecture. System calls on modern x86 have less
>> overhead than, for example, on PPC32.
>>
>> Cheers,
>> -Michal
> --
> To unsubscribe from this list: send the line "unsubscribe linux-can" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
  2015-02-04 20:27 Standard CAN over IP Mike Purvis
  2015-02-04 20:44 ` Armin Burchardt
  2015-02-04 23:43 ` Tom Evans
@ 2015-02-18 17:57 ` Maximilian Güntner
       [not found]   ` <CACsJT9M4QbYkDvQkGfhFuwA6haNyV5zesUFtLzB5VEbxP=obBA@mail.gmail.com>
                     ` (2 more replies)
  2 siblings, 3 replies; 23+ messages in thread
From: Maximilian Güntner @ 2015-02-18 17:57 UTC (permalink / raw)
  To: Mike Purvis; +Cc: linux-can, socketcan, tom_usenet

Hi all,

2015-02-04 21:27 GMT+01:00 Mike Purvis <mpurvis@clearpathrobotics.com>:
> I'm interested in any proposals for how to achieve this, though the
> idea I have in mind is basically a simple microcontroller which
> provides a CAN-over-UDP bridge.

I wrote a program called cannelloni which exactly does that.
It creates a UDP tunnel between two SocketCAN interfaces and
uses a fixed timeout to aggregate the frames (e.g. 100 ms) and either sends
a full UDP packet once the buffer matches the MTU (which also resets
the timeout) or what is currently in the buffer when the timer runs out.

This way you can achieve high data rates with very little overhead.
If you have high priority frames you can create a .csv file
to change the individual timeout for certain frames.

Some features are still missing, like packet loss detection and the
re-transmission of lost UDP packets. CAN_FD is also not implemented.
Please note that cannelloni is still beta and may contain bugs.
=> Pull requests are always welcome :).

cannelloni bridges exactly two SocketCAN interfaces over UDP. If you need to
connect more interfaces, either run multiple instances of cannelloni
(just change the
local and remote port accordingly) or "merge" multiple CAN interfaces into
one vcan interface using cangw.

You can grab cannelloni from https://github.com/mguentner/cannelloni

Don't hesitate to contact me when you have questions!

Thanks,

Maximilian

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
       [not found]   ` <CACsJT9M4QbYkDvQkGfhFuwA6haNyV5zesUFtLzB5VEbxP=obBA@mail.gmail.com>
@ 2015-02-19  3:21     ` Mike Purvis
  2015-02-19 14:58     ` Maximilian Güntner
  1 sibling, 0 replies; 23+ messages in thread
From: Mike Purvis @ 2015-02-19  3:21 UTC (permalink / raw)
  To: Maximilian Güntner; +Cc: linux-can, socketcan, tom_usenet

Maximilian—

Interesting project, looks like you've made some good progress. Is the
protocol documented, or do you really only see this as suitable for
use between instances of itself?

Have you given thought to any kind of unit or end-to-end regression
testing strategies for the project?

On 18 February 2015 at 22:19, Mike Purvis <mpurvis@clearpathrobotics.com> wrote:
> Maximilian—
>
> Interesting project, looks like you've made some good progress. Is the
> protocol documented, or do you really only see this as suitable for use
> between instances of itself?
>
> Have you given thought to any kind of unit or end-to-end regression testing
> strategies for the project?
>
> M.
>
> On 18 February 2015 at 12:57, Maximilian Güntner
> <maximilian.guentner@gmail.com> wrote:
>>
>> Hi all,
>>
>> 2015-02-04 21:27 GMT+01:00 Mike Purvis <mpurvis@clearpathrobotics.com>:
>> > I'm interested in any proposals for how to achieve this, though the
>> > idea I have in mind is basically a simple microcontroller which
>> > provides a CAN-over-UDP bridge.
>>
>> I wrote a program called cannelloni which exactly does that.
>> It creates a UDP tunnel between two SocketCAN interfaces and
>> uses a fixed timeout to aggregate the frames (e.g. 100 ms) and either
>> sends
>> a full UDP packet once the buffer matches the MTU (which also resets
>> the timeout) or what is currently in the buffer when the timer runs out.
>>
>> This way you can achieve high data rates with very little overhead.
>> If you have high priority frames you can create a .csv file
>> to change the individual timeout for certain frames.
>>
>> Some features are still missing, like packet loss detection and the
>> re-transmission of lost UDP packets. CAN_FD is also not implemented.
>> Please note that cannelloni is still beta and may contain bugs.
>> => Pull requests are always welcome :).
>>
>> cannelloni bridges exactly two SocketCAN interfaces over UDP. If you need
>> to
>> connect more interfaces, either run multiple instances of cannelloni
>> (just change the
>> local and remote port accordingly) or "merge" multiple CAN interfaces into
>> one vcan interface using cangw.
>>
>> You can grab cannelloni from https://github.com/mguentner/cannelloni
>>
>> Don't hesitate to contact me when you have questions!
>>
>> Thanks,
>>
>> Maximilian
>
>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
       [not found]   ` <CACsJT9M4QbYkDvQkGfhFuwA6haNyV5zesUFtLzB5VEbxP=obBA@mail.gmail.com>
  2015-02-19  3:21     ` Mike Purvis
@ 2015-02-19 14:58     ` Maximilian Güntner
  1 sibling, 0 replies; 23+ messages in thread
From: Maximilian Güntner @ 2015-02-19 14:58 UTC (permalink / raw)
  To: Mike Purvis; +Cc: linux-can, socketcan, tom_usenet

Hi Mike,


2015-02-19 4:19 GMT+01:00 Mike Purvis <mpurvis@clearpathrobotics.com>:
> Maximilian—
>
> Interesting project, looks like you've made some good progress. Is the
> protocol documented, or do you really only see this as suitable for use
> between instances of itself?

The protocol is not documented yet (UTSL). I will add a document to
the repository within
the next few days and send an update once it is on github.

I have chosen UDP since the latency is lower compared to
TCP and it is easier to use on memory constraint platforms (think 4 KB RAM).
It should be pretty easy to come up with a solution for, say an Atmel
AT90CAN with
uip [1] on board.
Also, I did not include fancy features like service discovery or
setup/management
of the CAN interface since that is something I think a bridge should not do.
There needs to be a separate channel for that, like ssh with proper auth.

> Have you given thought to any kind of unit or end-to-end regression testing
> strategies for the project?

Sure. I was thinking about writing a black box test (e.g. with python)
which checks whether
all frames sent by cangen/canplayer to vcan0 come out on vcan1 as expected, with
vcan0 connected to vcan1 using cannelloni.
In the mean time, you can manually check if everything works by
enabling frame debugging (-d cu)
and comparing the output of cangen, candump and cannelloni.

[1] https://en.wikipedia.org/wiki/UIP_(micro_IP)

Thanks,

Max

> M.
>
> On 18 February 2015 at 12:57, Maximilian Güntner
> <maximilian.guentner@gmail.com> wrote:
>>
>> Hi all,
>>
>> 2015-02-04 21:27 GMT+01:00 Mike Purvis <mpurvis@clearpathrobotics.com>:
>> > I'm interested in any proposals for how to achieve this, though the
>> > idea I have in mind is basically a simple microcontroller which
>> > provides a CAN-over-UDP bridge.
>>
>> I wrote a program called cannelloni which exactly does that.
>> It creates a UDP tunnel between two SocketCAN interfaces and
>> uses a fixed timeout to aggregate the frames (e.g. 100 ms) and either
>> sends
>> a full UDP packet once the buffer matches the MTU (which also resets
>> the timeout) or what is currently in the buffer when the timer runs out.
>>
>> This way you can achieve high data rates with very little overhead.
>> If you have high priority frames you can create a .csv file
>> to change the individual timeout for certain frames.
>>
>> Some features are still missing, like packet loss detection and the
>> re-transmission of lost UDP packets. CAN_FD is also not implemented.
>> Please note that cannelloni is still beta and may contain bugs.
>> => Pull requests are always welcome :).
>>
>> cannelloni bridges exactly two SocketCAN interfaces over UDP. If you need
>> to
>> connect more interfaces, either run multiple instances of cannelloni
>> (just change the
>> local and remote port accordingly) or "merge" multiple CAN interfaces into
>> one vcan interface using cangw.
>>
>> You can grab cannelloni from https://github.com/mguentner/cannelloni
>>
>> Don't hesitate to contact me when you have questions!
>>
>> Thanks,
>>
>> Maximilian
>
>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
  2015-02-18 17:57 ` Maximilian Güntner
       [not found]   ` <CACsJT9M4QbYkDvQkGfhFuwA6haNyV5zesUFtLzB5VEbxP=obBA@mail.gmail.com>
@ 2015-02-20 11:43   ` Oliver Hartkopp
  2015-02-23 12:25     ` Maximilian Güntner
  2015-03-20 16:54   ` Maximilian Güntner
  2 siblings, 1 reply; 23+ messages in thread
From: Oliver Hartkopp @ 2015-02-20 11:43 UTC (permalink / raw)
  To: Maximilian Güntner, Mike Purvis; +Cc: linux-can, tom_usenet

On 18.02.2015 18:57, Maximilian Güntner wrote:

> Some features are still missing, like packet loss detection and the
> re-transmission of lost UDP packets. CAN_FD is also not implemented.

Hi Maximilian,

I would suggest to implement CAN FD from the beginning.

When creating the CAN RAW socket just try to switch it into CAN FD mode:

const int canfd_on = 1;

/* try to switch the socket into CAN FD mode */
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &canfd_on, sizeof(canfd_on));

No need to check for the return value here if you are able to handle CAN FD in 
your application.

And do this CAN FD sockopt on the target socket too.
When you are getting CAN FD frames and the target CAN interface only supports 
CAN2.0 the FD frames have to be dropped - people will surely detect this :-)

The only problem will remain how to encapsulate two different frame lengths 
and parse them correctly at the target node.

I wasn't able to get behind your UDP CAN frame encapsulation concept (missing 
C++ knowledge) so you definitely know better than me :-)

Regards,
Oliver

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
  2015-02-20 11:43   ` Oliver Hartkopp
@ 2015-02-23 12:25     ` Maximilian Güntner
  2015-02-23 13:08       ` Oliver Hartkopp
  0 siblings, 1 reply; 23+ messages in thread
From: Maximilian Güntner @ 2015-02-23 12:25 UTC (permalink / raw)
  To: Oliver Hartkopp; +Cc: Mike Purvis, linux-can, tom_usenet

Hi Oliver,

2015-02-20 12:43 GMT+01:00 Oliver Hartkopp <socketcan@hartkopp.net>:
> I would suggest to implement CAN FD from the beginning.
>
> When creating the CAN RAW socket just try to switch it into CAN FD mode:
>
thank you for the input. CAN FD is now (1ef0769900b) supported :)

Each instance determines whether it is possible to write CAN FD frames
to the socket, a configuration is not necessary.
In a setup where a host that uses CAN FD is connected to a host that
uses traditional CAN, frames with a payload of under 9 Bytes can also be
bridged using cannelloni - only frames that exceed 8 Bytes will be dropped.

> I wasn't able to get behind your UDP CAN frame encapsulation concept
> (missing C++ knowledge) so you definitely know better than me :-)

The protocol does not send "raw" canfd/can_frames since only the
necessary information is transmitted.
Here is how a cannelloni frame looks like:

[ VERSION | TYPE | SEQ_NO | COUNT |
                                                   COUNT * [ CANID |
LEN | LEN * DATA ] ]

To save space, the LEN attribute is used to determine how
many data bytes will follow.
The protocol has been left unchanged since LEN just gets bigger for
CAN FD frames.

As I said, I will put a document on Github with a complete documentation.

> Regards,
> Oliver

Thanks,

Maximilian

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
  2015-02-23 12:25     ` Maximilian Güntner
@ 2015-02-23 13:08       ` Oliver Hartkopp
  2015-02-23 14:27         ` Maximilian Güntner
  0 siblings, 1 reply; 23+ messages in thread
From: Oliver Hartkopp @ 2015-02-23 13:08 UTC (permalink / raw)
  To: Maximilian Güntner; +Cc: Mike Purvis, linux-can, tom_usenet

On 23.02.2015 13:25, Maximilian Güntner wrote:

> 2015-02-20 12:43 GMT+01:00 Oliver Hartkopp <socketcan@hartkopp.net>:
>> I would suggest to implement CAN FD from the beginning.
>>
>> When creating the CAN RAW socket just try to switch it into CAN FD mode:
>>
> thank you for the input. CAN FD is now (1ef0769900b) supported :)

Great!

>
> Each instance determines whether it is possible to write CAN FD frames
> to the socket, a configuration is not necessary.
> In a setup where a host that uses CAN FD is connected to a host that
> uses traditional CAN, frames with a payload of under 9 Bytes can also be
> bridged using cannelloni - only frames that exceed 8 Bytes will be dropped.

Hm. This is not the correct distinction for CAN and CAN FD.

There can be CAN FD frames with <=8 bytes too.

You need to make sure that the difference between CAN FD with 8 bytes and 
CAN2.0 with 8 bytes does not get lost. So I would suggest to add an additional 
attribute to each transfered CAN frame which tells you:

- Is a CAN FD frame (or not)
- Has bitrate setting (CANFD_BRS) enabled (for CAN FD)
- Has error state (CANFD_ESI) enabled (for CAN FD)

My suggestion would be to add a single byte for each frame that contains 
CANFD_BRS and CANFD_ESI as-is and e.g. 0x80 when this is a CAN FD frame.

> Here is how a cannelloni frame looks like:
>
> [ VERSION | TYPE | SEQ_NO | COUNT | COUNT * [ CANID |
> LEN | LEN * DATA ] ]

You would have COUNT * [ CANID | FLAGS | LEN | LEN * DATA ] ]

then with a single FLAGS byte.

On the sender side 0x80 is OR'ed when the read frame length was CANFD_MTU.
And on the receiver a CAN or CAN FD frame is created based on 0x80 in FLAGS.

Regards,
Oliver


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
  2015-02-23 13:08       ` Oliver Hartkopp
@ 2015-02-23 14:27         ` Maximilian Güntner
  2015-02-23 16:22           ` Oliver Hartkopp
  0 siblings, 1 reply; 23+ messages in thread
From: Maximilian Güntner @ 2015-02-23 14:27 UTC (permalink / raw)
  To: Oliver Hartkopp; +Cc: Mike Purvis, linux-can, tom_usenet

Hi Oliver,

2015-02-23 14:08 GMT+01:00 Oliver Hartkopp <socketcan@hartkopp.net>:
>> In a setup where a host that uses CAN FD is connected to a host that
>> uses traditional CAN, frames with a payload of under 9 Bytes can also be
>> bridged using cannelloni - only frames that exceed 8 Bytes will be
>> dropped.
>
> Hm. This is not the correct distinction for CAN and CAN FD.
>
> There can be CAN FD frames with <=8 bytes too.

Sure. My intent was not to make a distinction between CAN and CAN FD
based on the frame length but rather to check whether it is possible to send the
data section on that particular bus.
But I think dropping CAN FD frames on non CAN FD interfaces is the right choice
in the long run.

> You need to make sure that the difference between CAN FD with 8 bytes and
> CAN2.0 with 8 bytes does not get lost. So I would suggest to add an
> additional attribute to each transfered CAN frame which tells you:
>
> - Is a CAN FD frame (or not)
> - Has bitrate setting (CANFD_BRS) enabled (for CAN FD)

Both flags make sense to me. Maybe we can use the MSB of LEN (so 0x80)
to encode whether it is a CAN FD frame. The next byte is either
the first DATA byte or FLAGS followed by the first DATA byte.

> - Has error state (CANFD_ESI) enabled (for CAN FD)

Do you think that this flag is necessary for two independent CAN buses?
When sending the frame on a physical bus, the error state of that
interface/node can be different compared to the original sender.
If host A receives a frame on bus A where CANFD_ESI is set and
transmits it to host B which in return writes it to bus B, the CANFD_ESI
bit will represent the state of a different node (host B instead of the
original sender).
Maybe I am wrong, but I think that the CANFD_ESI flag needs to be
masked prior to transmission on bus B.

>
> My suggestion would be to add a single byte for each frame that contains
> CANFD_BRS and CANFD_ESI as-is and e.g. 0x80 when this is a CAN FD frame.
>
> [...]
> On the sender side 0x80 is OR'ed when the read frame length was CANFD_MTU.
> And on the receiver a CAN or CAN FD frame is created based on 0x80 in FLAGS.

Sounds good.

>
> Regards,
> Oliver
>
Thanks,

Maximilian

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
  2015-02-23 14:27         ` Maximilian Güntner
@ 2015-02-23 16:22           ` Oliver Hartkopp
  0 siblings, 0 replies; 23+ messages in thread
From: Oliver Hartkopp @ 2015-02-23 16:22 UTC (permalink / raw)
  To: Maximilian Güntner; +Cc: Mike Purvis, linux-can, tom_usenet

On 23.02.2015 15:27, Maximilian Güntner wrote:

>> There can be CAN FD frames with <=8 bytes too.
>
> Sure. My intent was not to make a distinction between CAN and CAN FD
> based on the frame length but rather to check whether it is possible to send the
> data section on that particular bus.
> But I think dropping CAN FD frames on non CAN FD interfaces is the right choice
> in the long run.
>

Yep :-)

>> You need to make sure that the difference between CAN FD with 8 bytes and
>> CAN2.0 with 8 bytes does not get lost. So I would suggest to add an
>> additional attribute to each transfered CAN frame which tells you:
>>
>> - Is a CAN FD frame (or not)
>> - Has bitrate setting (CANFD_BRS) enabled (for CAN FD)
>
> Both flags make sense to me. Maybe we can use the MSB of LEN (so 0x80)
> to encode whether it is a CAN FD frame. The next byte is either
> the first DATA byte or FLAGS followed by the first DATA byte.

Yes. That was my intention too.

>> - Has error state (CANFD_ESI) enabled (for CAN FD)
>
> Do you think that this flag is necessary for two independent CAN buses?
> When sending the frame on a physical bus, the error state of that
> interface/node can be different compared to the original sender.
> If host A receives a frame on bus A where CANFD_ESI is set and
> transmits it to host B which in return writes it to bus B, the CANFD_ESI
> bit will represent the state of a different node (host B instead of the
> original sender).
> Maybe I am wrong, but I think that the CANFD_ESI flag needs to be
> masked prior to transmission on bus B.

Good catch. Indeed this was discussed at CAN in Automation too.
When you think of a gateway (in automotive) the original ESI bit can be 
interesting for the receiver placed behind the gateway.

Therefore the ability to set the ESI bit explicitly in an outgoing CAN FD 
frame is specified for CAN controllers.

So the ESI bit on the wire is an OR'ed value of the value set into the 
controllers registers and the internal state of the controller.
For your implementation this turns out to forward the ESI bit value transparently.

>
>>
>> My suggestion would be to add a single byte for each frame that contains
>> CANFD_BRS and CANFD_ESI as-is and e.g. 0x80 when this is a CAN FD frame.
>>
>> [...]
>> On the sender side 0x80 is OR'ed when the read frame length was CANFD_MTU.
>> And on the receiver a CAN or CAN FD frame is created based on 0x80 in FLAGS.
>
> Sounds good.
>

:-)

Regards,
Oliver

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
  2015-02-18 17:57 ` Maximilian Güntner
       [not found]   ` <CACsJT9M4QbYkDvQkGfhFuwA6haNyV5zesUFtLzB5VEbxP=obBA@mail.gmail.com>
  2015-02-20 11:43   ` Oliver Hartkopp
@ 2015-03-20 16:54   ` Maximilian Güntner
  2015-03-23 10:28     ` Pankajkumar Misra (RBEI/EEA2)
  2 siblings, 1 reply; 23+ messages in thread
From: Maximilian Güntner @ 2015-03-20 16:54 UTC (permalink / raw)
  To: linux-can; +Cc: Oliver Hartkopp, tom_usenet, Mike Purvis

Hi again,

cannelloni now [0] has full CAN FD support and a new alternative transport for
connections where packet loss and reordering is likely.

I decided to use SCTP instead of TCP since the original UDP packet structure
can be reused for parsing and sending using SCTP.
It also seems to be far better suited for this task and provides
interesting angles
for future use cases (out-of-bound transmits etc.).

Instead of SOCK_SEQPACKET, the implementation uses SOCK_STREAM
which appeared to be simpler to use, especially for cannelloni where some
fancy features of SCTP, like multiple associations for one socket,
are not (yet) needed.

Unlike with UDP where the connection is peer-to-peer, with SCTP one cannelloni
instance binds to an IP+port and therefore becomes a server for another
cannelloni instance which connects to it (the client). Example: [1]

While it is possible to use simultaneous init/open for SCTP connections,
it creates a lot of traffic during the initialization phase. It was
also difficult
for me to get reliable results on low latency connections (e.g.
loopback) without
continuously spamming INITs.

Other things I have fixed:

* smaller timeouts (like 100us) do not stress the CPU as much
* when a buffer is full, the oldest frame will be dropped - not the newest
  (ring buffer behavior)
* frame sorting is *disabled* by default and can be *enabled* using
the -s option

I have also added a file [2] that documents the structure of UDP/SCTP packets.

A small note on traffic control:

Applications that send whenever the write function does not return
-ENOBUFS need to be limited. This can be achieved by using a token
bucket filter [3]. There are however some limitations using this method.
If one would simply restrict the vcan interface to say 1 Mbit/s for a
remote 1 Mbit/s
physical CAN bus, both RX and TX are taken into account since the vcan interface
"repeats" everything back to other applications.
That means a TBF rate limit of 1 Mbit/s will effectively limit the interface
to 500 kbit/s.
The solution here is to double the TBF limit. However, since both CAN interfaces
are not really in-sync using cannelloni, an application might still be
sending too
fast for the actual bus on the remote host.
A very eager application like cangen -g0 -i could also suppress
a cannelloni instance.
You can not reduce the rate limit of the whole interface since cannelloni still
needs to be able to write all frames from the remote, which can reach a data
rate of up to 1 Mbit/s in this example.
One possible solution could be to put all sending/"real" applications
into a cgroup
and limit the egress traffic rate using tc. This limits applications like cangen
depending on the expected bus load of the physical bus while cannelloni is still
able to write with full speed. I haven't tried this though.
Please report back if this works for you!

I hope that you find cannelloni useful. It still needs testing but most bugs
should be fixed by now.
If you find one, please report it :)

Thanks,

Max

[0] https://github.com/mguentner/cannelloni/commit/7e59e941cd9b977ff6bbfc3389c3fc9858318e1a
[1] https://github.com/mguentner/cannelloni#sctp
[2] https://github.com/mguentner/cannelloni/blob/master/doc/udp_format.md
[3] https://github.com/mguentner/cannelloni#example

^ permalink raw reply	[flat|nested] 23+ messages in thread

* RE: Standard CAN over IP
  2015-03-20 16:54   ` Maximilian Güntner
@ 2015-03-23 10:28     ` Pankajkumar Misra (RBEI/EEA2)
  2015-03-23 13:15       ` Maximilian Güntner
  2015-03-23 13:23       ` GARNERO, PIERRE (P.)
  0 siblings, 2 replies; 23+ messages in thread
From: Pankajkumar Misra (RBEI/EEA2) @ 2015-03-23 10:28 UTC (permalink / raw)
  To: Maximilian Güntner; +Cc: linux-can

Hi Max,

I am trying to compile cannelloni, but getting errors.

First:
	The compiler was fixed to /usr/bin/c++.
	In case of doing cross compilation this will not work. Please provide option to choose compiler.

Second:
	Once above issue fixed I got error saying :
		root@xxxVM:/CANonIP/cannelloni# make
		[ 12%] Building CXX object CMakeFiles/addsources.dir/connection.cpp.o
		In file included from /usr/arm-linux-gnueabihf/include/c++/4.6.3/thread:35:0,
                 from /CANonIP/cannelloni/thread.h:23,
                 from /CANonIP/cannelloni/connection.h:26,
                 from /CANonIP/cannelloni/connection.cpp:21:
		/usr/arm-linux-gnueabihf/include/c++/4.6.3/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the upcoming ISO C++ standard, C++0x. This 			support is currently experimental, and must be enabled with the -std=c++0x or -std=gnu++0x compiler options.
			.
			.
			.
		To fix this I changed the option in CMakeLists.txt
			ADD_DEFINITIONS(
			#    -std=c++11
			    -std=c++0x
			)

Third:  error: ‘canfd_frame’ has not been declared

root@xxxVM:/CANonIP/cannelloni# make
-- Configuring done
-- Generating done
-- Build files have been written to: /CANonIP/cannelloni
[ 12%] Building CXX object CMakeFiles/addsources.dir/connection.cpp.o
In file included from /CANonIP/cannelloni/connection.h:27:0,
                 from /CANonIP/cannelloni/connection.cpp:21:
/CANonIP/cannelloni/framebuffer.h:65:5: error: ‘canfd_frame’ does not name a type
/CANonIP/cannelloni/framebuffer.h:68:26: error: ‘canfd_frame’ has not been declared
/CANonIP/cannelloni/framebuffer.h:71:22: error: ‘canfd_frame’ has not been declared
/CANonIP/cannelloni/framebuffer.h:74:22: error: ‘canfd_frame’ has not been declared
/CANonIP/cannelloni/framebuffer.h:82:5: error: ‘canfd_frame’ does not name a type
/CANonIP/cannelloni/framebuffer.h:84:5: error: ‘canfd_frame’ does not name a type
/CANonIP/cannelloni/framebuffer.h:96:45: error: ‘canfd_frame’ was not declared in this scope
/CANonIP/cannelloni/framebuffer.h:96:57: error: template argument 1 is invalid
/CANonIP/cannelloni/framebuffer.h:96:57: error: template argument 2 is invalid
/CANonIP/cannelloni/framebuffer.h:96:69: error: expected unqualified-id before ‘start’
/CANonIP/cannelloni/framebuffer.h:96:69: error: expected ‘)’ before ‘start’
/CANonIP/cannelloni/framebuffer.h:96:60: error: expected ‘;’ at end of member declaration
/CANonIP/cannelloni/framebuffer.h:96:69: error: ‘start’ does not name a type
/CANonIP/cannelloni/framebuffer.h:103:15: error: ‘canfd_frame’ was not declared in this scope
/CANonIP/cannelloni/framebuffer.h:103:27: error: template argument 1 is invalid
/CANonIP/cannelloni/framebuffer.h:103:27: error: template argument 2 is invalid
/CANonIP/cannelloni/framebuffer.h:120:15: error: ‘canfd_frame’ was not declared in this scope
/CANonIP/cannelloni/framebuffer.h:120:27: error: template argument 1 is invalid
/CANonIP/cannelloni/framebuffer.h:120:27: error: template argument 2 is invalid
/CANonIP/cannelloni/framebuffer.h:121:15: error: ‘canfd_frame’ was not declared in this scope
/CANonIP/cannelloni/framebuffer.h:121:27: error: template argument 1 is invalid
/CANonIP/cannelloni/framebuffer.h:121:27: error: template argument 2 is invalid
/CANonIP/cannelloni/framebuffer.h:122:15: error: ‘canfd_frame’ was not declared in this scope
/CANonIP/cannelloni/framebuffer.h:122:27: error: template argument 1 is invalid
/CANonIP/cannelloni/framebuffer.h:122:27: error: template argument 2 is invalid
In file included from /CANonIP/cannelloni/connection.cpp:21:0:
/CANonIP/cannelloni/connection.h:43:32: error: ‘canfd_frame’ has not been declared
make[2]: *** [CMakeFiles/addsources.dir/connection.cpp.o] Error 1
make[1]: *** [CMakeFiles/addsources.dir/all] Error 2
make: *** [all] Error 2


Please correct if something wrong in my approach.

Best Regards,
Pankaj

-----Original Message-----
From: linux-can-owner@vger.kernel.org [mailto:linux-can-owner@vger.kernel.org] On Behalf Of Maximilian Güntner
Sent: Friday, March 20, 2015 10:25 PM
To: linux-can@vger.kernel.org
Cc: Oliver Hartkopp; tom_usenet@optusnet.com.au; Mike Purvis
Subject: Re: Standard CAN over IP

Hi again,

cannelloni now [0] has full CAN FD support and a new alternative transport for
connections where packet loss and reordering is likely.

I decided to use SCTP instead of TCP since the original UDP packet structure
can be reused for parsing and sending using SCTP.
It also seems to be far better suited for this task and provides
interesting angles
for future use cases (out-of-bound transmits etc.).

Instead of SOCK_SEQPACKET, the implementation uses SOCK_STREAM
which appeared to be simpler to use, especially for cannelloni where some
fancy features of SCTP, like multiple associations for one socket,
are not (yet) needed.

Unlike with UDP where the connection is peer-to-peer, with SCTP one cannelloni
instance binds to an IP+port and therefore becomes a server for another
cannelloni instance which connects to it (the client). Example: [1]

While it is possible to use simultaneous init/open for SCTP connections,
it creates a lot of traffic during the initialization phase. It was
also difficult
for me to get reliable results on low latency connections (e.g.
loopback) without
continuously spamming INITs.

Other things I have fixed:

* smaller timeouts (like 100us) do not stress the CPU as much
* when a buffer is full, the oldest frame will be dropped - not the newest
  (ring buffer behavior)
* frame sorting is *disabled* by default and can be *enabled* using
the -s option

I have also added a file [2] that documents the structure of UDP/SCTP packets.

A small note on traffic control:

Applications that send whenever the write function does not return
-ENOBUFS need to be limited. This can be achieved by using a token
bucket filter [3]. There are however some limitations using this method.
If one would simply restrict the vcan interface to say 1 Mbit/s for a
remote 1 Mbit/s
physical CAN bus, both RX and TX are taken into account since the vcan interface
"repeats" everything back to other applications.
That means a TBF rate limit of 1 Mbit/s will effectively limit the interface
to 500 kbit/s.
The solution here is to double the TBF limit. However, since both CAN interfaces
are not really in-sync using cannelloni, an application might still be
sending too
fast for the actual bus on the remote host.
A very eager application like cangen -g0 -i could also suppress
a cannelloni instance.
You can not reduce the rate limit of the whole interface since cannelloni still
needs to be able to write all frames from the remote, which can reach a data
rate of up to 1 Mbit/s in this example.
One possible solution could be to put all sending/"real" applications
into a cgroup
and limit the egress traffic rate using tc. This limits applications like cangen
depending on the expected bus load of the physical bus while cannelloni is still
able to write with full speed. I haven't tried this though.
Please report back if this works for you!

I hope that you find cannelloni useful. It still needs testing but most bugs
should be fixed by now.
If you find one, please report it :)

Thanks,

Max

[0] https://github.com/mguentner/cannelloni/commit/7e59e941cd9b977ff6bbfc3389c3fc9858318e1a
[1] https://github.com/mguentner/cannelloni#sctp
[2] https://github.com/mguentner/cannelloni/blob/master/doc/udp_format.md
[3] https://github.com/mguentner/cannelloni#example
--
To unsubscribe from this list: send the line "unsubscribe linux-can" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: Standard CAN over IP
  2015-03-23 10:28     ` Pankajkumar Misra (RBEI/EEA2)
@ 2015-03-23 13:15       ` Maximilian Güntner
  2015-03-23 16:57         ` Pankajkumar Misra (RBEI/EEA2)
  2015-03-23 13:23       ` GARNERO, PIERRE (P.)
  1 sibling, 1 reply; 23+ messages in thread
From: Maximilian Güntner @ 2015-03-23 13:15 UTC (permalink / raw)
  To: Pankajkumar Misra (RBEI/EEA2); +Cc: linux-can

Hi Pankaj,

2015-03-23 11:28 GMT+01:00 Pankajkumar Misra (RBEI/EEA2)
<Pankaj.Kumar@in.bosch.com>:
> Hi Max,
>
> I am trying to compile cannelloni, but getting errors.
>
> First:
>         The compiler was fixed to /usr/bin/c++.
>         In case of doing cross compilation this will not work. Please provide option to choose compiler.

This is possible with CMake. Have a look here:

http://www.cmake.org/Wiki/CMake_FAQ#How_do_I_use_a_different_compiler.3F

Since you are cross compiling, this might also help:

http://www.cmake.org/Wiki/CMake_Cross_Compiling

> Second:
>         Once above issue fixed I got error saying :
>                 root@xxxVM:/CANonIP/cannelloni# make

>                 /usr/arm-linux-gnueabihf/include/c++/4.6.3/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the upcoming ISO C++ standard, C++0x. This                      support is currently experimental, and must be enabled with the -std=c++0x or -std=gnu++0x compiler options.
>                 To fix this I changed the option in CMakeLists.txt
>                         ADD_DEFINITIONS(
>                         #    -std=c++11
>                             -std=c++0x
>                         )

Your compiler was released in 2012 and c++11/c++0x was very new
back then.
If you can, try to upgrade to something newer, like GCC 4.9.x.
Linaro also has current releases of GCC for gnueabihf target platforms. [1]

> Third:  error: ‘canfd_frame’ has not been declared

This is most likely due to the fact that your kernel is pretty old.
struct canfd_frame was introduced with kernel commit 7c9416365c
and the first kernel release to support it was v3.6 [2], released in 2012.
I am guessing that your kernel version is < v3.6, if so update it to v3.6+.

Another solution would be to define canfd_frame inside the application if
LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0).
I have created an issue for that [3].

>
> Please correct if something wrong in my approach.
>
> Best Regards,
> Pankaj

Regards,

Max

[1] git tag --contains 7c9416365c60f150ef8961a2855fafbc7394ad6b
[2] https://wiki.linaro.org/WorkingGroups/ToolChain
[3] https://github.com/mguentner/cannelloni/issues/2

^ permalink raw reply	[flat|nested] 23+ messages in thread

* RE: Standard CAN over IP
  2015-03-23 10:28     ` Pankajkumar Misra (RBEI/EEA2)
  2015-03-23 13:15       ` Maximilian Güntner
@ 2015-03-23 13:23       ` GARNERO, PIERRE (P.)
  1 sibling, 0 replies; 23+ messages in thread
From: GARNERO, PIERRE (P.) @ 2015-03-23 13:23 UTC (permalink / raw)
  To: Pankajkumar Misra (RBEI/EEA2), Maximilian Güntner; +Cc: linux-can

Hi Pankaj,

You could cross compile according to your own installed toolchain by providing a file that describes your toolchain. Please look at http://www.vtk.org/Wiki/CMake_Cross_Compiling#The_toolchain_file on how to proceed.
There is, may be, just a small change to apply to the current CMakelists.txt:  -std=c++11 definition should be set only if a GNU compiler is used (gcc>=4.7 or clang).

Cheers,

Pierre

-----Message d'origine-----
De : linux-can-owner@vger.kernel.org [mailto:linux-can-owner@vger.kernel.org] De la part de Pankajkumar Misra (RBEI/EEA2)
Envoyé : Monday, March 23, 2015 11:29 AM
À : Maximilian Güntner
Cc : linux-can@vger.kernel.org
Objet : RE: Standard CAN over IP

Hi Max,

I am trying to compile cannelloni, but getting errors.

First:
	The compiler was fixed to /usr/bin/c++.
	In case of doing cross compilation this will not work. Please provide option to choose compiler.

Second:
	Once above issue fixed I got error saying :
		root@xxxVM:/CANonIP/cannelloni# make
		[ 12%] Building CXX object CMakeFiles/addsources.dir/connection.cpp.o
		In file included from /usr/arm-linux-gnueabihf/include/c++/4.6.3/thread:35:0,
                 from /CANonIP/cannelloni/thread.h:23,
                 from /CANonIP/cannelloni/connection.h:26,
                 from /CANonIP/cannelloni/connection.cpp:21:
		/usr/arm-linux-gnueabihf/include/c++/4.6.3/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the upcoming ISO C++ standard, C++0x. This 			support is currently experimental, and must be enabled with the -std=c++0x or -std=gnu++0x compiler options.
			.
			.
			.
		To fix this I changed the option in CMakeLists.txt
			ADD_DEFINITIONS(
			#    -std=c++11
			    -std=c++0x
			)

Third:  error: ‘canfd_frame’ has not been declared

root@xxxVM:/CANonIP/cannelloni# make
-- Configuring done
-- Generating done
-- Build files have been written to: /CANonIP/cannelloni [ 12%] Building CXX object CMakeFiles/addsources.dir/connection.cpp.o
In file included from /CANonIP/cannelloni/connection.h:27:0,
                 from /CANonIP/cannelloni/connection.cpp:21:
/CANonIP/cannelloni/framebuffer.h:65:5: error: ‘canfd_frame’ does not name a type
/CANonIP/cannelloni/framebuffer.h:68:26: error: ‘canfd_frame’ has not been declared
/CANonIP/cannelloni/framebuffer.h:71:22: error: ‘canfd_frame’ has not been declared
/CANonIP/cannelloni/framebuffer.h:74:22: error: ‘canfd_frame’ has not been declared
/CANonIP/cannelloni/framebuffer.h:82:5: error: ‘canfd_frame’ does not name a type
/CANonIP/cannelloni/framebuffer.h:84:5: error: ‘canfd_frame’ does not name a type
/CANonIP/cannelloni/framebuffer.h:96:45: error: ‘canfd_frame’ was not declared in this scope
/CANonIP/cannelloni/framebuffer.h:96:57: error: template argument 1 is invalid
/CANonIP/cannelloni/framebuffer.h:96:57: error: template argument 2 is invalid
/CANonIP/cannelloni/framebuffer.h:96:69: error: expected unqualified-id before ‘start’
/CANonIP/cannelloni/framebuffer.h:96:69: error: expected ‘)’ before ‘start’
/CANonIP/cannelloni/framebuffer.h:96:60: error: expected ‘;’ at end of member declaration
/CANonIP/cannelloni/framebuffer.h:96:69: error: ‘start’ does not name a type
/CANonIP/cannelloni/framebuffer.h:103:15: error: ‘canfd_frame’ was not declared in this scope
/CANonIP/cannelloni/framebuffer.h:103:27: error: template argument 1 is invalid
/CANonIP/cannelloni/framebuffer.h:103:27: error: template argument 2 is invalid
/CANonIP/cannelloni/framebuffer.h:120:15: error: ‘canfd_frame’ was not declared in this scope
/CANonIP/cannelloni/framebuffer.h:120:27: error: template argument 1 is invalid
/CANonIP/cannelloni/framebuffer.h:120:27: error: template argument 2 is invalid
/CANonIP/cannelloni/framebuffer.h:121:15: error: ‘canfd_frame’ was not declared in this scope
/CANonIP/cannelloni/framebuffer.h:121:27: error: template argument 1 is invalid
/CANonIP/cannelloni/framebuffer.h:121:27: error: template argument 2 is invalid
/CANonIP/cannelloni/framebuffer.h:122:15: error: ‘canfd_frame’ was not declared in this scope
/CANonIP/cannelloni/framebuffer.h:122:27: error: template argument 1 is invalid
/CANonIP/cannelloni/framebuffer.h:122:27: error: template argument 2 is invalid In file included from /CANonIP/cannelloni/connection.cpp:21:0:
/CANonIP/cannelloni/connection.h:43:32: error: ‘canfd_frame’ has not been declared
make[2]: *** [CMakeFiles/addsources.dir/connection.cpp.o] Error 1
make[1]: *** [CMakeFiles/addsources.dir/all] Error 2
make: *** [all] Error 2


Please correct if something wrong in my approach.

Best Regards,
Pankaj

-----Original Message-----
From: linux-can-owner@vger.kernel.org [mailto:linux-can-owner@vger.kernel.org] On Behalf Of Maximilian Güntner
Sent: Friday, March 20, 2015 10:25 PM
To: linux-can@vger.kernel.org
Cc: Oliver Hartkopp; tom_usenet@optusnet.com.au; Mike Purvis
Subject: Re: Standard CAN over IP

Hi again,

cannelloni now [0] has full CAN FD support and a new alternative transport for connections where packet loss and reordering is likely.

I decided to use SCTP instead of TCP since the original UDP packet structure can be reused for parsing and sending using SCTP.
It also seems to be far better suited for this task and provides interesting angles for future use cases (out-of-bound transmits etc.).

Instead of SOCK_SEQPACKET, the implementation uses SOCK_STREAM which appeared to be simpler to use, especially for cannelloni where some fancy features of SCTP, like multiple associations for one socket, are not (yet) needed.

Unlike with UDP where the connection is peer-to-peer, with SCTP one cannelloni instance binds to an IP+port and therefore becomes a server for another cannelloni instance which connects to it (the client). Example: [1]

While it is possible to use simultaneous init/open for SCTP connections, it creates a lot of traffic during the initialization phase. It was also difficult for me to get reliable results on low latency connections (e.g.
loopback) without
continuously spamming INITs.

Other things I have fixed:

* smaller timeouts (like 100us) do not stress the CPU as much
* when a buffer is full, the oldest frame will be dropped - not the newest
  (ring buffer behavior)
* frame sorting is *disabled* by default and can be *enabled* using the -s option

I have also added a file [2] that documents the structure of UDP/SCTP packets.

A small note on traffic control:

Applications that send whenever the write function does not return -ENOBUFS need to be limited. This can be achieved by using a token bucket filter [3]. There are however some limitations using this method.
If one would simply restrict the vcan interface to say 1 Mbit/s for a remote 1 Mbit/s physical CAN bus, both RX and TX are taken into account since the vcan interface "repeats" everything back to other applications.
That means a TBF rate limit of 1 Mbit/s will effectively limit the interface to 500 kbit/s.
The solution here is to double the TBF limit. However, since both CAN interfaces are not really in-sync using cannelloni, an application might still be sending too fast for the actual bus on the remote host.
A very eager application like cangen -g0 -i could also suppress a cannelloni instance.
You can not reduce the rate limit of the whole interface since cannelloni still needs to be able to write all frames from the remote, which can reach a data rate of up to 1 Mbit/s in this example.
One possible solution could be to put all sending/"real" applications into a cgroup and limit the egress traffic rate using tc. This limits applications like cangen depending on the expected bus load of the physical bus while cannelloni is still able to write with full speed. I haven't tried this though.
Please report back if this works for you!

I hope that you find cannelloni useful. It still needs testing but most bugs should be fixed by now.
If you find one, please report it :)

Thanks,

Max

[0] https://github.com/mguentner/cannelloni/commit/7e59e941cd9b977ff6bbfc3389c3fc9858318e1a
[1] https://github.com/mguentner/cannelloni#sctp
[2] https://github.com/mguentner/cannelloni/blob/master/doc/udp_format.md
[3] https://github.com/mguentner/cannelloni#example
--
To unsubscribe from this list: send the line "unsubscribe linux-can" in the body of a message to majordomo@vger.kernel.org More majordomo info at  http://vger.kernel.org/majordomo-info.html
\x13  칻\x1c & ~ & \x18  +-  ݶ\x17  w  ˛   m b  \jx  \x17  ܨ}   Ơz &j:+v        zZ+  +zf   h   ~    i   z \x1e w   ?    & )ߢ^[f

^ permalink raw reply	[flat|nested] 23+ messages in thread

* RE: Standard CAN over IP
  2015-03-23 13:15       ` Maximilian Güntner
@ 2015-03-23 16:57         ` Pankajkumar Misra (RBEI/EEA2)
  0 siblings, 0 replies; 23+ messages in thread
From: Pankajkumar Misra (RBEI/EEA2) @ 2015-03-23 16:57 UTC (permalink / raw)
  To: Maximilian Güntner; +Cc: linux-can

Hi Max,

Thanks for quick response.

Yes, the kernel & compiler are old, I will update, as suggested.

Thanks & Best Regards,
Pankaj

-----Original Message-----
From: Maximilian Güntner [mailto:maximilian.guentner@gmail.com] 
Sent: Monday, March 23, 2015 6:45 PM
To: Pankajkumar Misra (RBEI/EEA2)
Cc: linux-can@vger.kernel.org
Subject: Re: Standard CAN over IP

Hi Pankaj,

2015-03-23 11:28 GMT+01:00 Pankajkumar Misra (RBEI/EEA2)
<Pankaj.Kumar@in.bosch.com>:
> Hi Max,
>
> I am trying to compile cannelloni, but getting errors.
>
> First:
>         The compiler was fixed to /usr/bin/c++.
>         In case of doing cross compilation this will not work. Please provide option to choose compiler.

This is possible with CMake. Have a look here:

http://www.cmake.org/Wiki/CMake_FAQ#How_do_I_use_a_different_compiler.3F

Since you are cross compiling, this might also help:

http://www.cmake.org/Wiki/CMake_Cross_Compiling

> Second:
>         Once above issue fixed I got error saying :
>                 root@xxxVM:/CANonIP/cannelloni# make

>                 /usr/arm-linux-gnueabihf/include/c++/4.6.3/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the upcoming ISO C++ standard, C++0x. This                      support is currently experimental, and must be enabled with the -std=c++0x or -std=gnu++0x compiler options.
>                 To fix this I changed the option in CMakeLists.txt
>                         ADD_DEFINITIONS(
>                         #    -std=c++11
>                             -std=c++0x
>                         )

Your compiler was released in 2012 and c++11/c++0x was very new
back then.
If you can, try to upgrade to something newer, like GCC 4.9.x.
Linaro also has current releases of GCC for gnueabihf target platforms. [1]

> Third:  error: ‘canfd_frame’ has not been declared

This is most likely due to the fact that your kernel is pretty old.
struct canfd_frame was introduced with kernel commit 7c9416365c
and the first kernel release to support it was v3.6 [2], released in 2012.
I am guessing that your kernel version is < v3.6, if so update it to v3.6+.

Another solution would be to define canfd_frame inside the application if
LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0).
I have created an issue for that [3].

>
> Please correct if something wrong in my approach.
>
> Best Regards,
> Pankaj

Regards,

Max

[1] git tag --contains 7c9416365c60f150ef8961a2855fafbc7394ad6b
[2] https://wiki.linaro.org/WorkingGroups/ToolChain
[3] https://github.com/mguentner/cannelloni/issues/2

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2015-03-23 16:57 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-04 20:27 Standard CAN over IP Mike Purvis
2015-02-04 20:44 ` Armin Burchardt
2015-02-04 21:38   ` Mike Purvis
2015-02-04 22:42     ` Gerhard Bertelsmann
2015-02-05  0:50     ` Tom Evans
2015-02-05 13:15       ` Mike Purvis
2015-02-06  8:33         ` Michal Sojka
2015-02-09 16:00           ` Mike Purvis
2015-02-09 18:32             ` Oliver Hartkopp
2015-02-04 23:43 ` Tom Evans
2015-02-18 17:57 ` Maximilian Güntner
     [not found]   ` <CACsJT9M4QbYkDvQkGfhFuwA6haNyV5zesUFtLzB5VEbxP=obBA@mail.gmail.com>
2015-02-19  3:21     ` Mike Purvis
2015-02-19 14:58     ` Maximilian Güntner
2015-02-20 11:43   ` Oliver Hartkopp
2015-02-23 12:25     ` Maximilian Güntner
2015-02-23 13:08       ` Oliver Hartkopp
2015-02-23 14:27         ` Maximilian Güntner
2015-02-23 16:22           ` Oliver Hartkopp
2015-03-20 16:54   ` Maximilian Güntner
2015-03-23 10:28     ` Pankajkumar Misra (RBEI/EEA2)
2015-03-23 13:15       ` Maximilian Güntner
2015-03-23 16:57         ` Pankajkumar Misra (RBEI/EEA2)
2015-03-23 13:23       ` GARNERO, PIERRE (P.)

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.