W5100 Shared Access

Oliver Schmidt edited this page Oct 25, 2016 · 1 revision

Motivation

The TCP/IP stack of the W5100 makes it feasible to integrate network functionality into 8-bit operating systems. The obvious use case is a redirector allowing to access network drives. But doing so brings up the question what happens if a program is run which uses the W5100 for own purposes. One option would be to define a software API to be used by the program instead of accessing the W5100 directly. However such an approach would require way too much memory resources and make the program dependent on the API.

Therefore it is much more reasonable to let both the (operating) system and the program access the W5100 directly. Such a shared access is in general no problem as the W5100 comes with 4 individual 'sockets'. One socket is used by the system leaving 3 sockets for use by the program. It's only necessary that the system and the program agree on certain aspects.

Considerations

Only socket 0 may be opened in MAC-Raw mode. Most currently existing programs use MAC-Raw mode but the system for sure doesn't use MAC-Raw mode so it's obvious that socket 0 is left to the program.

Given that 8-bit systems operate synchronously the system is supposed to use some stop-and-wait protocol with messages not much larger than its native block size. From that perspective the system doesn't benefit from reserving more than 1kB of W5100 TX/RX memory for its socket. This leads to the following setup:

  • Socket 0: 4kB TX/RX memory, program usage
  • Socket 1: 2kB TX/RX memory, program usage
  • Socket 2: 1kB TX/RX memory, program usage
  • Socket 3: 1kB TX/RX memory, system usage

Conventions

Directly after hardware detection the program detects if the W5100 is already in use by the system. It does so by checking if RX Memory Size Register at 0x001A contains the value 0x06.

If the system already uses the W5100 the program must prepare for shared access meaning to not reset the W5100. Instead the program can presume the following setup:

  • S/W Reset performed
  • Mode Register at 0x0000: 0x03
  • Source Hardware Address Register at 0x009-0x00E: Valid MAC address
  • RX Memory Size Register at 0x001A: 0x06
  • TX Memory Size Register at 0x001B: 0x06

The program must not presume any valid values for the Gateway IP Address Register at 0x0001-0x004, the Subnet Mask Register at 0x0005-0x0008 and the Source IP Address Register at 0x000F-0x0012. The system may i.e. fully rely on UDP broadcasts or may even not use the W5100 at all but rather use shared access just as means to provide a prefered MAC address to the program.

The program must use the MAC address found in the Source Hardware Address Register - especially for DHCP.

The program is presumed to handle its IP setup in the very same way it would do without shared access. This explicitly includes setting the Source IP Address Register, Subnet Mask Register and Gateway IP Address Register for W5100 modes other than MAC-Raw. With DHCP the DHCP server is presumed to provide the same IP setup to the program it provided before to the system. Without DHCP it's up to the user to enter the same IP setup for the system and the program.

Notes

If the program uses solely socket 0 it may choose to use 8kB of W5100 TX/RX memory in the non-shared access scenario. However I personally suggest to avoid different setups and just use 4kB TX/RX memory in both scenarios. It simplifies things and I don't see an actual benefit of 8kB for typical programs in typical environments. If doing so I suggest to set the two Memory Size Registers in the non-shared scenario to the value 0x0A. A value different from 0x06 makes sure that a subsequent program doesn't mistakenly detect shared access.

If the program (potentially) uses 3 sockets it may choose to set the two Memory Size Registers in the non-shared scenario to the value 0x06 (used in the shared access scenario) in order to simplify things. However that means that the program needs to set the RX Memory Size Register to a different value on exit to make sure that a subsequent program doesn't mistakenly detect shared access. Therefore I personally suggest to set the two Memory Size Registers in the non-shared scenario to the value 0x16. Doing so of course requires to distinguish both scenarios regarding access to socket 2. But I can see an actual benefit of 2kB instead of 1kB - and there's no need for any exit handling.

If the program uses MAC-Raw mode and comes with its own ICMP responder it may want to set bit 4 in the Mode Register in order to enable the Ping Block Mode. However the user might have choosen a different IP setup for the system. Therefore the Ping Block Mode should only be enabled after making sure that the values of the Source IP Address Register, Subnet Mask Register and Gateway IP Address Register match the IP setup of the program. Additionally the program needs to disable Ping Block Mode on exit. So maybe simply living with superfluous ICMP responses is actually more appropriate.

Samples

The W5100 code located in udp.s and tcp.s (with C test programs located in udp_main.c and tcp_main.c) follows the conventions for the system.

The W5100 code located in stream.c (with a test program representing the upper layers located in stream_main.c) and w5100.s follows the conventions for the program.

There's a test program located in shared.c that includes both udp.s and stream.c to demonstrate the actual shared access.

There's a Win32 communication peer for the test programs located in peer.c.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.