I am trying to implement a very small IP stack for 8-bit AVR MCUs. I do not want it to support TCP because it is really too big and I do not need it, but rather UDP (and, of course, ARP and ICMP).
I want the stack code to fit in 16 kilobytes of ROM and 1 kilobyte of RAM, of course, allowing as much space as possible for the application. I use an ENC28J60 based board for PHY / MAC control, which has an internal 8KB RX / TX circular buffer. When packets arrive on this chip, it writes them one by one to the RX buffer, but does not overwrite the oldest one. The oldest pointer indicates the pointer that needs to be updated to indicate the next package when the user has read it. It also sends an interrupt to one of its contacts when a new package arrives.
For the RX part, I want to work in the same way as lwIP: to signal that a new packet is ready when we receive an interrupt (save its address and size), but continue it only when the user calls our IP stack function. This should work fine; if the user does not call our function often enough, new arriving packets will be discarded and what it will be. The user provides a stack with a UDP callback.
Now the problem is in TX. Let's say I want to send a UDP packet to some IP address, for which I do not know the link address. An ARP request must be sent before sending my package. What if UDP packet comes before ARP reply? It should be handled by my UDP callback, but what if I want to send some of this callback? I'm still waiting for a response from ARP here. Surely this locking mechanism is wrong.
My question is: Is it good / accepted to have asynchronous sending? Thus, if I want to send something, I provide a send function with a callback and is called when a UDP packet can be sent. Thus, everything is event driven.
eepp source share