Improving third-party hardware support:

- moving back to multple cores per platform
- using target instead of platform
- moving per-board and per-programmer preferences out of Preferences.java and into a new Target class
- adding a new "target" preference
- support for platform:value values in board preferences for bootloader path and core
- XXX: need to support platform:value syntax for board upload.using preferences.
This commit is contained in:
David A. Mellis 2009-11-21 23:23:43 +00:00
parent 8720addcba
commit d2a38e4b5a
28 changed files with 205 additions and 203 deletions

View File

@ -30,6 +30,7 @@ import java.util.*;
import javax.swing.*; import javax.swing.*;
import processing.app.debug.Compiler; import processing.app.debug.Compiler;
import processing.app.debug.Target;
import processing.core.*; import processing.core.*;
@ -85,7 +86,7 @@ public class Base {
// found in the sketchbook) // found in the sketchbook)
static public String librariesClassPath; static public String librariesClassPath;
static public HashMap<String, File> platformsTable; static public HashMap<String, Target> targetsTable;
// Location for untitled items // Location for untitled items
static File untitledFolder; static File untitledFolder;
@ -278,7 +279,7 @@ public class Base {
} }
} }
platformsTable = new HashMap<String, File>(); targetsTable = new HashMap<String, Target>();
loadHardware(getHardwareFolder()); loadHardware(getHardwareFolder());
loadHardware(getSketchbookHardwareFolder()); loadHardware(getSketchbookHardwareFolder());
@ -997,19 +998,26 @@ public class Base {
//System.out.println("rebuilding boards menu"); //System.out.println("rebuilding boards menu");
menu.removeAll(); menu.removeAll();
ButtonGroup group = new ButtonGroup(); ButtonGroup group = new ButtonGroup();
for (String board : Preferences.getSubKeys("boards")) { for (Target target : targetsTable.values()) {
AbstractAction action = for (String board : target.getBoards().keySet()) {
new AbstractAction(Preferences.get("boards." + board + ".name")) { AbstractAction action =
public void actionPerformed(ActionEvent actionevent) { new AbstractAction(target.getBoards().get(board).get("name")) {
//System.out.println("Switching to " + board); public void actionPerformed(ActionEvent actionevent) {
Preferences.set("board", (String) getValue("board")); //System.out.println("Switching to " + target + ":" + board);
} Preferences.set("target", (String) getValue("target"));
}; Preferences.set("board", (String) getValue("board"));
action.putValue("board", board); }
JMenuItem item = new JRadioButtonMenuItem(action); };
if (board.equals(Preferences.get("board"))) item.setSelected(true); action.putValue("target", target.getName());
group.add(item); action.putValue("board", board);
menu.add(item); JMenuItem item = new JRadioButtonMenuItem(action);
if (target.getName().equals(Preferences.get("target")) &&
board.equals(Preferences.get("board"))) {
item.setSelected(true);
}
group.add(item);
menu.add(item);
}
} }
} }
@ -1017,17 +1025,21 @@ public class Base {
public void rebuildBurnBootloaderMenu(JMenu menu) { public void rebuildBurnBootloaderMenu(JMenu menu) {
//System.out.println("rebuilding burn bootloader menu"); //System.out.println("rebuilding burn bootloader menu");
menu.removeAll(); menu.removeAll();
for (String programmer : Preferences.getSubKeys("programmers")) { for (Target target : targetsTable.values()) {
AbstractAction action = for (String programmer : target.getProgrammers().keySet()) {
new AbstractAction( AbstractAction action =
"w/ " + Preferences.get("programmers." + programmer + ".name")) { new AbstractAction(
public void actionPerformed(ActionEvent actionevent) { "w/ " + target.getProgrammers().get(programmer).get("name")) {
activeEditor.handleBurnBootloader((String) getValue("programmer")); public void actionPerformed(ActionEvent actionevent) {
} activeEditor.handleBurnBootloader((String) getValue("target"),
}; (String) getValue("programmer"));
action.putValue("programmer", programmer); }
JMenuItem item = new JMenuItem(action); };
menu.add(item); action.putValue("target", target.getName());
action.putValue("programmer", programmer);
JMenuItem item = new JMenuItem(action);
menu.add(item);
}
} }
} }
@ -1228,30 +1240,9 @@ public class Base {
// replaced hella slow bubble sort with this feller for 0093 // replaced hella slow bubble sort with this feller for 0093
Arrays.sort(list, String.CASE_INSENSITIVE_ORDER); Arrays.sort(list, String.CASE_INSENSITIVE_ORDER);
for (String platform : list) { for (String target : list) {
File subfolder = new File(folder, platform); File subfolder = new File(folder, target);
targetsTable.put(target, new Target(target, subfolder));
File boardsFile = new File(subfolder, "boards.txt");
try {
if (boardsFile.exists()) {
Preferences.load(new FileInputStream(boardsFile), "boards");
}
} catch (Exception e) {
System.err.println("Error loading boards from " +
boardsFile + ": " + e);
}
File programmersFile = new File(subfolder, "programmers.txt");
try {
if (programmersFile.exists()) {
Preferences.load(new FileInputStream(programmersFile), "programmers");
}
} catch (Exception e) {
System.err.println("Error loading programmers from " +
programmersFile + ": " + e);
}
platformsTable.put(platform, subfolder);
} }
} }
@ -1524,6 +1515,16 @@ public class Base {
} }
} }
static public Target getTarget() {
return Base.targetsTable.get(Preferences.get("target"));
}
static public Map<String, String> getBoardPreferences() {
return getTarget().getBoards().get(Preferences.get("board"));
}
static public File getSketchbookFolder() { static public File getSketchbookFolder() {
return new File(Preferences.get("sketchbook.path")); return new File(Preferences.get("sketchbook.path"));

View File

@ -2279,14 +2279,14 @@ public class Editor extends JFrame implements RunnerListener {
} }
protected void handleBurnBootloader(final String programmer) { protected void handleBurnBootloader(final String target, final String programmer) {
console.clear(); console.clear();
statusNotice("Burning bootloader to I/O Board (this may take a minute)..."); statusNotice("Burning bootloader to I/O Board (this may take a minute)...");
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
public void run() { public void run() {
try { try {
Uploader uploader = new AvrdudeUploader(); Uploader uploader = new AvrdudeUploader();
if (uploader.burnBootloader(programmer)) { if (uploader.burnBootloader(target, programmer)) {
statusNotice("Done burning bootloader."); statusNotice("Done burning bootloader.");
} else { } else {
statusError("Error while burning bootloader."); statusError("Error while burning bootloader.");

View File

@ -131,7 +131,6 @@ public class Preferences {
static Hashtable defaults; static Hashtable defaults;
static Hashtable table = new Hashtable();; static Hashtable table = new Hashtable();;
static Hashtable prefixes = new Hashtable();
static File preferencesFile; static File preferencesFile;
@ -550,12 +549,7 @@ public class Preferences {
load(input, table); load(input, table);
} }
static protected void load(InputStream input, String prefix) throws IOException { static public void load(InputStream input, Map table) throws IOException {
if (!prefixes.containsKey(prefix)) prefixes.put(prefix, new LinkedHashMap());
load(input, (Map) prefixes.get(prefix));
}
static protected void load(InputStream input, Map table) throws IOException {
String[] lines = PApplet.loadStrings(input); // Reads as UTF-8 String[] lines = PApplet.loadStrings(input); // Reads as UTF-8
for (String line : lines) { for (String line : lines) {
if ((line.length() == 0) || if ((line.length() == 0) ||
@ -609,24 +603,7 @@ public class Preferences {
//return get(attribute, null); //return get(attribute, null);
//} //}
static public String get(String prefix, String selector, String suffix) {
if (get(selector) == null) return null;
return get(prefix + "." + get(selector) + "." + suffix);
}
static public String get(String attribute /*, String defaultValue */) { static public String get(String attribute /*, String defaultValue */) {
// if the attribute starts with a prefix used by one of our subsidiary
// preference files, look up the attribute in that file's Hashtable
// (don't override with or fallback to the main file). otherwise,
// look up the attribute in the main file's Hashtable.
Map table = Preferences.table;
if (attribute.indexOf('.') != -1) {
String prefix = attribute.substring(0, attribute.indexOf('.'));
if (prefixes.containsKey(prefix)) {
table = (Map) prefixes.get(prefix);
attribute = attribute.substring(attribute.indexOf('.') + 1);
}
}
return (String) table.get(attribute); return (String) table.get(attribute);
/* /*
//String value = (properties != null) ? //String value = (properties != null) ?
@ -639,28 +616,6 @@ public class Preferences {
} }
/**
* Get the top-level key prefixes defined in the subsidiary file loaded with
* the given prefix. For example, if the file contains:
* foo.count=1
* bar.count=2
* baz.count=3
* this will return { "foo", "bar", "baz" }.
*/
static public Set<String> getSubKeys(String prefix) {
if (!prefixes.containsKey(prefix))
return null;
Set subkeys = new LinkedHashSet();
for (Iterator i = ((Map) prefixes.get(prefix)).keySet().iterator(); i.hasNext(); ) {
String subkey = (String) i.next();
if (subkey.indexOf('.') != -1)
subkey = subkey.substring(0, subkey.indexOf('.'));
subkeys.add(subkey);
}
return subkeys;
}
static public String getDefault(String attribute) { static public String getDefault(String attribute) {
return (String) defaults.get(attribute); return (String) defaults.get(attribute);
} }

View File

@ -1447,7 +1447,7 @@ public class Sketch {
protected void size(String buildPath, String suggestedClassName) protected void size(String buildPath, String suggestedClassName)
throws RunnerException { throws RunnerException {
long size = 0; long size = 0;
long maxsize = Preferences.getInteger("boards." + Preferences.get("board") + ".upload.maximum_size"); long maxsize = Integer.parseInt(Base.getBoardPreferences().get("upload.maximum_size"));
Sizer sizer = new Sizer(buildPath, suggestedClassName); Sizer sizer = new Sizer(buildPath, suggestedClassName);
try { try {
size = sizer.computeSize(); size = sizer.computeSize();

View File

@ -45,8 +45,8 @@ public class AvrdudeUploader extends Uploader {
public boolean uploadUsingPreferences(String buildPath, String className, boolean verbose) public boolean uploadUsingPreferences(String buildPath, String className, boolean verbose)
throws RunnerException { throws RunnerException {
this.verbose = verbose; this.verbose = verbose;
String uploadUsing = Map<String, String> boardPreferences = Base.getBoardPreferences();
Preferences.get("boards." + Preferences.get("board") + ".upload.using"); String uploadUsing = boardPreferences.get("upload.using");
if (uploadUsing == null) { if (uploadUsing == null) {
// fall back on global preference // fall back on global preference
uploadUsing = Preferences.get("upload.using"); uploadUsing = Preferences.get("upload.using");
@ -54,7 +54,8 @@ public class AvrdudeUploader extends Uploader {
if (uploadUsing.equals("bootloader")) { if (uploadUsing.equals("bootloader")) {
return uploadViaBootloader(buildPath, className); return uploadViaBootloader(buildPath, className);
} else { } else {
Collection params = getProgrammerCommands(uploadUsing); // XXX: this needs to handle programmers in other targets.
Collection params = getProgrammerCommands(Base.getTarget().getName(), uploadUsing);
params.add("-Uflash:w:" + buildPath + File.separator + className + ".hex:i"); params.add("-Uflash:w:" + buildPath + File.separator + className + ".hex:i");
return avrdude(params); return avrdude(params);
} }
@ -62,9 +63,9 @@ public class AvrdudeUploader extends Uploader {
private boolean uploadViaBootloader(String buildPath, String className) private boolean uploadViaBootloader(String buildPath, String className)
throws RunnerException { throws RunnerException {
Map<String, String> boardPreferences = Base.getBoardPreferences();
List commandDownloader = new ArrayList(); List commandDownloader = new ArrayList();
String protocol = String protocol = boardPreferences.get("upload.protocol");
Preferences.get("boards." + Preferences.get("board") + ".upload.protocol");
// avrdude wants "stk500v1" to distinguish it from stk500v2 // avrdude wants "stk500v1" to distinguish it from stk500v2
if (protocol.equals("stk500")) if (protocol.equals("stk500"))
@ -73,56 +74,59 @@ public class AvrdudeUploader extends Uploader {
commandDownloader.add( commandDownloader.add(
"-P" + (Base.isWindows() ? "\\\\.\\" : "") + Preferences.get("serial.port")); "-P" + (Base.isWindows() ? "\\\\.\\" : "") + Preferences.get("serial.port"));
commandDownloader.add( commandDownloader.add(
"-b" + Preferences.getInteger("boards." + Preferences.get("board") + ".upload.speed")); "-b" + Integer.parseInt(boardPreferences.get("upload.speed")));
commandDownloader.add("-D"); // don't erase commandDownloader.add("-D"); // don't erase
commandDownloader.add("-Uflash:w:" + buildPath + File.separator + className + ".hex:i"); commandDownloader.add("-Uflash:w:" + buildPath + File.separator + className + ".hex:i");
if (Preferences.get("boards", "board", "upload.disable_flushing") == null || if (boardPreferences.get("upload.disable_flushing") == null ||
Preferences.getBoolean("boards." + Preferences.get("board") + ".upload.disable_flushing") == false) { boardPreferences.get("upload.disable_flushing").toLowerCase().equals("false")) {
flushSerialBuffer(); flushSerialBuffer();
} }
return avrdude(commandDownloader); return avrdude(commandDownloader);
} }
public boolean burnBootloader(String programmer) throws RunnerException { public boolean burnBootloader(String target, String programmer) throws RunnerException {
return burnBootloader(getProgrammerCommands(programmer)); return burnBootloader(getProgrammerCommands(target, programmer));
} }
private Collection getProgrammerCommands(String programmer) { private Collection getProgrammerCommands(String targetName, String programmer) {
Target target = Base.targetsTable.get(targetName);
Map<String, String> programmerPreferences = target.getProgrammers().get(programmer);
List params = new ArrayList(); List params = new ArrayList();
params.add("-c" + Preferences.get("programmers." + programmer + ".protocol")); params.add("-c" + programmerPreferences.get("protocol"));
if ("usb".equals(Preferences.get("programmers." + programmer + ".communication"))) { if ("usb".equals(programmerPreferences.get("communication"))) {
params.add("-Pusb"); params.add("-Pusb");
} else if ("serial".equals(Preferences.get("programmers." + programmer + ".communication"))) { } 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 (Preferences.get("programmers." + programmer + ".speed") != null) { if (programmerPreferences.get("speed") != null) {
params.add("-b" + Preferences.getInteger("programmers." + programmer + ".speed")); params.add("-b" + Integer.parseInt(programmerPreferences.get("speed")));
} }
} }
// XXX: add support for specifying the port address for parallel // XXX: add support for specifying the port address for parallel
// programmers, although avrdude has a default that works in most cases. // programmers, although avrdude has a default that works in most cases.
if (Preferences.get("programmers." + programmer + ".force") != null && if (programmerPreferences.get("force") != null &&
Preferences.getBoolean("programmers." + programmer + ".force")) programmerPreferences.get("force").toLowerCase().equals("true"))
params.add("-F"); params.add("-F");
if (Preferences.get("programmers." + programmer + ".delay") != null) if (programmerPreferences.get("delay") != null)
params.add("-i" + Preferences.get("programmers." + programmer + ".delay")); params.add("-i" + programmerPreferences.get("delay"));
return params; return params;
} }
protected boolean burnBootloader(Collection params) protected boolean burnBootloader(Collection params)
throws RunnerException { throws RunnerException {
Map<String, String> boardPreferences = Base.getBoardPreferences();
List fuses = new ArrayList(); List fuses = new ArrayList();
fuses.add("-e"); // erase the chip fuses.add("-e"); // erase the chip
fuses.add("-Ulock:w:" + Preferences.get("boards", "board", "bootloader.unlock_bits") + ":m"); fuses.add("-Ulock:w:" + boardPreferences.get("bootloader.unlock_bits") + ":m");
if (Preferences.get("boards", "board", "bootloader.extended_fuses") != null) if (boardPreferences.get("bootloader.extended_fuses") != null)
fuses.add("-Uefuse:w:" + Preferences.get("boards", "board", "bootloader.extended_fuses") + ":m"); fuses.add("-Uefuse:w:" + boardPreferences.get("bootloader.extended_fuses") + ":m");
fuses.add("-Uhfuse:w:" + Preferences.get("boards", "board", "bootloader.high_fuses") + ":m"); fuses.add("-Uhfuse:w:" + boardPreferences.get("bootloader.high_fuses") + ":m");
fuses.add("-Ulfuse:w:" + Preferences.get("boards", "board", "bootloader.low_fuses") + ":m"); fuses.add("-Ulfuse:w:" + boardPreferences.get("bootloader.low_fuses") + ":m");
if (!avrdude(params, fuses)) if (!avrdude(params, fuses))
return false; return false;
@ -130,16 +134,26 @@ public class AvrdudeUploader extends Uploader {
try { try {
Thread.sleep(1000); Thread.sleep(1000);
} catch (InterruptedException e) {} } catch (InterruptedException e) {}
String platform = Preferences.get("boards", "board", "build.core"); Target t;
File platformFile = Base.platformsTable.get(platform); String bootloaderPath = boardPreferences.get("bootloader.path");
String bootloadersPath = new File(platformFile, "bootloaders").getAbsolutePath();
if (bootloaderPath.indexOf(':') == -1) {
t = Base.getTarget(); // the current target (associated with the board)
} else {
String targetName = bootloaderPath.substring(0, bootloaderPath.indexOf(':'));
t = Base.targetsTable.get(targetName);
bootloaderPath = bootloaderPath.substring(bootloaderPath.indexOf(':') + 1);
}
File bootloadersFile = new File(t.getFolder(), "bootloaders");
File bootloaderFile = new File(bootloadersFile, bootloaderPath);
bootloaderPath = bootloaderFile.getAbsolutePath();
List bootloader = new ArrayList(); List bootloader = new ArrayList();
bootloader.add("-Uflash:w:" + bootloadersPath + File.separator + bootloader.add("-Uflash:w:" + bootloaderPath + File.separator +
Preferences.get("boards", "board", "bootloader.path") + File.separator + boardPreferences.get("bootloader.file") + ":i");
Preferences.get("boards", "board", "bootloader.file") + ":i"); bootloader.add("-Ulock:w:" + boardPreferences.get("bootloader.lock_bits") + ":m");
bootloader.add("-Ulock:w:" + Preferences.get("boards", "board", "bootloader.lock_bits") + ":m");
return avrdude(params, bootloader); return avrdude(params, bootloader);
} }
@ -172,7 +186,7 @@ public class AvrdudeUploader extends Uploader {
commandDownloader.add("-q"); commandDownloader.add("-q");
commandDownloader.add("-q"); commandDownloader.add("-q");
} }
commandDownloader.add("-p" + Preferences.get("boards", "board", "build.mcu")); commandDownloader.add("-p" + Base.getBoardPreferences().get("build.mcu"));
commandDownloader.addAll(params); commandDownloader.addAll(params);
return executeUploadCommand(commandDownloader); return executeUploadCommand(commandDownloader);

View File

@ -71,9 +71,20 @@ public class Compiler implements MessageConsumer {
MessageStream pms = new MessageStream(this); MessageStream pms = new MessageStream(this);
String avrBasePath = Base.getAvrBasePath(); String avrBasePath = Base.getAvrBasePath();
String platform = Preferences.get("boards", "board", "build.core"); Map<String, String> boardPreferences = Base.getBoardPreferences();
File platformFile = Base.platformsTable.get(platform); String core = boardPreferences.get("build.core");
String corePath = new File(platformFile, "core").getAbsolutePath(); String corePath;
if (core.indexOf(':') == -1) {
Target t = Base.getTarget();
File coreFolder = new File(new File(t.getFolder(), "cores"), core);
corePath = coreFolder.getAbsolutePath();
} else {
Target t = Base.targetsTable.get(core.substring(0, core.indexOf(':')));
File coresFolder = new File(t.getFolder(), "cores");
File coreFolder = new File(coresFolder, core.substring(core.indexOf(':') + 1));
corePath = coreFolder.getAbsolutePath();
}
List<File> objectFiles = new ArrayList<File>(); List<File> objectFiles = new ArrayList<File>();
@ -89,7 +100,8 @@ public class Compiler implements MessageConsumer {
compileFiles(avrBasePath, buildPath, includePaths, compileFiles(avrBasePath, buildPath, includePaths,
findFilesInPath(corePath, "S", true), findFilesInPath(corePath, "S", true),
findFilesInPath(corePath, "c", true), findFilesInPath(corePath, "c", true),
findFilesInPath(corePath, "cpp", true)); findFilesInPath(corePath, "cpp", true),
boardPreferences);
List baseCommandAR = new ArrayList(Arrays.asList(new String[] { List baseCommandAR = new ArrayList(Arrays.asList(new String[] {
avrBasePath + "avr-ar", avrBasePath + "avr-ar",
@ -120,14 +132,16 @@ public class Compiler implements MessageConsumer {
compileFiles(avrBasePath, outputFolder.getAbsolutePath(), includePaths, compileFiles(avrBasePath, outputFolder.getAbsolutePath(), includePaths,
findFilesInFolder(libraryFolder, "S", false), findFilesInFolder(libraryFolder, "S", false),
findFilesInFolder(libraryFolder, "c", false), findFilesInFolder(libraryFolder, "c", false),
findFilesInFolder(libraryFolder, "cpp", false))); findFilesInFolder(libraryFolder, "cpp", false),
boardPreferences));
outputFolder = new File(outputFolder, "utility"); outputFolder = new File(outputFolder, "utility");
createFolder(outputFolder); createFolder(outputFolder);
objectFiles.addAll( objectFiles.addAll(
compileFiles(avrBasePath, outputFolder.getAbsolutePath(), includePaths, compileFiles(avrBasePath, outputFolder.getAbsolutePath(), includePaths,
findFilesInFolder(utilityFolder, "S", false), findFilesInFolder(utilityFolder, "S", false),
findFilesInFolder(utilityFolder, "c", false), findFilesInFolder(utilityFolder, "c", false),
findFilesInFolder(utilityFolder, "cpp", false))); findFilesInFolder(utilityFolder, "cpp", false),
boardPreferences));
// other libraries should not see this library's utility/ folder // other libraries should not see this library's utility/ folder
includePaths.remove(includePaths.size() - 1); includePaths.remove(includePaths.size() - 1);
} }
@ -138,7 +152,8 @@ public class Compiler implements MessageConsumer {
compileFiles(avrBasePath, buildPath, includePaths, compileFiles(avrBasePath, buildPath, includePaths,
findFilesInPath(buildPath, "S", false), findFilesInPath(buildPath, "S", false),
findFilesInPath(buildPath, "c", false), findFilesInPath(buildPath, "c", false),
findFilesInPath(buildPath, "cpp", false))); findFilesInPath(buildPath, "cpp", false),
boardPreferences));
// 4. link it all together into the .elf file // 4. link it all together into the .elf file
@ -146,7 +161,7 @@ public class Compiler implements MessageConsumer {
avrBasePath + "avr-gcc", avrBasePath + "avr-gcc",
"-Os", "-Os",
"-Wl,--gc-sections", "-Wl,--gc-sections",
"-mmcu=" + Preferences.get("boards", "board", "build.mcu"), "-mmcu=" + boardPreferences.get("build.mcu"),
"-o", "-o",
buildPath + File.separator + primaryClassName + ".elf" buildPath + File.separator + primaryClassName + ".elf"
})); }));
@ -197,7 +212,8 @@ public class Compiler implements MessageConsumer {
private List<File> compileFiles(String avrBasePath, private List<File> compileFiles(String avrBasePath,
String buildPath, List<File> includePaths, String buildPath, List<File> includePaths,
List<File> sSources, List<File> sSources,
List<File> cSources, List<File> cppSources) List<File> cSources, List<File> cppSources,
Map<String, String> boardPreferences)
throws RunnerException { throws RunnerException {
List<File> objectPaths = new ArrayList<File>(); List<File> objectPaths = new ArrayList<File>();
@ -207,7 +223,8 @@ public class Compiler implements MessageConsumer {
objectPaths.add(new File(objectPath)); objectPaths.add(new File(objectPath));
execAsynchronously(getCommandCompilerS(avrBasePath, includePaths, execAsynchronously(getCommandCompilerS(avrBasePath, includePaths,
file.getAbsolutePath(), file.getAbsolutePath(),
objectPath)); objectPath,
boardPreferences));
} }
for (File file : cSources) { for (File file : cSources) {
@ -215,7 +232,8 @@ public class Compiler implements MessageConsumer {
objectPaths.add(new File(objectPath)); objectPaths.add(new File(objectPath));
execAsynchronously(getCommandCompilerC(avrBasePath, includePaths, execAsynchronously(getCommandCompilerC(avrBasePath, includePaths,
file.getAbsolutePath(), file.getAbsolutePath(),
objectPath)); objectPath,
boardPreferences));
} }
for (File file : cppSources) { for (File file : cppSources) {
@ -223,7 +241,8 @@ public class Compiler implements MessageConsumer {
objectPaths.add(new File(objectPath)); objectPaths.add(new File(objectPath));
execAsynchronously(getCommandCompilerCPP(avrBasePath, includePaths, execAsynchronously(getCommandCompilerCPP(avrBasePath, includePaths,
file.getAbsolutePath(), file.getAbsolutePath(),
objectPath)); objectPath,
boardPreferences));
} }
return objectPaths; return objectPaths;
@ -448,14 +467,14 @@ public class Compiler implements MessageConsumer {
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
static private List getCommandCompilerS(String avrBasePath, List includePaths, static private List getCommandCompilerS(String avrBasePath, List includePaths,
String sourceName, String objectName) { String sourceName, String objectName, Map<String, String> boardPreferences) {
List baseCommandCompiler = new ArrayList(Arrays.asList(new String[] { List baseCommandCompiler = new ArrayList(Arrays.asList(new String[] {
avrBasePath + "avr-gcc", avrBasePath + "avr-gcc",
"-c", // compile, don't link "-c", // compile, don't link
"-g", // include debugging info (so errors include line numbers) "-g", // include debugging info (so errors include line numbers)
"-assembler-with-cpp", "-assembler-with-cpp",
"-mmcu=" + Preferences.get("boards", "board", "build.mcu"), "-mmcu=" + boardPreferences.get("build.mcu"),
"-DF_CPU=" + Preferences.get("boards", "board", "build.f_cpu"), "-DF_CPU=" + boardPreferences.get("build.f_cpu"),
"-DARDUINO=" + Base.REVISION, "-DARDUINO=" + Base.REVISION,
})); }));
@ -471,7 +490,7 @@ public class Compiler implements MessageConsumer {
static private List getCommandCompilerC(String avrBasePath, List includePaths, static private List getCommandCompilerC(String avrBasePath, List includePaths,
String sourceName, String objectName) { String sourceName, String objectName, Map<String, String> boardPreferences) {
List baseCommandCompiler = new ArrayList(Arrays.asList(new String[] { List baseCommandCompiler = new ArrayList(Arrays.asList(new String[] {
avrBasePath + "avr-gcc", avrBasePath + "avr-gcc",
@ -481,8 +500,8 @@ public class Compiler implements MessageConsumer {
"-w", // surpress all warnings "-w", // surpress all warnings
"-ffunction-sections", // place each function in its own section "-ffunction-sections", // place each function in its own section
"-fdata-sections", "-fdata-sections",
"-mmcu=" + Preferences.get("boards", "board", "build.mcu"), "-mmcu=" + boardPreferences.get("build.mcu"),
"-DF_CPU=" + Preferences.get("boards", "board", "build.f_cpu"), "-DF_CPU=" + boardPreferences.get("build.f_cpu"),
"-DARDUINO=" + Base.REVISION, "-DARDUINO=" + Base.REVISION,
})); }));
@ -498,7 +517,8 @@ public class Compiler implements MessageConsumer {
static private List getCommandCompilerCPP(String avrBasePath, static private List getCommandCompilerCPP(String avrBasePath,
List includePaths, String sourceName, String objectName) { List includePaths, String sourceName, String objectName,
Map<String, String> boardPreferences) {
List baseCommandCompilerCPP = new ArrayList(Arrays.asList(new String[] { List baseCommandCompilerCPP = new ArrayList(Arrays.asList(new String[] {
avrBasePath + "avr-g++", avrBasePath + "avr-g++",
@ -509,8 +529,8 @@ public class Compiler implements MessageConsumer {
"-fno-exceptions", "-fno-exceptions",
"-ffunction-sections", // place each function in its own section "-ffunction-sections", // place each function in its own section
"-fdata-sections", "-fdata-sections",
"-mmcu=" + Preferences.get("boards", "board", "build.mcu"), "-mmcu=" + boardPreferences.get("build.mcu"),
"-DF_CPU=" + Preferences.get("boards", "board", "build.f_cpu"), "-DF_CPU=" + boardPreferences.get("build.f_cpu"),
"-DARDUINO=" + Base.REVISION, "-DARDUINO=" + Base.REVISION,
})); }));

View File

@ -1,11 +1,10 @@
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/* /*
Target - represents a target platform Target - represents a hardware platform
Part of the Arduino project - http://arduino.berlios.de/ Part of the Arduino project - http://www.arduino.cc/
Copyright (c) 2005 Copyright (c) 2009 David A. Mellis
David A. Mellis
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -21,59 +20,72 @@
along with this program; if not, write to the Free Software Foundation, along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
$Id: Target.java 85 2006-01-12 23:24:12Z mellis $ $Id$
*/ */
package processing.app.debug; package processing.app.debug;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
/** import processing.app.Preferences;
* Represents a target platform (e.g. Wiring board, Arduino board).
*/
public class Target {
String path;
List sources = new ArrayList();
List objects = new ArrayList();
/** public class Target {
* Create a Target. private String name;
* @param path the directory containing config, source, and object files for private File folder;
* the target platform. private Map boards;
*/ private Map programmers;
public Target(String base, String target) throws IOException {
path = base + File.separator + target; public Target(String name, File folder) {
String[] files = (new File(path)).list(); this.name = name;
this.folder = folder;
this.boards = new LinkedHashMap();
this.programmers = new LinkedHashMap();
if (files == null) File boardsFile = new File(folder, "boards.txt");
throw new IOException("Target platform: \"" + target + "\" not found.\n" + try {
"Make sure that \"build.target\" in the \n" + if (boardsFile.exists()) {
"preferences file points to a subdirectory of \n" + Map boardPreferences = new LinkedHashMap();
base); Preferences.load(new FileInputStream(boardsFile), boardPreferences);
for (Object k : boardPreferences.keySet()) {
for (int i = 0; i < files.length; i++) { String key = (String) k;
if (files[i].endsWith(".S") || files[i].endsWith(".c") || files[i].endsWith(".cpp")) String board = key.substring(0, key.indexOf('.'));
sources.add(files[i]); if (!boards.containsKey(board)) boards.put(board, new HashMap());
if (files[i].endsWith(".o")) ((Map) boards.get(board)).put(
objects.add(files[i]); key.substring(key.indexOf('.') + 1),
boardPreferences.get(key));
}
}
} catch (Exception e) {
System.err.println("Error loading boards from " + boardsFile + ": " + e);
} }
File programmersFile = new File(folder, "programmers.txt");
try {
if (programmersFile.exists()) {
Map programmerPreferences = new LinkedHashMap();
Preferences.load(new FileInputStream(programmersFile), programmerPreferences);
for (Object k : programmerPreferences.keySet()) {
String key = (String) k;
String programmer = key.substring(0, key.indexOf('.'));
if (!programmers.containsKey(programmer)) programmers.put(programmer, new HashMap());
((Map) programmers.get(programmer)).put(
key.substring(key.indexOf('.') + 1),
programmerPreferences.get(key));
}
}
} catch (Exception e) {
System.err.println("Error loading programmers from " +
programmersFile + ": " + e);
}
} }
public String getPath() { return path; } public String getName() { return name; }
public File getFolder() { return folder; }
/** public Map<String, Map<String, String>> getBoards() {
* The source files in the library for the target platform. return boards;
* @return A read-only collection of strings containing the name of each source file.
*/
public Collection getSourceFilenames() {
return Collections.unmodifiableList(sources);
} }
public Map<String, Map<String, String>> getProgrammers() {
/** return programmers;
* The object files in the library for the target platform.
* @return A read-only collection of strings containing the name of each object file.
*/
public Collection getObjectFilenames() {
return Collections.unmodifiableList(objects);
} }
} }

View File

@ -65,7 +65,7 @@ public abstract class Uploader implements MessageConsumer {
public abstract boolean uploadUsingPreferences(String buildPath, String className, boolean verbose) public abstract boolean uploadUsingPreferences(String buildPath, String className, boolean verbose)
throws RunnerException; throws RunnerException;
public abstract boolean burnBootloader(String programmer) throws RunnerException; public abstract boolean burnBootloader(String target, String programmer) throws RunnerException;
protected void flushSerialBuffer() throws RunnerException { protected void flushSerialBuffer() throws RunnerException {
// Cleanup the serial buffer // Cleanup the serial buffer