NOTICE: The Processors Wiki will End-of-Life in December of 2020. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.
Using Preprocessor Support in Linker
The purpose of this article is to demonstrate the conditional processing capabilities of the linker and DSP/BIOS.
Many times developers create two or more projects in Code Composer Studio during the development/debug cycle. For instance, when developing with the F28xx DSC it is common for developers to create a project that runs from internal RAM and another that executes from on-chip Flash memory, since the section allocation and configuration differs between the two versions. Similar concepts are employed when developing on other DSP targets. This article demonstrates the usage of preprocessor directives in linker command file and environment variables in DSP/BIOS to create single CCS projects or migrate multiple CCS projects into a single project.
The F28xx example projects from application note Running an Application from Internal Flash Memory on the TMS320F28xxx DSP (SPRA958)are used as a starting point. Although this example is specific to F28xx processors the concepts can be applied to other TI DSP and MCU devices as well.
It is assumed the reader has read and understood the details of running from internal RAM and on-chip Flash as described in the application report. This article merely discusses the configuration aspects of the Code Composer Studio project for BIOS and non-BIOS code.
The application note, in essence, contains 4 projects for each DSP device:
- non BIOS RAM
- non BIOS Flash
- BIOS RAM
- BIOS Flash
The memory regions to where initialized and uninitialized sections are linked is different when running from RAM and running from on-chip Flash. Please refer to the application note for more details.
Using the older code generation tools (prior to the versions noted below), there were a couple of ways of handling this:
- Create 2 separate projects – one for RAM and another for Flash, each with their own set of linker command files and BIOS configuration files.
- Create 1 project with RAM and Flash configurations in CCS, add 2 sets of linker command files and BIOS tcf files to both configurations, and select "Exclude from build" on the files that do not apply to the specific configuration.
This article provides a template for creating a single Code Composer Studio project with multiple configurations, one for RAM and one for Flash, but both use the same set of linker command files and BIOS tcf file. This simplifies development and maintenance into a single project.
Supported Features in Code Generation Tools and DSP/BIOS
Preprocessing support in linker command file is a new feature in the new COFF linkers. This feature enables command files to contain the well-known preprocessing directives such as #define, #include, and #if/#endif. This support was first introduced in these versions of code generation tools:
- C2800 – 5.1.0
- C6000 – 6.1.0
- C5500 – 4.2.0
- MSP430 – 3.1.0
More details are in the <LINKER_README.tx> included with the code generation tools. Note that certain releases of code generation tools only work with a specific versions of BIOS as documented here, Compatibility_between_DSP/BIOS_versions_and_Code_Generation_Tools.
BIOS allows environment variables to be defined and accessed from a Tconf script. For example, this command defines global variable var1 for use within Tconf:
To access this variable within tconf, the following expression is used:
These environment variables are not to be confused with the System defined ones, these are only used by tconf during the configuration and build process.
Details are in DSP/BIOS 5.30 Textual Configuration (Tconf) User’s Guide (SPRU007), Section 2.2.1 "Environment Array Variables".
Using the above features of linker and DSP/BIOS, the RAM and Flash examples in SPRA958 are converted to single projects. The zip file attached with this article contains modified examples of BIOS and non-BIOS versions for F2812, F2808 and F28335 devices.
Versions of Tools used:
- Code Composer Studio 3.3 SR11 – 188.8.131.52
- BIOS 5.33.03
- C2000 Code Generation Tools 5.1.2
Ensure the following BIOS settings all point to 5.33.03:
- BIOS_INSTALL_DIR under System->Environment variables
- Version of BIOS selected within CCS component manager
- -Dconfig.importPath specified in Project Build Options under DspBiosBuilder tab is set to %BIOS_INSTALL_DIR%/packages
The migration steps are the same for the example projects for F2812, F2808 and F28335. The steps below describe the process used for the F2812 projects.
Non BIOS project (<F2812_example_nonBIOS.pj>)
- Start with F2812 non-BIOS example project <F2812_example_nonBIOS.pjt> which is in \spra958h\eZdspF2812\projects
- Copy <F2812_example_nonBIOS_flash.pjt> file to <F2812_example_nonBIOS.pjt>. The Flash version is used as starting point as the Flash projects include a couple of extra source files – <Flash.c> and <Passwords.asm>
- Open the <F2812_example_nonBIOS.pjt> in CCS. Create new CCS configurations of the project called Flash and RAM by copying over default settings from Debug configuration. This can be done from CCS menu Project->Configurations. Remove Debug configuration from project as it is not needed any more.
- Verify that <Flash.c> and <Passwords.asm> source files are included in the Flash configuration but are "excluded from build" in RAM configuration. This is done by right-clicking on the source file, going to File Specific Options, General tab and check "Exclude file from build".
- Combine <F2812_nonBIOS_flash.cmd> and <F2812_nonBIOS_ram.cmd> into one common linker command file <F2812_nonBIOS.cmd>, by keeping the common MEMORY directive and adding #ifdef directives for the SECTIONS allocation. For example, #ifdef SECTIONS_RAM or #ifdef SECTIONS_FLASH for RAM and Flash specific section allocations respectively. Add this linker command file to project in place of old ones.
- In Project build options, Compiler tab, make sure the preprocessor directives match the configuration, (ie) EXAMPLE_RAM or EXAMPLE_FLASH. This is set in the original projects based on the code. Also save the output files (set in -fs, -fr, -ft etc options) to /RAM or /Flash sub-directory.
- In Project build options, Linker tab, add --define=SECTIONS_FLASH=1 or SECTIONS_RAM=1 depending on configuration. This option is not available as a CCS GUI selection but can be added by typing them directly on the build command line.
- In Project build options, Linker tab, make sure the Output Filename and Map Filename are in /Flash or /RAM sub-directory and have appropriate filename for the specific configuration.
BIOS project (<F2812_example_BIOS.pjt>)
- Start with F2812 BIOS example project <F2812_example_BIOS.pjt> which is in \spra958h\eZdspF2812\projects
- Do steps 2 through 8 listed above for F2812_example_BIOS project files
- Copy <F2812_example_BIOS_flash.tcf> to <F2812_example_BIOS.tcf>. Edit <F2812_example_BIOS.tcf> to place Flash specific allocations into conditional block using directives like:
- Replace the .tcf file in both Flash and RAM configurations with <F2812_example_bios.tcf>
- Under Project Options for each configuration (RAM and Flash), do the following:
- in DspBiosbuilder->Advanced, under –Dconfig.programName, specify the file name for BIOS generated files for each configuration. For example, specify F2812_example_BIOS_flash for the Flash configuration and F2812_example_BIOS_ram for RAM configuration. Also under –Dname=value, add version=Flash for Flash version, leave it blank for RAM version.
- In Linker->Libraries, -l option, specify the BIOS generated *cfg.cmd file specific to each configuration. For example, specify <F2812_example_BIOS_flashcfg.cmd> for the Flash configuration and <F2812_example_BIOS_ramcfg.cmd> for the RAM configuration.
- Remove the file <F2812_example_BIOS_flashcfg.cmd> or <F2812_example_BIOS_ramcfg.cmd> from the project. Since the appropriate file will now be picked up from the –l option specified above, this file can be removed from project.
Editing the BIOS tcf file
The initial BIOS configuration for the project can still be created using the Graphical tool, however the .tcf file needs to be textually edited to access the environment variables defined using –Dname= option. For this example, the existing tcf files in the project were used as starting point.
If changes are made to the BIOS config using graphical editor, such as section allocation to memory regions, the changes are recorded in the .tcf file at the end of file and not necessarily within the if() code. So if, for example, changes are made to the Flash version using the graphical tool, they will not get saved within the if (environment["version"]=="Flash") block of code. User has to then manually edit the tcf file to ensure it is within the required conditionals.
The attached zip file contains the modified projects and demonstrates usage of linker preprocessing and environment variables in DSP/BIOS to enable conditional processing. Note that these examples have been minimally tested by running the code on eZdspF2812, eZdspF2808, and eZdspF28335 development boards and are provided “as-is”. Their main purpose is to demonstrate the functionality of the toolset.