/** * Command to write the leJOS Virtual Machine and Menu system to the NXT Flash. */ package lejos.pc.tools; import lejos.pc.comm.*; import java.io.*; import java.io.PrintWriter; import java.io.StringWriter; import js.tinyvm.TinyVMException; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; /** * * @author andy */ /** * CommandLineParser */ class CommandLineParser { /** * Parse commandline. * * @param args * command line * @return the parsed commands * @throws TinyVMException */ public CommandLine parse(String[] args) throws TinyVMException { Options options = new Options(); options.addOption("h", "help", false, "help"); options.addOption("f", "format", false, "format file system"); options.addOption("v", "verify", false, "backward compatibility switch (verify is now default)"); options.addOption("q", "quiet", false, "quiet mode - do not report progress"); CommandLine result; try { try { result = new GnuParser().parse(options, args); } catch (ParseException e) { System.out.println("Parse error " + e); throw new TinyVMException(e.getMessage(), e); } if (result.hasOption("h")) throw new TinyVMException("Help:"); if (result.getArgs().length == 1) throw new TinyVMException( "Must provide firmware and menu files"); if (result.getArgs().length > 2) throw new TinyVMException("Too many files"); } catch (TinyVMException e) { StringWriter writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); printWriter.println(e.getMessage()); String commandName = System.getProperty("COMMAND_NAME", "java lejos.pc.tools.NXJFlash"); String usage = commandName + " [options] [firmware menu]"; new HelpFormatter().printHelp(printWriter, 80, usage.toString(), null, options, 0, 2, null); throw new TinyVMException(writer.toString()); } return result; } } public class NXJFlash implements NXJFlashUI { NXJFlashUpdate updater = new NXJFlashUpdate(this); public void message(String str) { System.out.println(str); } public void progress(String str, int percent) { System.out.printf("%s %3d%%\r", str, percent); System.out.flush(); } int getChoice() throws IOException { // flush any old input while (System.in.available() > 0) System.in.read(); char choice = (char) System.in.read(); // flush any old input while (System.in.available() > 0) System.in.read(); if (choice >= '0' && choice <= '9') return (int) (choice - '0'); return -1; } /** * Locate and open an NXT device ready for the firmware to be updated. First * we look for devices that are already in SAM-BA mode. If we do not find * any we look for devices in normal mode and attempt to re-boot them into * SAM-BA mode. * * @param commandLine * @return */ NXTSamba openDevice() throws NXTCommException, IOException { // First look to see if there are any devices already in SAM-BA mode NXTSamba samba = updater.openSambaDevice(0); // Look for devices in SAM-BA mode if (samba == null) { NXTInfo[] nxts; System.out .println("No devices in firmware update mode were found.\nSearching for other NXT devices."); NXTConnector conn = new NXTConnector(); nxts = conn.search(null, null, NXTCommFactory.USB); if (nxts.length <= 0) { System.out .println("No NXT found. Please check that the device is turned on and connected."); return null; } int devNo = 0; do { System.out .println("The following NXT devices have been found:"); for (int i = 0; i < nxts.length; i++) System.out.println(" " + (i + 1) + ": " + nxts[i].name + " " + nxts[i].deviceAddress); System.out .println("Select the device to update, or enter 0 to exit."); System.out.print("Device number to update: "); devNo = getChoice(); } while (devNo < 0 || devNo > nxts.length); if (devNo == 0) return null; updater.resetDevice(nxts[devNo - 1]); samba = updater.openSambaDevice(30000); } if (samba == null) System.out .println("No NXT found. Please check that the device is turned on and connected."); return samba; } /** * Run the flash command. * * @param args * the command line arguments * @throws Exception */ public void run(String[] args) throws Exception { CommandLineParser parser = new CommandLineParser(); CommandLine commandLine = parser.parse(args); String vmFile = null; String menuFile = null; if (commandLine.getArgs().length > 0) vmFile = commandLine.getArgs()[0]; if (commandLine.getArgs().length > 1) menuFile = commandLine.getArgs()[1]; String home = System.getProperty("nxj.home"); if (home == null) home = System.getenv("NXJ_HOME"); byte[] memoryImage = updater .createFirmwareImage(vmFile, menuFile, home); byte[] fs = null; if (commandLine.hasOption("f")) fs = updater.createFilesystemImage(); NXTSamba nxt = openDevice(); if (nxt != null) { updater.updateDevice(nxt, memoryImage, fs, true, true, true); } } /** * @param args * the command line arguments * @throws Exception */ public static void main(String[] args) throws Exception { try { NXJFlash instance = new NXJFlash(); instance.run(args); } catch (Throwable t) { System.err.println("an error occurred: " + t.getMessage()); } } }