Subversion Repositories DevTools

Rev

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

########################################################################
# Copyright (c) VIX TECHNOLOGY (AUST) LTD
#
# Module name   : MSP430.PL
# Module type   : Makefile system
# Compiler(s)   : Perl
# Environment(s): jats
#
# Description   : Toolset for the Texas Instruments CC Studio
#
#......................................................................#

use strict;
use JatsVersionUtils;

our $s;
our $o;
our $so;
our $exe;
our $tool_vxp430img;
our $itp_mode;
our $msp430_procdef;

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

ToolsetInit();

sub ToolsetInit
{
    my( $version, $product, @defines, @dirs, @flags, @asflags, @asdefines );

    #.. Parse Toolset Arguments
    #
    Debug( "msp430(@::ScmToolsetArgs)\n" );

    foreach $_ ( @::ScmToolsetArgs ) {
        if (/^--Version=(.*)/) {                # Compiler version
            $version = $1;
        } elsif ( /^--itp/ ) {
            $itp_mode = 1;
        } elsif ( /^--procFlags=(.+)/ ) {
            $msp430_procdef = $1;
        } else {
            Message( "msp430: unknown toolset argument $_ -- ignored\n" );
        }
    }

    #.. Parse Platform Arguments
    #
    foreach $_ ( @::ScmPlatformArgs ) {
        Message( "msp430: unknown platform argument $_ -- ignored\n" );
    }


    #.. Standard.rul requirements
    #
    $s = 'asm';             # Assembler source file
    $o = 'obj';             # Object file
    $a = 'lib';             # Library file
    $so = '';               # Shared library
    $exe = '.out';          # 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
#
#
#    ToolsetGenerate( "SomeFile" );


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

    ToolsetDefine ( "#################################################" );
    ToolsetDefine ( "# MSP430 compiler version" );
    ToolsetDefine ( "#" );
    ToolsetDefine ( "msp430_ver         = $version" );
    ToolsetDefine ( "" );
    ToolsetDefine ( "#" );
    ToolsetDefines( "msp430.def" );
    ToolsetRules  ( "msp430.rul" );
    ToolsetRules  ( "standard.rul" );

    # Support for ITP and different processor types
    ToolsetDefine ( "ITP_MODE = 1" )    if $itp_mode;
    ToolsetDefine ( "MSP430_PROCDEF = $msp430_procdef" )    if $msp430_procdef;
    
}


##############################################################################
#   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" );

    #
    #   Mark generated assembler files to be deleted
    #
    ToolsetGenerate( "\$(OBJDIR)/$_[1].asm" );
}

###############################################################################
#   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\$(CC)\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\$(CC)\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
#   Currently not supported
#   Add only if required
#
#{
#    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:
#       --Script=filename   Specify the name of a linker script file
#       --NoImg             Do not create IMG file, only COFF
#
#   Output:
#
#       name.map                - Map file
#       name.???
#       name.???
#       name.???
#
###############################################################################

sub ToolsetLD
{
    my( $name, $pArgs, $pObjs, $pLibs ) = @_;
    my $progName = $name;
    my $script;
    my $img_file = 1 unless $itp_mode;
    my $hex_file = 1 if $itp_mode;
    my $noVersion;



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

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

        } elsif (/^--NoImg/i ) {
            $img_file = undef;

        } elsif (/^--NoHex/i ) {
            $hex_file = undef;

        } elsif (/^--NoVersion/i ) {
            $noVersion = 1;

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

#
#   Sanity check
#       - Ensure a linker script has been provided
#
Error ("Cannot generate 'image' and 'hex' at the same time") if $hex_file and $img_file;
unless ( $script )
{
    $script = "$name.cmd";
    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 );

#
#   If creating an IMG file, then ensure that the tools are available
#
if ( $img_file )
{
    unless ( defined $tool_vxp430img )
    {
        $tool_vxp430img = ToolExtensionProgram( 'vxp430img', '.exe', '' );
        if ( $tool_vxp430img )
        {
            MakePrint ( "#################################################\n" );
            MakePrint ( "#  The path to tools required to build programs\n" );
            MakePrint ( "#\n" );
            MakePrint ( "TOOL_VXP430IMG := $tool_vxp430img\n" );
            MakePrint ( "\n" );
        }
        else
        {
            Error( 'Tool program required by toolset not found:',
                   'vxp430img',
                   'Check that the vxp430img package is present' );
        }
    }
}

#
#   Insert version number into the output name
#
    unless ( $noVersion )
    {
        $name .= "_\$(BUILDVERNUM)";
    }

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

#
#   Determine the target output name(s)
#
    my $root = "\$(BINDIR)/${name}";
    my $phonyProgName = "\$(BINDIR)/${progName}" . $::exe;
    my $full = $root . $::exe;
    my $img = $img_file ? $root . '.img' : '';
    my $hex = $root . '.hex';
    my $map = $root . '.map';

#
#   Add runtime support libaries
#   These are transparent to the user
#
    push @$pLibs, 'libc.a';

########################################################################
#
#   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
#
    unless ( $noVersion )
    {
        $io->Label( "Program", $progName );                     # label
        $io->Prt( ".PHONY:\t$phonyProgName\n" );                # Mark as phony
        $io->Prt( "$phonyProgName: \t$full\n" );                # Dependencies
        $io->Newline();
    }

    #
    #   Rules to generate the program
    #
    $io->Label( "Program", $name );                     # label
    $io->Prt( "$full $img $hex: \t$dep" );                   # Dependencies
    $io->Prt( "\\\n\t\t$script" );
    $io->Entry( "", "", "\\\n\t", ".$::o ", @$pObjs );  # Object Files
    $io->Prt( "\n\t\$(LD)" );
    $io->Prt( "\n\t\$(call COFF2IMG,$full,$img,\$(BUILDVER))\n" ) if ($img);
    $io->Prt( "\n\t\$(call COFF2HEX,$full,$hex)\n" ) if ($hex_file);
    $io->Newline();

    #
    #   Specify files created by the linker
    #   These will be added to the clean list
    #
    ToolsetGenerate( $full );
    ToolsetGenerate( $map );
    ToolsetGenerate( $root . '.ld' );
    ToolsetGenerate( $hex ) if ( $img || $hex_file) ;
    ToolsetGenerate( $img ) if ($img );

    #
    #   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 recipe
    #
    $io->SetTag( "${name}_ld" );                            # macro tag
    $io->Label( "Linker commands", $name );                 # label
    unless ( $itp_mode )
    {
        $io->Cmd("--stack_size=160");
        $io->Cmd("--heap_size=160");
        $io->Cmd("--use_hw_mpy=F5");
        $io->Cmd("--entry_point=main" );                        # Fixed entry point
    }
    else
    {
        $io->Cmd("--stack_size=50");
        $io->Cmd("--heap_size=0");
#        $io->Cmd("--symdebug:dwarf");
        $io->Cmd("--rom_model");

    }
        $io->Cmd("--warn_sections" );                           # Warn if creating unused sections
        $io->Cmd("-o $full" );                                  # Output file
        $io->Cmd("-m $map" );                                   # Map file
        $io->Cmd("--reread_libs" );                             # Multipass on lib files
        $io->Cmd("-l $script" );                                # User script file

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

    #
    #   Specify the library files
    #
    $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, $full );
    $io->LDDEPEND(); 

    #
    #   Add the MAP file to the program package
    #
    PackageProgAddFiles ( $progName, $full );
    PackageProgAddFiles ( $progName, $img ) if ($img);
    PackageProgAddFiles ( $progName, $hex ) if ($img || $hex_file );
    PackageProgAddFiles ( $progName, $map , 'Class=map' );
}

########################################################################
#
#   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) = @_;

    #
    #   Run time libraries will have a .a suffix
    #   Do not append .lib if this is the case
    #
    $lib .= '.' . $::a unless ( $lib =~ m~\.a$~ );


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

#.. Successful termination
1;