1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-22 08:22:04 +03:00

First attemp to generalize upload for mutiplatform IDE

This commit is contained in:
Cristian Maglie
2012-02-01 14:34:29 +01:00
parent b295ab911e
commit 30ec90aca3
7 changed files with 227 additions and 162 deletions

View File

@ -35,57 +35,87 @@ import processing.app.Base;
import processing.app.Preferences;
import processing.app.SerialException;
import processing.app.helpers.PreferencesMap;
import processing.app.helpers.StringReplacer;
public class AvrdudeUploader extends Uploader {
public boolean uploadUsingPreferences(String buildPath, String className, boolean usingProgrammer)
throws RunnerException, SerialException {
PreferencesMap boardPreferences = Base.getBoardPreferences();
// FIXME: Preferences should be reorganized
PreferencesMap prefs = Preferences.getMap();
prefs.putAll(Base.getBoardPreferences());
// if no protocol is specified for this board, assume it lacks a
// bootloader and upload using the selected programmer.
if (usingProgrammer || boardPreferences.get("upload.protocol") == null) {
String programmer = Preferences.get("programmer");
TargetPlatform targetPlatform = Base.getTargetPlatform();
if (usingProgrammer || prefs.get("upload.protocol") == null) {
return uploadUsingProgrammer(buildPath, className);
}
if (programmer.contains(":")) {
String[] split = programmer.split(":", 2);
targetPlatform = Base.getTargetPlatform(split[0], Preferences
.get("target_platform"));
programmer = split[1];
prefs.put("build.path", buildPath);
prefs.put("build.project_name", className);
TargetPlatform targetPlatform = Base.getTargetPlatform();
prefs.putAll(targetPlatform.getTool(prefs.get("upload.tool")));
if (verbose)
prefs.put("upload.verbose", prefs.get("upload.params.verbose"));
else
prefs.put("upload.verbose", prefs.get("upload.params.quiet"));
String pattern = prefs.get("upload.pattern");
try {
if (prefs.get("upload.disable_flushing") == null
|| prefs.get("upload.disable_flushing").toLowerCase().equals("false")) {
flushSerialBuffer();
}
Collection<String> params = getProgrammerCommands(targetPlatform, programmer);
params.add("-Uflash:w:" + buildPath + File.separator + className + ".hex:i");
return avrdude(params);
}
return uploadViaBootloader(buildPath, className);
String[] cmd = StringReplacer.formatAndSplit(pattern, prefs, true);
return executeUploadCommand(cmd);
} catch (Exception e) {
throw new RunnerException(e);
}
}
private boolean uploadViaBootloader(String buildPath, String className)
throws RunnerException, SerialException {
PreferencesMap boardPreferences = Base.getBoardPreferences();
List<String> commandDownloader = new ArrayList<String>();
String protocol = boardPreferences.get("upload.protocol");
// avrdude wants "stk500v1" to distinguish it from stk500v2
if (protocol.equals("stk500"))
protocol = "stk500v1";
commandDownloader.add("-c" + protocol);
commandDownloader.add(
"-P" + (Base.isWindows() ? "\\\\.\\" : "") + Preferences.get("serial.port"));
commandDownloader.add(
"-b" + Integer.parseInt(boardPreferences.get("upload.speed")));
commandDownloader.add("-D"); // don't erase
commandDownloader.add("-Uflash:w:" + buildPath + File.separator + className + ".hex:i");
if (boardPreferences.get("upload.disable_flushing") == null ||
boardPreferences.get("upload.disable_flushing").toLowerCase().equals("false")) {
flushSerialBuffer();
public boolean uploadUsingProgrammer(String buildPath, String className)
throws RunnerException {
String programmer = Preferences.get("programmer");
TargetPlatform targetPlatform = Base.getTargetPlatform();
if (programmer.contains(":")) {
String[] split = programmer.split(":", 2);
targetPlatform = Base.getTargetPlatform(split[0], Preferences
.get("target_platform"));
programmer = split[1];
}
return avrdude(commandDownloader);
PreferencesMap prefs = Preferences.getMap();
prefs.putAll(Base.getBoardPreferences());
prefs.putAll(targetPlatform.getProgrammers().get(programmer));
prefs.put("build.path", buildPath);
prefs.put("build.project_name", className);
PreferencesMap programmers = targetPlatform.getPreferences()
.createSubTree("programmers");
prefs.putAll(programmers.createSubTree(prefs.get("program.tool")));
if (verbose)
prefs.put("program.verbose", prefs.get("program.params.verbose"));
else
prefs.put("program.verbose", prefs.get("program.params.quiet"));
String pattern = prefs.get("program.pattern");
try {
if (prefs.get("program.disable_flushing") == null
|| prefs.get("program.disable_flushing").toLowerCase().equals("false")) {
flushSerialBuffer();
}
String[] cmd = StringReplacer.formatAndSplit(pattern, prefs, true);
return executeUploadCommand(cmd);
} catch (Exception e) {
throw new RunnerException(e);
}
}
public boolean burnBootloader() throws RunnerException {
@ -108,14 +138,15 @@ public class AvrdudeUploader extends Uploader {
if ("usb".equals(programmerPreferences.get("communication"))) {
params.add("-Pusb");
} else if ("serial".equals(programmerPreferences.get("communication"))) {
params.add("-P" + (Base.isWindows() ? "\\\\.\\" : "") + Preferences.get("serial.port"));
params.add("-P" + (Base.isWindows() ? "\\\\.\\" : "")
+ Preferences.get("serial.port"));
if (programmerPreferences.get("speed") != null) {
params.add("-b" + Integer.parseInt(programmerPreferences.get("speed")));
params.add("-b" + Integer.parseInt(programmerPreferences.get("speed")));
}
}
// XXX: add support for specifying the port address for parallel
// programmers, although avrdude has a default that works in most cases.
if (programmerPreferences.get("force") != null &&
programmerPreferences.get("force").toLowerCase().equals("true"))
params.add("-F");
@ -129,7 +160,7 @@ public class AvrdudeUploader extends Uploader {
protected boolean burnBootloader(Collection<String> params)
throws RunnerException {
PreferencesMap boardPreferences = Base.getBoardPreferences();
List<String> fuses = new ArrayList<String>();
List<String> fuses = new ArrayList<String>(params);
fuses.add("-e"); // erase the chip
if (boardPreferences.get("bootloader.unlock_bits") != null)
fuses.add("-Ulock:w:" + boardPreferences.get("bootloader.unlock_bits") + ":m");
@ -138,7 +169,7 @@ public class AvrdudeUploader extends Uploader {
fuses.add("-Uhfuse:w:" + boardPreferences.get("bootloader.high_fuses") + ":m");
fuses.add("-Ulfuse:w:" + boardPreferences.get("bootloader.low_fuses") + ":m");
if (!avrdude(params, fuses))
if (!avrdude(fuses))
return false;
try {
@ -170,18 +201,14 @@ public class AvrdudeUploader extends Uploader {
if (boardPreferences.get("bootloader.lock_bits") != null)
bootloader.add("-Ulock:w:" + boardPreferences.get("bootloader.lock_bits") + ":m");
if (bootloader.size() > 0)
return avrdude(params, bootloader);
if (bootloader.size() > 0) {
params.addAll(bootloader);
return avrdude(params);
}
return true;
}
public boolean avrdude(Collection<String> p1, Collection<String> p2) throws RunnerException {
List<String> p = new ArrayList<String>(p1);
p.addAll(p2);
return avrdude(p);
}
public boolean avrdude(Collection<String> params) throws RunnerException {
List<String> commandDownloader = new ArrayList<String>();

View File

@ -50,7 +50,6 @@ public class Compiler implements MessageConsumer {
private Sketch sketch;
private String primaryClassName;
private List<File> objectFiles;
private PreferencesMap prefs;
@ -71,86 +70,17 @@ public class Compiler implements MessageConsumer {
String _primaryClassName, boolean _verbose)
throws RunnerException {
sketch = _sketch;
primaryClassName = _primaryClassName;
verbose = _verbose;
objectFiles = new ArrayList<File>();
TargetPlatform targetPlatform = Base.getTargetPlatform();
// Merge all the global preference configuration in order of priority
prefs = new PreferencesMap();
prefs.putAll(Preferences.getMap());
prefs.putAll(targetPlatform.getPreferences());
prefs.putAll(Base.getBoardPreferences());
for (String k : prefs.keySet()) {
if (prefs.get(k) == null)
prefs.put(k, "");
}
prefs.put("build.path", _buildPath);
String idePath = System.getProperty("user.dir");
if (Base.isMacOS())
idePath += "/Arduino.app/Contents/Resources/Java";
prefs.put("ide.path", idePath);
prefs.put("ide.version", "" + Base.REVISION);
if (!prefs.containsKey("compiler.path"))
prefs.put("compiler.path", Base.getAvrBasePath());
// Core folder
String core = prefs.get("build.core");
if (core == null) {
RunnerException re = new RunnerException(
_("No board selected; please choose a board from the Tools > Board menu."));
re.hideStackTrace();
throw re;
}
TargetPlatform tp;
if (!core.contains(":")) {
tp = targetPlatform;
} else {
String[] split = core.split(":", 2);
tp = Base.getTargetPlatform(split[0], Preferences.get("target_platform"));
core = split[1];
}
File coreFolder = new File(tp.getFolder(), "cores");
coreFolder = new File(coreFolder, core);
prefs.put("build.core.path", coreFolder.getAbsolutePath());
// System Folder
File systemFolder = targetPlatform.getFolder();
systemFolder = new File(systemFolder, "system");
prefs.put("build.system.path", systemFolder.getAbsolutePath());
// Variant Folder
String variantPath;
String variant = prefs.get("build.variant");
if (variant != null) {
TargetPlatform t;
if (!variant.contains(":")) {
t = targetPlatform;
} else {
String[] split = variant.split(":", 2);
t = Base.getTargetPlatform(split[0], Preferences
.get("target_platform"));
variant = split[1];
}
File variantFolder = new File(t.getFolder(), "variants");
variantFolder = new File(variantFolder, variant);
variantPath = variantFolder.getAbsolutePath();
prefs.put("build.variant.path", variantPath);
} else {
variantPath = null;
prefs.put("build.variant.path", "");
}
prefs = createBuildPreferences(_buildPath, _primaryClassName);
// 0. include paths for core + all libraries
sketch.setCompilingProgress(20);
List<String> includePaths = new ArrayList<String>();
includePaths.add(prefs.get("build.core.path"));
if (variantPath != null)
includePaths.add(variantPath);
if (!prefs.get("build.variant.path").isEmpty())
includePaths.add(prefs.get("build.variant.path"));
for (File file : sketch.getImportedLibraries())
includePaths.add(file.getPath());
@ -184,6 +114,74 @@ public class Compiler implements MessageConsumer {
return true;
}
private PreferencesMap createBuildPreferences(String _buildPath,
String _primaryClassName)
throws RunnerException {
TargetPlatform targetPlatform = Base.getTargetPlatform();
// Merge all the global preference configuration in order of priority
PreferencesMap p = new PreferencesMap();
p.putAll(Preferences.getMap());
p.putAll(targetPlatform.getPreferences());
p.putAll(Base.getBoardPreferences());
for (String k : p.keySet()) {
if (p.get(k) == null)
p.put(k, "");
}
p.put("build.path", _buildPath);
p.put("build.project_name", _primaryClassName);
if (!p.containsKey("compiler.path"))
p.put("compiler.path", Base.getAvrBasePath());
// Core folder
String core = p.get("build.core");
if (core == null) {
RunnerException re = new RunnerException(
_("No board selected; please choose a board from the Tools > Board menu."));
re.hideStackTrace();
throw re;
}
TargetPlatform tp;
if (!core.contains(":")) {
tp = targetPlatform;
} else {
String[] split = core.split(":", 2);
tp = Base.getTargetPlatform(split[0], Preferences.get("target_platform"));
core = split[1];
}
File coreFolder = new File(tp.getFolder(), "cores");
coreFolder = new File(coreFolder, core);
p.put("build.core.path", coreFolder.getAbsolutePath());
// System Folder
File systemFolder = targetPlatform.getFolder();
systemFolder = new File(systemFolder, "system");
p.put("build.system.path", systemFolder.getAbsolutePath());
// Variant Folder
String variant = p.get("build.variant");
if (variant != null) {
TargetPlatform t;
if (!variant.contains(":")) {
t = targetPlatform;
} else {
String[] split = variant.split(":", 2);
t = Base
.getTargetPlatform(split[0], Preferences.get("target_platform"));
variant = split[1];
}
File variantFolder = new File(t.getFolder(), "variants");
variantFolder = new File(variantFolder, variant);
p.put("build.variant.path", variantFolder.getAbsolutePath());
} else {
p.put("build.variant.path", "");
}
return p;
}
private List<File> compileFiles(String outputPath, File sourcePath,
boolean recurse, List<String> includePaths)
throws RunnerException {
@ -640,7 +638,6 @@ public class Compiler implements MessageConsumer {
dict.put("compiler.c.elf.flags", dict
.get("compiler.c.elf.flags" + optRelax));
dict.put("archive_file", "core.a");
dict.put("project_name", primaryClassName);
dict.put("object_files", objectFileList);
dict.put("ide_version", "" + Base.REVISION);
@ -657,7 +654,6 @@ public class Compiler implements MessageConsumer {
// 5. extract EEPROM data (from EEMEM directive) to .eep file.
void compileEep(List<String> includePaths) throws RunnerException {
PreferencesMap dict = new PreferencesMap(prefs);
dict.put("project_name", primaryClassName);
dict.put("ide_version", "" + Base.REVISION);
String[] cmdArray;
@ -673,7 +669,6 @@ public class Compiler implements MessageConsumer {
// 6. build the .hex file
void compileHex(List<String> includePaths) throws RunnerException {
PreferencesMap dict = new PreferencesMap(prefs);
dict.put("project_name", primaryClassName);
dict.put("ide_version", "" + Base.REVISION);
String[] cmdArray;

View File

@ -92,6 +92,10 @@ public class TargetPlatform {
return programmers;
}
public PreferencesMap getTool(String tool) {
return getPreferences().createSubTree("tools").createSubTree(tool);
}
public PreferencesMap getPreferences() {
return preferences;
}

View File

@ -26,26 +26,17 @@
package processing.app.debug;
import processing.app.Base;
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;
import processing.app.I18n;
import static processing.app.I18n._;
import java.io.*;
import java.util.*;
import java.util.zip.*;
import javax.swing.*;
//#ifndef RXTX
//import javax.comm.*;
//#else
// rxtx uses package gnu.io, but all the class names
// are the same as those used by javax.comm
import gnu.io.*;
//#endif
public abstract class Uploader implements MessageConsumer {
static final String BUGS_URL =
@ -54,18 +45,12 @@ public abstract class Uploader implements MessageConsumer {
I18n.format(_("Compiler error, please submit this code to {0}"), BUGS_URL);
RunnerException exception;
//PdePreferences preferences;
//Serial serialPort;
static InputStream serialInput;
static OutputStream serialOutput;
//int serial; // last byte of data received
boolean verbose;
public Uploader() {
}
public abstract boolean uploadUsingPreferences(String buildPath, String className, boolean usingProgrammer)
throws RunnerException, SerialException;
@ -75,9 +60,8 @@ public abstract class Uploader implements MessageConsumer {
// Cleanup the serial buffer
try {
Serial serialPort = new Serial();
byte[] readBuffer;
while(serialPort.available() > 0) {
readBuffer = serialPort.readBytes();
serialPort.readBytes();
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
@ -102,7 +86,14 @@ public abstract class Uploader implements MessageConsumer {
}
}
protected boolean executeUploadCommand(Collection commandDownloader)
protected boolean executeUploadCommand(Collection 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
@ -110,17 +101,12 @@ public abstract class Uploader implements MessageConsumer {
notFoundError = false;
int result=0; // pre-initialized to quiet a bogus warning from jikes
String userdir = System.getProperty("user.dir") + File.separator;
try {
String[] commandArray = new String[commandDownloader.size()];
commandDownloader.toArray(commandArray);
if (verbose || Preferences.getBoolean("upload.verbose")) {
for(int i = 0; i < commandArray.length; i++) {
System.out.print(commandArray[i] + " ");
}
System.out.println();
if (verbose || Preferences.getBoolean("upload.verbose")) {
}
Process process = Runtime.getRuntime().exec(commandArray);
new MessageSiphon(process.getInputStream(), this);