changing DHCP usage in runtime when using FREERTOS+TCP

beaker1969 wrote on Friday, April 24, 2015:

Hi

I have managed to port over the FREERTOS+TCP for the STM32F429 (and have a simple webserver going… am now going to implement your new webserver) but needed to be able to change if the DHCP is used or not in runtime and not at build level.

I managed to get it going by a few minor changes to the void ‘vDHCPProcess’ function in FreeRTOS_DHCP.c

if the DHCP is to be run i set the default IP address to 0.0.0.0

in the ‘vDHCPProcess’ routine it detects if the IP address is 0.0.0.0, if so it lets the routine continue as before. If not then DHCP state is set to a state where it thinks it has failed and therefore uses the default settings.

if the DHCP fails then the it is presumed that the default IP address is not be used and therefore fails to configure. I believe in a future release there will be mechanism for when a DHCP server fails, an IP addresses is allocated in the private range 169.254.0.1 to 169.254.255.254.

overall i find FreeRTOS+TCP much easier to use than my old lwip setup.

A

here are my changes.

void vDHCPProcess( BaseType_t xReset )
{
/* Is DHCP starting over? */
if( xReset != pdFALSE )
{
xDHCPData.eDHCPState = eWaitingSendFirstDiscover;

	// START OF added code
	if(xNetworkAddressing.ulDefaultIPAddress != 0x00)
		{
			xDHCPData.eDHCPState = eWaitingOffer;
			xDHCPData.xDHCPTxTime = 0;
			xDHCPData.xDHCPTxPeriod = 0;
		}
	// END of added code
}

//if( xDHCPData.xDHCPTxPeriod <= ipconfigMAXIMUM_DISCOVER_TX_PERIOD) // original.

if( xDHCPData.xDHCPTxPeriod <= ipconfigMAXIMUM_DISCOVER_TX_PERIOD && (TickType_t)xNetworkAddressing.ulDefaultIPAddress == 0x00 ) //new version

edit:

had to modify last statement. needed to add (TickType_t) to xNetworkAddressing.ulDefaultIPAddress as it didn’t work without it.

rtel wrote on Saturday, April 25, 2015:

Great info - thanks.

heinbali01 wrote on Saturday, April 25, 2015:

Hi Alan,

I have managed to port over the FREERTOS+TCP for the STM32F429

Glad to hear that.

am now going to implement your new webserver

The HTML/FTP servers depend on the new +FAT library. +FAT can either use a RAM disk or an SD-card (or any other memory).

At this moment the HTML server is quite simple: it only serves the GET requests. The FTP server, on the contrary, is very complete already.

An update of the HTML-server is planned quite soon: it will be extended with HEAD/POST/PUT and also there will be support for (CGI-style) requests from JavaScript.

For example:

GET /tcp_info?dhcp=? HTTP/1.1

which may trigger a typical JSON answer like this:

/tcp_info?dhcp={"ip":"192.168.2.100",
    "netmask":"255.255.255.0","gw":"192.168.2.1"}

The FTP and HTML server are extremely ‘cheap’ in the sense that they do not create any new task. They have a common “work” function which can be called like this:

const TickType_t xInitialBlockTime = pdMS_TO_TICKS( 200UL );
for( ;; )
{
    FreeRTOS_TCPServerWork( pxTCPServer, xInitialBlockTime );
}

overall I find FreeRTOS+TCP much easier to use than my old lwip setup.

+TCP has a big advantage, it is based on FreeRTOS. LWIP has the difficult task of being compatible with any OS on any platform.
The dependencies of +TCP are much smaller: it uses the standard types (uint32_t and so), and it uses all great features of FreeRTOS (queues, events, semaphores).

In fact there are only two dependencies on the hardware:

  • send and receive Ethernet packets, as implemented in:
    FreeRTOS-Plus-TCP/portable/NetworkInterface//NetworkInterface.c
  • endianness: big or little endian, which is just a switch defined as:
    #define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN

All other dependencies are already “covered by” FreeRTOS.

if the DHCP is to be run I set the default IP address to 0.0.0.0

I’m trying to get clear what it is that you want to add?

As you will understand, xNetworkAddressing.ulDefaultIPAddress will be used as The IP address in case DHCP has failed.

I made an embedded device which has these user options:

1) Use DHCP
2) Use DHCP as an advice
3) Do not use DHCP at all

Most people make the easiest and safest choice 1). DHCP dictates all data and the device just follows. The device will always store the latest:

- IP address
- Netmask
- Gateway

Now in case a device boots and does not get a DHCP response, it will use the last known settings. This works very well in most cases.

Option 2) the device gets a fixed IP address and netmask. Now only if the DHCP offer is incompatible with the currently used settings, the offer will be used.
This will happen if the IP address is 192.168.1.xxx and DHCP comes with a 10.x.x.x address.

Option 3) use fixed settings. That would be OK if the situation never changes, each devices has its fixed place and IP address.

I must say that I miss a possibility to stop the DHCP negotiation. In the third case (ignore DHCP), there is no way to avoid the DHCP negotiation.

In the seconds case (advisory), I would like to have a callback, in which my application is asked for a confirmation:

BaseType_t xApplicationDHCPConfirmHook( struct XDHCP *pxData )

.

I keep on stressing, if possible: give your embedded devices a FIXED name and a VARIABLE IP address.

I make audio amplifiers with a HTML interface. The amplifier on my desk has 2 nicknames: e.g. “amplifier” and “ampli_lab”.

Enable two protocols in your “FreeRTOSIPConfig.h”:

#define ipconfigUSE_LLMNR    ( 1 )
#define ipconfigUSE_NBNS     ( 1 )

and define a callback:

BaseType_t xApplicationDNSQueryHook( const char *pcName )
{
    return
        stricmp( pcName, "amplifier" ) == 0 ) ||
        stricmp( pcName, "ampli_lab" ) == 0 );
}

With this your devices can be found by ping, FTP-clients and browser. Windows XP will only use NBNS, whereas Linux and Win7 prefer to use LLMNR.

Regards, Hein