The DS80C400 microcontroller ROM features can be accessed by programs written in 8051 assembly language, C, or Java?. A wide variety of applications can be built using the ROM features and software libraries developed by Maxim. This application note describes how to use the 8051 IAR Embedded Workbench? to build a C language application for the DS80C400. A simple HTTP server example is used to demonstrate the DS80C400 ROM features.
The ROM of the DS80C400 microcontroller contains a variety of functions that can be accessed by programs written in 8051 assembly language, C, or Java. The ROM functions of the DS80C400 provide a mature MxTNI? network stack, process scheduling, and memory management, making it the best choice to start building C and assembly programs. For simple programs, it can be easily implemented in assembly language. For more complex programs, C language can make full use of ROM components and software libraries provided by Dallas S EMI conductor. These software libraries help you build applications using Keil? Vision2?, SD CC , and IAR 8051 compilers.
This application note explains how to get started using the 8051 IAR Embedded Workbench? to create C applications for the DS80C400. A simple HTTP server is used to demonstrate how to use the ROM features of the DS80C400. All development was done using the TINIm400 Verification Module and the 8051 IAR Embedded Workbench with version 6.11A C compiler.
Getting Started with 8051 IAR Embedded Workbench
This section explains how to create a Hello World program written in C, your first DS80C400 C application, using the IAR Embedded Workbench suite.
1. Install IAR Embedded Workbench
2. Select File → New → Works PAC e, in the workspace window, enter the workspace name appnote
3. Select Project→Create New Project. In the dialog box that appears, enter the project name hellowworld and make sure 8051 is selected as the tool chain
4. When the project window on the left opens, select Project→Add Files… In the dialog box that pops up, change the files of type to assembler files. Add the file Cstartup.s51, which can be found in the zip file in Download
5. Double-click and open the file Cstartup.s51. Find the program segment declaration RSEG CSTART:CODE:ROOT(0). This is the start of the code segment. The start address of the variable segment is declared in link51ew_400.xcl. The start of the code is declared at 0x400000h in the file. In addition, there should be a DB 'TINI' line followed by another DB, high (? INIT)' with the comment Target Bank. This ensures that the application corresponds to the start address of the TINIm400 flash.
6. Create a new file main.c and write the following code in it:
#include
#include
void main ()
{
printf("Test program using IAR compiler");
while (1)
{
}
Save the file contents. Add the file you just created to the hellowworld project by selecting Project→Add Files and then selecting main.c in the file dialog box. Make sure that the file you added is the file main.c that you created; there is a good chance that there is another file with the same name in the default directory.
7. Similarly, add the files low_level_init.s51 and putchar.c to the project. The low_level_init.s51 file contains the basic DS80C400 initialization program; the putchar.c file contains the basic program to output characters to the default console.
8. Copy the ROM initialization library file from ftp://ftp.dalsemi.com/pub/tini/ds80c400/c_libraries/iar/bin/init.zip and unzip it to the same directory. Add the rominit.r51 library file to the project
9. Before compiling the Hello_World application, we need to configure the IAR toolchain to meet the target requirements of the DS80C400
1). Select Project→Options→General
Click the Target tab and browse to select DS80C400 in Derivative. Change the address value for Extended stack at: to 0xFFDC00. This is because the IAR starter code relocates the DS80C400 hardware stack to 0xFFDC00. Refer to Figure 1 for these settings.
Click the Data Pointer tab. Select Number of DPTRs = 1. This is because the library file provided by Dallas Sem IC onductor was generated under this option.
Figure 1. Selecting the Target option for a new IAR 8051 project
2) Select Project-Options→Options→ICC8051
Click the Code tab. Select Size and None under Optimizations.
Click the List tab. Select Output List File and Output assembler File.
Click the Preprocessor tab. Place the following program in the include path:
$TOOLKIT_DIR$INC
$TOOLKIT_DIR$INCCLIB
$TOOLKIT_DIR$ SRC lib
$TOOLKIT_DIR$srclibclib
include
The last line above is the include path where the header files (*.h) of the library are located. Make sure the header files are in the path specified above. $TOOLKIT_DIR$ is related to the IAR installation path (for example, c:/program files/iar syst EMS /embedded workbench 3.n/8051).
3) Select Project→Options→A8051
Click the List tab. Select Output List File.
Click the Preprocessor tab and put the following program in the include path:
$TOOLKIT_DIR$INC
$TOOLKIT_DIR$srclib
include
The last line above is the include path where the header files (*.h; *.inc) of the library are located. Make sure the header files are in the path specified above.
4). Select Project-→Options→XLINK
Click the Output tab
In Output file, select Override default and change the text file name to hello_world.hex.
In Format, select Other, and select Intel Extended from the options. See Figure 2 for details.
Click the List tab. Select Generate Linker Listing.
Click the include tab, refer to Figure 3.
Select Ignore CSTARTUP in Library.
Click Override default and change the file name to $TOOLKIT_DIR$configlnk51ew_400.xcl. $TOOLKIT_DIR$ is related to the IAR installation path (for example, c:/program files/iar systems/embedded workbench 3.n/8051). Make sure that the files lnk51ew_400.xcl and lnk_base_400.xcl are in the specified path. You can find these files in the zip file Download.
Figure 2. Selecting the XLINK Output option for a new IAR 8051 project.
Figure 3. Selecting the XLINK Include option for a new IAR 8051 project.
Build the Hello_World application. If you have completed each step correctly, there should be no errors or warnings during the build process; then hello_world.hex will be generated in the
Now that the executable has been generated, we need to load the application into the TINIm400 module and run it.
Load the sample application to the TINIm400 module:
This section describes how to load a hex file generated by the IAR compiler into the TINIm400 verification module using the Microcontroller Tool Kit (MTK) tool provided by Maxim/Dallas Semiconductor. Currently available versions of the MTK support Windows only . If your development environment is not Windows?, you will need to use the JavaKit application to load and execute the application. To use JavaKit, you must have a Java Runtime Environment? (at least version 1.2) and have the Java Communications API? installed. The JavaKit tool is included in the MxTNI Software Development Kit. Please download the MxTNI SDK. At the time of writing this article, the latest firmware released is 1.15. Instructions for running JavaKit can be found in the Running_JavaKit.txt file in the TINI SDK docs directory. If you have problems running MTK or JavaKit, it is possible that someone else has already encountered a similar problem and has posted it on the Dallas Semiconductor discussion group. You can search the discussion group for existing posts (and new posts).
The latest version of the application can be downloaded here. To install MTK, run the installation file and follow the prompts. After successful installation, a new menu group will be added: Start→All Programs→Dallas Semiconductor MTK. After MTK is started, the dialog box shown in Figure 4 will appear.
Figure 4. MTK options at startup.
Select the TINI option to operate the TINIm400 evaluation board.
After selecting TINI, the MTK main window will open. Select the serial port you will use to communicate with the TINIm400 from the Options→Configure Serial Port menu option. Then, select the Tini→Tini Options menu and the following dialog box will appear. Select the DSTINIm400 button to configure MTK for communication with the TINIm400 board. Figure 5 shows the dialog box with the DSTINIm400 button.
Figure 5. Selecting TINIm400 configuration options.
Select Tini→Open COMx in the xxx baud menu option to open the serial port. Then select Tini→Reset option to reset the evaluation board. The DS80C400 loading prompt will appear as shown below:
DS80C400 SIL icon SOF tware - Copyright (C) 2002 Maxim Integrated Products
Detai LED product information available at http://www.maxim-ic.com
Welcome to the TINI DS80C400 Auto Boot Loader 1.0.1
>
Select Load HEX File from the File menu. Find and select the hello_world.hex file we just generated. After loading the program, there are two ways to run it. Since we loaded the program into bank 40, you can enter:
> B40
> X
To select area 40 and run the code there, you can also type:
> E
This causes the ROM to look for executable code. It looks for a special tag that identifies the current bank as having executable code. This tag consists of the text 'TINI' followed by the current bank number and is located at address 0x0002 of the current bank. The application start code declares this tag with the following lines:
?VECTOR_TABLE:
sjmp ?INIT
DB 'TINI' ; Tag for TINI Environment 1.02c
; or later (ignored in 1.02b)
DB high(?INIT); Target bank
Notice that the sjmp ?INIT statement is located at address 0x0000 in the 0x40 area. This is followed by the executable label {'T', 'I', 'N', 'I', 0h}, which is located at address 0x0002 because the sjmp statement is two bytes. When you type E, the ROM starts searching for executable code in the C0h area and moves downward. If other code is executed when you type E, it means that the ROM found an executable label at a higher address than the 0x400000 address where your code was loaded. If this happens, you may need to find the location of this label and delete the contents of that area.
Interfacing with ROM and IAR ROM library
The process of calling ROM functions in assembly language is described in the High-Speed Microcontroller User's Guide DS80C4003 Supplement. However, calling these ROM functions in C is a bit more complicated. The parameters must be converted from the IAR C compiler's rules to the rules used by the ROM. The IAR compiler passes parameters using a combination of the hardware stack and registers. ROM functions accept parameters in a number of different ways. For example, socket functions receive parameters stored in an argument buffer . In contrast, many utility functions receive parameters passed in special function registers or stack memory. In order to convert from the IAR calling method to the ROM parameter method, Dallas Semiconductor has written a library to access the ROM functions.
To use ROM functions in your C program, just include a header file and link with the corresponding library file. The ROM library for IAR compilers includes:
ROM Initialization Procedure
DHCP Client
Process Scheduling
Sockets (TCP, UDP and Multicast)
TFTP Client
Function (CRC16, random number)
At the time of writing, there are no extension libraries for IAR compilers, including file systems, mail clients, and HTTP servers. Please keep an eye on the IAR library home page for updates to the DS80C4004 as we add more IAR-supported libraries.
Simple application: HTTP server
A simple http server is written here to illustrate how to use some of the ROM library functions, especially the socket and process scheduling libraries. The sample application consists of two modules: an HTTP server and an SNTP client. The main program generates a new child task to run the http server to handle client connections on port 80. The parent task will try to synchronize the current time with the time server every 60 seconds.
SNTP Client Module
The following code implements the core functions of the SNTP client module.
socket_handle = socket(0, SOCKET_TYPE_DATAGRAM, 0);
for (i=0;i<256;i++)
buffer[i] = 0;
// set a timeout of about 2 seconds
buffer[0] = 0x0;
buffer[1] = 0x0;
buffer[2] = 0x8;
buffer[3] = 0x0;
setsockopt(socket_handle, 0, SO_TIMEOUT, buffer, 200);
buffer[2] = 0; //reset since we used this in call to setsockopt
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 = htons(NTP_PORT) // port number
sendto(socket_handle, buffer, 48, 0, &address, sizeof(struct sockaddr));
recvfrom(socket_handle, buffer, 256, 0, &address, sizeof(struct sockaddr));
//IAR uses little Endian for storing data, so reorganize the data before //converting it to long
buffer[0]=buffer[43];
buffer[1]=buffer[42];
buffer[2]=buffer[41];
buffer[3]=buffer[40];
timeStamp = *(unsigned long *)(&buffer[0]);
formatTimeString(timeStamp, "London", last_time_reading_1);
formatTimeString(timeStamp - (6 * SECONDS_PER_HOUR), "Dallas", last_time_reading_2);
formatTimeString(timeStamp + (5 * SECONDS_PER_HOUR) + (30 * SECONDS_PER_MINUTE), "Bangalore", last_time_reading_3);
formatTimeString(timeStamp - (10 * SECONDS_PER_HOUR), "Honolulu",
last_time_reading_4);
last_reading_seconds = getTimeSeconds();
closesocket(socket_handle);
The SNTP client module is implemented using RFC 1361. The SNTP module communicates with time.nist.gov using the UDP protocol and requests a timestamp. Please note that DNS lookup support was not available at the time of writing this application note, so the IP address of time.nist.gov was set manually.
First, we create a packet socket and assign it a timeout of about 2 seconds (0x800 == 2048 milliseconds). This will ensure that if communication with our chosen server fails, we don't wait indefinitely for a response.
The next line sets the request options. These bits are described in Section 3 of RFC 1361. 0x23 does not generate an alarm on a leap second, requires the use of version 4 NTP, and declares the mode to be Client. We use the normal packet functions sendto and recvfrom to request and receive the response, assigning the seconds of the timestamp to the variable timeStamp, and then adjusting it to the reference date of January 1, 1970. The function formatTimeString converts the timestamp into a readable string, such as "In London it is 05:33:19 on May 11, 2005".
The getTimeSeconds function is used to determine the last update time based on the DS80C400's internal clock. Since the program updates approximately every 60 seconds, the HTML page time.html will use this value to report how much time has passed since the last time update. Finally, the socket is closed and the SNTP client enters another 60-second sleep period.
Simple HTTP Server
Another submodule of this time server application is the web server. The HTTP server in this application implements a simplified version of the HTTP server described in RFC 2068. In our version, only the GET method is supported, input headers are ignored, and almost no output headers are given. The file system library was not available at the time of writing this application note, so the example application generates HTML pages dynamically.
The server socket is created by calling the Berkley-style socket function. This makes it very easy to establish a server socket. The following code shows how our simple HTTP server creates, binds, and accepts new connections.
struct sockaddr LOC al;
unsigned int socket_handle, new_socket_handle, temp;
socket_handle = socket(0, SOCKET_TYPE_STREAM, 0);
local.sin_port = htons(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 received, this simple application does not start a new thread or process to handle the request, but handles the request in the same process. Any HTTP server that is better than this demonstration will handle incoming requests in a new thread, allowing multiple connections to occur and be processed simultaneously. After the request is processed we close the socket and wait for the next incoming connection.
The handleRequest method parses the filename from the incoming request and verifies that the request method is GET. No other methods (even POST, HEAD, or OPTIONS) are allowed.
Notes on Writing DS80C400 Assembly Functions for the IAR Compiler
The IAR documentation provides a method for writing programs in 8051 assembly that can be called from a C program. If 8051 assembly functions are called from a C program written with the IAR compiler, the following points should be kept in mind when writing these assembly languages. If there are no available registers to pass variables, the variables will be pushed onto the stack in little endian order.
1. Function parameter passing convention
The following table explains how variables are passed.
The following table shows the rules for function return values.
The variables and return values of the function int foo (int x, int y, void* ptr); are passed as follows:
2. Data type storage rules
IAR follows the Little Endian storage convention. Note that IAR uses the least significant byte first binary data storage format.
For example, a 4-byte value 0xDEADBEEF would be stored as follows:
3. A simple assembler interfaced with 'C'
This section demonstrates how to write an assembly program and interface it with a 'C' program using IAR Embedded Workbench. The application swaps 16-bit and 32-bit bytes and outputs the swapped bytes to the default console. The C callable function prototype is int ltob(int *shortptr, long *longptr).
This example program consists of two files: main.c and eswap.s51.main.c calls our example function ltob() written in assembly language. Create a new project and name it endian; add cstartup.s51, low_level_init.s51, putchar.c files, and the Dallas Semiconductor ROM initialization library rominit.r51. For details, refer to the above Getting Started with 8051 IAR Embedded Workbench.
Create a new main.c file with the following content and add it to the project endian. In C, a function must be declared so that the compiler knows how to call it. The ltob() function is declared before main(). Note that the ltob() function returns '0' on a successful run, and a non-zero value if any pointer is NULL. The program should output the following to the console:
Create a new file eswap.s51, enter the following assembly code and add it to the project endian. This assembly program declares our function ltob() as PUBLIC so it can be called from a 'C' program. The first argument to ltob() is a pointer and is passed via registers r3:r2:r1 of the DS80C400 controller. The second argument is also a pointer and is pushed onto the stack at offsets 3 to 5 by the IAR compiler (offset 3 contains the least significant byte and offset 5 contains the most significant byte). First, the function retrieves the pointer stored on the stack (pointing to a 32-bit value), swaps the value it points to, and stores the swapped bytes in the same location. Similarly, the 16-bit value is also byte-swapped and stored in the same location before the swap. Note that registers r6 and r7 are preserved through the assembly function. This is because the IAR compiler treats these registers as permanent registers, meaning that any function call should not modify these registers.
#include "reg400.inc"
r0_b0 equ 0; Register bank 0 equates.
r1_b0 equal 1
r2_b0 equal 2
r3_b0 equal 3
r4_b0 equal 4
r5_b0 equal 5
r6_b0 equal 6
r7_b0 equal 7
PROGRAM ENDIAN_SWAP
PUBLIC ltob
RSEG FAR_CODE:CODE:NOROOT (0)
;************************************************ *******************
;
; int ltob (unsigned int* shortptr, unsigned long* longptr)
;
;************************************************ *******************
ltob:
// shortptr is in r3:r2:r1
// longptr is in stack at offset 5
; get the longptr stored in the stack
mov a,SP
clr c
subb a,#5
mov b,a
mov a,esp
anl a,#0x3
orl a,#0xDC ; extended stack is at 0xff dc00
subb a,#00 ; subtract 0x0005 to point to MSB of 2nd argument
mov DPX,#0xFF
mov DPH,a
mov DPL,b
push r6_b0 ; save r6:r7 for the compiler
push r7_b0
movx a,@DPTR
mov r4,a ;store least signifi CAN t byte of 'longptr' in r4
inc DPTR
movx a,@DPTR
mov r5,a ;store middle byte of 'longptr' in r5
inc DPTR
movx a,@DPTR
mov r6,a ;store most significant byte of 'longptr' in r6
mov a,r4_b0
orl a,r5_b0
orl a,r6_b0
jz ltob_err; is (longptr == NULL)?
mov dpx,r6_b0 ; point to the memory where 'longptr' is pointing to
mov dph,r5_b0
mov dpl,r4_b0
pop r6_b0 ; restore r6:r7 for the compiler
pop r7_b0
push dpx
push dpl
movx a,@dptr ; get the long value (in r4:r3:r2:r1) from the memory
mov r4,a
inc dptr
movx a,@dptr
mov r5,a
inc dptr
movx a,@dptr
mov r6,a
inc dptr
movx a,@dptr
mov r7,a
inc dptr
pop dpl
pop dph
pop dpx
mov a,r7_b0 ; swap the long value bytes and store it in memory
movx @dptr,a
inc dptr
mov a,r6_b0
movx @dptr,a
inc dptr
mov a,r5_b0
movx @dptr,a
inc dptr
mov a,r4_b0
movx @dptr,a
mov a,r1_b0 ; is (shortptr == NULL)?
orl a,r2_b0
orl a,r3_b0
jz ltob_err
mov dpx,r3_b0 ; point to a memory where the 'shortptr' is pointing to
mov dph,r2_b0
mov dpl,r1_b0
push dpx
push dph
push dpl
movx a,@DPTR ; get the integer value from memory
mov r2,a
inc dptr
movx a,@dptr
mov r1,a
inc dptr
pop dpl
pop dph
pop dpx
mov a,r1_b0 ; swap the integer bytes
movx @dptr,a
inc dptr
mov a,r2_b0
movx @dptr,a ; bytes of an integer are swapped and stored in memory
mov r3,#00 ; return 'success'
mov r2,#00
sjmp ltob_exit
ltob_err:
mov r3,#00 ; return 'error'
mov r2,#01
ltob_exit:
ret
END; end of assembly program
Limitations and Development Issues
The following limitations have been observed when using IAR compiler version 6.11A:
The IAR compiler uses the stack to store local variables. In the DS80C400, the stack is limited to 1024 bytes. The default stack swap for the DS80C400 library is 384 bytes (ROM_SAVESIZE). If your program declares multiple stack variables, make sure that limit is changed appropriately. To change the default task swap size, use the Dallas Semiconductor task_genesis (unsigned int savesize) library or task_fork (unsigned char priority, unsigned int savesize) defined in rom400_task.h and provide the correct value for the savesize parameter.
There are some problems with printf, sprintf, etc.: the functions will work properly only if the 'lowest optimization level' is selected. To select the optimization level, go to project→options→ICC8051 and select 'None' in the Code tab.
The default libraries of IAR printf, sprintf do not work properly. To make them work properly, your C program should include the C files provided by IAR (such as #include
in conclusion
Dallas Semiconductor provides IAR compilers with support for C programs to access the functions of the DS80C400 ROM software. C programs can access the network stack, memory manager, process scheduler, and many other functions of the DS80C400. DS80C400 microcontroller developers using C language can write more streamlined applications, giving the system enough speed, power, and code space. Dallas Semiconductor is working on porting all DS80C400 libraries that currently work with the Keil compiler to IAR. Please visit the DS80C400 IAR library home page frequently for updates.
Previous article:Design of reactive power compensation controller based on ATT7022A and AVR microcontroller
Next article:Vehicle stable driving and acceleration and deceleration control based on PID control strategy of Atmega8
- Popular Resources
- Popular amplifiers
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- Design techniques for machine learning algorithm generation (provided by ST official, Chinese subtitles)
- Add a startup program to the itop4412 development board
- IWR1642 Vehicle Occupant Detection Routine Problem
- How can I use an oscilloscope to capture pulses within a certain time range, such as capturing waveforms between 100us and 200us?
- Next-generation wireless network standard technology HiperLAN/2
- Products + DC brushless motor control + drive kit
- Due to the epidemic, you are under home quarantine. Has your salary been reduced?
- ARM9-compatible soft-core processor design: based on FPGA
- 5G era promotes PCB development in multiple fields
- What is the principle of keyless entry for cars?