The Makefile

The makefile includes a few other .make files found in some of the common directories. Every target-specific makefile includes common/monitor/common.make , common/zlib/zlib.make , and common/monitor/tools.make . These three .make files keep the target-specific makefile minimal by putting the common stuff in one place. There are fancier ways to do this; however, keeping things simple works just fine for me.

Note 

I was ˜˜born and raised on UNIX, using one of a few different UNIX-based shells and the many wonderful tools that UNIX weenies have grown to love (with good reason!) Despite this, I still wanted to have my embedded development setup on a PC so that I could work more portably. Being very comfortable with the UNIX shell, I was very happy to come across the MicroCross GNU X-Tools, which provide a UNIX-like cross development environment for the PC. The X-Tools package includes pre-built GNU cross compilers for several CPU architectures, the bash shell, and other UNIX tools (find, grep, rm, cp, ls, awk, sed, etc.) available for a Win32 platform. With this bash shell as my console on a Win32 platform, I get the best of both worlds . Thus, even though I am working on a PC, I use make to drive my builds, and I assume that the UNIX-like tools are available. The basic MicroCross toolset and installation instructions are included on the books CD.

The common.make file includes all of the make targets for the common modules, plus some conveniences that use the GNU cross development tools to build a variety of different output listings. These ancilliary build targets include helpful things like symbol tables, S-records, and C/disassembler mixed files. The common.make file also provides for the common clobber and clean facilities (to remove unwanted object and executable files) and a target that builds a .tar file for the target-specific source.

To implement all of these conveniences, the target-specific makefile must follow some guidelines. The majority of these guidelines involve initializing certain make variables within the makefile so that the common.make file can use them. The only other guideline is that all object modules are placed under an obj directory beneath the target-specific monitor directory.

Listings 13.1 through 13.4 present the basic makefile to be used for this port.

Listings 13.1: Basic Makefile.
image from book
 ############################################################################### # # Makefile for building a monitor for the MCF5272 evaluation platform. # # Currently, the only target supported for 5272 platform is EVAL.  When # the platform count increases to more than 1, the target name should be # specified on the command line. # # NOTE: This port has only been tested running in RAM space of the # MCF5272 eval board.  It is downloaded using the DBUG command "DL" or "DN". # PLATFORM    = CFEVAL FLASH       = 29pl160c TGTDIR      = eval5272 MONBASE     = ../../.. TGTBASE     = $(MONBASE)/targets/$(TGTDIR) COMBASE     = $(MONBASE)/common COMCPU      = $(COMBASE)/cpu ZLIB        = $(COMBASE)/zlib COMMON      = $(COMBASE)/monitor FLASHDIR    = $(COMBASE)/flash/$(FLASH) INFO        = info TARGET      = m68k-coff include     $(COMMON)/tools.make CFLAGS      = -Wall -D PLATFORM_$(PLATFORM)=1 -Wno-format \               -fno-builtin -msoft-float -g -c -m5200 -I. -I$(COMMON) \               -I$(COMCPU) -I$(FLASHDIR) -o $@ ASFLAGS     = -m5200 -o $@ ASMCPP      = cpp -D PLATFORM_$(PLATFORM)=1 -D ASSEMBLY_ONLY \               -I$(COMCPU) -I$(COMMON) LDFLAGS     = -Map=$(AOUT).map AOUT        = mon$(PLATFORM) LIBS        = libz.a $(LIBGCC) 
image from book
 

In Listing 13.1, the top set of variables are used to identify the environment within which the monitor source code resides. This environment supports convenient I arguments for directories that have include files and allows the common.make file to perform some common tasks based on these variables. The rest of these variables are typical for a makefile. The value of the PLATFORM variable is used to allow this directory and makefile to support more than one platform potentially . Ill talk more about this feature when I get to the config.h file.

The pre-built tools in the MicroCross X-Tools package are distinguished by names of the form <target><output file type><base tool name>. Thus, to generate code for an ARM board using ELF format object files, you would invoke the compiler named arm-elf-gcc. In Listing 13.1, the included file tools.make uses the value of the TARGET variable to build X-Tools compatible tool names (for CC, LD, ASM, etc.) For the ColdFire port, the CPU is a member of the Motorola 68K family (m68k) and I want to generate COFF output files, so TARGET is set to m68k-coff.

Listings 13.2: Object List for the ColdFire 5272 Make File
image from book
 OBJS=obj/reset.o obj/start.o obj/cpuio.o obj/chario.o obj/mprintf.o \ obj/main.o obj/mstat.o obj/sbrk.o obj/malloc.o obj/docmd.o obj/cmdtbl.o \ obj/go.o obj/env.o obj/memcmds.o obj/xmodem.o obj/flash.o obj/except.o \ obj/flashpic.o obj/flashdev.o obj/ethernet.o obj/reg_cache.o obj/vectors.o \ obj/tfs.o obj/if.o obj/misccmds.o obj/genlib.o obj/edit.o obj/lineedit.o \ obj/tfsapi.o obj/tfsclean1.o obj/tfscli.o obj/tfslog.o obj/symtbl.o \ obj/tfsloader.o obj/redirect.o obj/monprof.o obj/bbc.o obj/etherdev.o \ obj/icmp.o obj/arp.o obj/nbuf.o obj/dhcpboot.o obj/dhcp_00.o obj/tftp.o \ obj/tcpstuff.o obj/crypt.o obj/password.o obj/moncom.o obj/cache.o \ obj/misc.o obj/dis_cf.o include $(ZLIB)/zlib.objlist 
image from book
 

The object list of Listing 13.2 is based on the features that are to be part of the monitor build. The majority of these files are object files that are built from the common space. The objects are specified here so that each target can be built to include only the features that are needed for that application. Hence, this list is very target specific. The one important thing to note is that the build assumes that reset.o is the first module in the list. This assumption allows the linker to place the code that is in reset.s at the beginning of the memory map. Notice the inclusion of zlib.objlist . The zlib.objlist file (in the common/zlib directory) contains the objects that make up the zlib compression facility. This list is kept in common space because it is always used the same way. It can simply be included here if you use it.

Listings 13.3: Release vs. Development Build Versions.
image from book
 ##################################################################### # # rom: # Standard monitor build, destined for installation using newmon tool. # rom: $(INFO) $(OBJS) libz.a makefile     $(LD) $(LDFLAGS) -TROM.lnk -nostartfiles -e coldstart \     -o $(AOUT) $(OBJS) $(LIBS)     coff -m $(AOUT)     coff -B $(AOUT).bin $(AOUT) ##################################################################### # # ram: # Version of monitor for download into RAM. # ram: $(INFO) $(OBJS) libz.a makefile     $(LD) $(LDFLAGS) -TRAM.lnk -nostartfiles -e coldstart \     -o $(AOUT) $(OBJS)     coff -m $(AOUT)     coff -B $(AOUT).bin $(AOUT) 
image from book
 

For each monitor build, I usually have the option of building a release version of the monitor that boots out of flash memory (the rom tag in Listing 13.3) or a development version that loads in RAM (the ram tag in Listing 13.3). (I often use the RAM resident version when Im testing some new monitor feature. For this example port, I use the ram tag to create a monitor that can be downloaded into RAM space not used by the evaluation boards DBUG monitor.) The rom make tag is the top tag in the makefile, so it is the default.

Note 

The coff tool (referenced in Listing 13.3) could be replaced by various GNU tools with similar capabilities. I wrote the coff tool as an exercise to improve my own understanding of the COFF file format. The m option dumps a memory map of the executable, and the B option builds a binary image based on the executable, as I discussed in one of the earlier chapters of the book. This same capability is available for COFF, ELF, and A.OUT file formats. The source and executables are on the CD.

Notice the use of the $(AOUT) variable. This variable is used throughout the target makefile and common.make file as the base name for various files created by the make process. In this case, AOUT is set to mon$(PLATFORM) , and PLATFORM is set to CFEVAL; AOUT then, is monCFEVAL . This base name is used for several other outputs, such as monCFEVAL.bin for the raw binary image, monCFEVAL.srec for an S-record, monCFEVAL.sym for a symbol file, and so on. I find that this simple naming scheme keeps things a bit more organized from one target to the next , plus using a common base name makes it very convenient for the clobber tag to remove all of the files related to a particular target.

Listings 13.4: Miscellaneous Rules Section.
image from book
 ##################################################################### # # Miscellaneous rules: # include $(COMMON)/common.make include $(ZLIB)/zlib.make libz.a: $(ZOBJS)     m68k-coff-ar rc libz.a $(ZOBJS) info:     defdate -f %H:%M:%S BUILDTIME >info.h     defdate -f %m/%d/%Y BUILDDATE >>info.h 
image from book
 

The miscellaneous rules section (see Listing 13.4) includes the two other common .make files. Including these files pulls in the core set of targets and their dependencies. The libz.a tag builds the list of libz objects into a library. The info tag builds a simple header file ( info.h) that contains the time and date of the build. This info.h file is then included by one of the source files of the monitor to provide part of the information reported by MicroMonitors version command.

image from book
A Cross-Platform Date Tool

The info.h file is built with another home-grown tool called defdate (source and executable on CD). I wrote defdate because I build on both UNIX and Win32 and could not find a good cross-platform means of creating a date string that could be included in an #include file. If you look at the source on the CD, youll see it took a total of about five minutes to write defdate .

image from book
 
Listiing 13.5: info.h .
image from book
 info.h: #define BUILDTIME "12:26:16" #define BUILDDATE "12/23/2000" function called by 'Version' command: void ShowVersion(void) {     printf("Monitor built: %s @ %s\n",BUILDDATE, BUILDTIME); } 
image from book
 

Listing 13.5 shows the typical content of info.h (as it would be built by the defdate tool) and how it is used by the monitors version command. Note that most compilers provide the __DATE__ and __TIME__ intrinsic definitions. One of my earlier projects used a compiler that did not support these definitions, and defdate become very handy; so Ive been sticking with it.

The (incomplete) list of individual module tags shown in Listing 13.6 demonstrates the use of the various shell variables established at the top of the file. Notice in the last rule that I make assembly a two-step process. The source file is first passed through the C preprocessor ( ASMCPP ) and then through the assembler. Depending on the assembler, this process could be reduced to a single step. I chose to use the two-step process, however, rather than have toolset dependencies in the makefile. Notice that all modules are in the obj directory. This partitioning keeps the object module clutter out of the directory that holds the source code.

Listings 13.6: Individual Module Targets.
image from book
 ##################################################################### # # Individual modules: # obj/dis_cf.o:   $(COMCPU)/dis_cf.c $(COMMON)/genlib.h config.h     $(CC) $(CFLAGS) $(COMCPU)/dis_cf.c obj/flashdev.o: $(FLASHDIR)/flashdev.c     $(CC) $(CFLAGS) $(FLASHDIR)/flashdev.c obj/main.o: main.c config.h cpu.h $(COMMON)/tfs.h \     $(COMMON)/genlib.h $(COMMON)/ether.h \     $(COMMON)/monflags.h $(COMMON)/stddefs.h     $(CC) $(CFLAGS) main.c obj/reset.o:    reset.s  config.h     $(ASMCPP) reset.s >tmp.s     $(ASM) tmp.s     rm tmp.s 
image from book
 

The final section of the makefile (see Listing 13.7) sets up a make tag that is used by the common.make clobber tag. As you will see shortly, common.make has the clobber target, but, to allow clobber to be customized, it depends on clobber1 , which must be provided by the target makefile.

image from book
Use cpp with Assembly Language

I find the trivial differences among assemblers annoying. Different assemblers use different comment delimiters and different directives. Rather than deal with these nuisance differences, I write my assembly code in a partially ˜˜normalized syntax and then use the C preprocessor to translate my code to the form that the particu lar assembler wants. This translation tactic lets me use the familiar c-style com ment delimiters ( /* and */ ). More importantly, I can use #include at the top of the assembler file, letting me share the same header files across both assembly and C code. Sharing headers is a great convenience when writing firmware.

This technique is common enough that many compilers support the ability to pre-process assembly files through some command line option. Even if your com piler doesnt support this feature, you can still accomplish the same goal by using a two step translation process. Run CPP on the ˜˜normalized assembly file, then assemble the output of the preprocessor.

Listing 13.8: clobber1 Target.
image from book
 ##################################################################### # # Miscellaneous utilities: # (generic utilities are in $(COMMON)/common.make) # clobber1:     rm -f $(AOUT).map 
image from book
 
image from book
 

Listing 13.8 shows what I consider to be the most interesting parts of the common.make file. The first portion of common.make (not shown in the listing) consists of tags for each of the common modules and tags for a bunch of common tools. The tools (as can be seen from the text in the help tag in common.make) provide the facilities that are most commonly used in the cross compilation-process: conversion to S-records or binary, generation of a symbol table, generation of a file that contains both C-source and assembly language mixed, and so forth. Note that this portion of common.make depends on some of the variables that were established at the top of the makefile.

Listing 13.8: Common Miscellaneous Targets.
image from book
 ##################################################################### # # COMMON miscellaneous targets: # clean:     rm -rf obj     rm -rf libz.a symtbl     mkdir obj clobber:    clean clobber1     rm -f $(AOUT)     rm -f $(AOUT).bin $(AOUT).srec $(AOUT).fcd $(AOUT).dis $(AOUT).sym tar:    clean     rm -f $(AOUT).srec $(AOUT).sym  $(AOUT).fcd $(AOUT).dis $(AOUT).tar     /bin/sh -c "cd $(MONBASE) ; \     tar -cf $(AOUT).tar common/monitor common/zlib common/cpu \     common/flash/$(FLASH) targets/$(TGTDIR)/app targets/$(TGTDIR)/monitor"     mv $(MONBASE)/$(AOUT).tar . gnusrec:     $(OBJCOPY) -F srec $(AOUT) $(AOUT).srec bin2srec:     bin2srec $(AOUT).bin > $(AOUT).srec bindump:     $(OBJDUMP) --full-contents $(AOUT) >$(AOUT).fcd showmap:     $(OBJDUMP) --section-headers $(AOUT) dis:     $(OBJDUMP) --source --disassemble $(AOUT) >$(AOUT).dis disx:     $(OBJDUMP) --source --disassemble --show-raw-insn $(AOUT) >$(AOUT).dis sym:     $(NM) --numeric-sort $(AOUT) >$(AOUT).sym symtbl: sym     monsym -p0x $(AOUT).sym >symtbl help:     @echo "gnusrec  : use objcopy to produce $(AOUT).srec"     @echo "bin2srec : use bin2srec to produce $(AOUT).srec"     @echo "showmap  : display section headers"     @echo "dis      : source/assembly dump to $(AOUT).dis"     @echo "disx     : like dis, but show instruction in hex & symbolic"     @echo "sym      : numerically sorted symbol table dump to $(AOUT).sym"     @echo "symtbl   : rearrange output of sym to create monitor's symtbl file"     @echo "bindump  : ascii-coded hex full-content dump to $(AOUT).fcd"     @echo "clean    : delete entire obj directory"     @echo "tar      : create a tar file of the current source and binary." 
image from book
 

Thats it for the makefile and its components . Absolutely no rocket science, just simple and easy-to-duplicate rules for other targets and compilers and for both Win32 and UNIX.



Embedded Systems Firmware Demystified
Embedded Systems Firmware Demystified (With CD-ROM)
ISBN: 1578200997
EAN: 2147483647
Year: 2002
Pages: 118
Authors: Ed Sutter

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net