Subversion Repositories DevTools

Rev

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

#..
# Copyright (c) VIX TECHNOLOGY (AUST) LTD
#
# Module name   : avr_air
# 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 AVR
#
# Revision History:
#       16-Aug-04   DDP     Created
#       13-Jul-06   DCP     Added AT90SC7272C chipset
#       02-Oct-07   DCP     Added AT90SC144144CT chipset
#............................................................................#

use strict;
use JatsVersionUtils;

our $s;
our $o;
our $so;
our $exe;
our $ScmBuildVersionFull;

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

ToolsetInit();

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

    #.. Parse arguments
    #
    Debug( "avr_iar(@args)\n" );

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

    #.. Parse Platform Arguments
    #
    @args = @::ScmPlatformArgs;                 # Platform arguments
    foreach $_ ( @args ) {
        if (/^--product=(.*)/) {                # GBE product
            $product = $1;
        } else {
            Message( "avr_iar: 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/clib';
    push @dirs,    '$(COMPILER_HOME_AVR)/inc';

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

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

        #   Assembler flags and definitions
        push @asdefines, '_AT90SC3232CS';
    }
    elsif ( $product eq "AT90SC7272C" )
    {
        $productFound = $product;
        push @flags , '--eeprom_size=65536';    # maximum size allowed by IAR

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

        #   Assembler flags and definitions
        push @asdefines, '_AT90SC7272C';
    }
    elsif ( $product eq "AT90SC144144CT" )
    {
        $productFound = $product;
        push @flags , '--eeprom_size=65536';    # maximum size allowed by IAR

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

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

    # common flags
    if ( $productFound )
    {
        #
        #   Compiler flags and definitions
        #
        push @flags , '-v6';
        push @flags , '-ms';
        push @flags , '-y';
        push @flags , '--enhanced_core';
        push @flags , '--diag_suppress=pa050';
        push @flags , '--initializers_in_flash';
        push @flags , '--require_prototypes';

        push @defines, '_EEP_EOW_MODE=IDLE_EEP_WRITE';


        #
        #   Assembler flags and definitions
        #
        push @asflags , '-v6';                  # processor configuration
        push @asflags , '-s+';                  # Case-sensitive user symbols
        push @asflags , '-t8';                  # tab spacing...
        push @asflags , '-u_enhancedCore';      # enable AVR-specific enhanced instructions

        push @asdefines, '__MEMORY_MODEL__=2';
        push @asdefines, '__HAS_ELPM__=1 ';
        push @asdefines, '__HAS_ENHANCED_CORE__=1 ';
        push @asdefines, 'ASSEMBLER';
    }

    #.. Standard.rul requirements
    #
    $s = 's90';             # Assembler source file
    $o = 'r90';             # Object file
    $a = 'r90';             # Library file
    $so = '';               # Shared library
    $exe = '.s19';          # 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
#
#   9 Files that appear to be created by the USB licence dongle
#
    ToolsetGenerate( "clauth1.dll" );
    ToolsetGenerate( "clauth2.dll" );
    ToolsetGenerate( "lsprst7.dll" );
    ToolsetGenerate( "lsprst7.tgz" );
    ToolsetGenerate( "ssprs.dll" );
    ToolsetGenerate( "ssprs.tgz" );
    ToolsetGenerate( "sysprs7.dll" );
    ToolsetGenerate( "sysprs7.tgz" );
    ToolsetGenerate( "tmpPrst.tgz" );


    #.. Define IAR environment
    #
    #
    #   Define initialisation targets
    #   These will be used to ensure that correct versions of the toolset are present
    #
    Init( "iar" );

    ToolsetDefine ( "#################################################" );
    ToolsetDefine ( "# AVR IAR compiler version" );
    ToolsetDefine ( "#" );
    ToolsetDefine ( "avr_iar_ver         = $version" );
    ToolsetDefine ( "avr_iar_prod        = $product" );
    ToolsetDefine ( "" );
    ToolsetDefine ( "#" );
    ToolsetDefines( "avr_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
#
#   Output:
#
#       name.map                - Loadable module
#       name.s19                -
#       name.d90                -
#       name.sxml               - Wrapped s19 file
#
#   Linker Flags
#
#       -O[format]=filename         Specify output filename and format
#       -o filename                 Specify an output file
#       -r                          Output file indebug format
#       -z                          Reduce segment overlap errors
#       -l filename                 Generate a listing file
#       -xmsn                       Add info to the map file
#       -Pnnn                       Number of line per page
#       -Ipath                      Specify a path to search for object files
#       -f filename                 Read arguments from file
#       -C filename                 Load filename as a library

###############################################################################

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


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

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

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

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

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

#
#   Sanity check
#       - Ensure a linker script has been provided
#
unless ( $script )
{
    $script = "$name.xcl";
    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 $d90 = $root . '.d90';
    my $s19 = $root . '.s19';
    

########################################################################
#
#   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)\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( $d90 );
    ToolsetGenerate( $map );
    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("-Omotorola=$s19" );                           # Output file
    $io->Cmd("-o $d90" );                                   # Output file
    $io->Cmd("-l $map" );                                   # Map file
    $io->Cmd("-r" );                                        # Output with debug
    $io->Cmd("-z" );                                        # Reduce segment overlap errors
    $io->Cmd("-xmsn" );                                     # Add info to the map file
    $io->Cmd("-p100" );                                     # Number of line per page
    $io->Cmd("-f $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, $s19 );
    $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: $s19\n");
    $io->Prt( "\t\$(call GENERATE_SXML, \\" .
              "\n\t\t\$(BINDIR)/${name}$exe, \\" .
              "\n\t\t$sxml,$type_text,$major,$minor,$patch,$build,Atmel)\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("-C @(vpath2,\"$lib.$::a\",IAR_LIB)" );
    } else {                                    # depend
        $io->Cmd( "$dp:\t@(vlib2,\"$lib.$::a\",IAR_LIB)" );
    }
}

#.. Successful termination
1;