Subversion Repositories DevTools

Rev

Rev 5830 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#..
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
#
# Module name   : CORTEXM3_IAR.PL
# Module type   : Makefile system
# Compiler(s)   : ANSI C
# Environment(s): Atmel AVR
#
# Description:
#       This file provides Toolset initialisation and plugin functions
#       to makelib.pl2
#
# Contents:     IAR rules as used for the CORTEXM3
#               Similar to the AVR_IAR
#
#............................................................................#

use strict;
use JatsVersionUtils;

our $s;
our $o;
our $so;
our $exe;
my $ToolSetName = 'cortexm3_iar';

##############################################################################
#   ToolsetInit()
#       Runtime initialisation
#
##############################################################################

ToolsetInit();

sub ToolsetInit
{
    my( @args ) = @::ScmToolsetArgs;             # Toolset arguments
    my( $version, $product, @defines, @dirs, @flags, @asflags, @asdefines );
    my $productFound;

    #.. Parse arguments
    #
    Debug( "$ToolSetName:(@args)\n" );

    foreach $_ ( @args ) {
        if (/^--Version=(.*)/) {                # Compiler version
            $version = "$1";
        } else {
            Message( "$ToolSetName: unknown toolset argument $_ -- ignored\n" );
        }
    }

    #.. Parse Platform Arguments
    #
    @args = @::ScmPlatformArgs;                 # Platform arguments
    foreach $_ ( @args ) {
        if (/^--product=(.*)/) {                # GBE product
            $product = $1;
        } else {
            Message( "$ToolSetName: unknown platform argument $_ -- ignored\n" );
        }
    }

    #
    #   Definitions common to all products
    #   These will be picked up when no platform has been defined
    #
    push @defines, 'JATS_BUILD';
    push @dirs,    '$(COMPILER_HOME_AVR)/inc/c';
    push @dirs,    '$(COMPILER_HOME_AVR)/inc';

    #
    #   Platform specific definitions
    #
    if ( $product eq "MS6001" )
    {
        $productFound = $product;
        #push @flags , '--eeprom_size=32768';

        #   Compiler flags and definitions
        push @defines, '_MS6001';

        #   Assembler flags and definitions
        push @asdefines, '_MS6001';
    }
    elsif ( $product )
    {
        Message( "$ToolSetName: Unknown product: $product -- ignored\n" );
    }

    # common flags
    if ( $productFound )
    {
        #
        #   Compiler flags and definitions
        #
       push @flags , '--endian=little';
       push @flags , '--cpu=Cortex-M3';
       push @flags , '--diag_suppress=Pa050,Pa091';
       push @flags , '-e';
       push @flags , '--fpu=None';
       push @flags , '-Oh';
       push @flags , '--vla';
       push @flags , '--require_prototypes';
       push @flags , '--remarks';
       push @flags , '--dlib_config=DLib_Config_Normal.h';

       # Defines
       #push @defines, 'xxxxxx';


        #
        #   Assembler flags and definitions
        #

      push @asflags , '-s+';                    # Case-sensitive user symbols
      push @asflags , '-w+';                    # enable all warnings
      push @asflags , '-r';                     # generate debug information
      push @asflags , '--cpu Cortex-M3';
      push @asflags , '--fpu None';

      # Assember Defines
      #push @asdefines, 'xxxx';
    }

    #.. Standard.rul requirements
    #
    $s = 's';               # Assembler source file
    $o = 'o';               # Object file
    $a = 'a';               # Library file
    $so = '';               # Shared library
    $exe = '.srec';         # Linked binary images

    AddSourceType( ".$s", '.asm' );
    

    #.. Toolset configuration
    #
    $::ScmToolsetVersion = "1.0.0";               # our version
    $::ScmToolsetGenerate = 0;                    # generate optional
    $::ScmToolsetProgDependancies = 0;            # handle Prog dependancies myself

#.. Cleanup rules
#
#   Files that appear to be created by the compiler
#
   ToolsetGenerate( '$(OBJDIR)/tmp*' );
   ToolsetGenerate( '$(LIBDIR)/tmp*' );
   ToolsetGenerate( '$(BINDIR)/tmp*' );

    #.. Define IAR environment
    #
    #
    #   Define initialisation targets
    #   These will be used to ensure that correct versions of the toolset are present
    #   Retain 'avr_air' so we can reuse the .RUL file
    #
    Init( "cortexm3" );

    ToolsetDefine ( "#################################################" );
    ToolsetDefine ( "# CORTEX IAR compiler version" );
    ToolsetDefine ( "#" );
    ToolsetDefine ( "avr_iar_ver         = $version" );
    ToolsetDefine ( "avr_iar_prod        = $product" );
    ToolsetDefine ( "" );
    ToolsetDefine ( "#" );
    ToolsetDefines( "cortexm3_iar.def" );
    ToolsetRules  ( "avr_iar.rul" );
    ToolsetRules  ( "standard.rul" );

    #
    #   Specify compiler parameters
    #   Note: AVR_IAR_INCLUDES is ";" seperated as it may contain spaces
    #         when expanded ("Program Files")
    #

    PlatformEntry( "AVR_IAR_DEFINES\t=",    "\n", "\\\n\t", "", @defines )
        if ( scalar @defines );
    PlatformEntry( "AVR_IAR_INCLUDES\t=",    "\n", "\\\n\t", ";", @dirs )
        if ( scalar @dirs );
    PlatformEntry( "AVR_IAR_FLAGS\t=",    "\n", "\\\n\t", "", @flags )
        if ( scalar @flags );

    PlatformEntry( "AVR_IAR_ASFLAGS\t=",    "\n", "\\\n\t", "", @asflags )
        if ( scalar @asflags );
    PlatformEntry( "AVR_IAR_ASDEFINES\t=",    "\n", "\\\n\t", "", @asdefines )
        if ( scalar @asdefines );

}


##############################################################################
#   ToolsetPreprocess()
#       Process collected data before the makefile is generated
#       This, optional, routine is called from within MakefileGenerate()
#       It allows the toolset to massage any of the collected data before
#       the makefile is created
#
##############################################################################

#sub ToolsetPreprocess
#{
#}

###############################################################################
#   ToolsetCC( $source, $obj, \@args )
#       This subroutine takes the user options and builds the rule(s)
#       required to compile the source file 'source' to 'obj'
#
###############################################################################

sub ToolsetCC
{
    MakePrint( "\n\t\$(CC)\n" );
}

###############################################################################
#   ToolsetCCDepend( $depend, \@sources )
#       This subroutine takes the user options and builds the
#       rule(s) required to build the dependencies for the source
#       files 'sources' to 'depend'.
#
###############################################################################

sub ToolsetCCDepend
{
    MakePrint( "\t\$(CCDEPEND)\n" );
}


###############################################################################
#   ToolsetCXX( $source, $obj, \@args )
#       This subroutine takes the user options and builds the rule(s)
#       required to compile the source file 'source' to 'obj'
#
###############################################################################

sub ToolsetCXX
{
    MakePrint( "\n\t\$(CXX)\n" );
}

###############################################################################
#   ToolsetCXXDepend( $depend, \@sources )
#       This subroutine takes the user options and builds the
#       rule(s) required to build the dependencies for the source
#       files 'sources' to 'depend'.
#
###############################################################################

sub ToolsetCXXDepend
{
    ToolsetCCDepend();
}


###############################################################################
#   ToolsetAS( $source, $obj, \@args )
#       This subroutine takes the user options and builds the rule(s)
#       required to compile the source file 'source' to 'obj'
#
###############################################################################

sub ToolsetAS
{
    MakePrint( "\n\t\$(AS)\n" );
}

sub ToolsetASDepend
{
}

###############################################################################
#   ToolsetAR( $name, \@args, \@objs )
#       This subroutine takes the user options and builds the rules
#       required to build the library 'name'.

#
#   Arguments:
#       --xxx                   No arguments currently defined
#
#   Output:
#       [ $(BINDIR)/name$.${a}:   .... ]
#           $(AR)
#
###############################################################################

sub ToolsetAR
{
    my( $name, $pArgs, $pObjs ) = @_;

    Debug("ToolsetAR");

#.. Parse arguments
#
    foreach $_ ( @$pArgs ) {
        if (/^--/) {
            Message( "AR: unknown option $_ -- ignored\n" );
        }
    }

#.. Target
#
    MakeEntry( "\$(LIBDIR)/$name\$(GBE_TYPE).${a}:\t", "", " \\\n\t\t", ".${o}", @$pObjs );

#.. Build library rule (just append to standard rule)
#
    MakePrint( "\n\t\$(AR)\n\n" );
}


###############################################################################
#   ToolsetARMerge()
#       Generate the recipe to merge libraries.
#       The dependency list is created by the caller.
#
###############################################################################

sub ToolsetARMerge
{
    MakePrint( "\n\t\$(ARMERGE)\n\n" );
}


###############################################################################
#   ToolsetLD( $name, \@args, \@objs, \@libraries )
#       This subroutine takes the user options and builds the rules
#       required to link the program 'name'.
#
#   Arguments:
#       --xxx                   No Arguments currently specified
#
#       Linker specific:
#       --LinkScript=filename   Specify the name of a linker script file
#       --Loader=filename       Specify a loader file to be merged
#                               This will be a program
#       --Type=typetext         Text to be placed in type field
#       --Entry=Name            Alternate Program Entry Point
#       --CrcRange=Text         Text used in the elftool command for fill and checksum ranges
#                               ie: app_start-app_checksum_end+3
#
#   Output:
#
#       name.map                - Loadable module
#       name.out                - Output from the linker
#       name.srec               - Output from the elftool
#       name.d90                -
#       name.sxml               - Wrapped srec file
#
###############################################################################

sub ToolsetLD
{
    my( $name, $pArgs, $pObjs, $pLibs ) = @_;
    my( $script );
    my( $loader, $loader_file);
    my  $type_text = '';
    my  $entyPoint = '__iar_program_start';
    my $crcRange;


#.. Parse arguments
#
    foreach $_ ( @$pArgs )
    {
    #.. Target specific
    #

    #.. Toolset specific
    #
        if (/^--Script=(.*)/) {           # External file
            $script = $1;
            $script .= ".icf" unless ( $script =~ m~\.icf$~ );

        } elsif ( /^--ProgLoader=(.*)/ ) {   # Loader/Burner file
            $loader = $1;
            $loader =~ s~$exe$~~;

        } elsif ( /^--Type=(.*)/ ) {        # Type of Payload
            $type_text = $1;

        } elsif ( /^--Entry=(.*)/ ) {        # Entry Point
            $entyPoint = $1;

        } elsif ( /^--CrcRange=(.*)/ ) {     # Crc Range
            $crcRange = $1;

        } else {
            Message( "Prog: unknown option $_ -- ignored\n" );
        }
    }

#
#   Sanity check
#       - Ensure a linker script has been provided
#
unless ( $script )
{
    $script = "$name.icf";
    Warning( "Prog: Linker Script file not provided. Using $script" );
}

#
#   Locate the true path of the provided script file
#   If it is a generate file so it will be in the SRCS hash
#   Other wise the use will have to use Src to locate the file
#
    $script = MakeSrcResolve ( $script );

#
#   Locate the loader file, if it has been provided
#   The file must be a program and should be created within this makefile
#
if ( $loader )
{
    if ( $::PROGS->Get( $loader) )
    {
        $loader_file = "\$(BINDIR)/$loader$exe";
    }
    elsif ( $::SRCS{$loader} )
    {
        $loader_file = $::SRCS{$loader};
    }
    else
    {
        Error ("Prog: ProgLoader file not found" );
    }
}

#
#   Extend the list of libraries with compiler specific libraries
#
#    push( @$pLibs, "\$(avr_linker_lib)" );

#
#   Create a ToolsetPrinter
#
    my ($io) = ToolsetPrinter::New();
    my $dep = $io->SetLdTarget( $name );

#
#   Determine the target output name
#
    my $root = "\$(BINDIR)/$name";
    my $full = $root . $::exe;
    my $map = $root . '.map';
    my $log = $root . '.log';
    my $out = $root . '.out';
    my $srec = $root . '.srec';
    

########################################################################
#
#   Before this function was called, makelib.pl2 has generated a
#   partial rule consisting of:
#
#       $(BINDIR)/${name}${exe} :
#               All the specified object files
#
#   Add the names of all the other files required in the process
#   This will then serve as a target fo all things that need to be
#   created when a "program" is required
#
#       These are:
#               User linker script file
#               Library dependency file
# 
    $io->Label( "Program", $name );                     # label
    $io->Prt( "$full : \t$dep" );                       # Dependencies
    $io->Prt( "\\\n\t\t$script" );
    $io->Prt( " \\\n\t\t$loader_file" ) if ($loader_file);
    $io->Entry( "", "", "\\\n\t", ".$::o ", @$pObjs );  # Object Files
    $io->Prt( "\n\t\$(LD_IAR)" );

    #
    #   Convert elf to srec file
    #   (if $3,--fill 0xFF;$3 --checksum checksum:4\,crc32\,0xFFFFFFFF;$3)
    #
    my  $sRecRange = '';
    if ($crcRange)
    {
        $sRecRange = "--fill \"0xFF;$crcRange\" --checksum \"checksum:4\$(comma)crc32\$(comma)0xFFFFFFFF;$crcRange\"" 
    }
    $io->Prt( "\n\t\$(call GENERATE_SREC, \\" .
              "\n\t\t$out, \\" .
              "\n\t\t$full, \\" .
              "\n\t\t$sRecRange)\n");

    #
    #   Insert post processing call if a program loader is needed
    #
    $io->Prt( "\t\$(call LD_IAR_PROCESS, \\" .
              "\n\t\t$full, \\" .
              "\n\t\t$loader_file)\n"
            ) if ($loader_file);

    $io->Newline();

    #
    #   Specify files created by the linker
    #   These will be added to the clean list
    #
    ToolsetGenerate( $map );
    ToolsetGenerate( $log );
    ToolsetGenerate( $out );
    ToolsetGenerate( $srec );
    ToolsetGenerate( "$full.keep" );

    #
    #   Create a linker command file
    #   Piecing together a variable $(name_ld) which ends up in the command file.
    #   This bit of magic will be performed by the LD_IAR recipe
    #
    $io->SetTag( "${name}_ld" );                            # macro tag
    $io->Label( "Linker commands", $name );                 # label

#    $io->Cmd("-S" );                                       # Silent
    $io->Cmd("-o $out" );                                   # Output file
    $io->Cmd("--map $map" );                                # Map file
                                                            # Configue Logging
    $io->Cmd("--log libraries,initialization,modules,redirects,sections,veneers,unused_fragments,call_graph" );
    $io->Cmd("--log_file $log" );                           # Log file
    $io->Cmd("--semihosting" );
    $io->Cmd("--entry $entyPoint" );
    $io->Cmd("--inline" );
    $io->Cmd("--vfe" );
    $io->Cmd("--config $script" );                          # User script file

    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );      # Object files

    #
    #   Specify the library files
    #
#    $io->Cmd( '"-I$(avr_linker_lib_dir)"' );                # Toolset library directory
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );      # Specify the libraries too
    $io->Newline();

    #.. Dependency link,
    #   Create a library dependency file
    #       Create command file to build applicaton dependency list
    #       from the list of dependent libraries
    #
    #       Create makefile directives to include the dependency
    #       list into the makefile.
    #
    $io->DepRules( $pLibs, \&ToolsetLibRecipe, $out );
    $io->LDDEPEND(); 

    #
    #   Add the MAP file to the program package
    #
    PackageProgAddFiles ( $name, $full );
    PackageProgAddFiles ( $name, $map , 'Class=map' );

    #
    #   Create the .sxml file
    #
    my $sxml = "\$(BINDIR)/${name}.sxml";
    my ($major, $minor, $patch, $build, $raw_patch) = SplitVersion($ScmBuildVersionFull);

    $io->Label( "SXML File", $name );
    $io->Prt( "$sxml: $srec\n");
    $io->Prt( "\t\$(call GENERATE_SXML, \\" .
              "\n\t\t\$(BINDIR)/${name}$exe, \\" .
              "\n\t\t$sxml,$type_text,$major,$minor,$patch,$build,InsideSecure)\n"
              );
    $io->Newline();

    #
    #   Generated files to be added to the program file list
    #
    ToolsetGenerate( $sxml );
    PackageProgAddFiles( $name, $sxml, 'Class=extras' );
    ProgAddExtra( $name, $sxml );

}

########################################################################
#
#   Generate a linker object recipe.  This is a helper function used 
#   within this toolset.
#
#   Arguments:
#       $io         I/O stream
#
#       $target     Name of the target
#
#       $obj        Library specification
#
########################################################################

sub ToolsetObjRecipe
{
    my ($io, $target, $obj) = @_;

    $io->Cmd("$obj.$::o" );
}

########################################################################
#
#   Generate a linker/depend library recipe.  This is a helper function
#   used within this toolset.
#
#   Arguments:
#       $io         I/O stream
#
#       $target     Name of the target
#
#       $lib        Library specification
#
#       $dp         If building a depend list, the full target name.
#
########################################################################

sub ToolsetLibRecipe
{
    my ($io, $target, $lib, $dp) = @_;

    if ( !defined($dp) ) {                      # linker
        $io->Cmd("--semihosting @(vpath2,\"$lib.$::a\",IAR_LIB)" );
    } else {                                    # depend
        $io->Cmd( "$dp:\t@(vlib2,\"$lib.$::a\",IAR_LIB)" );
    }
}

#.. Successful termination
1;