Bare metal UDP - what's involved - Page 1
Forum section: electronics / projects

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: May 10, 2016, 09:50:57 am
content: Just looking at a project where I have to receive UDP packets over 10/100 ethernet (don't yet know if it runs at 10 or 100). The format and content is already defined and not changeable.IP addresses are fixed ( at install time), and it is receive only.If it's sufficiently easy I'd sooner write my own code to talk to an ethernet peripheral than try to use an existing stack, which will inevitably include a lot of stuff I don't need. It's possible that some or all may be done in a FPGA. Or an MCU with ethernet peripheral throwing the packets straight into an FPGA.I've had a quick scan round the net but can't immediately find a simple description of exactly how the content of a UDP packet appears on the wire as the raw ethernet packets - sure I could if I looked harder but someone here with experience can probably answer off the top of their head...Just looking for a quick idea of how much work is involved as I've never done anything with TCP/IP of any sort.There may be some scope for doing some shortcuts as the packets are the only thing on the wire.

author: Zbig
author_rank: Frequent Contributor
timestamp: May 10, 2016, 10:08:13 am
content: There are several one-chip Ethernet solutions that have the TCP stack built-in and abstracted away like theWizznet 5100used in Arduino Ethernet shields.

author: nctnico
author_rank: Super Contributor
timestamp: May 10, 2016, 10:15:12 am
content: UDP is relatively easy but you'll need to be able to parse ethernet and UDP headers and probably implement the ARP protocol as well. This is all very doable but it can be handy to use an existing network stack IF it has been written in a sensible way (so skip uIP). Things get hairy when you need to have TCP/IP support. One advantage of UDP is that you can leave the checksum to 0 which means there is no checksum. This saves a lot of processing time and the checksum over the data doesn't add much since there is already a CRC32 checksum over the data on ethernet.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: May 10, 2016, 10:47:42 am
content: Quote from: nctnico on May 10, 2016, 10:15:12 amPresumably ARP is how the sender knows what ethernet MAC to send data to.Though it could presumably be done with an ethernet interface in promiscuous mode, this would lose the benefit of hardware address matching in the ethernet interface.I may take a look at the PIC32MZ - the project just needs to take an ethernet stream and spit out 72 UART streams at 50-100kbaud - I've (just) done 12 ports at 250Kbaud in the past on a 50MHz PIC32MX, so maybe the 200MHz 32MZ will have the grunt to do it. If not I could probably use it to push packets into an FPGA via the PMP. With the large flash and negligible processing needed, I can use a stupidly big lookup table for any bit-juggling that may be needed!There is a small amount of configuration UI needed so it will need a processor of some sort anyway.Has anyone seen any nice graphics showing how ethernet packets break down into the various IP stuff?

author: amyk
author_rank: Super Contributor
timestamp: May 10, 2016, 11:00:40 am
content: You'll need to respond to ARP requests for your IP address with the MAC, so it won't be completely receive-only, but the ARP protocol is simple enough if you don't need the request part too.This might be a good intro to all the layers involved:http://www.analog.com/media/en/technical-documentation/application-notes/EE-269.pdf10M you should be able tobitbang with an MCU(or maybe some clever tricks with the SPI port and/or UARTs), 100M is definitely FPGA territory, and 1G will require some RF voodoo.

author: stmdude
author_rank: Frequent Contributor
timestamp: May 10, 2016, 12:04:47 pm
content: UDP is the easiest way to go, so you're not facing something tremendously difficult.Basically, you'll be dealing with this:That's an ethernet frame. Now, where it says "DATA", thats where this goes:Now, ARP is the protocol that's used by a host (the PC or whatever in this case) to determine which MAC-address a particular IP has.For now, you can skip that part, and just tell the host manually (by adding an entry in the ARP-table using the "arp" command). If you need dynamic ARP functionality later, you can add it then.The most naive/simplest implementation of this would be to:1. Check the first 6 bytes to make sure the packet is for you (MAC-address)2. Skip the next 32 bytes. The next two bytes will tell you the length of the UDP payload.3. Skip 2 more bytes4. This is your payloadNow, to make this a bit more robust, you'd want to check the ethernet checksum, as well as the UDP checksum. Also, check that the destination IP address is "yours".If you expect more than one stream of data, you'd want to check the UDP port number field as well.

author: sync
author_rank: Frequent Contributor
timestamp: May 10, 2016, 12:30:07 pm
content: Quote from: stmdude on May 10, 2016, 12:04:47 pmThis is only valid if the IP header has the minimum size of 20 bytes. It's unlikely that the header will be larger. But hardcoding the IP header size doesn't sound right.

author: MrSlack
author_rank: Frequent Contributor
timestamp: May 10, 2016, 12:34:40 pm
content: There's a tiny IP stack here that does the basics i.e. MAC, ARP, IP, UDP etc:https://github.com/adamdunkels/uipSource is easy enough to read as well.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: May 10, 2016, 12:37:03 pm
content: Quote from: stmdude on May 10, 2016, 12:04:47 pmThanks, that's exactly what I was looking for. As I'm only receiving I can probably just ignore a lot of the fields.QuoteWill need this, but probably not too complicatedQuoteI would hope/expect the ethernet hardware would do thisQuoteAgain I'd expect the hardware to do the ethernet CRC check, if that's right then it's reasonable to assume the UDP sum is ok and ignore it.

author: Scrts
author_rank: Frequent Contributor
timestamp: May 10, 2016, 12:57:58 pm
content: I've done UDP sending and receiving for video multicast streams using FPGA. The main problem was servicing ARP, ICMP and other non-video packets. I had a channel mux in front of the MAC, so the softcore processor was dealing with non-video data while incoming video streams were moved to FPGA processing. I basically switched the mux according to the packet type. If it's UDP -> go to FPGA, otherwise -> softcore. Since the FPGA was capable of doing several streams, the mux also filtered the data according to the UDP port.I used Nios+LwIP without RTOS.

author: madires
author_rank: Super Contributor
timestamp: May 10, 2016, 01:14:17 pm
content: A little bit more detail about the scope of the network would be helpful to answer your question. Are you talking about IPv4 and/or IPv6? Unicast or multicast traffic? Will it need to run just inside an isolated LAN or is routing required? What about ICMP, especially echo request/reply?

author: coppice
author_rank: Super Contributor
timestamp: May 10, 2016, 01:26:18 pm
content: You can't do receive only UDP. You have to send packets for address resolution (ARP), if for nothing else. If you are doing simple send and receive and doing ARP you might as well use one of the freely available basic TCP/IP stacks, like uIP or LwIP. If your needs are simple you can use them standalone. They integrate with various RTOSes if you are doing something more complex.One or two fields, such as the UDP checksum, are ignorable, but don't be too keen to limit the checking you do. There will almost certainly be a mixture of packets coming down that pipe at one time or another, and you'd better be sure you don't get confused or create a security issue.

author: Siwastaja
author_rank: Super Contributor
timestamp: May 10, 2016, 01:39:05 pm
content: UDP is very simple as a stateless protocol with a few simple header fields. You can download a VHDL implementation for UDP and ARP fromhttp://www.tkt.cs.tut.fi/research/nocbench/download.html, just download Trace Monitor Release Package and look at vhd files. It's all licenced under LGPL; if this is no good for you, you can still use it as reference material to do your own. This work was done by me and a coworker sometime in 2009-2011, we were dumping data from FPGA to PC over 100M ethernet. We also implemented a working controller for Davicom DM9000A integrated MAC/PHY, also included. Hope this helps.

author: nctnico
author_rank: Super Contributor
timestamp: May 10, 2016, 01:54:39 pm
content: Quote from: MrSlack on May 10, 2016, 12:34:40 pmWhat planet are you on? uIP is a heap of crap! It has several bugs which are hard to fix because the author thought he'd write his code as spaghetti so the C compiler wouldn't need to optimise it.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: May 10, 2016, 01:56:38 pm
content: This is for a system whose sole job is to get data from a custom PC to a bunch of LEDs over ethernet. There will be no other traffic. If it was a system I'd designed it would probably have been done with multiple RS485 buses.One reason for rolling my own code is that it may be simpler than trying to understand someone else's, especially when the latter includes a lot of stuff I don't need.And if it ends up as an all software solution, there may be some significant timing/latency constraints so I'd like to be in total control of exactly what happens when. Doing stuff like 72 soft UARTS is the sort of code I actually like writing!At this stage it's just a case of understanding roughly what's involved - seems like ARP is the most complex bit, which I'll look into but don't expect it will be too complicated.

author: Kjelt
author_rank: Super Contributor
timestamp: May 10, 2016, 01:59:21 pm
content: Or skip the whole hassle and use a BBB board with embedded linux and using python your prototype is finished within a day.

author: madires
author_rank: Super Contributor
timestamp: May 10, 2016, 02:00:32 pm
content: Quote from: coppice on May 10, 2016, 01:26:18 pmFor a proper IP stack. But if you really want to cut corners you can also do it without ARP in a specific environment. The sender needs to know the receiver's MAC addresses via configuration. And you would have to check the senders IP stack on how it handles some extras like duplicate address detection or how to turn it off. If the sender is happy with the configured MAC address table and doesn't send ARP requests for the configured MACs, it should work.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: May 10, 2016, 02:14:31 pm
content: Quote from: Kjelt on May 10, 2016, 01:59:21 pmA day plus however time it takes to learn enough Linux and figure out how to implement the 72 UARTS. Oh, and it also has to fit the form factor of an existing board it's replacing.

author: madires
author_rank: Super Contributor
timestamp: May 10, 2016, 02:14:38 pm
content: Quote from: mikeselectricstuff on May 10, 2016, 01:56:38 pmARP is fairly simple. The receiver listens also on the broadcast MAC (FF:FF:FF:FF:FF:FF) for ARP requests. If it receives a request with it's own IP address, it replies with it's MAC and IP address. Requests for other IP addresses are ignored. Optionally the host may also support ARP announcements. BTW, ARP is IPv4, IPv6 uses ND.

author: MrSlack
author_rank: Frequent Contributor
timestamp: May 10, 2016, 02:40:03 pm
content: Quote from: nctnico on May 10, 2016, 01:54:39 pmTo be fair it did target the 6502 and a shitty compiler to start with.

author: matseng
author_rank: Frequent Contributor
timestamp: May 10, 2016, 02:42:34 pm
content: Will there actually be any ARP requests if the sending machine (PC?) already have the IP/MAC mapping set as permanent/static entries in the ARP-table?

author: stmdude
author_rank: Frequent Contributor
timestamp: May 10, 2016, 02:47:54 pm
content: Quote from: matseng on May 10, 2016, 02:42:34 pmThis.. Just as I mentioned above as well. Since it's a custom system, you can just bypass the whole ARP issue completely...

author: sync
author_rank: Frequent Contributor
timestamp: May 10, 2016, 02:55:07 pm
content: Maybe just use raw ethernet?Then no IP, ARP, UDP is needed. Your application just sends raw ethernet frames to the device MAC address.

author: Kjelt
author_rank: Super Contributor
timestamp: May 10, 2016, 02:59:27 pm
content: Quote from: mikeselectricstuff on May 10, 2016, 02:14:31 pmI knew barely nothing about Linux and Python last year when I started with a pi2 boards, and it took around 6 hours to learn a bit about Linux and Python.Then I had an UDP program ready and finished within about another 8 hours (so two or three days) just looking at some example code, it is that easy because everything is already done for you.Then you output the data through the (many) GPIO pins to your hardware fpga/soc or whatever is doing the 72 uarts.The form factor fitting is going to be the hard part as costs per board (how many you need) as well as reliability (linux board can not be shutdown hard or the logfiles may corrupt the flashdrive) so need a soft shutdown. So yeah there are some drawbacks but nothing like building a reliable ip stack from scratch which can be pretty tough unless you can copy/paste it from someone somewhere.So if you definitely want to go that route I suggest you buy some middleware from some big company like Keil or Segger and use that, at least it is tested, ready and you have support, problem is it will set you back at least 4 figures.

author: Kjelt
author_rank: Super Contributor
timestamp: May 10, 2016, 03:02:25 pm
content: Quote from: sync on May 10, 2016, 02:55:07 pmThat could work, so option three from this picture? But I would not call that UDP anymore

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: May 10, 2016, 03:12:12 pm
content: My customer is still gathering info on the system so I don't know the detals, other than they were previously using an XMOS devboard which is now unobtanium along with the chip it used.I think the host software was done in-house but I don't know if whoever did it is still there - there was a comment about lack of documentation so maybe not.It now seems like the Ethernet stuff should be pretty straightforward, and could be a useful learning excersise, working in a very controlled environment- that was the only unknown for me - I never take on a job until I'm sure I can do it.

author: stmdude
author_rank: Frequent Contributor
timestamp: May 10, 2016, 03:32:18 pm
content: Quote from: mikeselectricstuff on May 10, 2016, 03:12:12 pmIf the protocol is undocumented, your new best friend will be a network protocol analyzer, such as WireShark. "Just" sniff the comms of the existing system, and then start figuring it out on a PC before you start doing the embedded part.

author: Siwastaja
author_rank: Super Contributor
timestamp: May 10, 2016, 03:39:02 pm
content: You don't need to implement ARP if you use a fixed ethernet card in the PC, or if you bother reprogramming the MAC addresses every time you connect it to a different machine.We decided to implement ARP because it's not difficult and makes the usage easier because we didn't have "secondary" interface to reprogram the PC MAC address into the FPGA, so we decided to use fixed IP address for PC (something like 192.168.0.5). If you implement UDP and IP, it makes sense to do ARP, too. And it eases the software side on PC as you can work through standard networking stack, lot of examples available everywhere.Really, if you end up doing it with FPGA, just use our code. It's highly modular and the UDP/IP+ARP modules should be fairly easy to use as they are, because we went for simplicity.

author: Scrts
author_rank: Frequent Contributor
timestamp: May 10, 2016, 03:51:51 pm
content: Quote from: Kjelt on May 10, 2016, 02:59:27 pmI agree on this. Adding a microcontroller/microprocessor in the middle would help if the data is not high bandwidth. Then transfer the data from micro to the FPGA using SPI, Parallel or any other interface.

author: Yansi
author_rank: Super Contributor
timestamp: May 10, 2016, 04:07:52 pm
content: Hi Mike!If you only need to move large amounts of data quickly for a long distance, you can only use the MAC+PHY layers of the ethernet (assuming only a point to point connection). The MAC layer works as simple as it can get: Whatever is given to it is spit down the cable.Any decent MCU with HW MAC layer is simple enough to use in such way, only a config of the PHY chip is needed using the MDC/MDIO bus (which is handled by the ETH peripheral in the MCU anyway)

author: daqq
author_rank: Super Contributor
timestamp: May 10, 2016, 05:06:25 pm
content: Try this:http://www.fpga4fun.com/10BASE-T.html

author: stmdude
author_rank: Frequent Contributor
timestamp: May 10, 2016, 05:08:38 pm
content: Hmm.. What kind of data-rates are we actually talking about here?If it's old crusty hardware you're replacing, chances are that things aren't moving very quick either... Maybe something like this could suffice?http://www.microchip.com/wwwproducts/en/en022889If so, hook that up to your favorite flavor of MCU, and (as Dave says) Bobs your uncle.. ARP+IP+UDP would be stupid easy to implement on an MCU.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: May 10, 2016, 05:26:04 pm
content: Quote from: Scrts on May 10, 2016, 03:51:51 pmAssuming the ethernet hardware can deal with packet filtering , so the code only sees the stuff aimed its own address, the bandwidth isn't going to be too bad - 72 UARTS at 100kbaud is only 720kbytes/second at 100% bus utilisation. If it can't do all 72 UARTS in software, it shouldn't be a problem to throw it out of SPI at 10MHz to something that can. 138nS per UART bit = 11 cycles on an 80MHz PIC32MX or 27 on a 200MHz PIC32MZ. Maybe time to learn MIPS assembler...What I've done in the past to avoid baud jitter is output data via HC595's, latched on a PWM output, so as long as you can get the data out fast enough, interrupt latency doesn't cause any jitter.

author: Kjelt
author_rank: Super Contributor
timestamp: May 10, 2016, 05:48:56 pm
content: That could work if you got enough RAM most PHY's have something like 32kB buffer so if you need to move 720kB/s now and then you're micro should be able to transport and temporarily buffer that.I guess if you reserve 64kB for the IP stack and the micro is fast enough it should suffice as long as you do not have to do TLS

author: Scrts
author_rank: Frequent Contributor
timestamp: May 10, 2016, 05:51:35 pm
content: STM32F4 does UDP video streaming (Camera interface -> Ethernet) up to ~80Mbps, plus all the ARP, ICMP, etc support. The DMA is used, so CPU is not loaded at all. I'd say you could use small micro, which would DMA UDP data to SPI or other bus, then grab it with the FPGA and that's it.For FPGA it's also not a difficult design. You create a FIFO with channel data and demux after it, create UART interface, iterate it 72 times and connect to the according demux output buses. Altera Avalon-ST bus is great for that.

author: dgtl
author_rank: Regular Contributor
timestamp: May 10, 2016, 06:48:20 pm
content: You shouldn't need ARP if you are sending broadcast packets. If the sending host can transmit the UDP stream to its broadcast IP address, the packets are delivered to all interfaces in that local segment and nothing matters inbetween. So you can put a switch inline and add a number of microcontrollers, each servicing some of the UARTs. Probably the synchronization between uc's on eth packet rx irq is good enough.For example of a cheap and small uc, you can use STM32F107 (if this is not enough, you can go up to F2x7 or F4xx series; almost same eth controller inside). You need an external PHY chip with RMII interface, ie KSZ8081RNACA. The eth controller will DMA the packets to SRAM. If more is not needed, you can manually handle the data. Otherwise, you can add LwIP or some other TCP/IP stack and get the full ethernet connectivity for example for monitoring, configuration and FW updates.For low jitter soft-UART, it should be possible to pre-parse UART port output data in main loop and then have a couple of DMAs dumping out pre-formatted tables from SRAM to GPIO registers (16-bit gpios, so 16 bits at a time); DMAs can be triggered by timer compare outputs. This would remove the irq overhead and the preprocessing algorithm could be a bit more optimal, but I haven't done the maths if it would give any advantage to IRQ-only solution.A nice solution would include a FPGA or CPLD inbetween; the uc streams one SPI stream to FPGA and the FPGA does serial->parallel->72x serial shifting. (assuming the uarts are tx-only).

author: kfitch42
author_rank: Frequent Contributor
timestamp: May 10, 2016, 07:12:19 pm
content: Quote from: mikeselectricstuff on May 10, 2016, 05:26:04 pmInteresting, 720KBytes/s is 5.76MBits/s. So, with 10baseT ethernet the PC only has enough bandwidth to talk to one of these guys (at 100% bus utilization). Also, the efficiency of the protocol might become important. Let's say it puts 1 byte for each UART in each UDP packet (just a guess at a simple/naive implementation). This would give 10,000 packets per second. Each UDP packet has 18+20+8=46 bytes of overhead for the stuff already mentioned, but another 20 bytes if you include the 8 byte preamble/start-of-frame and the 12 byte interframe gap. 10000*66*8=5.28Mbits/s of overhead. At which point our 10baseT is overflowing. Obviously putting more bytes of payload in each UDP packet would help bring that overhead down.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: May 10, 2016, 07:40:52 pm
content: Quote from: dgtl on May 10, 2016, 06:48:20 pmThe problem with that is you can't use the ethernet hardware's address filtering to only give you the data aimed at your Ip address. ( assuming the hardware isn't smart enough to do IP address filtering)QuoteIt's 100mbit. In practice the avarage load will be much lower. As long as the ethernet hardware deals with the address filtering so you only see the data for you, it all seems pretty manageable.A figure I was just told is that each board has to support up to 72 bytes per (display) frame on each of the 72 ports, though only half that is currently used. Assuming 60fps, that's about 300kbytes/sec.I would expect that each frame is sent as a single packet to keep overhead sensible.

author: stmdude
author_rank: Frequent Contributor
timestamp: May 10, 2016, 08:08:23 pm
content: Ok,I think I found the solution to your ARP+IP+UDP+Ethernet, problems..http://www.mouser.se/new/wiznet/wiznetW5200/$5 chip, 100Mbps ethernet, with built-in TCP/IP stack. 80MHz SPI interface.Sure, inventing is fun, but $5 can buy you a lot of time to get those 72 UARTs to work.

author: blacksheeplogic
author_rank: Frequent Contributor
timestamp: May 10, 2016, 08:46:26 pm
content: Quote from: mikeselectricstuff on May 10, 2016, 07:40:52 pmARP's only required if you need to map the IP address to the MAC address. Layer 1 & 2 only uses the MAC. If you need a 'registration' (Dynamic rather than a static table somewhere) send a frame to some hard coded MAC address. Depending on how bare bones your looking at, do you even care about an IP stack?

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: May 10, 2016, 10:37:26 pm
content: Quote from: stmdude on May 10, 2016, 08:08:23 pmLooks interesting, definitely worth a look. Also has onboard Phy, unlike the PIC32s.Looking at their website, the W5500 looks even better - 15 vs. 10Mb/s network performance, and only £1.74 1-off. As long as the 15mbit/sec performance is actually achievable in practice it looks like a very promising option.

author: Zbig
author_rank: Frequent Contributor
timestamp: May 11, 2016, 06:35:16 am
content: Quote from: mikeselectricstuff on May 10, 2016, 10:37:26 pmSo you guys haven't seen my suggestion; the very first reply in this thread?

author: Kjelt
author_rank: Super Contributor
timestamp: May 11, 2016, 07:54:17 am
content: @Mike, as discussed one of the downsides of a BBB was the formsize.Well I wanted to mention that there are alternatives. Since the hardware is opensource there is a german company who has put it on a small form factor pcb (see picture), it is called a beaglecore.It has lots of smd pads for expansion on the back and you do need to add the connector and magnetics.They do have some delivery issues (time) but still it is out there and could be a valid alternative. Also you could do this yourself and make your own custom BBB hardware pcb.But perhaps way overkill if a W5500 is enough for you.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: May 11, 2016, 09:04:20 am
content: Quote from: Zbig on May 11, 2016, 06:35:16 amYes thanks - I was already vaguely aware of these parts but it was only when the price and 80MHz SPI was mentioned that I took a closer look.