mirror of
https://github.com/arduino/Arduino.git
synced 2025-03-14 11:29:26 +01:00
First refactoring of uploaders
This commit is contained in:
parent
6b05276b7e
commit
4b0a976686
137
app/src/cc/arduino/packages/Uploader.java
Normal file
137
app/src/cc/arduino/packages/Uploader.java
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Uploader - abstract uploading baseclass (common to both uisp and avrdude)
|
||||||
|
Part of the Arduino project - http://www.arduino.cc/
|
||||||
|
|
||||||
|
Copyright (c) 2004-05
|
||||||
|
Hernando Barragan
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
$Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cc.arduino.packages;
|
||||||
|
|
||||||
|
import static processing.app.I18n._;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import processing.app.I18n;
|
||||||
|
import processing.app.Preferences;
|
||||||
|
import processing.app.debug.MessageConsumer;
|
||||||
|
import processing.app.debug.MessageSiphon;
|
||||||
|
import processing.app.debug.RunnerException;
|
||||||
|
|
||||||
|
public abstract class Uploader implements MessageConsumer {
|
||||||
|
|
||||||
|
private String error = null;
|
||||||
|
|
||||||
|
protected boolean verbose = Preferences.getBoolean("upload.verbose");
|
||||||
|
|
||||||
|
public abstract boolean uploadUsingPreferences(String buildPath, String className, boolean usingProgrammer)
|
||||||
|
throws RunnerException;
|
||||||
|
|
||||||
|
public abstract boolean burnBootloader() throws RunnerException;
|
||||||
|
|
||||||
|
public boolean requiresAuthorization() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthorizationKey() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean executeUploadCommand(Collection<String> command)
|
||||||
|
throws RunnerException {
|
||||||
|
return executeUploadCommand(command.toArray(new String[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean executeUploadCommand(String command[])
|
||||||
|
throws RunnerException {
|
||||||
|
notFoundError = false;
|
||||||
|
int result = -1;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (verbose) {
|
||||||
|
for (String c : command)
|
||||||
|
System.out.print(c + " ");
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
Process process = Runtime.getRuntime().exec(command);
|
||||||
|
new MessageSiphon(process.getInputStream(), this);
|
||||||
|
new MessageSiphon(process.getErrorStream(), this);
|
||||||
|
|
||||||
|
// wait for the process to finish.
|
||||||
|
result = process.waitFor();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error != null) {
|
||||||
|
RunnerException exception = new RunnerException(error);
|
||||||
|
exception.hideStackTrace();
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean notFoundError;
|
||||||
|
|
||||||
|
public void message(String s) {
|
||||||
|
// selectively suppress a bunch of avrdude output for AVR109/Caterina that should already be quelled but isn't
|
||||||
|
if (!verbose && (
|
||||||
|
s.indexOf("Connecting to programmer:") != -1 ||
|
||||||
|
s.indexOf("Found programmer: Id = \"CATERIN\"; type = S") != -1 ||
|
||||||
|
s.indexOf("Software Version = 1.0; No Hardware Version given.") != -1 ||
|
||||||
|
s.indexOf("Programmer supports auto addr increment.") != -1 ||
|
||||||
|
s.indexOf("Programmer supports buffered memory access with buffersize=128 bytes.") != -1 ||
|
||||||
|
s.indexOf("Programmer supports the following devices:") != -1 ||
|
||||||
|
s.indexOf("Device code: 0x44") != -1))
|
||||||
|
s = "";
|
||||||
|
|
||||||
|
System.err.print(s);
|
||||||
|
|
||||||
|
// ignore cautions
|
||||||
|
if (s.contains("Error")) {
|
||||||
|
notFoundError = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (notFoundError) {
|
||||||
|
error = I18n.format(_("the selected serial port {0} does not exist or your board is not connected"), s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (s.contains("Device is not responding")) {
|
||||||
|
error = _("Device is not responding, check the right serial port is selected or RESET the board right before exporting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (s.contains("Programmer is not responding") ||
|
||||||
|
s.contains("programmer is not responding") ||
|
||||||
|
s.contains("protocol error") ||
|
||||||
|
s.contains("avrdude: ser_open(): can't open device") ||
|
||||||
|
s.contains("avrdude: ser_drain(): read error") ||
|
||||||
|
s.contains("avrdude: ser_send(): write error") ||
|
||||||
|
s.contains("avrdude: error: buffered memory access not supported.")) {
|
||||||
|
error = _("Problem uploading to board. See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (s.contains("Expected signature")) {
|
||||||
|
error = _("Wrong microcontroller found. Did you select the right board from the Tools > Board menu?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,20 +1,22 @@
|
|||||||
package processing.app;
|
package cc.arduino.packages;
|
||||||
|
|
||||||
import processing.app.debug.BasicUploader;
|
import processing.app.AbstractMonitor;
|
||||||
import processing.app.debug.HttpUploader;
|
import processing.app.Base;
|
||||||
|
import processing.app.Constants;
|
||||||
|
import processing.app.NetworkMonitor;
|
||||||
|
import processing.app.SerialMonitor;
|
||||||
import processing.app.debug.TargetBoard;
|
import processing.app.debug.TargetBoard;
|
||||||
import processing.app.debug.Uploader;
|
import cc.arduino.packages.uploaders.HttpUploader;
|
||||||
|
import cc.arduino.packages.uploaders.SerialUploader;
|
||||||
|
|
||||||
import java.util.regex.Pattern;
|
public class UploaderFactory {
|
||||||
|
|
||||||
public class PerPortObjectFactory {
|
|
||||||
|
|
||||||
public Uploader newUploader(TargetBoard board, String port) {
|
public Uploader newUploader(TargetBoard board, String port) {
|
||||||
if ("true".equals(board.getPreferences().get("upload.via_http")) && Constants.IPV4_ADDRESS.matcher(port).find()) {
|
if ("true".equals(board.getPreferences().get("upload.via_http")) && Constants.IPV4_ADDRESS.matcher(port).find()) {
|
||||||
return new HttpUploader(port);
|
return new HttpUploader(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BasicUploader();
|
return new SerialUploader();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractMonitor newMonitor(String port, Base base) {
|
public AbstractMonitor newMonitor(String port, Base base) {
|
@ -1,4 +1,4 @@
|
|||||||
package processing.app.debug;
|
package cc.arduino.packages.uploaders;
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import org.apache.commons.httpclient.HttpClient;
|
import org.apache.commons.httpclient.HttpClient;
|
||||||
@ -6,9 +6,14 @@ import org.apache.commons.httpclient.HttpStatus;
|
|||||||
import org.apache.commons.httpclient.NameValuePair;
|
import org.apache.commons.httpclient.NameValuePair;
|
||||||
import org.apache.commons.httpclient.methods.GetMethod;
|
import org.apache.commons.httpclient.methods.GetMethod;
|
||||||
import org.apache.commons.httpclient.methods.PostMethod;
|
import org.apache.commons.httpclient.methods.PostMethod;
|
||||||
|
|
||||||
|
import cc.arduino.packages.Uploader;
|
||||||
|
|
||||||
import processing.app.Base;
|
import processing.app.Base;
|
||||||
import processing.app.Constants;
|
import processing.app.Constants;
|
||||||
import processing.app.Preferences;
|
import processing.app.Preferences;
|
||||||
|
import processing.app.debug.RunnerException;
|
||||||
|
import processing.app.debug.TargetPlatform;
|
||||||
import processing.app.helpers.PreferencesMap;
|
import processing.app.helpers.PreferencesMap;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
@ -1,7 +1,322 @@
|
|||||||
|
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
BasicUploader - generic command line uploader implementation
|
||||||
|
Part of the Arduino project - http://www.arduino.cc/
|
||||||
|
|
||||||
|
Copyright (c) 2004-05
|
||||||
|
Hernando Barragan
|
||||||
|
Copyright (c) 2012
|
||||||
|
Cristian Maglie <c.maglie@bug.st>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
$Id$
|
||||||
|
*/
|
||||||
|
|
||||||
package cc.arduino.packages.uploaders;
|
package cc.arduino.packages.uploaders;
|
||||||
|
|
||||||
|
import static processing.app.I18n._;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import cc.arduino.packages.Uploader;
|
import cc.arduino.packages.Uploader;
|
||||||
|
|
||||||
public class SerialUploader implements Uploader {
|
import processing.app.Base;
|
||||||
|
import processing.app.I18n;
|
||||||
|
import processing.app.Preferences;
|
||||||
|
import processing.app.Serial;
|
||||||
|
import processing.app.SerialException;
|
||||||
|
import processing.app.debug.RunnerException;
|
||||||
|
import processing.app.debug.TargetPlatform;
|
||||||
|
import processing.app.helpers.PreferencesMap;
|
||||||
|
import processing.app.helpers.StringReplacer;
|
||||||
|
|
||||||
|
public class SerialUploader extends Uploader {
|
||||||
|
|
||||||
|
public boolean uploadUsingPreferences(String buildPath, String className,
|
||||||
|
boolean usingProgrammer)
|
||||||
|
throws RunnerException {
|
||||||
|
// FIXME: Preferences should be reorganized
|
||||||
|
TargetPlatform targetPlatform = Base.getTargetPlatform();
|
||||||
|
PreferencesMap prefs = Preferences.getMap();
|
||||||
|
prefs.putAll(Base.getBoardPreferences());
|
||||||
|
prefs.putAll(targetPlatform.getTool(prefs.get("upload.tool")));
|
||||||
|
|
||||||
|
// if no protocol is specified for this board, assume it lacks a
|
||||||
|
// bootloader and upload using the selected programmer.
|
||||||
|
if (usingProgrammer || prefs.get("upload.protocol") == null) {
|
||||||
|
return uploadUsingProgrammer(buildPath, className);
|
||||||
|
}
|
||||||
|
|
||||||
|
// need to do a little dance for Leonardo and derivatives:
|
||||||
|
// open then close the port at the magic baudrate (usually 1200 bps) first
|
||||||
|
// to signal to the sketch that it should reset into bootloader. after doing
|
||||||
|
// this wait a moment for the bootloader to enumerate. On Windows, also must
|
||||||
|
// deal with the fact that the COM port number changes from bootloader to
|
||||||
|
// sketch.
|
||||||
|
String t = prefs.get("upload.use_1200bps_touch");
|
||||||
|
boolean doTouch = t != null && t.equals("true");
|
||||||
|
|
||||||
|
t = prefs.get("upload.wait_for_upload_port");
|
||||||
|
boolean waitForUploadPort = (t != null) && t.equals("true");
|
||||||
|
|
||||||
|
if (doTouch) {
|
||||||
|
String uploadPort = prefs.get("serial.port");
|
||||||
|
try {
|
||||||
|
// Toggle 1200 bps on selected serial port to force board reset.
|
||||||
|
List<String> before = Serial.list();
|
||||||
|
if (before.contains(uploadPort)) {
|
||||||
|
if (verbose)
|
||||||
|
System.out
|
||||||
|
.println(_("Forcing reset using 1200bps open/close on port ") +
|
||||||
|
uploadPort);
|
||||||
|
Serial.touchPort(uploadPort, 1200);
|
||||||
|
}
|
||||||
|
if (waitForUploadPort) {
|
||||||
|
// Scanning for available ports seems to open the port or
|
||||||
|
// otherwise assert DTR, which would cancel the WDT reset if
|
||||||
|
// it happened within 250 ms. So we wait until the reset should
|
||||||
|
// have already occured before we start scanning.
|
||||||
|
if (!Base.isMacOS())
|
||||||
|
Thread.sleep(300);
|
||||||
|
|
||||||
|
uploadPort = waitForUploadPort(uploadPort, before);
|
||||||
|
} else {
|
||||||
|
Thread.sleep(400);
|
||||||
|
}
|
||||||
|
} catch (SerialException e) {
|
||||||
|
throw new RunnerException(e.getMessage());
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RunnerException(e.getMessage());
|
||||||
|
}
|
||||||
|
prefs.put("serial.port", uploadPort);
|
||||||
|
if (uploadPort.startsWith("/dev/"))
|
||||||
|
prefs.put("serial.port.file", uploadPort.substring(5));
|
||||||
|
else
|
||||||
|
prefs.put("serial.port.file", uploadPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
prefs.put("build.path", buildPath);
|
||||||
|
prefs.put("build.project_name", className);
|
||||||
|
if (verbose)
|
||||||
|
prefs.put("upload.verbose", prefs.get("upload.params.verbose"));
|
||||||
|
else
|
||||||
|
prefs.put("upload.verbose", prefs.get("upload.params.quiet"));
|
||||||
|
|
||||||
|
boolean uploadResult;
|
||||||
|
try {
|
||||||
|
// if (prefs.get("upload.disable_flushing") == null
|
||||||
|
// || prefs.get("upload.disable_flushing").toLowerCase().equals("false")) {
|
||||||
|
// flushSerialBuffer();
|
||||||
|
// }
|
||||||
|
|
||||||
|
String pattern = prefs.get("upload.pattern");
|
||||||
|
String[] cmd = StringReplacer.formatAndSplit(pattern, prefs, true);
|
||||||
|
uploadResult = executeUploadCommand(cmd);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RunnerException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the magic baud rate (1200bps) to avoid
|
||||||
|
// future unwanted board resets
|
||||||
|
try {
|
||||||
|
if (uploadResult && doTouch) {
|
||||||
|
String uploadPort = Preferences.get("serial.port");
|
||||||
|
if (waitForUploadPort) {
|
||||||
|
// For Due/Leonardo wait until the bootloader serial port disconnects and the
|
||||||
|
// sketch serial port reconnects (or timeout after a few seconds if the
|
||||||
|
// sketch port never comes back). Doing this saves users from accidentally
|
||||||
|
// opening Serial Monitor on the soon-to-be-orphaned bootloader port.
|
||||||
|
Thread.sleep(500);
|
||||||
|
long timeout = System.currentTimeMillis() + 2000;
|
||||||
|
while (timeout > System.currentTimeMillis()) {
|
||||||
|
List<String> portList = Serial.list();
|
||||||
|
if (portList.contains(uploadPort)) {
|
||||||
|
try {
|
||||||
|
Serial.touchPort(uploadPort, 9600);
|
||||||
|
break;
|
||||||
|
} catch (SerialException e) {
|
||||||
|
// Port already in use
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Thread.sleep(250);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
Serial.touchPort(uploadPort, 9600);
|
||||||
|
} catch (SerialException e) {
|
||||||
|
throw new RunnerException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
}
|
||||||
|
return uploadResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String waitForUploadPort(String uploadPort, List<String> before)
|
||||||
|
throws InterruptedException, RunnerException {
|
||||||
|
// Wait for a port to appear on the list
|
||||||
|
int elapsed = 0;
|
||||||
|
while (elapsed < 10000) {
|
||||||
|
List<String> now = Serial.list();
|
||||||
|
List<String> diff = new ArrayList<String>(now);
|
||||||
|
diff.removeAll(before);
|
||||||
|
if (verbose) {
|
||||||
|
System.out.print("PORTS {");
|
||||||
|
for (String p : before)
|
||||||
|
System.out.print(p + ", ");
|
||||||
|
System.out.print("} / {");
|
||||||
|
for (String p : now)
|
||||||
|
System.out.print(p + ", ");
|
||||||
|
System.out.print("} => {");
|
||||||
|
for (String p : diff)
|
||||||
|
System.out.print(p + ", ");
|
||||||
|
System.out.println("}");
|
||||||
|
}
|
||||||
|
if (diff.size() > 0) {
|
||||||
|
String newPort = diff.get(0);
|
||||||
|
if (verbose)
|
||||||
|
System.out.println("Found upload port: " + newPort);
|
||||||
|
return newPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep track of port that disappears
|
||||||
|
before = now;
|
||||||
|
Thread.sleep(250);
|
||||||
|
elapsed += 250;
|
||||||
|
|
||||||
|
// On Windows, it can take a long time for the port to disappear and
|
||||||
|
// come back, so use a longer time out before assuming that the
|
||||||
|
// selected
|
||||||
|
// port is the bootloader (not the sketch).
|
||||||
|
if (((!Base.isWindows() && elapsed >= 500) || elapsed >= 5000) &&
|
||||||
|
now.contains(uploadPort)) {
|
||||||
|
if (verbose)
|
||||||
|
System.out.println("Uploading using selected port: " +
|
||||||
|
uploadPort);
|
||||||
|
return uploadPort;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Something happened while detecting port
|
||||||
|
throw new RunnerException(
|
||||||
|
_("Couldn't find a Board on the selected port. Check that you have the correct port selected. If it is correct, try pressing the board's reset button after initiating the upload."));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean uploadUsingProgrammer(String buildPath, String className)
|
||||||
|
throws RunnerException {
|
||||||
|
|
||||||
|
TargetPlatform targetPlatform = Base.getTargetPlatform();
|
||||||
|
String programmer = Preferences.get("programmer");
|
||||||
|
if (programmer.contains(":")) {
|
||||||
|
String[] split = programmer.split(":", 2);
|
||||||
|
targetPlatform = Base.getCurrentTargetPlatformFromPackage(split[0]);
|
||||||
|
programmer = split[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
PreferencesMap prefs = Preferences.getMap();
|
||||||
|
prefs.putAll(Base.getBoardPreferences());
|
||||||
|
prefs.putAll(targetPlatform.getProgrammer(programmer));
|
||||||
|
prefs.putAll(targetPlatform.getTool(prefs.get("program.tool")));
|
||||||
|
|
||||||
|
prefs.put("build.path", buildPath);
|
||||||
|
prefs.put("build.project_name", className);
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
prefs.put("program.verbose", prefs.get("program.params.verbose"));
|
||||||
|
else
|
||||||
|
prefs.put("program.verbose", prefs.get("program.params.quiet"));
|
||||||
|
|
||||||
|
try {
|
||||||
|
// if (prefs.get("program.disable_flushing") == null
|
||||||
|
// || prefs.get("program.disable_flushing").toLowerCase().equals("false"))
|
||||||
|
// {
|
||||||
|
// flushSerialBuffer();
|
||||||
|
// }
|
||||||
|
|
||||||
|
String pattern = prefs.get("program.pattern");
|
||||||
|
String[] cmd = StringReplacer.formatAndSplit(pattern, prefs, true);
|
||||||
|
return executeUploadCommand(cmd);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RunnerException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean burnBootloader() throws RunnerException {
|
||||||
|
TargetPlatform targetPlatform = Base.getTargetPlatform();
|
||||||
|
|
||||||
|
// Find preferences for the selected programmer
|
||||||
|
PreferencesMap programmerPrefs;
|
||||||
|
String programmer = Preferences.get("programmer");
|
||||||
|
if (programmer.contains(":")) {
|
||||||
|
String[] split = programmer.split(":", 2);
|
||||||
|
TargetPlatform platform = Base
|
||||||
|
.getCurrentTargetPlatformFromPackage(split[0]);
|
||||||
|
programmer = split[1];
|
||||||
|
programmerPrefs = platform.getProgrammer(programmer);
|
||||||
|
} else {
|
||||||
|
programmerPrefs = targetPlatform.getProgrammer(programmer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build configuration for the current programmer
|
||||||
|
PreferencesMap prefs = Preferences.getMap();
|
||||||
|
prefs.putAll(Base.getBoardPreferences());
|
||||||
|
prefs.putAll(programmerPrefs);
|
||||||
|
|
||||||
|
// Create configuration for bootloader tool
|
||||||
|
PreferencesMap toolPrefs = new PreferencesMap();
|
||||||
|
String tool = prefs.get("bootloader.tool");
|
||||||
|
if (tool.contains(":")) {
|
||||||
|
String[] split = tool.split(":", 2);
|
||||||
|
TargetPlatform platform = Base.getCurrentTargetPlatformFromPackage(split[0]);
|
||||||
|
tool = split[1];
|
||||||
|
toolPrefs.putAll(platform.getTool(tool));
|
||||||
|
if (toolPrefs.size() == 0)
|
||||||
|
throw new RunnerException(
|
||||||
|
I18n.format(_("Could not find tool {0} from package {1}"), tool,
|
||||||
|
split[0]));
|
||||||
|
}
|
||||||
|
toolPrefs.putAll(targetPlatform.getTool(tool));
|
||||||
|
if (toolPrefs.size() == 0)
|
||||||
|
throw new RunnerException(I18n.format(_("Could not find tool {0}"),
|
||||||
|
tool));
|
||||||
|
|
||||||
|
// Merge tool with global configuration
|
||||||
|
prefs.putAll(toolPrefs);
|
||||||
|
if (verbose) {
|
||||||
|
prefs.put("erase.verbose", prefs.get("erase.params.verbose"));
|
||||||
|
prefs.put("bootloader.verbose", prefs.get("bootloader.params.verbose"));
|
||||||
|
} else {
|
||||||
|
prefs.put("erase.verbose", prefs.get("erase.params.quiet"));
|
||||||
|
prefs.put("bootloader.verbose", prefs.get("bootloader.params.quiet"));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
String pattern = prefs.get("erase.pattern");
|
||||||
|
String[] cmd = StringReplacer.formatAndSplit(pattern, prefs, true);
|
||||||
|
if (!executeUploadCommand(cmd))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
pattern = prefs.get("bootloader.pattern");
|
||||||
|
cmd = StringReplacer.formatAndSplit(pattern, prefs, true);
|
||||||
|
return executeUploadCommand(cmd);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RunnerException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,9 @@ import javax.swing.text.*;
|
|||||||
import javax.swing.undo.*;
|
import javax.swing.undo.*;
|
||||||
|
|
||||||
import cc.arduino.packages.BoardPort;
|
import cc.arduino.packages.BoardPort;
|
||||||
|
import cc.arduino.packages.Uploader;
|
||||||
|
import cc.arduino.packages.UploaderFactory;
|
||||||
|
import cc.arduino.packages.uploaders.SerialUploader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main editor panel for the Processing Development Environment.
|
* Main editor panel for the Processing Development Environment.
|
||||||
@ -204,7 +207,7 @@ public class Editor extends JFrame implements RunnerListener {
|
|||||||
//sketchbook = new Sketchbook(this);
|
//sketchbook = new Sketchbook(this);
|
||||||
|
|
||||||
if (serialMonitor == null) {
|
if (serialMonitor == null) {
|
||||||
serialMonitor = new PerPortObjectFactory().newMonitor(Preferences.get("serial.port"), base);
|
serialMonitor = new UploaderFactory().newMonitor(Preferences.get("serial.port"), base);
|
||||||
serialMonitor.setIconImage(getIconImage());
|
serialMonitor.setIconImage(getIconImage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -970,7 +973,7 @@ public class Editor extends JFrame implements RunnerListener {
|
|||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
serialMonitor.setVisible(false);
|
serialMonitor.setVisible(false);
|
||||||
serialMonitor = new PerPortObjectFactory().newMonitor(Preferences.get("serial.port"), base);
|
serialMonitor = new UploaderFactory().newMonitor(Preferences.get("serial.port"), base);
|
||||||
|
|
||||||
onBoardOrPortChange();
|
onBoardOrPortChange();
|
||||||
|
|
||||||
@ -2507,7 +2510,7 @@ public class Editor extends JFrame implements RunnerListener {
|
|||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Uploader uploader = new BasicUploader();
|
Uploader uploader = new SerialUploader();
|
||||||
if (uploader.burnBootloader()) {
|
if (uploader.burnBootloader()) {
|
||||||
statusNotice(_("Done burning bootloader."));
|
statusNotice(_("Done burning bootloader."));
|
||||||
} else {
|
} else {
|
||||||
|
@ -5,23 +5,21 @@ import processing.app.debug.MessageSiphon;
|
|||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
public class NetworkMonitor extends AbstractMonitor {
|
public class NetworkMonitor extends AbstractMonitor {
|
||||||
|
|
||||||
private static final int MAX_CONNECT_RETRIES = 3;
|
|
||||||
|
|
||||||
private final String ipAddress;
|
private final String ipAddress;
|
||||||
private final Base base;
|
|
||||||
|
|
||||||
private Socket socket;
|
private Socket socket;
|
||||||
private MessageSiphon consumer;
|
private MessageSiphon consumer;
|
||||||
|
|
||||||
public NetworkMonitor(String port, Base base) {
|
public NetworkMonitor(String port, Base base) {
|
||||||
super(port);
|
super(port);
|
||||||
this.base = base;
|
|
||||||
|
|
||||||
Matcher matcher = Constants.IPV4_ADDRESS.matcher(port);
|
Matcher matcher = Constants.IPV4_ADDRESS.matcher(port);
|
||||||
matcher.find();
|
matcher.find();
|
||||||
@ -30,9 +28,10 @@ public class NetworkMonitor extends AbstractMonitor {
|
|||||||
onSendCommand(new ActionListener() {
|
onSendCommand(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent event) {
|
public void actionPerformed(ActionEvent event) {
|
||||||
try {
|
try {
|
||||||
socket.getOutputStream().write(textField.getText().getBytes());
|
OutputStream out = socket.getOutputStream();
|
||||||
socket.getOutputStream().write('\n');
|
out.write(textField.getText().getBytes());
|
||||||
socket.getOutputStream().flush();
|
out.write('\n');
|
||||||
|
out.flush();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -54,14 +53,6 @@ public class NetworkMonitor extends AbstractMonitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sleep(long millis) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(millis);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
if (socket != null) {
|
if (socket != null) {
|
||||||
|
@ -24,6 +24,9 @@
|
|||||||
package processing.app;
|
package processing.app;
|
||||||
|
|
||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
|
|
||||||
|
import cc.arduino.packages.Uploader;
|
||||||
|
import cc.arduino.packages.UploaderFactory;
|
||||||
import processing.app.debug.*;
|
import processing.app.debug.*;
|
||||||
import processing.app.debug.Compiler;
|
import processing.app.debug.Compiler;
|
||||||
import processing.app.forms.PasswordAuthorizationDialog;
|
import processing.app.forms.PasswordAuthorizationDialog;
|
||||||
@ -1663,7 +1666,7 @@ public class Sketch {
|
|||||||
TargetPlatform target = Base.getTargetPlatform();
|
TargetPlatform target = Base.getTargetPlatform();
|
||||||
String board = Preferences.get("board");
|
String board = Preferences.get("board");
|
||||||
|
|
||||||
Uploader uploader = new PerPortObjectFactory().newUploader(target.getBoards().get(board), Preferences.get("serial.port"));
|
Uploader uploader = new UploaderFactory().newUploader(target.getBoards().get(board), Preferences.get("serial.port"));
|
||||||
|
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
do {
|
do {
|
||||||
|
@ -1,318 +0,0 @@
|
|||||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
BasicUploader - generic command line uploader implementation
|
|
||||||
Part of the Arduino project - http://www.arduino.cc/
|
|
||||||
|
|
||||||
Copyright (c) 2004-05
|
|
||||||
Hernando Barragan
|
|
||||||
Copyright (c) 2012
|
|
||||||
Cristian Maglie <c.maglie@bug.st>
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
$Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
package processing.app.debug;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import processing.app.Base;
|
|
||||||
import processing.app.I18n;
|
|
||||||
import processing.app.Preferences;
|
|
||||||
import processing.app.Serial;
|
|
||||||
import processing.app.SerialException;
|
|
||||||
import processing.app.helpers.PreferencesMap;
|
|
||||||
import processing.app.helpers.StringReplacer;
|
|
||||||
|
|
||||||
import static processing.app.I18n._;
|
|
||||||
|
|
||||||
public class BasicUploader extends Uploader {
|
|
||||||
|
|
||||||
public boolean uploadUsingPreferences(String buildPath, String className,
|
|
||||||
boolean usingProgrammer)
|
|
||||||
throws RunnerException {
|
|
||||||
// FIXME: Preferences should be reorganized
|
|
||||||
TargetPlatform targetPlatform = Base.getTargetPlatform();
|
|
||||||
PreferencesMap prefs = Preferences.getMap();
|
|
||||||
prefs.putAll(Base.getBoardPreferences());
|
|
||||||
prefs.putAll(targetPlatform.getTool(prefs.get("upload.tool")));
|
|
||||||
|
|
||||||
// if no protocol is specified for this board, assume it lacks a
|
|
||||||
// bootloader and upload using the selected programmer.
|
|
||||||
if (usingProgrammer || prefs.get("upload.protocol") == null) {
|
|
||||||
return uploadUsingProgrammer(buildPath, className);
|
|
||||||
}
|
|
||||||
|
|
||||||
// need to do a little dance for Leonardo and derivatives:
|
|
||||||
// open then close the port at the magic baudrate (usually 1200 bps) first
|
|
||||||
// to signal to the sketch that it should reset into bootloader. after doing
|
|
||||||
// this wait a moment for the bootloader to enumerate. On Windows, also must
|
|
||||||
// deal with the fact that the COM port number changes from bootloader to
|
|
||||||
// sketch.
|
|
||||||
String t = prefs.get("upload.use_1200bps_touch");
|
|
||||||
boolean doTouch = t != null && t.equals("true");
|
|
||||||
|
|
||||||
t = prefs.get("upload.wait_for_upload_port");
|
|
||||||
boolean waitForUploadPort = (t != null) && t.equals("true");
|
|
||||||
|
|
||||||
if (doTouch) {
|
|
||||||
String uploadPort = prefs.get("serial.port");
|
|
||||||
try {
|
|
||||||
// Toggle 1200 bps on selected serial port to force board reset.
|
|
||||||
List<String> before = Serial.list();
|
|
||||||
if (before.contains(uploadPort)) {
|
|
||||||
if (verbose || Preferences.getBoolean("upload.verbose"))
|
|
||||||
System.out
|
|
||||||
.println(_("Forcing reset using 1200bps open/close on port ") +
|
|
||||||
uploadPort);
|
|
||||||
Serial.touchPort(uploadPort, 1200);
|
|
||||||
}
|
|
||||||
if (waitForUploadPort) {
|
|
||||||
// Scanning for available ports seems to open the port or
|
|
||||||
// otherwise assert DTR, which would cancel the WDT reset if
|
|
||||||
// it happened within 250 ms. So we wait until the reset should
|
|
||||||
// have already occured before we start scanning.
|
|
||||||
if (!Base.isMacOS())
|
|
||||||
Thread.sleep(300);
|
|
||||||
|
|
||||||
uploadPort = waitForUploadPort(uploadPort, before);
|
|
||||||
} else {
|
|
||||||
Thread.sleep(400);
|
|
||||||
}
|
|
||||||
} catch (SerialException e) {
|
|
||||||
throw new RunnerException(e.getMessage());
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RunnerException(e.getMessage());
|
|
||||||
}
|
|
||||||
prefs.put("serial.port", uploadPort);
|
|
||||||
if (uploadPort.startsWith("/dev/"))
|
|
||||||
prefs.put("serial.port.file", uploadPort.substring(5));
|
|
||||||
else
|
|
||||||
prefs.put("serial.port.file", uploadPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
prefs.put("build.path", buildPath);
|
|
||||||
prefs.put("build.project_name", className);
|
|
||||||
if (verbose)
|
|
||||||
prefs.put("upload.verbose", prefs.get("upload.params.verbose"));
|
|
||||||
else
|
|
||||||
prefs.put("upload.verbose", prefs.get("upload.params.quiet"));
|
|
||||||
|
|
||||||
boolean uploadResult;
|
|
||||||
try {
|
|
||||||
// if (prefs.get("upload.disable_flushing") == null
|
|
||||||
// || prefs.get("upload.disable_flushing").toLowerCase().equals("false")) {
|
|
||||||
// flushSerialBuffer();
|
|
||||||
// }
|
|
||||||
|
|
||||||
String pattern = prefs.get("upload.pattern");
|
|
||||||
String[] cmd = StringReplacer.formatAndSplit(pattern, prefs, true);
|
|
||||||
uploadResult = executeUploadCommand(cmd);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RunnerException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the magic baud rate (1200bps) to avoid
|
|
||||||
// future unwanted board resets
|
|
||||||
try {
|
|
||||||
if (uploadResult && doTouch) {
|
|
||||||
String uploadPort = Preferences.get("serial.port");
|
|
||||||
if (waitForUploadPort) {
|
|
||||||
// For Due/Leonardo wait until the bootloader serial port disconnects and the
|
|
||||||
// sketch serial port reconnects (or timeout after a few seconds if the
|
|
||||||
// sketch port never comes back). Doing this saves users from accidentally
|
|
||||||
// opening Serial Monitor on the soon-to-be-orphaned bootloader port.
|
|
||||||
Thread.sleep(500);
|
|
||||||
long timeout = System.currentTimeMillis() + 2000;
|
|
||||||
while (timeout > System.currentTimeMillis()) {
|
|
||||||
List<String> portList = Serial.list();
|
|
||||||
if (portList.contains(uploadPort)) {
|
|
||||||
try {
|
|
||||||
Serial.touchPort(uploadPort, 9600);
|
|
||||||
break;
|
|
||||||
} catch (SerialException e) {
|
|
||||||
// Port already in use
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Thread.sleep(250);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
Serial.touchPort(uploadPort, 9600);
|
|
||||||
} catch (SerialException e) {
|
|
||||||
throw new RunnerException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (InterruptedException ex) {
|
|
||||||
}
|
|
||||||
return uploadResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String waitForUploadPort(String uploadPort, List<String> before)
|
|
||||||
throws InterruptedException, RunnerException {
|
|
||||||
// Wait for a port to appear on the list
|
|
||||||
int elapsed = 0;
|
|
||||||
while (elapsed < 10000) {
|
|
||||||
List<String> now = Serial.list();
|
|
||||||
List<String> diff = new ArrayList<String>(now);
|
|
||||||
diff.removeAll(before);
|
|
||||||
if (verbose || Preferences.getBoolean("upload.verbose")) {
|
|
||||||
System.out.print("PORTS {");
|
|
||||||
for (String p : before)
|
|
||||||
System.out.print(p + ", ");
|
|
||||||
System.out.print("} / {");
|
|
||||||
for (String p : now)
|
|
||||||
System.out.print(p + ", ");
|
|
||||||
System.out.print("} => {");
|
|
||||||
for (String p : diff)
|
|
||||||
System.out.print(p + ", ");
|
|
||||||
System.out.println("}");
|
|
||||||
}
|
|
||||||
if (diff.size() > 0) {
|
|
||||||
String newPort = diff.get(0);
|
|
||||||
if (verbose || Preferences.getBoolean("upload.verbose"))
|
|
||||||
System.out.println("Found upload port: " + newPort);
|
|
||||||
return newPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep track of port that disappears
|
|
||||||
before = now;
|
|
||||||
Thread.sleep(250);
|
|
||||||
elapsed += 250;
|
|
||||||
|
|
||||||
// On Windows, it can take a long time for the port to disappear and
|
|
||||||
// come back, so use a longer time out before assuming that the
|
|
||||||
// selected
|
|
||||||
// port is the bootloader (not the sketch).
|
|
||||||
if (((!Base.isWindows() && elapsed >= 500) || elapsed >= 5000) &&
|
|
||||||
now.contains(uploadPort)) {
|
|
||||||
if (verbose || Preferences.getBoolean("upload.verbose"))
|
|
||||||
System.out.println("Uploading using selected port: " +
|
|
||||||
uploadPort);
|
|
||||||
return uploadPort;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Something happened while detecting port
|
|
||||||
throw new RunnerException(
|
|
||||||
_("Couldn't find a Board on the selected port. Check that you have the correct port selected. If it is correct, try pressing the board's reset button after initiating the upload."));
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean uploadUsingProgrammer(String buildPath, String className)
|
|
||||||
throws RunnerException {
|
|
||||||
|
|
||||||
TargetPlatform targetPlatform = Base.getTargetPlatform();
|
|
||||||
String programmer = Preferences.get("programmer");
|
|
||||||
if (programmer.contains(":")) {
|
|
||||||
String[] split = programmer.split(":", 2);
|
|
||||||
targetPlatform = Base.getCurrentTargetPlatformFromPackage(split[0]);
|
|
||||||
programmer = split[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
PreferencesMap prefs = Preferences.getMap();
|
|
||||||
prefs.putAll(Base.getBoardPreferences());
|
|
||||||
prefs.putAll(targetPlatform.getProgrammer(programmer));
|
|
||||||
prefs.putAll(targetPlatform.getTool(prefs.get("program.tool")));
|
|
||||||
|
|
||||||
prefs.put("build.path", buildPath);
|
|
||||||
prefs.put("build.project_name", className);
|
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
prefs.put("program.verbose", prefs.get("program.params.verbose"));
|
|
||||||
else
|
|
||||||
prefs.put("program.verbose", prefs.get("program.params.quiet"));
|
|
||||||
|
|
||||||
try {
|
|
||||||
// if (prefs.get("program.disable_flushing") == null
|
|
||||||
// || prefs.get("program.disable_flushing").toLowerCase().equals("false"))
|
|
||||||
// {
|
|
||||||
// flushSerialBuffer();
|
|
||||||
// }
|
|
||||||
|
|
||||||
String pattern = prefs.get("program.pattern");
|
|
||||||
String[] cmd = StringReplacer.formatAndSplit(pattern, prefs, true);
|
|
||||||
return executeUploadCommand(cmd);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RunnerException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean burnBootloader() throws RunnerException {
|
|
||||||
TargetPlatform targetPlatform = Base.getTargetPlatform();
|
|
||||||
|
|
||||||
// Find preferences for the selected programmer
|
|
||||||
PreferencesMap programmerPrefs;
|
|
||||||
String programmer = Preferences.get("programmer");
|
|
||||||
if (programmer.contains(":")) {
|
|
||||||
String[] split = programmer.split(":", 2);
|
|
||||||
TargetPlatform platform = Base
|
|
||||||
.getCurrentTargetPlatformFromPackage(split[0]);
|
|
||||||
programmer = split[1];
|
|
||||||
programmerPrefs = platform.getProgrammer(programmer);
|
|
||||||
} else {
|
|
||||||
programmerPrefs = targetPlatform.getProgrammer(programmer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build configuration for the current programmer
|
|
||||||
PreferencesMap prefs = Preferences.getMap();
|
|
||||||
prefs.putAll(Base.getBoardPreferences());
|
|
||||||
prefs.putAll(programmerPrefs);
|
|
||||||
|
|
||||||
// Create configuration for bootloader tool
|
|
||||||
PreferencesMap toolPrefs = new PreferencesMap();
|
|
||||||
String tool = prefs.get("bootloader.tool");
|
|
||||||
if (tool.contains(":")) {
|
|
||||||
String[] split = tool.split(":", 2);
|
|
||||||
TargetPlatform platform = Base.getCurrentTargetPlatformFromPackage(split[0]);
|
|
||||||
tool = split[1];
|
|
||||||
toolPrefs.putAll(platform.getTool(tool));
|
|
||||||
if (toolPrefs.size() == 0)
|
|
||||||
throw new RunnerException(
|
|
||||||
I18n.format(_("Could not find tool {0} from package {1}"), tool,
|
|
||||||
split[0]));
|
|
||||||
}
|
|
||||||
toolPrefs.putAll(targetPlatform.getTool(tool));
|
|
||||||
if (toolPrefs.size() == 0)
|
|
||||||
throw new RunnerException(I18n.format(_("Could not find tool {0}"),
|
|
||||||
tool));
|
|
||||||
|
|
||||||
// Merge tool with global configuration
|
|
||||||
prefs.putAll(toolPrefs);
|
|
||||||
if (verbose) {
|
|
||||||
prefs.put("erase.verbose", prefs.get("erase.params.verbose"));
|
|
||||||
prefs.put("bootloader.verbose", prefs.get("bootloader.params.verbose"));
|
|
||||||
} else {
|
|
||||||
prefs.put("erase.verbose", prefs.get("erase.params.quiet"));
|
|
||||||
prefs.put("bootloader.verbose", prefs.get("bootloader.params.quiet"));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
String pattern = prefs.get("erase.pattern");
|
|
||||||
String[] cmd = StringReplacer.formatAndSplit(pattern, prefs, true);
|
|
||||||
if (!executeUploadCommand(cmd))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
pattern = prefs.get("bootloader.pattern");
|
|
||||||
cmd = StringReplacer.formatAndSplit(pattern, prefs, true);
|
|
||||||
return executeUploadCommand(cmd);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RunnerException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,227 +0,0 @@
|
|||||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
|
||||||
|
|
||||||
/*
|
|
||||||
Uploader - abstract uploading baseclass (common to both uisp and avrdude)
|
|
||||||
Part of the Arduino project - http://www.arduino.cc/
|
|
||||||
|
|
||||||
Copyright (c) 2004-05
|
|
||||||
Hernando Barragan
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
$Id$
|
|
||||||
*/
|
|
||||||
|
|
||||||
package processing.app.debug;
|
|
||||||
|
|
||||||
import static processing.app.I18n._;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import processing.app.I18n;
|
|
||||||
import processing.app.Preferences;
|
|
||||||
import processing.app.Serial;
|
|
||||||
import processing.app.SerialException;
|
|
||||||
import processing.app.SerialNotFoundException;
|
|
||||||
|
|
||||||
public abstract class Uploader implements MessageConsumer {
|
|
||||||
static final String BUGS_URL =
|
|
||||||
_("https://developer.berlios.de/bugs/?group_id=3590");
|
|
||||||
static final String SUPER_BADNESS =
|
|
||||||
I18n.format(_("Compiler error, please submit this code to {0}"), BUGS_URL);
|
|
||||||
|
|
||||||
RunnerException exception;
|
|
||||||
|
|
||||||
static InputStream serialInput;
|
|
||||||
static OutputStream serialOutput;
|
|
||||||
|
|
||||||
boolean verbose;
|
|
||||||
|
|
||||||
public abstract boolean uploadUsingPreferences(String buildPath, String className, boolean usingProgrammer)
|
|
||||||
throws RunnerException;
|
|
||||||
|
|
||||||
public abstract boolean burnBootloader() throws RunnerException;
|
|
||||||
|
|
||||||
public boolean requiresAuthorization() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAuthorizationKey() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void flushSerialBuffer() throws RunnerException, SerialException {
|
|
||||||
// Cleanup the serial buffer
|
|
||||||
try {
|
|
||||||
Serial serialPort = new Serial();
|
|
||||||
while(serialPort.available() > 0) {
|
|
||||||
serialPort.readBytes();
|
|
||||||
try {
|
|
||||||
Thread.sleep(100);
|
|
||||||
} catch (InterruptedException e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
serialPort.setDTR(false);
|
|
||||||
serialPort.setRTS(false);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Thread.sleep(100);
|
|
||||||
} catch (InterruptedException e) {}
|
|
||||||
|
|
||||||
serialPort.setDTR(true);
|
|
||||||
serialPort.setRTS(true);
|
|
||||||
|
|
||||||
serialPort.dispose();
|
|
||||||
} catch (SerialNotFoundException e) {
|
|
||||||
throw e;
|
|
||||||
} catch(Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw new RunnerException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean executeUploadCommand(Collection<String> commandDownloader)
|
|
||||||
throws RunnerException {
|
|
||||||
String[] commandArray = new String[commandDownloader.size()];
|
|
||||||
commandDownloader.toArray(commandArray);
|
|
||||||
return executeUploadCommand(commandArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean executeUploadCommand(String commandArray[])
|
|
||||||
throws RunnerException
|
|
||||||
{
|
|
||||||
firstErrorFound = false; // haven't found any errors yet
|
|
||||||
secondErrorFound = false;
|
|
||||||
notFoundError = false;
|
|
||||||
int result=0; // pre-initialized to quiet a bogus warning from jikes
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (verbose || Preferences.getBoolean("upload.verbose")) {
|
|
||||||
for(int i = 0; i < commandArray.length; i++) {
|
|
||||||
System.out.print(commandArray[i] + " ");
|
|
||||||
}
|
|
||||||
System.out.println();
|
|
||||||
}
|
|
||||||
Process process = Runtime.getRuntime().exec(commandArray);
|
|
||||||
new MessageSiphon(process.getInputStream(), this);
|
|
||||||
new MessageSiphon(process.getErrorStream(), this);
|
|
||||||
|
|
||||||
// wait for the process to finish. if interrupted
|
|
||||||
// before waitFor returns, continue waiting
|
|
||||||
//
|
|
||||||
boolean compiling = true;
|
|
||||||
while (compiling) {
|
|
||||||
try {
|
|
||||||
result = process.waitFor();
|
|
||||||
compiling = false;
|
|
||||||
} catch (InterruptedException intExc) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(exception!=null) {
|
|
||||||
exception.hideStackTrace();
|
|
||||||
throw exception;
|
|
||||||
}
|
|
||||||
if(result!=0)
|
|
||||||
return false;
|
|
||||||
} catch (Exception e) {
|
|
||||||
String msg = e.getMessage();
|
|
||||||
if ((msg != null) && (msg.indexOf("uisp: not found") != -1) && (msg.indexOf("avrdude: not found") != -1)) {
|
|
||||||
//System.err.println("uisp is missing");
|
|
||||||
//JOptionPane.showMessageDialog(editor.base,
|
|
||||||
// "Could not find the compiler.\n" +
|
|
||||||
// "uisp is missing from your PATH,\n" +
|
|
||||||
// "see readme.txt for help.",
|
|
||||||
// "Compiler error",
|
|
||||||
// JOptionPane.ERROR_MESSAGE);
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
e.printStackTrace();
|
|
||||||
result = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//System.out.println("result2 is "+result);
|
|
||||||
// if the result isn't a known, expected value it means that something
|
|
||||||
// is fairly wrong, one possibility is that jikes has crashed.
|
|
||||||
//
|
|
||||||
if (exception != null) throw exception;
|
|
||||||
|
|
||||||
if ((result != 0) && (result != 1 )) {
|
|
||||||
exception = new RunnerException(SUPER_BADNESS);
|
|
||||||
//editor.error(exception);
|
|
||||||
//PdeBase.openURL(BUGS_URL);
|
|
||||||
//throw new PdeException(SUPER_BADNESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (result == 0); // ? true : false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean firstErrorFound;
|
|
||||||
boolean secondErrorFound;
|
|
||||||
|
|
||||||
// part of the PdeMessageConsumer interface
|
|
||||||
//
|
|
||||||
boolean notFoundError;
|
|
||||||
|
|
||||||
public void message(String s) {
|
|
||||||
// selectively suppress a bunch of avrdude output for AVR109/Caterina that should already be quelled but isn't
|
|
||||||
if (!Preferences.getBoolean("upload.verbose") && (
|
|
||||||
s.indexOf("Connecting to programmer:") != -1 ||
|
|
||||||
s.indexOf("Found programmer: Id = \"CATERIN\"; type = S") != -1 ||
|
|
||||||
s.indexOf("Software Version = 1.0; No Hardware Version given.") != -1 ||
|
|
||||||
s.indexOf("Programmer supports auto addr increment.") != -1 ||
|
|
||||||
s.indexOf("Programmer supports buffered memory access with buffersize=128 bytes.") != -1 ||
|
|
||||||
s.indexOf("Programmer supports the following devices:") != -1 ||
|
|
||||||
s.indexOf("Device code: 0x44") != -1))
|
|
||||||
s = "";
|
|
||||||
|
|
||||||
System.err.print(s);
|
|
||||||
|
|
||||||
// ignore cautions
|
|
||||||
if (s.indexOf("Error") != -1) {
|
|
||||||
//exception = new RunnerException(s+" Check the serial port selected or your Board is connected");
|
|
||||||
//System.out.println(s);
|
|
||||||
notFoundError = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(notFoundError) {
|
|
||||||
//System.out.println("throwing something");
|
|
||||||
exception = new RunnerException(I18n.format(_("the selected serial port {0} does not exist or your board is not connected"), s));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (s.indexOf("Device is not responding") != -1 ) {
|
|
||||||
exception = new RunnerException(_("Device is not responding, check the right serial port is selected or RESET the board right before exporting"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (s.indexOf("Programmer is not responding") != -1 ||
|
|
||||||
s.indexOf("programmer is not responding") != -1 ||
|
|
||||||
s.indexOf("protocol error") != -1 ||
|
|
||||||
s.indexOf("avrdude: ser_open(): can't open device") != -1 ||
|
|
||||||
s.indexOf("avrdude: ser_drain(): read error") != -1 ||
|
|
||||||
s.indexOf("avrdude: ser_send(): write error") != -1 ||
|
|
||||||
s.indexOf("avrdude: error: buffered memory access not supported.") != -1) {
|
|
||||||
exception = new RunnerException(_("Problem uploading to board. See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (s.indexOf("Expected signature") != -1) {
|
|
||||||
exception = new RunnerException(_("Wrong microcontroller found. Did you select the right board from the Tools > Board menu?"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -2,8 +2,12 @@ package processing.app.debug;
|
|||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import cc.arduino.packages.Uploader;
|
||||||
|
import cc.arduino.packages.UploaderFactory;
|
||||||
|
import cc.arduino.packages.uploaders.HttpUploader;
|
||||||
|
import cc.arduino.packages.uploaders.SerialUploader;
|
||||||
import processing.app.AbstractWithPreferencesTest;
|
import processing.app.AbstractWithPreferencesTest;
|
||||||
import processing.app.PerPortObjectFactory;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
@ -21,7 +25,7 @@ public class UploaderFactoryTest extends AbstractWithPreferencesTest {
|
|||||||
@Test
|
@Test
|
||||||
public void shouldCreateAnInstanceOfHttpUploader() throws Exception {
|
public void shouldCreateAnInstanceOfHttpUploader() throws Exception {
|
||||||
TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("yun");
|
TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("yun");
|
||||||
Uploader uploader = new PerPortObjectFactory().newUploader(board, "192.168.0.1 (yun)");
|
Uploader uploader = new UploaderFactory().newUploader(board, "192.168.0.1 (yun)");
|
||||||
|
|
||||||
assertTrue(uploader instanceof HttpUploader);
|
assertTrue(uploader instanceof HttpUploader);
|
||||||
}
|
}
|
||||||
@ -29,16 +33,16 @@ public class UploaderFactoryTest extends AbstractWithPreferencesTest {
|
|||||||
@Test
|
@Test
|
||||||
public void shouldCreateAnInstanceOfBasicUploaderWhenHTTPIsUnsupported() throws Exception {
|
public void shouldCreateAnInstanceOfBasicUploaderWhenHTTPIsUnsupported() throws Exception {
|
||||||
TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("uno");
|
TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("uno");
|
||||||
Uploader uploader = new PerPortObjectFactory().newUploader(board, "192.168.0.1 (myyun)");
|
Uploader uploader = new UploaderFactory().newUploader(board, "192.168.0.1 (myyun)");
|
||||||
|
|
||||||
assertTrue(uploader instanceof BasicUploader);
|
assertTrue(uploader instanceof SerialUploader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldCreateAnInstanceOfBasicUploaderWhenPortIsSerial() throws Exception {
|
public void shouldCreateAnInstanceOfBasicUploaderWhenPortIsSerial() throws Exception {
|
||||||
TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("uno");
|
TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("uno");
|
||||||
Uploader uploader = new PerPortObjectFactory().newUploader(board, "/dev/ttyACM0 (Arduino Leonardo)");
|
Uploader uploader = new UploaderFactory().newUploader(board, "/dev/ttyACM0 (Arduino Leonardo)");
|
||||||
|
|
||||||
assertTrue(uploader instanceof BasicUploader);
|
assertTrue(uploader instanceof SerialUploader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user