Small Exemplar Network Stack

For customers who do not have an appropriately capable ethernet/IP multicast stack, we want to provide a minimal solution which enables the use of libudpard on platforms which at least have an ethernet driver which can send and receive frames along with some other minor requirements.

This small IP stack would be required to only support, per Cyphal specification, UDP multicast (and Ethernet Multicast) and IGMP in order to get a functional implementation with 1 network interface. These may have consequences that more features are needed to bring the stack up but for now this seems like the minimal set.

Since the library would pair with lidudpard, it would also be in “C” although I would prefer C23 or C17 or eariler.

Other features under discussion to aid customers:

  • ARP request/response
  • ICMP echo/response
  • unicast support in UDP
  • IPv6 support for UDP

Additionally T1S support in the future may cause some necessary changes but I can’t forsee what that may be right now.

An API discussion or feature discussion is welcome.

I’m not in favor of a socket API as these deeply embedded projects without an existing stack don’t need that abstraction. I would prefer something simple, with APIs to register intent to listen/transmit to a specific multicast addresses and port, as well as either a callback/RunOnce or an active call to Receive. The IGMP packets could be automatic w/ time-outs or explicit via the “intent” API.

Thoughts?

That sounds good. I don’t have any inputs on API yet.

No objections to C17; it seems well-supported already as far as I can tell. C23 notably lacks support from IAR at the moment, but it may change quickly so not sure if that’s a deal breaker.

It is available in GCC-15, which just recently released.

Do we know when it’s going to be supported in IAR?

Some initial thoughts on API

  • Status Initialize(Context, ExternalContext Dependencies) - then depedencies are a bunch of function pointers in a structure back to customer APIs which can provide. External context here is whatever the Ethernet driver needs.
    • Frame* Acquire(ExternalContext);
    • void Release(ExternalContext, Frame*);
    • Status Receive(ExternalContext, Frame*);
    • Status Transmit(ExternalContext, Frame*);
    • utility functions like print or a monotonic timestamp, no assumed external functions, except memset and memcpy, even those could be supplied.
  • Deinitialize(Context);
  • Status PrepareListen(Context, multicast_ip);
  • Status PrepareTransmit(Context, multicast_ip);
  • Either a direct call or an indirect callback
    • Status ReceiveUdp(Context, Metadata*, cspan);
    • Status RunOnce(Context, Callback);
  • Status TransmitUdp(Context, Metadata *, cspan);

https://en.cppreference.com/w/c/compiler_support/23

IAR is not mentioned there

Hmm, do they not support any C specifications? I keep getting 404 pages on many google links.

https://www.iar.com/knowledge/learn/programming/exploring-c-and-cpp/#:~:text=C11%20is%20a%20superset%20of,low%20level%20drivers%20in%20C.

https://www.iar.com/knowledge/learn/programming/exploring-c-and-cpp/

They claim at least C18 (which I guess is the ISO version?)

https://netstorage.iar.com/SuppDB/Public/UPDINFO/013857/arm/doc/infocenter/readme.ENU.html

Wikipedia Page is a bit old IAR Systems - Wikipedia

I was thinking about consequences of not supporting unicast yet is that we may not need an IP address, except that we do need to put an address into the source field of any outgoing packet. So I think we’ll need to have that at least properly supported as a normal endpoint in the network from the beginning.

And now the hardest part, the name, in four parts; common name, namespacing prefix,MACRO prefix and variable prefix

  • Micro IP, MicroIpFunctionName, MICRO_IP_DEFINE, micro_ip_var
  • Nano IP, NanoIpFunctionName, NANO_IP_DEFINE, nano_ip_var
  • Cyphal IP, CyphalIpFunctionName, CYPHAL_IP_DEFINE, cyphal_ip_var
  • Cilia IP, CiliaIpFunctionName, CILIA_IP_DEFINE, cilia_ip_var
  • Cilium IP, CiliumIpFunctionName, CILIUM_IP_DEFINE, cilium_ip_var
  • Hypha IP, HyphaIpFunctionName, HYPHA_IP_DEFINE, hypha_ip_var

I’m partial to Hypha now

Hypha sounds fine to me