The Configuration Header File

To maintain some type of global configuration control over all files in the monitor build, one file, mysteriously named config.h , should be at the top of the #include list for every file in the build. The following sections walk through each of the sets of definitions in config.h and explains how to adjust various operational parameters.

FORCE_BSS_INIT

When the CPU resets, it transfers control to the non-volatile code located at the address of the CPUs reset vector. The code in the file reset.s is supposed to be mapped to that location. After the lowest level of initialization, reset.s calls start() (the first C function). The start() function depends on a parameter passed to it by the reset code to know what type of startup (warm or cold) just occurred. If the reset is a cold start (meaning that the power was just applied or the system reset button was pushed ), then all of the monitors .bss space must be initialized to zero. If the reset is not a cold start, then the .bss is left as is so that state already established before the reset remains available. The decision whether or not to initialize .bss is based on an incoming parameter set up by assembly language code in reset.s .

When bringing up a new piece of hardware, this .bss initialization should be independent of the type of startup to avoid the case where .bss is erroneously not initialized when it should be. Defining FORCE_BSS_INIT makes this brute force .bss initialization occur in start() . Once the target boot source code has stabilized, this definition should be removed so that .bss is appropriately touched or left alone.

PLATFORM_XXX

In general, each directory below the targets directory is for one specific target system. This directory structure keeps target-specific interfaces cleanly in their own directory space. However, sometimes multiple targets are so close in architecture that it just doesnt make sense to isolate them by directory. The PLATFORM_XXX definition (see Listing 13.9) in config.h , the makefile, and any of the target-specific files support the need for minor differences between nearly identical targets.

At reset, the monitor dumps a verbose header to the console port. One of the lines in the header is the name of the platform, derived from the PLATFORM_NAME definition (see Listing 13.9.) The ColdFire port only supports one platform, so this definition isnt absolutely necessary. However, following the established model just makes things consistent from one port to the next . Also, if a future design comes up that is very close to the evaluation platform, we are ready for it.

Listing 13.9: PLATFORM_XXX Definition.
image from book
 #if PLATFORM_CFEVAL #define PLATFORM_NAME     "Coldfire 5272 Evaluation Board" #else #error                    "Platform name is not specified" #endif 
image from book
 

Flash Configuration

Because the flash drivers are written to be independent of the address space they use, they must be supplied with some basic information about where the devices reside in the target memory space. This information is provided by the definitions in Listing 13.10.

Listing 13.10: Flash Bank Configuration Definitions.
image from book
 /* Flash bank configuration:  */ #define FLASHBANKS              1 #define FLASH_BANK0_WIDTH       2 #define FLASH_BANK0_BASE_ADDR   0xFFE00000 #define FLASH_PROTECT_RANGE     "0-6" 
image from book
 

Recall from the chapter on flash drivers that there can be multiple banks of flash memory. This platform contains only one flash device. If there were more than one, FLASHBANKS would reflect that, and there would be multiple sets of FLASH_BANKX_WIDTH (in bytes) and FLASH_BANKX_BASE_ADDR (starting point of the device in CPU memory space) definitions. The final definition of FLASH_PROTECT_RANGE is used to tell the flash driver which sectors to apply software protection (refer to the chapter on flash drivers for details on software protection). This sector range can span multiple banks and/or devices and can specify multiple ranges (use a hyphen for a multi-sector range and a comma to separate multiple ranges).

TFS Configuration

When TFS is compiled, it must be told where in memory it is to exist and where in memory the spare sector is to reside. The config.h definitions specific to TFS allow TFS to configure itself for optionally multiple, non-contiguous blocks (TFS devices) of memory. The configuration data here works in coordination with information in the tfsdev.h header file, which defines the structure or table of structures if more than one TFS device is supported that describes each block.

Listing 13.11: TFS Definitions in config.h .
image from book
 Portion of config.h: /* TFS definitions:  */ #define TFSSPARESIZE            0x40000 #define TFSSECTORCOUNT          2 #define TFSSTART                0xfff40000 #define TFSEND                  0xfffbffff #define TFSSPARE                0xfffc0000 #define TFS_EBIN_COFF           1 #define TFSNAMESIZE             23 Portion of tfsdev.h: /* TFS Device table:  */ struct tfsdev tfsdevtbl[] = {     {   "//AM29160/",         TFSSTART,         TFSEND,         TFSSPARE,         TFSSPARESIZE,         TFSSECTORCOUNT,         TFS_DEVTYPE_FLASH, },     /* If there was another TFS device, an      * additional tfsdev entry would be here.      */     { 0, TFSEOT,0,0,0,0,0 } }; #define TFSDEVTOT ((sizeof(tfsdevtbl))/(sizeof(struct tfsdev))) 
image from book
 

Listing 13.11 shows the related portions of config.h and tfsdev.h . The entries in config.h are used by tfsdev.h and in other parts of the TFS code. In the majority of cases, the file system is built with only one TFS device, so there is a one-to-one mapping of start, end, spare size , and sector count between config.h and tfsdev.h . If I were building a system for multiple TFS devices, then there would be an additional tfsdev structure in the tfsdevtbl[] array for each additional device. Also, there would be additional definitions in config.h that tfsdev.h would reference.

The TFS definitions establish the target-specific information needed to compile the file system. The parameters include the base and end address of the flash space used by TFS ( TFSSTART and TFSEND ), the address and size of the spare sector ( TFSSPARE and TFSSPARESIZE ), and the number of sectors allocated to TFS for storage space ( TFSSECTORCOUNT ), which does not include the spare sector. The definition of TFSNAMESIZE is only needed if the size is to be something other than the default of 23. (For all systems so far, 23 has been fine. However, if there ever is a need to make it bigger or smaller, TFSNAMESIZE is where you do it. The only requirement is that the size be one less than some value divisible by four.)

One additional TFS definition, TFS_EBIN_COFF , tells TFS what loader to include with TFS when built. Currently COFF, ELF, and A.OUT are supported; others are easily added to the platform.

The INCLUDE List

The monitor can be built with a fairly wide variety of options. In general, the options specific capabilities are supported by corresponding CLI commands. The first obvious advantage to being able to configure different capabilities selectively is that eliminating unneeded capabilities saves memory space. The less obvious advantage is that during a port to a new target, fewer capabilities means less complexity in the initial build and less debugging. At the start, all but the most basic features can be configured out, and then, one by one, features that correspond to specific hardware peripherals can be added. For example, when I start the port, I dont want to have to worry about TFS and Ethernet or even flash memory when I dont even know how to configure the RAM and serial port, so I start with these other components disabled. Then, one by one, I enable the features. This approach allows me to tackle one problem at a time as I continue the port.

The definitions in Listing 13.12 show an example configuration for a monitor platform. The included inc_check.h header file, found in the common/monitor directory, is used to do a sanity check on the list. The majority of these definitions would be set to zero at the start of a port, and then one by one they can be enabled to add functionality. An early configuration for starting a port would be to set INCLUDE_MEMCMDS and INCLUDE_XMODEM , which allows me to start the port working on reset.s and the serial port. After the target boots with the serial port working, I can use some of the memory modify and display commands to look around at the address space. If memory seems to be correctly configured, then I can use xmodem to download small test programs into RAM.

Note 

The inclusion of inc_check.h below the list of INCLUDE_XXX definitions enforces the requirement that these defines in Listing 13.12 be set to zero or one not just omitted. I chose this alternative because it forces the user to be aware of the configuration and reduces the likelihood that a section is omitted just because the user was unaware of the option.

Listing 13.12
image from book
 /* INCLUDE_XXX Macros:  * The sanity of this list is tested through the inclusion of  * "inc_check.h" at the bottom of this list...  */ #define INCLUDE_MEMCMDS         1 #define INCLUDE_PIO             0 #define INCLUDE_EDIT            1 #define INCLUDE_DEBUG           0 #define INCLUDE_DISASSEMBLER    0 #define INCLUDE_UNPACK          0 #define INCLUDE_UNZIP           1 #define INCLUDE_ETHERNET        0 #define INCLUDE_TFTP            0 #define INCLUDE_TFS             1 #define INCLUDE_FLASH           1 #define INCLUDE_XMODEM          1 #define INCLUDE_LINEEDIT        1 #define INCLUDE_CRYPT           0 #define INCLUDE_DHCPBOOT        0 #define INCLUDE_TFSAPI          1 #define INCLUDE_TFSAUTODEFRAG   1 #define INCLUDE_TFSSYMTBL       0 #define INCLUDE_TFSSCRIPT       0 #define INCLUDE_TFSCLI          1 #define INCLUDE_EE              0 #define INCLUDE_GDB             0 #define INCLUDE_STRACE          0 #define INCLUDE_CAST            0 #define INCLUDE_EXCTEST         0 #define INCLUDE_IDEV            0 #define INCLUDE_REDIRECT        0 #define INCLUDE_QUICKMEMCPY     1 #define INCLUDE_PROFILER        0 #include "inc_check.h" 
image from book
 

Miscellaneous Configuration

This section discusses two important definitions required by the platform:

ALLOCSIZE The monitor comes with its own memory allocator because, although I dont advocate use of malloc all over the place in an embedded system, intelligent use of memory allocation can be very handy in some situations. The definition of ALLOCSIZE tells the monitor how much memory to allocate statically to the heap in the monitor. The block of memory used for the malloc heap is part of the static memory configured into the monitor. I chose to keep the memory allocated to the heap within the monitors .bss space so that an application can reside in memory space after the monitor without worrying about clashing with a heap growing from the monitor. In addition, the monitors allocator supports the ability to allocate from two different non-contiguous blocks of memory (two heaps essentially ). This design is useful for cases where the monitor is built with a small heap to keep RAM usage low but occasionally runs an application that needs a larger heap. The application can use the monitors allocator and add more to the heap by simply expanding the heap into some new address space assigned by the application.

SYMFILE If the shell variable SYMFILE is not set as an override, then this definition will set the default name for the symbol table file, usually symtbl.



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