Using Multiple Network Interfaces

The initialization sequence followed to set up a single network interface in µC/TCP-IP can, for the most part, be repeated to establish additional interfaces.

For many embedded systems, a single Ethernet or Wi-Fi interface is sufficient for implementing network communication. However, thanks in part to end users' increasingly high expectations for connectivity options, it is not uncommon for devices to require multiple interfaces. With Micriµm’s µC/TCP-IP stack, it is possible to meet this requirement.

If you are familiar with µC/TCP-IP’s API calls, then you’ve probably seen Micriµm's example start-up code for creating a single interface over Ethernet. When dealing with multiple interfaces, you'll mostly rely on the same calls involved in the single-interface scenario.

The following flowchart illustrates the multiple-interface initialization process. After application code initializes the core TCP/IP stack, this code then adds and starts a new network interface. For a Wi-Fi connection, it may be necessary to subsequently scan and join the wireless access point, although, in the case of a hidden network (with a name known to application code), the scan operation would normally be skipped. At this point, application code must configure the interface for the desired IP host address, subnet mask, and default gateway.

multiple-interface-initialization

In code, this process would resemble the following:

net_err = Net_Init(...);             /* Initialize core stack           */ 

                                     /* BEGIN INTERFACE CONFIGURATION   */
if_1 = NetIF_Add(...);               /* Add Interface 1 Initialization  */
                                     /* Specifics                       */

NetIF_Start(if_1,                    /* Start Network Interface 1       */
            ...);

NetIPv4_CfgAddrAdd(if_1,             /* Add static IPv4 address         */
                   ...);

NetIF_LinkStateSubscribe(if_1,       /* Create link-state callback for  */
                         ...);       /* specified interface             */ 
                                     /* BEGIN CONFIGURATION OF "N"      */ 
                                     /* OTHER INTERFACES                */
if_N = NetIF_Add(...);               /* Add Interface N Initialization  */
                                     /* Specifics                       */

NetIF_Start(if_N,                    /* Start Network Interface N       */
            ...);

NetIPv4_CfgAddrAdd(if_N,             /* Add static IPv4 address         */ 
                   ...);

NetIF_LinkStateSubscribe(if_N,       /* Create link-state callback for  */
                         ...);       /* specified interface             */

After completing one interface's initialization, application code would follow a similar procedure for additional interfaces, as the code above indicates. At the conclusion of the initialization process, it should be possible to ping each of the network interfaces. Application code, of course, is ultimately responsible for establishing sockets to send and receive data via the interfaces.

Aside from the actual creation of each interface, there are several configuration parameters for you to take into account if you plan on establishing multiple interfaces in your application. Projects that incorporate µC/TCP-IP typically contain a file named net_dev_cfg.c that declares a configuration struct for each of the underlying hardware's network interfaces. Within the structs are fields for buffer size, memory pool type, and other network interface characteristics. The values of these fields will be applied by µC/TCP-IP to your network interfaces, and they have a direct effect on the stack's RAM usage.

If you'd like to approximate the RAM usage for your system's interfaces, you can simply count the number of buffers set aside for the interfaces. As indicated below, each structure in your project's copy of net_dev_cfg.c, should include a value specifying the corresponding interface's number of receive (Rx) buffers, along with a pair of values for transmit (Tx) buffers. (Two numbers are necessary for the Tx case because µC/TCP-IP employs buffers of two different sizes for transmission operations.) A given interface's total buffer requirements, which normally represent a sizeable majority of the interface's total RAM footprint, can be obtained by simply multiplying each buffer quantity by the corresponding buffer size and then adding the results for the three types of buffer.

const  NET_DEV_CFG_ETHER_DEMO  NetDev_Cfg_Demo_EtherC0 = {
    NET_IF_MEM_TYPE_MAIN,           /* Desired receive buffer memory  */
                                    /* pool type:                     */
                                    /* NET_IF_MEM_TYPE_MAIN           */
                                    /* Buffers use main memory        */
                                    /* NET_IF_MEM_TYPE_DEDICATED      */      
                                    /* Buffers have dedicated memory  */
    1520u,                          /* Size of Rx buffers             */
      10u,                          /* Number of Rx buffers           */
      32u,                          /* Alignment of Rx buffers        */
       0u,                          /* Offset of Rx buffers           */
.....
.....
    1520u,                          /* Size of large Tx buffers       */
      10u,                          /* Number of large Tx buffers     */
      60u,                          /* Size of small Tx buffers       */
      10u,                          /* Number of small Tx buffers     */
      32u,                          /* Alignment of Tx buffers        */
       0u,                          /* Offset of Tx buffers           */

If, in addition to managing memory usage, you'd like to keep track of the link state for each of your interfaces, you can take advantage of the new link-subscribe function that has been added to the most recent version of µC/TCP-IP, NetIF_LinkStateSubscribe(). Through this function, your application can specify a callback routine to be executed upon any state changes for a particular interface. The callback is a helpful mechanism for preventing unexpected behavior due to a suddenly unresponsive link.

You can consult µC/TCP-IP's online documentation for additional information on NetIF_LinkStateSubscribe() and other stack API functions. Amongst this documentation, you'll also find a multiple-interface example application that further illustrates the procedures described above.

Tags: ,

Questions or Comments?

Have a question or a suggestion for a future article?
Don't hesitate to contact us and let us know!
All comments and ideas are welcome.