How to Integrate ENC28J60 with lwIP Using an STM32 Microcontroller

Software and Hardware Requirements

To follow this tutorial, you should have completed this section.

DNS: Name resolve on Linux

To confirm that the DNS server is resolving the correct IP, I also ran it on Linux. The command to resolve a domain name to an IP address is:


nestor@nestor:~$ host test.mosquitto.org
test.mosquitto.org has address 54.36.178.49
test.mosquitto.org has IPv6 address 2001:41d0:303:4831::1
Domain name resolution on Linux

DNS: Name resolve on lwIP using ENC28J60

The below are needed for the server to resolve a domain name to an IP address.

One function worth noting:


void dns_gethostbyname(const char *hostname, ip_addr_t *addr,
                       dns_found_callback found, void *callback_arg);

The below snippets show some of the code I wrote to get DNS client working.


struct mqttBrokerDetails {
    const char * name;
    union {
        ip_addr_t ip;
        uint8_t bytes[4];
    };
    const char * user;
    const char * password;
};
Struct containing the name and IP for MQTT usage

dns_init();

// Set the server
ip_addr_t dnsServer;
IP4_ADDR(&dnsServer, 8, 8, 8, 8);
dns_setserver(0, &dnsServer);

ip_addr_t mosquitoIp;
dns_gethostbyname(mqttBroker.name, &mosquitoIp, ipObtained, NULL);
Initialization of DNS module

static void ipObtained(const char *name,
                       const ip_addr_t *ipaddr,
                       void *callback_arg) {
    if(strcmp(mqttBroker.name, name) == 0) {
        mqttBroker.ip = *ipaddr;
    }
}
Callback for DNS Client success

Screenshot from STM32CubeIDE

DNS Client IP Screenshot
DNS Client IP Screenshot

Source Code

The source code for the project can be found here — checkout the dns tag.

NB: The union in Figure 2 was added to expose individual bytes. lwIP stores IP addresses as a uint32_t internally.