Tech Tips #7101 MICRO/C-51 V1.xx

Making MICRO/C-51 Application Programs Work with Monitor Programs

This Tech Tip explains how to make application programs built with MICRO/C-51 work with monitor programs. Techniques discussed here, including modifying and controlling the placement of program segments, have application when working with any pre-existing program modules.

Introduction

Manufacturers of single board computers based on the 8051 Family of microcontrollers often supply a monitor program to help load and execute application programs. These monitor programs usually take up the first 4K, 8K, or 16K bytes of Code Memory space for the monitor program itself. Additional memory is required for your application program. Monitor programs may also use other system resources such as a timer, a uart, interrupts, and some internal and external Data Memory space for stack, control variables, or memory mapped Input/Output devices. Before starting a new project, you should review the documentation provided with the monitor program to get a clear understanding of the system resources it uses.

When you load an application program with a monitor program, it stores your program into RAM or EEPROM in external 8051 Data Memory. An 8051 program (the monitor program) can only write (store your program) to Data Memory. The memory where your program is stored must also be addressable as Code Memory. An 8051 can only execute a program (your application) that is in Code Memory. In many 8051 based single-board computers, some memory chips may appear in both memory spaces at the same time by logically ORing Code and Data select lines. Various circuit designs can be used to achieve an appropriate program load (Data Memory) and execute (Code Memory) system configuration. Your board manufacturer should provide the information you require to understand your system's configuration.

What all this means is that the monitor program uses various system resources, and your application program cannot use these same resources at the same time.

By default, MICRO/C-51 builds a program that operates without a monitor program. If fact, it generates program code that loads at Code Memory address 0000H, right on top of most monitor programs. To build an application program with MICRO/C-51 that works with a monitor program, you need to move some things around so your application code won't land on top of the monitor program.

Application Programs

In response to C-statements in your source file, MICRO/C-51 generates Code and Data segments used to build your program. Code segments hold 8051 instructions or constant data. Data segments hold variables declared in your application. MICRO/C-51 uses two types of segments, Absolute and Relocatable, in generating your application program.

By default, MICRO/C-51 generates application programs that work stand-alone. That is, it generates program code that does not need a monitor program or any other type of operating system. This is the most common configuration for embedded processor applications. To build an application program that works with a monitor program, you will need to adjust the placement both Absolute and Relocatable segments. The following sections will explain how.

Absolute Code Segments

Absolute Code segments are fixed at a specific Code Memory address so it will match the built-in actions of the 8051 hardware. MICRO/C-51 uses Absolute Code segments to handle the 8051 Reset Vector (address 0000H) and 8051 Interrupt Vectors (address 0003H, 000BH, ...). Monitor programs usually handle the Reset Vector themselves, and remap the interrupt vectors to the application program area by placing an LJMP instruction within the monitor at the interrupt vector location.

By default, MICRO/C-51 generates application program code that handles the 8051 Reset and Interrupt Vectors without the need of a monitor program or any other type of operating system. Absolute Code addresses are set in the assembly language modules in the MICRO/C-51 Run-Time Library. To work with a monitor program, you need to make a few changes to the Absolute Code segments of source files included with MICRO/C-51, and rebuild these segments with the MICRO/ASM-51 Assembler.

Modifying the Reset Vector Handler

The following code example shows the standard 8051 Reset Vector module (CRV0.SRC) from the MICRO/C-51 Run-Time Library. This source file is found in the a_files sub-directory on the compiler distribution diskette.

; CRV0.SRC - RESET VECTOR/HANDLER

; REV: 1.1

; Arg: none

; Return: none

PUBLIC ?CRV0,?CSTACK
EXTRN CODE (MAIN)

CSEG AT 0000H ; RESET VECTOR ADDRESS

?CRV0: LJMP ?CRH0 ; JMP TO RESET HANDLER

?STACK SEGMENT IDATA
RSEG ?STACK
?CSTACK: DS 1 ; SYSTEM STACK

?CLIBC SEGMENT CODE
RSEG ?CLIBC

?CRH0: ; RESET HANDLER
MOV SP,#LOW ?CSTACK ; INITIALIZE STACK POINTER
MOV PSW,#00 ; CLEAR PSW
LCALL MAIN ; EXECUTE MAIN FUNCTION
LJMP ?CRV0 ; RESET ON RETURN

$EJECT
END

This module consists of both Absolute and Relocatable Code segments used to implement MICRO/C-51 Reset processing. The Absolute Code segment (the LJMP ?CRH0 instruction) is designed to load at location 0000H and handles the Reset Vector (hardware JMP instruction) generated automatically by the 8051 microcontroller upon the completion of a hardware reset sequence.

When working with a monitor program, the monitor program performs its own Reset processing, so the MICRO/C-51 Reset Absolute Code segment needs to be moved to the beginning of the application program area as defined by the circuits on your computer board. To change the segment address, copy the source file (CRV0.SRC) from the MICRO/C-51 distribution disk to your current working sub-directory and with any text editor change the instruction

CSEG AT 0000H ; RESET VECTOR ADDRESS

to

CSEG AT 0000H+xxxxH ; RESET VECTOR ADDRESS

where xxxxH should be 1000H, 2000H, 4000H, or 8000H depending on the starting address of the application program area as specified by your computer board manufacturer. Now use the MICRO/ASM-51 assembler to build your own custom version of the Reset segment by executing the following:

ma51 crv0.src

The MICRO/ASM-51 assembler will generate an object file (CRV0.OBJ) with the modified Reset Absolute Code segment. You will use this file later in the linking process. For complete details on MA51 operation see the "Using the MA51 Assembler" and "Writing Assembly Source Code" sections of the MCC 8051 Macro Cross Assembler Programmer's Guide.

Modifying Interrupt Vector Handlers

This section explains how to work with interrupts and a monitor program. If you are not using interrupts in your application, you can skip to the next section, "Relocatable Code Segments".

If you are using interrupts within you application program, AND you are using a monitor program, you will also need to modify the routines MICRO/C-51 uses to process 8051 Interrupt Vectors. You need only modify files for those interrupts used by your application. The source files for interrupt vector handlers are found in the a_files sub-directory on the compiler distribution diskette.

The following code example shows the standard 8051 External Interrupt 0 vector module (CIV0.SRC) from the MICRO/C-51 Run-Time Library. Equivalent files (CIV1.SRC, ... , CIV15.SRC) are present for handling all 8051 interrupt vectors.

; CIV0.SRC - INTERRUPT VECTOR NO. 0 PRE/POST-AMBLE

; REV: 1.0 ;

; Arg: none

; Return: none

PUBLIC ?CIV0
EXTRN CODE (?CIF0)

CSEG AT (0 * 8 + 3) ; INTERRUPT NO. 0 VECTOR ADDRESS
?CIV0:
PUSH B ; SAVE REGISTER CONTEXT
PUSH ACC
LJMP ?CIH0

?CLIBC SEGMENT CODE
RSEG ?CLIBC

?CIH0:
PUSH DPL
PUSH DPH
LCALL ?CIF0 ; EXECUTE INTERRUPT NO. 0 FUNCTION
POP DPH ; RESTORE REGISTER CONTEXT
POP DPL
POP ACC
POP B
RETI

$EJECT
END

This module consists of both Absolute and Relocatable Code segments used to implement MICRO/C-51 External Interupt 0 processing. The Absolute Code segment is designed to load at location 0003H and handles the External Interupt 0 Vector (hardware JMP instruction) generated automatically by the 8051 microcontroller upon detection of an External Interrupt 0 interrupt..

When working with a monitor program, the monitor program often handles interrupt vectors by placing a LJMP instruction at the vector address. This LJMP instruction usually jumps to an equivalent address near the beginning of the application program area. To process the remapped interrupt vector, the MICRO/C-51 Interrupt Vector Absolute Code segment needs to be moved to the address specified in the LJMP instruction. To change the segment address, copy the source file (CIV0.SRC) from the MICRO/C-51 distribution disk to your current working sub-directory and with any text editor change the instruction

CSEG AT (0 * 8 + 3) ; INTERRUPT NO. 0 VECTOR ADDRESS

to

CSEG AT (0 * 8 + 3)+xxxxH ; INTERRUPT NO. 0 VECTOR ADDRESS

where xxxxH should be 1000H, 2000H, 4000H, or 8000H depending on the starting address of the application program area as specified by your computer board manufacturer. Now use the MICRO/ASM-51 assembler to build your own custom version of the interrupt vector handler segment by executing the following:

ma51 civ0.src

The MICRO/ASM-51 assembler will generate an object file (CIV0.OBJ) with the modified Interrupt Vector Absolute Code segment. You will use this file later in the linking process.

Modifying and rebuilding the Reset Vector Handler and any required Interrupt Vector Handlers completes the Absolute Code segment changes required to build an MICRO/C-51 application program that will work with your monitor program.

Relocatable Code Segments

Relocatable segments are assigned a code memory address at link time, rather than at compiler or assembly time. MICRO/C-51 uses Relocatable segments to handle all program elements that do not need to be placed at a specific 8051 hardware-defined address. This includes Data Memory and Code Memory segments generated by the MICRO/C-51 C Compiler when processing your C-source files, and Relocatable segments extracted from the MICRO/C-51 Run-Time Library.

Relocatability provides the required flexibility needed when various pieces of code or data may be used in one application program but not in another. Relocatability allows the ML51 linker to load only the required MICRO/C-51 Run-Time Library modules used by an application program, thus reducing application program size.

Linker Operation

As explained in "Absolute Code Segments" above, the memory address of Absolute segments are set within the segment source file. The incorporation of modules into an application program, and the assignment of memory addresses to Relocatable segments, are controlled by the linking operation.

The ML51 linker program is the final step in building a MICRO/C-51 based application program. ML51 combines Absolute and Relocatable segments generated by your program files along with any modules referenced in library files specified on the linker command line. It also allocates Code and Data memory space for these segments and builds your executable application program file. For complete details on ML51 operation see the "Using the ML51 Linker" section of the MCC 8051 Macro Cross Assembler Programmer's Guide.

ML51 processes command line object filenames in a right-to-left order, so you can override any library module by specifying a replacement object filename on the linker command line ahead of the library filename. ML51 will use the replacement object file and skip over the module within the library.

For example:

ml51 hello+crv0+mcm51.lib mapmin(code=4000H) format(ihex)

This example builds the sample "Hello, World" (hello.c) program included with MICRO/C-51, and allows it to run with a 16K byte monitor program. As can be seen, the command line specifies a modified Reset module (CRV0.OBJ) before the standard MICRO/C-51 Run-Time Library file (MCM51.LIB). This causes the linker to load the modified module and skip over the standard module in the library. The command line also uses the ML51 MAPMIN location control to set the minimum Relocatable Code address to 4000H. This forces the linker to start allocating Relocatable segments in an application program area that starts at this address.

ml51 yourpgm+crv0+civ0+mcm51.lib mapmin(code=4000H) format(ihex)

This example is similar to the "Hello, World" example above, but adds a reference to a modified External Interrupt 0 interrupt handler (CIV0.OBJ). As above, the modified External Interrupt 0 interrupt handler module replaces the standard module in the Run-Time Library. Any number of standard library modules can be replaced in this manner.

Conclusion

This Tech Tip has discussed techniques used to allow application programs generated with MICRO/C-51 to work with a monitor program. Techniques discussed here have application when working with any pre-existing program modules.

When building an application program that must coexist with a pre-existing program, care must be taken to ensure that the application program and the pre-existing program do not use the same system resources at the same time. One way to determine the system resources used by a MICRO/C-51 based application program is to view the .MAP file generated by the ML51 linker. This file documents all Data and Code memory used by the application. This information can be compared to the list of resources used by the pre-existing program to determine conflicts.

We would like to receive your comments on this Tech Tip and suggestions for others. E-mail us at info@mcc-us.com