Abstract: This article starts with a C implementation of Hello World and moves on to a simple HTTP server. It describes how to set up the tools to write a simple tutorial program, and then demonstrates how to make use of the DS80C400's ROM functionality. All development was done using the TINIm400 verification module and Keil "Vision2" version 2.37, which includes the C compiler "C51" version 7.05.
Since the introduction of the TINI® Runtime Environment for the DS80C390, developers have clamored for a way to use the power of TINI without using the Java™ language. Unfortunately, the network stack and other features of TINI were too intertwined with the Java virtual machine and runtime environment to be used from a C or assembly program. Later, when the ROM for the DS80C400 networked microcontroller was designed, a suite of functionality was exposed that could be accessed from programs written in 8051 assembly, C, or Java. Size constraints limited the functionality in the ROM to a subset of the functionality in the TINI Runtime Environment. The ROM would therefore be a useful starting block for building C and assembly programs because it offers a proven network stack, process scheduler, and memory manager. Simple programs like a networked speaker could easily be implemented in assembly language, while C could be used for more complex programs like an HTTP server that interacts with a file system.
This article starts with a C implementation of Hello World and moves on to a simple HTTP server. It describes how to set up the tools to write a simple tutorial program, and then demonstrates how to make use of the DS80C400's ROM functionality. All development was done using the TINIm400 verification module and Keil µVision2™ version 2.37, which includes the C compiler "C51" version 7.05.
Getting Started with Keil's µVision2
You can build a simple Hello World-style program written in C using the Keil µVision2 development suite. Follow these instructions to complete your first C application for the DS80C400.
- Select Project->Create New Project. Enter the name of the project.
- The Select Device for Target dialog will pop up. Under Data base, select Dallas Semiconductor and the DS80C400. Select Use Extended Linker, and then select Use Extended Assembler. Hit OK to continue. Figure 1 shows the proper configuration for this dialog.
 Figure 1. Select the DS80C400 for a new Keil µVision2 project.
Loading the Sample Application onto the TINIm400 Module
This section describes how to load the hex file produced by the Keil compiler onto the TINIm400 verification module by using the tool JavaKit.
To use JavaKit, you must have the Java Runtime Environment (at least version 1.2) and the Java Communications API installed. The Java Runtime Environment can be downloaded at
http://java.sun.com/j2se/downloads.html, and the Java Communications API can be found at http://java.sun.com/products/javacomm/index.html. The JavaKit tool is included with the TINI Software Development Kit, available at www.maxim-ic.com/TINIdevkit. Instructions for running JavaKit can be found in the file Running_JavaKit.txt in the docs directory of the TINI Software Development Kit. If you encounter technical issues when running JavaKit, it is possible someone already had a similar problem, which is chronicled in the archives of the TINI Interest List. You can search the archives for this list at www.maxim-ic.com/TINI/lists.
 Figure 2. The Target Options dialog is used to enter configuration information for the target platform. The configuration shown is suitable for use with the TINIm400 module.
Use this command line to have the JavaKit talk to the TINIm400 module.
java JavaKit -400 -flash 40
Once JavaKit is running, select the serial port you will use to communicate with the
TINIm400. Open the serial port using the Open Port button. Then press the Reset button. The loader prompt for the DS80C400 should print and look like this:
DS80C400 Silicon Software -
Copyright (C) 2002 Maxim
Integrated Products
Detailed product information
available at http://www.maxim-ic.com
Welcome to the TINI DS80C400
Auto Boot Loader 1.0.1
>
From the File menu at the top of JavaKit, select Load HEX File as TBIN. Find the helloworld.hex file that we just created, and select it. The Load HEX File as TBIN option converts the input hex file to a TBIN file, and then loads it. This operation is faster than loading it as a hex file because an ASCII hex file is more than twice as large as a binary file for the same data set.
There are two ways to execute your program once it is loaded. Since the program was loaded into bank 40, you can type:
> B40
> X
To select bank 40 and execute the code there, you can also type:
> E
This will make the ROM search for executable code, a special tag signifying that the current bank has executable code. This tag consists of the text "TINI" followed by the current bank number. It is located at address 0002 of the current bank. Our Hello World program declares this tag in the startup400.a51 file with the following lines:
?C_STARTUP: SJMP STARTUP1
DB 'TINI' ; Tag for TINI Environment 1.02c
; or later (ignored in 1.02b)
DB 40h ; Target bank
 Figure 3. The JavaKit program is used to load applications and communicate with the serial port of the DS80C400.
Note that the SJMP STARTUP1 statement is located at address 0000 of bank 40. It is followed by the executable tag { 'T', 'I', 'N', 'I', 40h }, located at address 0002, since the sjmp statement is two bytes.
When you type "E," the ROM searches downward through the memory banks for executable
code. If you type "E" and some other code executes, it means that the ROM has found an
executable tag at an address higher than 400000h, where your code was loaded. You may need to
find that tag and delete the contents of that bank. You can erase a flash bank by using the Z loader command:
> Z41
You sure? Y
To erase all banks of flash, you need to zap from bank 40h to bank 4Fh.
Interfacing to the ROM and the ROM Libraries
Calling the ROM functions from C is complicated. (The procedure for calling ROM functions is
described in the High-Speed Microcontroller User's Guide: Network Microcontroller Supplement.¹) Parameters must be converted from the Keil C Compiler's conventions to the conventions used by the ROM. The Keil compiler passes parameters in a combination of XDATA locations and registers. The ROM functions accept parameters in different ways. For example, the socket functions accept parameters stored in a single parameter buffer, and many utility functions accept parameters passed in special function registers or direct memory locations. Dallas Semiconductor wrote libraries for accessing the ROM functions to translate from Keil calling conventions to the ROM's parameter conventions.
Using ROM functions in your C programs requires only importing the library and including a header file. To import a library in your project, right click on Source Group 1 in your Keil project window and select Add Files to Group 'Source Group 1.' Change the file filter to '*.lib' and select the library you need to include. Then include the header file at the top of your source. You can use any of the library functions. There are ROM libraries to support ROM initialization, DHCP client operations, process management, socket functions, TFTP client operations, and utility functions such as CRC and pseudo-random number generation.
¹Available online at www.maxim-ic.com/DS80C400UG.
Using the Extension Libraries
In addition to the ROM libraries, other libraries (more are still being written) provide useful
functionality not included in the ROM. Libraries have been developed for file system operations,
DNS lookups, I²C communication, and 1-Wire® communication.
The C Library project (including documentation, sample applications, and release notes) for the
DS80C400 can be found at www.maxim-ic.com/ds80C400/libraries.
A Simple HTTP Server and SNTP Client Application
Dallas Semiconductor wrote a small application to demonstrate the functionality of these libraries, specifically the file system, sockets, process scheduler, and TFTP libraries. The sample application consists of an SNTP client and an HTTP server that responds only to 'GET' requests. It uses the core Dallas Semiconductor-provided libraries to call socket and scheduler functions. It also uses the file system to store a few web pages. The application consists of two processes: (1) the HTTP server is spawned as a new process that handles connections on port 80, and (2) the main process sits in a loop, attempting a time synchronization approximately every 60 seconds. The source code and project files for this application are available at www.maxim-ic.com/timeserver.
Initializing the File System
Before the HTTP server can be started, the file system must be initialized. The demonstration program ensures that two static files, a home page (index.html) and the source to the program (source.html), are in the file system before the server starts.
The program initializes its file system by downloading the files it needs from a TFTP server. In our example, a TFTP server is running at a known IP address. The files index.html and source.html are requested from the TFTP server, then written to the file system.
SolarWinds provides a free TFTP server for Windows® platforms that was used in the
development of this demonstration. From SolarWinds' website (www.solarwinds.net), follow the Downloads - Free Software menu to find the TFTP server download. After installing, use the Configure option under the File menu to configure the available files. Make sure to change the program to use your TFTP server's IP address (TFTP_IP_MSB, TFTP_IP_2, TFTP_IP_3, and (TFTP_IP_LSB).
The Simple HTTP Server
The HTTP server in this application is implemented as a simple version of an HTTP server described by RFC 2068. In this version, only the 'GET' method is supported. Input headers are ignored, and few output headers are given.
The server socket is created by calling Berkley-style socket functions, which make the server
socket easy to set up. The following code shows how our simple HTTP server creates, binds, and
accepts new connections.
struct sockaddr local;
unsigned int socket_handle, new_socket_handle, temp;
socket_handle = socket(0, SOCKET_TYPE_STREAM, 0);
local.sin_port = 80;
bind(socket_handle, &local, sizeof(local));
listen(socket_handle, 5);
printf("Ready to accept HTTP connections...\r
");
// here is the main loop of the HTTP server
while (1)
{
new_socket_handle = accept(socket_handle,
&address, sizeof(address));
handleRequest(new_socket_handle);
closesocket(new_socket_handle);
}
Note that when a new socket is accepted, this simple application does not start a new thread or process to handle the request. Rather it handles the request in the same process. Any HTTP server of more-than-demonstration quality would handle the incoming request in a new thread, allowing multiple connections to occur and be handled simultaneously. After the request is handled, close the socket and wait for another incoming connection.
The handleRequest method consists of parsing the incoming request for a file name and verifying that the method is 'GET.' No other method (not even 'POST,' 'HEAD,' or 'OPTIONS') is allowed. Two file names are handled as a special case. When the file time.html is requested, the server dynamically generates a response consisting of the latest results from the timeserver, and the number of seconds that passed since the last instance the timeserver was queried. When the file stats.html is requested, statistics for server uptime and the number of requests are displayed.
If the file is not found or an invalid request method is given, an HTTP error code is reported.
The SNTP Client
The second major portion of the timeserver application is a Simple Network Time Protocol (SNTP) client, as described in RFC 1361. This is a version of the Network Time Protocol (RFC 1305). SNTP requires UDP communication to request a time stamp from a server listening on port 123. Our timeserver uses the following code to periodically synchronize with the server time.nist.gov. Note that when this article was written, DNS lookup was not supported, so the IP address for the server is set manually. DNS has since been added to the C library website, and the following code can be updated to perform a lookup for the IP address.
socket_handle = socket(0, SOCKET_TYPE_DATAGRAM, 0);
// set a timeout of about 2 seconds.
//'timeout' is unsigned long
timeout = 2000;
setsockopt(socket_handle, 0, SO_TIMEOUT, &timeout, 4);
// assume 'buffer' has already been cleared out
buffer[0] = 0x23; // No warning/NTP Ver 4/Client
address.sin_addr[12] = TIME_NIST_GOV_IP_MSB;
address.sin_addr[13] = TIME_NIST_GOV_IP_2;
address.sin_addr[14] = TIME_NIST_GOV_IP_3;
address.sin_addr[15] = TIME_NIST_GOV_IP_LSB;
address.sin_port = NTP_PORT;
sendto(socket_handle, buffer, 48, 0, &address,
sizeof(struct sockaddr));
recvfrom(socket_handle, buffer, 256, 0, &address,
sizeof(struct sockaddr));
timeStamp = *(unsigned long*)(&buffer[40]);
timeStamp = timeStamp - NTP_UNIX_TIME_OFFSET;
// now we have time since Jan 1 1970
formatTimeString(timeStamp, "London",
last_time_reading_1);
last_reading_seconds = getTimeSeconds();
closesocket(socket_handle);
A datagram socket is first created and given a timeout of about 2 seconds (0x800 = 2048ms). This ensures that if the communication fails with our chosen server, we will not wait indefinitely
for a response.
The next line sets the options for the request. These bits are described in Section 3 of RFC 1361. The value 0x23 requests no warning in case of a leap second, requests that NTP version 4 be used, and states that the mode is 'Client.' After we send the request and receive the reply using the common datagram functions sendto and recvfrom, the seconds portion of the time stamp value is assigned to the variable timeStamp, and then adjusted to the reference epoch January 1, 1970. The function formatTimeString is used to convert the time stamp into a readable string, such as "In London it is 15:37:37 on March 31, 2003."
The function getTimeSeconds is used to determine the last time update, based on the DS80C400's internal clock. Since the program only updates about once every 60 seconds, the HTML page time.html uses this value to report the interval since the last time update. Finally, the socket is closed and the SNTP client goes to sleep for another 60 seconds.
Conclusion
The Keil C Compiler and libraries provided by Dallas Semiconductor allow applications written in C to access the power and functionality formerly only accessible through TINI's Java environment. Programs written in C can now access the network stack, memory manager, process scheduler, file system, and many other features of the DS80C400 networked microcontroller. Additionally, applications written in C allow more space for user code and data, compared to the TINI Runtime Environment. Developers using the C language for the DS80C400 can write lean applications with plenty of speed, power, and code space to tackle any problem.
1-Wire is a registered trademark of Maxim Integrated Products, Inc.
Java is a trademark of Sun Microsystems, Inc.
TINI is a registered trademark of Maxim Integrated Products, Inc.
Windows is a registered trademark of Microsoft Corp.
의견을 보내주세요! 위 내용이 도움이 되셨나요? 여러분의 의견을 기다립니다 — Maxim은 보내주신 정정이나 제안사항을 반영하고 있습니다.
이 페이지를 평가하고 의견을 보내주십시오.
자동 업데이트
관심있는 분야의 애플리케이션 노트가 나올 때 자동으로 업데이트 받고 싶으세요? 그렇다면 EE-Mail™을 신청하십시오.
| 추가 정보 | |
APP 3048: May 10, 2004
|
|
|
|
다운로드, PDF 형식 (329kB)
AN3048,
AN 3048,
APP3048,
Appnote3048,
Appnote 3048
|
|