ol.sc Posted August 11, 2015 Share Posted August 11, 2015 Hi, In http://atariage.com/forums/topic/241436-contiki-august-2015/I mentioned the WIZnet W5100 Ethernet controller because Contiki (and IP65) have a driver for it. However the W5100 might be of some interest unrelated to Contiki so I opted for a new topic... - The current W5100 datasheet can be found at http://www.wiznet.co.kr/product-item/w5100/ - WIZnet also provides a module containing the W5100, see http://www.wiznet.co.kr/product-item/wiz811mj/ - I implemented several W5100 drivers (see links below) and recently wrote some notes on the W5100 I'm presenting here: 1. Operation Modes 1.1 MAC-Raw In MAC-Raw mode the W5100 behaves pretty much like a CS8900A or a LAN91C96. The W5100 is usually only configured with a MAC address which is used by the W5100 to limit incoming frames to those sent to its MAC address (or broadcasts). 1.2 IP-Raw IP-Raw mode is usable to implement non-UDP/non-TCP IP protocols like ICMP. The W5100 is usually configured with a full IP profile (IP addr, netmask, gateway). It transparently takes care of incoming/outgoing ARP and optionally of incoming ICMP Echo (aka Ping). 1.3 UDP UDP mode is pretty simlar to IP-Raw mode but additionally takes care of header checksum calculation. 1.4 TCP TCP mode is rather different from the other modes. Incoming/outgoing data isn't delimited by headers like in all other modes. Rather the W5100 behaves like a BSD socket delivering/taking a data stream - in chunks not necessarily related to data packets received/sent. The W5100 transparently takes care of TCP flow control by sending ACK packets. It advertises a receive window identical to the free space in the its receive memory buffer. The W5100 offers up to 4 'sockets' allowing to specify the operation mode for each socket individually. However MAC-Raw mode is only available for the first socket. It is possible to combine MAC-Raw mode with other modes for the other sockets - which is called 'hybrid TCP/IP stack'. I have no personal experience with this hybrid TCP/IP stack and see open questions: - Are packets delivered to other sockets filtered from the first socket? - Who takes care of incoming ARP and incoming ICMP Echo? The W5100 divides its 16kB memory buffer statically into 8kB for receive and 8kB for send (in contrast to the CS8900A and the LAN91C96 which both do dynamic receive/send buffer division). When using several sockets it is additionally necessary to statically assign the two 8kB memory buffers to the sockets. 2. Memory Buffer Access In 6502 machines the W5100 is accessed using its indirect bus interface. This interface optionally allows for pointer auto-increment (like the CS8900A and the LAN91C96). However in contrast to those two Ethernet controllers the W5100 does NOT virtualize access to its memory buffer! So when reading/writing data from/to the W5100 and reaching the end of the memory buffer assigned to the socket it's the responsibility of the 6502 program to continue reading/writing at the begin of the memory buffer. Please note that the pointer auto-increment does NOT take care of that wraparound operation! I have implemented several ways to handle this difficulty. 2.1 Copy Split If it is necessary or desired to have the interface to the upper layers being based on a receive/send buffer and one can afford the memory for a little more code than it is appropriate to check in advance if receive/send will require a wraparound and in that case split the copy from/to the buffer into two copy operations. That approach is used in all WIZnet code and I implemented it in pretty optimized 6502 code for the Contiki/IP65 MAC-Raw mode driver located in drivers/w5100.s - however the copy split technique is in general applicable to all W5100 operation modes. 2.2 Shadow Register When it comes to using as little memory as possible I consider it in general questionable if a buffer is the right interface paradigm. In many scenarios it makes more sense to read/write bytes individually. This allows i.e. to directly write bytes from individual already existing data structures to the W5100 or analyze bytes directly on reading from the W5100 to decide on processing of subsequent bytes - and maybe ignore them altogether. This approach splits a receive/send operation into three phases: The initialization, the individual byte read/write and the finalization. The initialization sets up a 16-bit shadow register to be as far away from overflow as the auto-increment pointer is away from the necessary wraparound. The individual byte read/write then increments the shadow register and on its overflow resets the auto-increment pointer to the begin of the memory buffer. I implemented this approach in two drivers using heavily size-optimized 6502 code for the W5100 UDP mode and TCP mode showing that the shadow register technique yields the smallest code. They are located in supplement/w5100_udp.s and supplement/w5100_tcp.s with C test programs located in test/w5100_udp_main.c and test/w5100_tcp_main.c. There's a Win32 communication peer for the test programs located in test/w5100_peer.c. 2.3 TCP Stream Split A correct BSD TCP socket program never presumes to be able to read/write any amount of data. Rather it is always prepared to call recv()/send() as often as necessary receive/send the expected amount data in whatever chunks - and the very same holds true for any program using the W5100 TCP mode! But this already necessary complexity in the upper layers allows to handle W5100 memory buffer wraparounds transparently by artificially limiting the size of a read/write operation to the end of the memory buffer if necessary. The next read/write operation then works with the begin of the memory buffer. This approach shares the benefits of the shadow register technique while avoiding its performance penalties coming from maintaining the shadow register. Additionally it allows the upper layers to directly access the auto-increment W5100 data register for individual byte read/write because it is known to stay within the memory buffer limits. Therefore the TCP stream split technique avoids both the overhead of a buffer as well as the overhead of function calls for individual bytes. It sort of combines the best of both sides but it means larger code than the shadow register technique and is only applicable to the W5100 TCP mode. I implemented the TCP stream split technique in a C-only driver located in supplement/w5100.c with a test program representing the upper layers located in test/w5100_main.c being compatible with test/w5100_peer.c. Regards, Oliver 2 Quote Link to comment Share on other sites More sharing options...
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.