EthernetInterface Library

16 Jul 2012

Hi Everyone,

We are progressing on creating the new EthernetInterface library, and we would be glad to get your bug reports/feature requests here!

The documentation of the library can be found in the handbook:

Cheers,

Donatien

02 Oct 2012

Hi, I've been working with the TCP API for the last two days.. here are just a few of my thoughts if i would redesign the C++ API:

  • Create separate namespaces/folders for IP, UDP and TCP. And move the classes to TCP- UDPSocket.h to TCP/Socket.h UDP/Socket.h; and add a Socket base class for both.
  • Add classes IP::Address. and IP::Endpoint. Where endpoint is a combination of IP::address and a port number.
  • Instead of passing pointers to TCP::Socket::accept() for the endpoint information, add an IP::Endpoint instance to the IP::Socket base class containing remote information.
  • It would be better to separate the ::select() call from the socket members all together, and to create a specific Select class that can be given multiple instances of the Socket class.
  • And add the ability to set the Socket to non-blocking in case functions like receive, accept, etc should return immediately, instead of using a timeout of 0 ms. (we are using the RTOS anyway for the network stack)
  • Let TCP::Socket::receive() return on any number of bytes received, instead of waiting for the complete buffer to be full.
  • Something like TCP::Socket::status() would be great. retuning an enum based status Accepting, Connected, Disconnected, Listening, etc.

Best Regards, Roy

Ps. oh please fix the compiler warnings :)

Edit: I took the freedom to implement some code for a new API.

18 Jul 2012

Thanks for this great feedback Roy. Let me check out your code and get back to you!

25 Jul 2012

latest update of the ethernetinterface gives a missing header file

25 Jul 2012

Gyro Gearloose wrote:

latest update of the ethernetinterface gives a missing header file

The file bsd_socket.h in the Socket library has been renamed socket.h.

NOTE: The Socket library is not yet stable and its API will change in the following weeks.

Cheers, Emilio

08 Aug 2012

I need to be able to alter the static IP of the mbed within the program. When I try doing so, the mbed crashes with the blue lights of death:

Here's a simple example:

    EthernetInterface eth;
    printf("init 1\r\n");
    eth.init(myip,"255.255.255.0",mygate);
    printf("discon\r\n");
    eth.disconnect();
    printf("init 2\r\n");
    eth.init(myip,"255.255.255.0",mygate);
    printf("after init 2\r\n");

"myip" and "mygate" are regular IP addresses that do work for communication if I only call init once.

The printout:

init 1
discon
init 2

I have also tried newing and deleting the ethernet so there's only one init per object, but I get the same crash. So I guess it's somewhere in the C code, but I haven't dug through that yet.

Any help is greatly appreciated.

08 Aug 2012

Hi S K,

S K UCI wrote:

I need to be able to alter the static IP of the mbed within the program.

    EthernetInterface eth;
    eth.init(myip,"255.255.255.0",mygate);
    eth.disconnect();
    eth.init(myip,"255.255.255.0",mygate);

We never tested that, I am afraid you discovered a bug. Thank you for reporting that.

My first guess is that eth.init should call tcpip_init only the first time it is called. I'll keep you posted about a fix.

Cheers, Emilio

08 Aug 2012

Thanks very much, Emilio. I will keep an eye on this thread.

If tcpip_init will be called only once, will it be possible to change the IP addresses that are being used, without resetting the mbed?

Thanks!

Emilio Monti wrote:

Hi S K,

We never tested that, I am afraid you discovered a bug. Thank you for reporting that.

My first guess is that eth.init should call tcpip_init only the first time it is called. I'll keep you posted about a fix.

Cheers, Emilio

08 Aug 2012

Hi S K,

S K UCI wrote:

If tcpip_init will be called only once, will it be possible to change the IP addresses that are being used, without resetting the mbed?

As you can see from the EthernetInterface.cpp source the IP address is set by netif_add, I guess there is no need to init the lwip tcp/ip stack twice (I'll test that in the following days):

netif_add(&lpcNetif, ipaddr, netmask, gw, NULL, lpc_enetif_init, tcpip_input);

Cheers, Emilio

02 Oct 2012

Hi,

I have just started to use this library for a project and have a problem that I hope you will be able to shed some light on.

sock.connect("mbed.org", 80) - works fine as in the example.

I have written a simple server application (running on a windows machine connected to my LAN) which listens for connections on port 55555, this is working fine.

sock.connect("192.168.1.5", 55555) - connects to the server and sends data with no problem.

sock.connect("upstairs", 55555) - does not connect at all.

It would appear that the library is able to resolve "mbed.org" and that it is able to connect to the server on my LAN using the IP address, but my problem is that it will not resolve the LAN computer name to an IP address and connect.

Any help on this problem would be very much appreciated.

Regards,

Arthur

02 Oct 2012

It appears to be that the ethernet library is resolving the address using a DNS server outside of your network. It just to be possible to force a specific DNS server address, but i'm not sure if that is still available with the new Ethernet api.

03 Oct 2012

Phil Chambers wrote:

sock.connect("upstairs", 55555) - does not connect at all.

It would appear that the library is able to resolve "mbed.org" and that it is able to connect to the server on my LAN using the IP address, but my problem is that it will not resolve the LAN computer name to an IP address and connect.

Any help on this problem would be very much appreciated.

Regards,

Arthur

computer names are not domain names. I've never assumed you can do this - unless you use some proprietary thing like a Windows Domain server or NETBIOS. But I don't think computer names are a concept in the Internet Engineering Task Force (IETF) standards for TCP/IP et al.

you could edit your PCs (all of them), the hosts file, and put "upstairs" in the file along with its (static?) LAN IP address.

03 Oct 2012

steve childress wrote:

Phil Chambers wrote:

sock.connect("upstairs", 55555) - does not connect at all.

It would appear that the library is able to resolve "mbed.org" and that it is able to connect to the server on my LAN using the IP address, but my problem is that it will not resolve the LAN computer name to an IP address and connect.

Any help on this problem would be very much appreciated.

Regards,

Arthur

computer names are not domain names. I've never assumed you can do this - unless you use some proprietary thing like a Windows Domain server or NETBIOS. But I don't think computer names are a concept in the Internet Engineering Task Force (IETF) standards for TCP/IP et al.

you could edit your PCs (all of them), the hosts file, and put "upstairs" in the file along with its (static?) LAN IP address.

Steve, you are correct that the mbed resolver is only a DNS resolver and not a WINS/NETBIOS resolver.

The suggestion of editing hist hosts file is the correct idea if he doesn't have a local DNS server that he can administer, however the embed has no hosts file.

Phil, you might be able to use dns_local_addhost() (see dns.c and dns.h) from the EthernetLibrary to accomplish the same thing.

I'm not sure that this is the correct API as I've not tried it, only just looked through the DNS code as of this posting.

Good luck

03 Oct 2012

Hi,

Thank you for your replies. I have now set up my router to always assign the same IP address to the machine that is running the server, this will resolve my immediate problem and allow me to continue with the project.

Regards,

Phil

04 Oct 2012

Hello. I have just tried to port my code to this new library. I have successfully compiled and run, in original and modified forms, the TCP Echo Server example. But when invoking the library in my actual project, the following compiler errors show up:

"a value of type "void *" cannot be used to initialize an entity of type "lpc_enetdata *"" in file "EthernetInterface/lwip-eth/arch//lpc17_emac.c", Line: 266, Col: 38
"a value of type "void *" cannot be assigned to an entity of type "eth_hdr *"" in file "EthernetInterface/lwip-eth/arch//lpc17_emac.c", Line: 454, Col: 11
"a value of type "void *" cannot be used to initialize an entity of type "lpc_enetdata *"" in file "EthernetInterface/lwip-eth/arch//lpc17_emac.c", Line: 764, Col: 38
"a value of type "void *" cannot be used to initialize an entity of type "lpc_enetdata *"" in file "EthernetInterface/lwip-eth/arch//lpc17_emac.c", Line: 785, Col: 38
"cannot open source input file "us_ticker_api.h": No such file or directory" in file "EthernetInterface/lwip-sys/arch//sys_arch.c", Line: 23, Col: 26
"expected an identifier" in file "mbed-rtos/rtx//rt_TypeDef.h", Line: 61, Col: 9
"expected an identifier" in file "mbed-rtos/rtx//rt_TypeDef.h", Line: 61, Col: 9

... and a lot other library-originated errors. None of the errors point to lines in my sources. I have instantiated the library by dragging the 'EthernetInterface' and 'mbed-rtos' libraries from my working TCPEchoServer program into my actual project. I had deleted the instantiations of the 'EthernetNetIf' and 'SimpleSocket' libraries, which were the ones I was using previously.

I have no issue with falling back to the old libraries, but I would really benefit from the reported performance improvement of the new official libraries. In case it helps (but I suspect it does not), here's a skeleton of my code (It has a lot of issue-unrelated code):

main.cpp

#include "mbed.h"

#include "main.h"

EthernetInterface eth;
//... other objects...
int main()
{   
    // Some critical, ethernet-unrelated code...
    
    // Ethernet and server setup
    eth.init();
    eth.connect();
    TCPSocketServer server;
    server.bind (SERVER_PORT);
    server.listen();
    TCPSocketConnection client;

    // More unrelated initialization code...

    while (true)
    {
        if (currently_unconnected)
        { 
            server.accept (client);  
            currently_unconnected = false;
        }
        else
        {
             if ( client.is_connected() )
             {
                  // Do stuff...
             }
             else
             {
                 currently_unconnected = true;
                 client.close();
             }
        }
    }

main.h

#ifndef _MAIN_H_
#define _MAIN_H_
    
#include "EthernetInterface.h"
// Other libraries...

// #defines and prototypes, etc.
#endif /* _MAIN_H_ */

Thank you!

12 Oct 2012

I am having a problem sending simple messages using this library. I am hoping eventually to send files I have stored on a memory card to a PC on my LAN, but my simple test program fails.

The symptoms are:

If I set wait to 100ms, then it successfully sends around 6 messages and then hangs. If I set wait to 3000ms, then it successfully sends around 30-40 messages, reports that it has sent the rest at -1 bytes and reaches the end of the loop.

I am very much a novice, but have ran Wireshark which reports that the "Ethernet Frame Check Sequence" is incorrect on every packet sent by the mbed. This appears to be a sequence of 8 bytes with a value of 0.

Ideally I would prefer not to have a wait command at all as this would obviously have a large impact if sending large files.

Any ideas?

I have spent many hours trying to understand the code, but practically all of it is way above my level. I notice that there is the ability to show debug info in the lwip libraries but I cannot see how enable this so that I can see the debug info through the serial connection to my PC (like the pc.printf commands in main). If anyone can give me simple instructions on how this can be done, then I can at least try and find the point at which the mbed hangs.

I've had days at this now (got printf working by not altering standard pc.baud), is it just me that cannot get this to work? - could I have a damaged Mbed? - is it a cabling problem? (I can get an IP address and send a few messages, so I thought not, but perhaps?).

Anyone?, this is starting to drive me crazy ;-(

Regards,

Phil

#include "mbed.h"
#include "EthernetInterface.h"

Serial pc(USBTX, USBRX); // set serial comms to PC

int main()
{
    pc.baud(921600); // set baud for comms
    pc.printf("Connecting\n");
    EthernetInterface eth; // set up the interface
    eth.init(); //Use DHCP
    eth.connect(); // connect
    pc.printf("IP Address aquired: %s\n", eth.getIPAddress());
    TCPSocketConnection sock; // set up a socket
    sock.connect("192.168.1.200", 55555); // connect to server
    pc.printf ("Connected to Server\n");
    char *testmessage = "Hello";
    int bytes;
    int i;
    for (i=0;i<100;i++)
    {
        bytes = sock.send_all(testmessage, strlen(testmessage)); 
        pc.printf("Message %d - Bytes sent: %d\n",i,bytes);
        wait_ms(3000);
    }
    pc.printf("Finished\n");
}
20 Oct 2012

I try to make Ethernet work with a LPC1768 Board and a DP83848VV PHY. The PHY has no connections for LED_LINK and LED_SPEED. Could I run the Lib without this???

Thats my code:

#include "mbed.h"
#include "EthernetInterface.h"

Serial device(p9, p10);  // tx, rx

extern "C" void mbed_mac_address(char *s) {
    char mac[6];
    mac[0] = 0x00;
    mac[1] = 0x02;
    mac[2] = 0xf7;
    mac[3] = 0xf0;
    mac[4] = 0x45;
    mac[5] = 0xbe;
    // Write your own mac address here
    memcpy(s, mac, 6);
    }



int main() {
device.baud(19200);
  device.printf("Start ");  
	EthernetInterface eth;
    eth.init(); //Use DHCP
  device.printf("got IP ");  
		eth.connect();
    device.printf("IP Address is %s\n", eth.getIPAddress());
    
    TCPSocketConnection sock;
    sock.connect("mbed.org", 80);
    
    char http_cmd[] = "GET /media/uploads/mbed_official/hello.txt HTTP/1.0\n\n";
    sock.send_all(http_cmd, sizeof(http_cmd)-1);
    
    char buffer[300];
    int ret;
    while (true) {
        ret = sock.receive(buffer, sizeof(buffer)-1);
        if (ret <= 0)
            break;
        buffer[ret] = '\0';
        device.printf("Received %d chars from server:\n%s\n", ret, buffer);
    }
      
    sock.close();
    
    eth.disconnect();
    
    while(1) {}
}

regards

Joerg

20 Oct 2012

Ok I think it works without LEDLINK and SPEED.

23 Oct 2012

Luis Linares wrote:

Hello. I have just tried to port my code to this new library. I have successfully compiled and run, in original and modified forms, the TCP Echo Server example. But when invoking the library in my actual project, the following compiler errors show up:

"a value of type "void *" cannot be used to initialize an entity of type "lpc_enetdata *"" in file "EthernetInterface/lwip-eth/arch//lpc17_emac.c", Line: 266, Col: 38
"a value of type "void *" cannot be assigned to an entity of type "eth_hdr *"" in file "EthernetInterface/lwip-eth/arch//lpc17_emac.c", Line: 454, Col: 11
"a value of type "void *" cannot be used to initialize an entity of type "lpc_enetdata *"" in file "EthernetInterface/lwip-eth/arch//lpc17_emac.c", Line: 764, Col: 38
"a value of type "void *" cannot be used to initialize an entity of type "lpc_enetdata *"" in file "EthernetInterface/lwip-eth/arch//lpc17_emac.c", Line: 785, Col: 38
"cannot open source input file "us_ticker_api.h": No such file or directory" in file "EthernetInterface/lwip-sys/arch//sys_arch.c", Line: 23, Col: 26
"expected an identifier" in file "mbed-rtos/rtx//rt_TypeDef.h", Line: 61, Col: 9
"expected an identifier" in file "mbed-rtos/rtx//rt_TypeDef.h", Line: 61, Col: 9

... and a lot other library-originated errors. None of the errors point to lines in my sources. I have instantiated the library by dragging the 'EthernetInterface' and 'mbed-rtos' libraries from my working TCPEchoServer program into my actual project. I had deleted the instantiations of the 'EthernetNetIf' and 'SimpleSocket' libraries, which were the ones I was using previously.

.....

Well after all, I solved this by cloning the TCPEchoServer program and manually adding the files and functions, modifying them suitably. It seems, EthernetInterface and mbed-rtos MUST be imported first and foremost before actual code development starts.

24 Oct 2012

.

29 Nov 2012

This is a copy of an earlier post on the UDPSocket thread.

I'm having trouble assigning the mbed a static IP address. I started with the simple UDP Echo Client shown here. When I use DHCP everything works great, but when I attempt to use static addressing as shown below I never see the "Hello World" message arrive at the echo server, nor do I see any evidence of associated network activity using tcpdump. What am I doing wrong?

const char* LOCAL_IP_ADDRESS = "192.168.0.3";
const char* NETWORK_MASK = "255.255.255.0";
const char* GATEWAY = "192.168.0.1";
   .
   .
   .
    //eth.init(); //Use DHCP
    eth.init(LOCAL_IP_ADDRESS, NETWORK_MASK, GATEWAY);
29 Nov 2012

ARP tables in switch need updating when you change IP?

29 Nov 2012

I rebooted my router, which I would expect to flush the ARP tables, with the same results. I also changed LOCAL_IP_ADDRESS to 192.168.0.129, which is outside of my router's DHCP pool.

It sure feels to me like static IP addressing is broken. Has anyone else attempted to use this feature recently? If so, what were your results?

30 Nov 2012

long shot guess.. to eliminate ARP table issue: If the mbed does any ethernet I/0 prior to your switching to Static IP, it might confuse the switch. This method is supposed to work: run the mbed code, let it establish static IP, subnet mask, gateway IP. Then unplug the cat5 for a few seconds then plug in again. The switch is supposed to ARP to re-learn. This presumes that the mbed responds properly to the ARP!

23 Dec 2012

Hi, I miss two functions. With the old version of EthernetNetIf I control the physical port state.

eth.link() = returns the current ethernet port state (link or no link).

eth.set_link() = sets the ethernet port parameter speed and duplex mode.

Do you plan to implement these functions in the future ?

Best regards, Horst

PS: Please excuse my bad english!

03 Jan 2013

Hi there,

nice work!

I tried compiling the library andor an example like TCP Server or UDP Server with an external toolchain (Codesourcery).

Finally it compiles, but the program will not run properly (mbed hangs at EthernetInterface::init()).

Since my toolchain displays sizes for .text 120k .data 21k .bss 8k

I think there is something going wrong, since the online compiler shows some k data but only 6.4Kb of RAM usage (compared to the >20k with the offlinbe toolchain).

Could you please give me a hint where to start search for?

Thank you!

(PS: compiling the code above with gcc4mbed gives me some linker error bss will not fit in ram and linker script says sth. like not enough space for heap in RAM)

05 Jan 2013

Hi,

Nice library. It works fine on unicast but i can't read multicast packet with UDPSocket. Wireshark says that the packets are sent correctly by remote host to multicast address but no packet is received by mbed. Does the new Api is multicast compliant ?

Thank's for help.

Hardware : LPC 1768 Library : Official EthernetInterface Library

Code sample :

   UDPSocket sock;
    Endpoint mcastip;

    

    int _result = sock.init(PORT);
    if (_result==-1) {
        printf("ERREUR : init impossible\r\n");
        sock.close();
        return -1;
    } 
    
    printf("DEBUG : socket initialisee\r\n");
    mcastip.set_address("239.0.10.11", 2012);

    sock.set_blocking(true,3000);
    
    
    char buffer[255];
    
    int nb=1;
    
    while( nb >=0) {
        nb=sock.receiveFrom(mcastip, buffer, 255);
        rcvLed = rcvLed ^ 1;
         
        printf("%d Octets recus de %s : ",nb, mcastip.get_address()); 
         
        for(int i=0;i<nb;i++){
            printf("%02X ",buffer[i]);
        }
        printf("\r\n");
    }
    
    printf("Trame multicast recue\r\n");
    
    rcvLed=1;
05 Jan 2013

Génaël VALET wrote:

Hi,

Nice library. It works fine on unicast but i can't read multicast packet with UDPSocket. Wireshark says that the packets are sent correctly by remote host to multicast address but no packet is received by mbed. Does the new Api is multicast compliant ?

see this thread and suggested solution:

http://mbed.org/questions/223/Unable-to-receive-UDP-broadcast-packets-/#answer283

09 Jan 2013

My answer to the question that Wim refers to allows broadcast packets, but not multicast, which are handled quite differently by the stack.

It seems multicast is a bit more complicated. I've not tried but it seems to need LWIP_IGMP to be defined (see reference in lwip/core/netif.c) and a call to igmp_joingroup(....) (see include/ip4/lwip/igmp.h). Not too many example on the Google to help, but try searching "LWIP_IGMP"

If you get it working please share with us all. Otherwise, the old network stack does support multicast.

29 Jan 2013

1. RMII management clock rate

low_level_init in lpc17_emac.c always sets the RMII management clock rate to the lowest speed. I found code that sets the optimal clock speed based on SystemCoreClock and EMAC_MCFG_MII_MAXCLK. Perhaps this can be of use to lower the PHY communication delay?

        // MII Mgmt Configuration register - Clock divider setting
        const uint8_t EMAC_clkdiv[] = { 4, 6, 8, 10, 14, 20, 28, 36, 40, 44, 48, 52, 56, 60, 64 };
        .....


        int loop, value;

        value = SystemCoreClock / EMAC_MCFG_MII_MAXCLK;
        for (loop = 0; loop < sizeof (EMAC_clkdiv); loop++)
        {
            if (EMAC_clkdiv[loop] >= value) break;
        }
        loop++;
        // Write to MAC configuration register
        LPC_EMAC->MCFG = EMAC_MCFG_CLK_SEL(loop) | EMAC_MCFG_RES_MII;

2. Other PHY

I am also trying to add another PHY to the lwip library: DM9161A. Currently, the init() and connect() functions seem to work, but the system gets stuck on the ethernet part. I'm having trouble to get ethernet communication working properly (timing problem?). If anyone is able to help - more info and code can be found at http://mbed.org/users/frankvnk/code/lpc_phy_DM9161A/