1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-03-21 12:29:23 +01: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);

View File

@ -1,6 +1,7 @@
##############################################################
uno.name=Arduino Uno
uno.upload.tool=avrdude
uno.upload.protocol=arduino
uno.upload.maximum_size=32256
uno.upload.speed=115200
@ -175,7 +176,7 @@ mega.build.variant=mega
##############################################################
mini328.name=Arduino Mini w/ ATmega328
mini328.upload.protocol=stk500
mini328.upload.protocol=stk500v1
mini328.upload.maximum_size=28672
mini328.upload.speed=115200
@ -452,3 +453,4 @@ atmega8.build.mcu=atmega8
atmega8.build.f_cpu=16000000L
atmega8.build.core=arduino
atmega8.build.variant=standard

View File

@ -26,22 +26,56 @@ compiler.upload.flags=
# --------------------
## Compile c files
recipe.c.o.pattern={compiler.path}{compiler.c.cmd} {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={ide.version} {includes} {source_file} -o {object_file}
recipe.c.o.pattern={compiler.path}{compiler.c.cmd} {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={runtime.ide.version} {includes} {source_file} -o {object_file}
## Compile c++ files
recipe.cpp.o.pattern={compiler.path}{compiler.cpp.cmd} {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={ide.version} {includes} {source_file} -o {object_file}
recipe.cpp.o.pattern={compiler.path}{compiler.cpp.cmd} {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={runtime.ide.version} {includes} {source_file} -o {object_file}
## Create archives
recipe.ar.pattern={compiler.path}{compiler.ar.cmd} {compiler.ar.flags} {build.path}/{archive_file} {object_file}
## Combine gc-sections, archives, and objects
recipe.c.combine.pattern={compiler.path}{compiler.c.elf.cmd} {compiler.c.elf.flags} -mmcu={build.mcu} -o {build.path}/{project_name}.elf {object_files} {build.path}/{archive_file} -L{build.path} -lm
recipe.c.combine.pattern={compiler.path}{compiler.c.elf.cmd} {compiler.c.elf.flags} -mmcu={build.mcu} -o {build.path}/{build.project_name}.elf {object_files} {build.path}/{archive_file} -L{build.path} -lm
## Create eeprom
recipe.objcopy.eep.pattern={compiler.path}{compiler.objcopy.cmd} {compiler.objcopy.eep.flags} {build.path}/{project_name}.elf {build.path}/{project_name}.eep
recipe.objcopy.eep.pattern={compiler.path}{compiler.objcopy.cmd} {compiler.objcopy.eep.flags} {build.path}/{build.project_name}.elf {build.path}/{build.project_name}.eep
## Create hex
recipe.objcopy.hex.pattern={compiler.path}{compiler.elf2hex.cmd} {compiler.elf2hex.flags} {build.path}/{project_name}.elf {build.path}/{project_name}.hex
recipe.objcopy.hex.pattern={compiler.path}{compiler.elf2hex.cmd} {compiler.elf2hex.flags} {build.path}/{build.project_name}.elf {build.path}/{build.project_name}.hex
# AVR Uploader/Programmers tools
# -------------------
tools.avrdude.upload.cmd=avrdude
tools.avrdude.upload.path={runtime.ide.path}/hardware/tools
tools.avrdude.upload.config.path={upload.path}/avrdude.conf
tools.avrdude.upload.params.verbose=-v -v -v -v
tools.avrdude.upload.params.quiet=-q -q
tools.avrdude.upload.pattern={upload.path}/{upload.cmd} -C{upload.config.path} {upload.verbose} -p{build.mcu} -c{upload.protocol} -P{serial.port} -b{upload.speed} -D -Uflash:w:{build.path}/{build.project_name}.hex:i
# /home/megabug/git/ARM-merged/build/linux/work/hardware/tools/avrdude
# -C/home/megabug/git/ARM-merged/build/linux/work/hardware/tools/avrdude.conf
# -q -q
# -patmega328p
# -carduino
# -P/dev/ttyACM0
# -b115200
# -D
# -Uflash:w:/tmp/build366783256629686367.tmp/Blink.cpp.hex:i
tools.avrdude.program.cmd=avrdude
tools.avrdude.program.path={runtime.ide.path}/hardware/tools
tools.avrdude.program.config.path={program.path}/avrdude.conf
tools.avrdude.program.params.verbose=-v -v -v -v
tools.avrdude.program.params.quiet=-q -q
tools.avrdude.program.pattern={program.path}/{program.cmd} -C{program.config.path} {program.verbose} -p{build.mcu} -c{protocol} {program.extra_params} -Uflash:w:{build.path}/{build.project_name}.hex:i
# /home/megabug/git/ARM-merged/build/linux/work/hardware/tools/avrdude
# -C/home/megabug/git/ARM-merged/build/linux/work/hardware/tools/avrdude.conf
# -q -q
# -patmega328p
# -cusbasp
# -Pusb
# -Uflash:w:/tmp/build8190214930979711138.tmp/Blink.cpp.hex:i

View File

@ -1,24 +1,41 @@
avrisp.name=AVR ISP
avrisp.communication=serial
avrisp.protocol=stk500v1
avrisp.program.protocol=stk500v1
avrisp.program.tool=avrdude
avrisp.program.extra_params=-P{serial.port}
avrispmkii.name=AVRISP mkII
avrispmkii.communication=usb
avrispmkii.protocol=stk500v2
avrispmkii.program.protocol=stk500v2
avrispmkii.program.tool=avrdude
avrispmkii.program.extra_params=-Pusb
usbtinyisp.name=USBtinyISP
usbtinyisp.protocol=usbtiny
usbtinyisp.program.tool=avrdude
usbtinyisp.program.extra_params=
usbasp.name=USBasp
usbasp.communication=usb
usbasp.protocol=usbasp
usbasp.program.protocol=usbasp
usbasp.program.tool=avrdude
usbasp.program.extra_params=-Pusb
parallel.name=Parallel Programmer
parallel.protocol=dapa
parallel.force=true
# parallel.delay=200
parallel.program.tool=avrdude
parallel.program.extra_params=
arduinoisp.name=Arduino as ISP
arduinoisp.communication=serial
arduinoisp.protocol=stk500v1
arduinoisp.speed=9600
arduinoisp.program.protocol=stk500v1
arduinoisp.program.speed=9600
arduinoisp.program.tool=avrdude
arduinoisp.program.extra_params=-P{serial.port} -b{program.speed}