Hey all,
I began to think how to cover basic interactions with CAN bus which
could serve a custom systems or ones which are closer to some narrow
cases. My intention here is to offer simplest possible way to become
CANbus client without any specific application layer protocol.
Results of my thought process are following.

Driver operations: CAN as protocol is rather event based hence CAN
driver should not support "read" but only write and subscribe. A "read"
in our api indicate rather an synchronous call for which we expect an
answer. This is not a case with CAN where you can keep broadcasting but
never expect any answer back or could have multiple replies. While
downstream protocols can offer such functionality (canopen does) at most
basic level we can't provide any handling for that. Definitely it would
make hard to port driver over different languages.
If this driver gets implemented end users can use it as a very thin
client API which gives them access to the bus and covers very basic
handling of subscriptions for specific COBs (CAN Object Identifier) and
possibly basic IEC types via field handlers.

Transports: an awful part of CAN is amount of APIs which can be used to
access a bus. The low level stuff is done by microcontrollers and hidden
from applications who interact with a bus. In the end socketcan, slcan,
usb2can or whathever-to-can are just multiple ways to publish CAN frame
onto physical medium.
I did hang on this for a moment, cause driver syntax we have is briefly:
<protocol>:<transport>://<transport-options>?<driver-options>

Currently connection string for CANopen looks like this:
canopen:socketcan://vcan0?heartbeat=false
Yet for slcan or can2usb it could look like this:
canopen:slcan://dev/ttyUSB0;baud=50000?heartbeat=false
canopen:can2usb://COM4;baud=50000?heartbeat=false
(eventually with baud= parameter in query string).

Whatever syntax we use to express transport and its configuration the
problem is later shifted to the edge of Driver and Transport. Different
APIs might bring different frame length estimators or discarded byte
handling nor filtering capabilities. Currently driver is one who is
responsible for that, yet in case of CAN - socketcan uses 0x00 to always
pad data while serial bridges do not require it at all. At present I see
no way to fit it without breaking some things.
CAN transport essentially must provide above estimators. Maybe in future
some other features specific to this transprot ie. message filtering
which seems to be very common thing. For driver it must provide a way to
publish "COB + byte[]" and receive "COB + byte[]".

So far we have support only for socketcan transport. It did the job to
get into CAN, yet it is not the only one. Its not portable over all
platforms. Because of above condition canopen driver actually depends on
socketcan transport and its encoding of frames.
My long term plan in this area is extraction of CANFrameBuilder part out
of canopen driver to plc4j-transprot-can. This transport should define
CAN specific transport APIs. What do you think about that?

Once this step is made we can bring simplistic CAN driver with very low
effort. It will also open a path for other CAN transports which could
utilize yet another hardware and serve other operating systems.

Best,
Łukasz

Reply via email to