tbuisp.in 3.69 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2004 University of Utah and the Flux Group.
# All rights reserved.
#

#
# tbuisp - An emulab frontend to UISP, which uploads programs to Mica motes
#

use lib '@prefix@/lib';
my $TB = '@prefix@';

use libdb;
use English;
use Getopt::Std;

use strict;

#
# Constants
#
my $UISP = "$TB/bin/uisp";
my $DEBUG = 1;

#
# Handle command-line arguments
# TODO: Allow a user to specify some of their own arguments to uisp
# TODO: Allow a user to reprogram all motes in an experiment
#
sub usage() {
    warn "Usage: $0 <operation> [filename] <motes...>\n";
    warn "Supported operations: upload\n";
    warn "[filename] is required with the 'upload' operation\n";
    return 1;
}

my $operation = shift @ARGV;
my $filename;
if (!$operation) {
    exit usage();
}
# Check the operation type
# XXX - support the other operations uisp supports, like downloading code
SWITCH: for ($operation) {
    /^upload$/ && do {
	$filename = shift @ARGV;
	if (!$filename) {
	    exit usage();
	}
	last SWITCH;
    };
    
    # Default
    warn "Uknown operation $operation\n";
    exit usage();
}

# They have to give us at least one mote
my @motes = @ARGV;
if (!@motes) {
    exit usage();
}

#
# Permission check
#
if (!TBNodeAccessCheck($UID,TB_NODEACCESS_LOADIMAGE,@motes)) {
    die "You do not have permission to modify one or more nodes\n";
}

#
# Check the file to make sure it's readable
#
if ($filename) {
    if (!-r $filename) {
	die "$filename not readable\n";
    }
}

#
# Program each mote
#
my $errors = 0;
MOTE: foreach my $mote (@motes) {
    #
    # Figure out the parameters we need to pass to uisp for this mote
    #
    my @uisp_args;

92 93 94 95 96
    #
    # Make sure they gave us an actual mote
    #
    my ($motetype, $moteclass) = TBNodeType($mote);
    if ($moteclass ne "mote") {
97 98 99 100 101
	warn "$mote is not a mote - skipping\n";
	$errors++;
	next MOTE;
    }

102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
    #
    # Find out the type of the mote's host, which we use for actual programming
    #
    my $host;
    if (!TBPhysNodeID($mote,\$host)) {
	warn "Error getting host for $mote - skipping\n";
	$errors++;
	next MOTE;
    }
    if ($host eq $mote) {
	warn "Error - no host found for $mote - skipping\n";
	$errors++;
	next MOTE;
    }
    my ($hosttype, $hostclass) = TBNodeType($host);

118 119 120
    #
    # Figure out how we talk to the programming board, and what chipset it has
    #
121
    TSWITCH: for ($hosttype) {
122 123 124 125
	/^emote$/ && do {
	    # Crossbow MIB600CA

	    # The name of the host to communicate with
126
	    push @uisp_args, "-dhost=$host";
127 128 129 130 131
	    # The type of programming board on a emote
	    push @uisp_args, "-dprog=stk500";
	    last TSWITCH;
	};
	# Default
132 133
	warn "Mote host $host for $mote has unsupported type $hosttype " .
	    "- skipping";
134 135 136 137 138 139 140
	$errors++;
	next MOTE;
    }

    #
    # Find the name of the microcontroller on the board
    #
141
    my ($proc, $speed) = TBNodeTypeProcInfo($motetype);
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
    PSWITCH: for ($proc) {
	/^ATmega128/i && do {
	    push @uisp_args, "-dpart=ATmega128";
	    last PSWITCH;
	};
	# Default
	warn "Unsupported processor $proc for $mote - skipping\n";
	$errors++;
	next MOTE;
    }

    #
    # The operation we want to perform
    #
    my $opstring;
    OSWITCH: for ($operation) {
	/^upload$/ && do {
	    $opstring = "--wr_fuse_e=ff --erase --upload if=$filename";
	    last OSWITCH;
	};

	# No default, we've checked for a valid operation above
    }

    #
    # Actually run uisp
    # TODO - Squelch output
    # TODO - Allow for some parallelism
    #
    print "Uploading code to $mote\n";
    my $commandstr = "$UISP " . join(" ",@uisp_args,$opstring);
    dprint("$commandstr\n");
    if (system($commandstr)) {
    }
}

if ($errors) {
    exit 1;
} else {
    exit 0;
}

sub dprint(@) {
    if ($DEBUG) {
	print @_;
    }
}