Sunday, June 9, 2013

Using the Microchip TCP/IP stack on Olimex SBCs

To build a web server application on an Olimex Ethernet SBC, you have to download the Olimex version of the Microchip TCP/IP stack and modify it. To get started with it, as a first step, I got rid of files that I don't need for implementing a web server. The Microchip stack uses a ~ variable embedded in HTML pages to serve your custom information on a web page.

The Olimex version of the stack

The Olimex code is a modified version of the original Microchip TCP/IP stack code. The current version on the Olimex web site (as on 1 May 2013) is based on the 5.42.02 version of the Microchip TCP/IP stack. This has already been superseded on the Microchip site and this version is available in the archived portion. The specific version of the TCP/IP stack is part of the V2012-08-22 file set. The details of the TCP/IP stack version can be found in Microchip\TCPIP Stack\TCPIP Stack Version.txt.

The original Microchip code and the Olimex have a few small differences. This is due to specific features or lack of them on the Olimex board. For example, the Olimex board has only one LED rather than 8. It also uses an Atmel Flash EEPROM which is quite different.

Trimming the file set

The directory you need to copy is PIC-WEB 5.42\TCPIP\Demo App. I made the following changes to trim down the number of files

  • Retain the files CustomHTTPApp.c, HardwareProfile.h, HTTPPrint.h (will be regenerated), MainDemo.c, MainDemo.h, SPIEEPROM.c, TCPIPConfig.h, PIC-WEB Demo.mcp and remove all other files
  • Retain the Configs directory with the two files in there
  • The WebPages2 directory was initially retained but soon trimmed down to retain just the main page and supporting elements for testing. The index.htm file was edited to remove all references to the removed files.
  • The Objects and Output sub-directory can be cleared and will be repopulated once the code is compiled

I made additional changes to trim down code included in the compiled code.

  • Edited Configs\TCPIP OLIMEX_PIC-WEB.h Some of the #defines can be commented out to reduce the number of modules linked in. I disabled STACK_USE_UART, STACK_USE_UART2TCP_BRIDGE, STACK_USE_SMTP_CLIENT, STACK_USE_SNMP_SERVER, STACK_USE_TELNET_SERVER, STACK_USE_DNS, STACK_USE_SNTP_CLIENT, STACK_USE_DYNAMICDNS_CLIENT, STACK_USE_BERKELEY_API, STACK_USE_HTTP_MD5_DEMO, STACK_USE_HTTP_EMAIL_DEMO, SNMP_TRAP_DEMO_ENABLED. You can also change the default IP address at the same time.
  • Edited CustomHTTPApp.c to comment out the includes for Custom_MOD-IO.h and My_Functions.h. I also put the I2C demo code in a #define so it is not included. In fact the whole section between the SPP + and SPP – comments can be removed.
  • Edited MainDemo.c to comment out the includes for Custom_MOD-IO.h, Custom_I2C.h and My_Functions.h.

The directory PIC-WEB 5.42\Microchip and sub-directories are largely retained.

How does it work

Web pages are written with embedded variables with ~ characters around it. When such a variable is encountered, the code makes function calls specific to that variable to get its value. For example, a variable ~xxx~ will result in a call to HTTPPrint_xxx(). The variable is then substituted by this value.

Internally, when the MPFS2 utility is used to combine all the web files into a single .bin file, the ~ variables are consolidated and assigned a 4 byte number. The variable is substituted with this number. When this number is encountered, code in the HTTPPrint.h calls the correct function. The MPFS2 utility also generates a new HTTPPrint.h file. Ensure that this file is used when you compile your code – it should be placed in the right directory. It also means that when you introduce or remove a variable from the web pages, the MPFS2 utility has to be run to get a new HTTPPrint.h. Only after this file is generated that you can compile your code.

The next step is to write the HTTPPrint_xxx() routine. Any HTTP arguments passed in the URL can be retrieved by calling the HTTPGetROMArg() function. Once the data for replacing the variable is ready, it can be output. Check if the TCP output buffer has enough space by calling TCPIsPutReady(sktHTTP) and checking the return value. The data is output using the TCPPut(sktHTTP, c) or TCPPutString(sktHTTP, s) calls. If the output buffer does not have enough space for the output, set the field curHTTP.callbackPos to a non-zero value and return. As long as this variable has a non-zero value, the HTTPPrint_xxx() routine will be repeatedly called. When the data has been output, set curHTTP.callbackPos to 0 and the routine will not be called again. The assembled page will be available to the browser.

Let us look at some of the code that uses this logic. The following is a code snippet from the Microchip code to return the build date.

void HTTPPrint_builddate(void)
{
    curHTTP.callbackPos = 0x01;
    if(TCPIsPutReady(sktHTTP) < strlenpgm((ROM char*)__DATE__" ""00:08:00"))
        return;
 
    curHTTP.callbackPos = 0x00;
    TCPPutROMString(sktHTTP, (ROM void*)__DATE__" ""00:08:00");
}

The first thing to do is to set the curHTTP.callbackPos to a non-zero value. This is in case we cannot output the data this time around. Setting it to a non-zero value ensures that the function will be repeatedly called till the data is all sent. The next step is to check if the output buffer has enough free space for the string to be output by checking the amount of space by calling TCPIsPutReady(sktHTTP). If there isn't enough space, just return and check this again on the next call. If there is enough space, output the string by calling TCPPutROMString(sktHTTP, ROM char *) or TCPPut(sktHTTP, char). Finally, set curHTTP.callbackPos to zero to indicate that the task is complete and this routine does not have to be called any more.

To write an Ajax style call where there is no web page but some raw data is returned to the browser, you still have to create a web page. This will have the usual file name. For example, if the URL uses test.cgi, a file with this name has to be created in the web pages directory. This file can contain nothing but a single variable reference, say, ~test~. Then all you have to do is to write an HTTPPrint_test() routine. I prefer to put this in its own C file so that the original files that came with the fileset are not affected.

PIC-WEB Rev C vs Rev B

I still have an old PIC-WEB Rev B board but the software on the Olimex site is for the new Rev C. I just tried the software for Rev C and it seems to work fine. I don’t know what the changes between the Rev B and Rev C boards are. The obvious one from the pictures is that the Rev C board has a UEXT connector and the ICSP connector has been changed. With the Rev C board you will need the ICSP adapter to connect the PICKit2.


No comments:

Post a Comment