OpenCyphal / public_regulated_data_types

Regulated DSDL definitions for Cyphal (standard and third-party)
https://nunaweb.opencyphal.org
MIT License
72 stars 96 forks source link

uavcan.can.iface is not exposing available interfaces #126

Open PetervdPerk-NXP opened 3 years ago

PetervdPerk-NXP commented 3 years ago

The uavcan.can.iface standard register specifies a key where you can change can interface to be used.

#   REGISTER NAME PATTERN                               TYPE            FLAGS                   RECOMMENDED DEFAULT
#   uavcan.can.iface                                    string          mutable, persistent     implementation-defined

# uavcan.can.iface is only relevant for software nodes or nodes that are capable of using different CAN interfaces.
# The value is a space-separated list of CAN interface names to use. The name format is implementation-defined
# (for example, "can0").

However the user cannot derive which CAN interfaces are available, in the worst case this would yield a misconfiguration and the node will not be available anymore on the bus.

To solve this I have two potential solutions:

  1. Create a new standard register e.g. uavcan.can.ifaces which is not mutable (i.e. read-only) and exposes a list of available interfaces.
  2. Change the data type of uavcan.can.iface from string to a bool array i.e. bool[n] where n indicates the number of CAN interfaces and bool[0] correspond to can0 etc, then user can then easily select one or more CAN interfaces to use and this minimize the memory footprint to implement this features as well.
pavel-kirienko commented 3 years ago

Not sure about option 2 because it doesn't provide a way for the user to make an informed decision about which interface to use (e..g, is bool[1] the can1 or slcan0?). Option 1 seems sensible although it may require some non-trivial logic for detection of the available interfaces. Would you be up to drafting up a prototype based on PyUAVCAN?

https://github.com/UAVCAN/pyuavcan/blob/9da3cf579b65cae4067b16c621cc3321156f17d4/pyuavcan/transport/can/media/_media.py#L147-L163

PetervdPerk-NXP commented 3 years ago

Not sure what you mean by a prototype using pyuavcan, you can easily make a register response in yakut right? Regarding that piece of code you can easily generate a list of CAN capable interfaces if that's what you want.

import re
import psutil
ifaces = [ s for s in psutil.net_if_addrs() if re.compile(r"^(v|sl|)can\d+").match(s) ]

For me it's more to understand/standardize the minimal set of registers i.e. uavcan.can.iface a node running on a small MCU has to implement. It's easy to come up with a custom register/service that exposes the available interfaces but I rather want to standardize it in the uavcan.register spec like is done for id,iface,bitrate etc.

pavel-kirienko commented 3 years ago

Not sure what you mean by a prototype using pyuavcan, you can easily make a register response in yakut right?

Yakut can't serve RPC-services. In PyUAVCAN you would integrate your sample like this:

import re
import psutil  # <-- these batteries are not included
your_node.registry["uavcan.can.ifaces"] = lambda: " ".join(s for s in psutil.net_if_addrs() if re.compile(r"^(v|sl|)can\d+").match(s))

For me it's more to understand/standardize the minimal set of registers i.e. uavcan.can.iface a node running on a small MCU has to implement.

I don't understand this part: why does a typical embedded node need to report the list of available CAN interfaces?

PetervdPerk-NXP commented 3 years ago

I don't understand this part: why does a typical embedded node need to report the list of available CAN interfaces?

To remotely configure redundancy ie. enabling 2 interfaces, but there are also commercially available MCU's that have up to 8 CAN controllers so it would be great to have to flexibility to change the CAN port remotely.

pavel-kirienko commented 3 years ago

Okay, that makes sense.

We still should update PyUAVCAN to expose this register before updating the Spec though.