I began to scratch surface of Driver/Protocol/Context and here is what I
found.

Currently it is *impossible* to do any customization with
ProtocolStackConfigurer or GeneratedDriverBase without really copying
whole classes.
Trouble I see is:
1) Protocol stack configurer rely on classes instead of actual instances.
Is there any reason why packet estimator and byte discarder are passed
there as classes and not actual instances? These are functions which
*should* not have side effects hence we should not require an reflection
to create instance of these.
2) Driver which is asked to create protocol stack has *no access* to
actual configuration.
3) Transport is "lost in transition" while creating pipelines.
It is not retained nor accessible to stack configurer making it
impossible to ie. make transport dependent stack configuration. As much
as this situation is not very common. yet we either force user to pass
extra URL parameters or let drivers do their defaults based on transport.

Very simplified startup flow for driver is:

generated driver initialization ->
  create configuration
  find transport ->
    configure transport
    transport -> create channel factory
  create connection ->
    create field handler
    create value handler
    create stack configurer

My proposal is to switch it to:
  create configuration
  find transport ->
    configure transport
    transport -> create channel factory
  create connection ->
    create field handler
    create value handler
    create stack configurer*(configuration, transport)*

Another finding I have - estimators and discarders are created by
reflection in hope to receive configuration from URI parameters.
Such situation so far does not happen and I think its rather rare (yet
we can face it some day), thus I would opt for having configuration
calls with them, however I would move that part from stack configurer
above - to the driver. In case if driver expects configuration options
for its wire processors it must enable it explicitly.
This will also leave a space to create base class for CAN drivers and
utilize transport and configuration to create estimator and discarder
dynamically.

Looking forward to hear your opinion about above changes.

Best,
Łukasz

On 29.03.2021 06:43, Andreas Oswald wrote:
> Hi Łukasz,, hi everybody,
> 
> that sounds pretty interesting, do you have plans to to implement "higher 
> level" protocols based on CAN e.g. UDS? Maybe we should exchange ideas as my 
> daytime job ist about developing a software package that takes care of 
> Software Versions and parameter sets for electrical vans, where we rely 
> heavily on UDS. Unfortunately not all of our ECUs implement fine UDS.
> 
> When Chris introduced me to the project I guess a bit more than two years 
> ago, Slack was the medium to use.
> 
> Maybe someone can give me a hint about how communication is dealt with.
> 
> Good to be back 😉
> 
> Have a great start for the new week.
> 
> Take care
> 
> Andreas
> 
> Andreas Oswald
> Marienstraße 12
> 52223 Stolberg
> Germany
> 
> ++49 2402 905 3852
> ++49 172   426 1598 (also Signal)
> WhatsApp/Telegram on ++49 157/38459358
> 
> ________________________________
> Von: Łukasz Dywicki <[email protected]>
> Gesendet: Montag, 29. März 2021 02:18
> An: [email protected] <[email protected]>
> Betreff: Further updates to CAN stuff in plc4j
> 
> 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