added support for a third optional memory section (currently only used on mac os x) +

added section address parsing debugging output +

removed unused code and + increased code readability
This commit is contained in:
fros4943 2010-01-20 16:21:36 +00:00
parent 27131dfa98
commit efdb9f6e04

View file

@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* $Id: ContikiMoteType.java,v 1.37 2009/06/03 17:27:37 fros4943 Exp $ * $Id: ContikiMoteType.java,v 1.38 2010/01/20 16:21:36 fros4943 Exp $
*/ */
package se.sics.cooja.contikimote; package se.sics.cooja.contikimote;
@ -34,20 +34,46 @@ package se.sics.cooja.contikimote;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Container; import java.awt.Container;
import java.awt.Dimension; import java.awt.Dimension;
import java.io.*; import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.security.*; import java.security.MessageDigest;
import java.util.*; import java.security.NoSuchAlgorithmException;
import java.util.regex.*; import java.util.ArrayList;
import javax.swing.*; import java.util.Collection;
import java.util.Properties;
import java.util.Random;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.jdom.Element; import org.jdom.Element;
import se.sics.cooja.*; import se.sics.cooja.AbstractionLevelDescription;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.CoreComm;
import se.sics.cooja.GUI;
import se.sics.cooja.Mote;
import se.sics.cooja.MoteInterface;
import se.sics.cooja.MoteType;
import se.sics.cooja.ProjectConfig;
import se.sics.cooja.SectionMoteMemory;
import se.sics.cooja.Simulation;
import se.sics.cooja.dialogs.CompileContiki; import se.sics.cooja.dialogs.CompileContiki;
import se.sics.cooja.dialogs.ContikiMoteCompileDialog; import se.sics.cooja.dialogs.ContikiMoteCompileDialog;
import se.sics.cooja.dialogs.MessageList; import se.sics.cooja.dialogs.MessageList;
import se.sics.cooja.dialogs.MessageList.MessageContainer; import se.sics.cooja.dialogs.MessageList.MessageContainer;
import se.sics.cooja.util.StringUtils;
/** /**
* The Contiki mote type holds the native library used to communicate with an * The Contiki mote type holds the native library used to communicate with an
@ -172,7 +198,7 @@ public class ContikiMoteType implements MoteType {
// Type specific class configuration // Type specific class configuration
private ProjectConfig myConfig = null; private ProjectConfig myConfig = null;
private int relAddressOfRefenceVariable = 0; private int relAddressOfReferenceVariable = 0;
private CoreComm myCoreComm = null; private CoreComm myCoreComm = null;
@ -211,10 +237,6 @@ public class ContikiMoteType implements MoteType {
return false; return false;
} }
/* Load compiled library */
doInit();
return true;
} else { } else {
if (getIdentifier() == null) { if (getIdentifier() == null) {
throw new MoteTypeCreationException("No identifier specified"); throw new MoteTypeCreationException("No identifier specified");
@ -328,11 +350,11 @@ public class ContikiMoteType implements MoteType {
!getContikiFirmwareFile().exists()) { !getContikiFirmwareFile().exists()) {
throw new MoteTypeCreationException("Contiki firmware file does not exist: " + getContikiFirmwareFile()); throw new MoteTypeCreationException("Contiki firmware file does not exist: " + getContikiFirmwareFile());
} }
/* Load compiled library */
doInit();
return true;
} }
/* Load compiled library */
doInit();
return true;
} }
public static File getExpectedFirmwareFile(File source) { public static File getExpectedFirmwareFile(File source) {
@ -350,7 +372,7 @@ public class ContikiMoteType implements MoteType {
* *
* @throws MoteTypeCreationException * @throws MoteTypeCreationException
*/ */
public void doInit() throws MoteTypeCreationException { private void doInit() throws MoteTypeCreationException {
if (myCoreComm != null) { if (myCoreComm != null) {
throw new MoteTypeCreationException( throw new MoteTypeCreationException(
@ -370,90 +392,102 @@ public class ContikiMoteType implements MoteType {
logger.info("Creating core communicator between Java class '" + javaClassName + "' and Contiki library '" + getContikiFirmwareFile().getName() + "'"); logger.info("Creating core communicator between Java class '" + javaClassName + "' and Contiki library '" + getContikiFirmwareFile().getName() + "'");
myCoreComm = CoreComm.createCoreComm(this.javaClassName, getContikiFirmwareFile()); myCoreComm = CoreComm.createCoreComm(this.javaClassName, getContikiFirmwareFile());
// Should we parse addresses using map file or command? /* Parse addresses using map file or command */
boolean useCommand = Boolean.parseBoolean(GUI.getExternalToolsSetting("PARSE_WITH_COMMAND", "false")); boolean useCommand = Boolean.parseBoolean(GUI.getExternalToolsSetting("PARSE_WITH_COMMAND", "false"));
int relDataSectionAddr = -1; int dataSectionAddr = -1, dataSectionSize = -1;
int dataSectionSize = -1; int bssSectionAddr = -1, bssSectionSize = -1;
int relBssSectionAddr = -1; int commonSectionAddr = -1, commonSectionSize = -1;
int bssSectionSize = -1;
if (useCommand) { if (useCommand) {
// Parse command output /* Parse command output */
Vector<String> commandData = loadCommandData(getContikiFirmwareFile()); String[] output = loadCommandData(getContikiFirmwareFile());
if (commandData == null) { if (output == null) {
logger.fatal("No parse command output could be loaded");
throw new MoteTypeCreationException("No parse command output loaded"); throw new MoteTypeCreationException("No parse command output loaded");
} }
boolean parseOK = parseCommandData(output, varAddresses);
boolean parseOK = parseCommandData(commandData, varAddresses);
if (!parseOK) { if (!parseOK) {
logger.fatal("Command output parsing failed"); logger.fatal("Command output parsing failed");
throw new MoteTypeCreationException("Command output parsing failed"); throw new MoteTypeCreationException("Command output parsing failed");
} }
relDataSectionAddr = loadCommandRelDataSectionAddr(commandData); dataSectionAddr = parseCommandDataSectionAddr(output);
dataSectionSize = loadCommandDataSectionSize(commandData); dataSectionSize = parseCommandDataSectionSize(output);
relBssSectionAddr = loadCommandRelBssSectionAddr(commandData); bssSectionAddr = parseCommandBssSectionAddr(output);
bssSectionSize = loadCommandBssSectionSize(commandData); bssSectionSize = parseCommandBssSectionSize(output);
commonSectionAddr = parseCommandCommonSectionAddr(output);
commonSectionSize = parseCommandCommonSectionSize(output);
} else { } else {
// Parse map file /* Parse command output */
if (mapFile == null || if (mapFile == null ||
!mapFile.exists()) { !mapFile.exists()) {
logger.fatal("Map file " + mapFile.getAbsolutePath() + " could not be found!"); throw new MoteTypeCreationException("Map file " + mapFile + " could not be found!");
throw new MoteTypeCreationException("Map file " + mapFile.getAbsolutePath() + " could not be found!");
} }
String[] mapData = loadMapFile(mapFile);
Vector<String> mapData = loadMapFile(mapFile);
if (mapData == null) { if (mapData == null) {
logger.fatal("No map data could be loaded"); logger.fatal("No map data could be loaded");
throw new MoteTypeCreationException("No map data could be loaded"); throw new MoteTypeCreationException("No map data could be loaded: " + mapFile);
} }
boolean parseOK = parseMapFileData(mapData, varAddresses); boolean parseOK = parseMapFileData(mapData, varAddresses);
if (!parseOK) { if (!parseOK) {
logger.fatal("Map data parsing failed"); logger.fatal("Map data parsing failed");
throw new MoteTypeCreationException("Map data parsing failed"); throw new MoteTypeCreationException("Map data parsing failed: " + mapFile);
} }
relDataSectionAddr = loadRelDataSectionAddr(mapData); dataSectionAddr = parseMapDataSectionAddr(mapData);
dataSectionSize = loadDataSectionSize(mapData); dataSectionSize = parseMapDataSectionSize(mapData);
relBssSectionAddr = loadRelBssSectionAddr(mapData); bssSectionAddr = parseMapBssSectionAddr(mapData);
bssSectionSize = loadBssSectionSize(mapData); bssSectionSize = parseMapBssSectionSize(mapData);
commonSectionAddr = parseMapCommonSectionAddr(mapData);
commonSectionSize = parseMapCommonSectionSize(mapData);
} }
// Create variable names to addresses mappings
if (varAddresses.size() == 0) { if (varAddresses.size() == 0) {
throw new MoteTypeCreationException( throw new MoteTypeCreationException("Library variables parsing failed");
"Variable name to addresses mappings could not be created");
} }
try { try {
// Get offset between relative and absolute addresses /* Relative <-> absolute addresses offset */
relAddressOfRefenceVariable = (Integer) varAddresses.get("referenceVar"); relAddressOfReferenceVariable = (Integer) varAddresses.get("referenceVar");
} catch (Exception e) { } catch (Exception e) {
throw (MoteTypeCreationException) new MoteTypeCreationException( throw (MoteTypeCreationException) new MoteTypeCreationException(
"JNI call error: " + e.getMessage()).initCause(e); "JNI call error: " + e.getMessage()).initCause(e);
} }
if (relDataSectionAddr <= 0 || dataSectionSize <= 0 if (dataSectionAddr <= 0 || dataSectionSize <= 0
|| relBssSectionAddr <= 0 || bssSectionSize <= 0) { || bssSectionAddr <= 0 || bssSectionSize <= 0) {
throw new MoteTypeCreationException( throw new MoteTypeCreationException("Library section addresses parsing failed");
"Could not parse section addresses correctly");
} }
myCoreComm.setReferenceAddress(relAddressOfRefenceVariable); myCoreComm.setReferenceAddress(relAddressOfReferenceVariable);
// Create initial memory /* Create initial memory: data+bss+optional common */
byte[] initialDataSection = new byte[dataSectionSize];
getCoreMemory(relDataSectionAddr, dataSectionSize,
initialDataSection);
byte[] initialBssSection = new byte[bssSectionSize];
getCoreMemory(relBssSectionAddr, bssSectionSize,
initialBssSection);
initialMemory = new SectionMoteMemory(varAddresses); initialMemory = new SectionMoteMemory(varAddresses);
initialMemory.setMemorySegment(relDataSectionAddr, initialDataSection);
initialMemory.setMemorySegment(relBssSectionAddr, initialBssSection); byte[] initialDataSection = new byte[dataSectionSize];
getCoreMemory(dataSectionAddr, dataSectionSize, initialDataSection);
initialMemory.setMemorySegment(dataSectionAddr, initialDataSection);
logger.info(getContikiFirmwareFile().getName() +
": data section at 0x" + Integer.toHexString(dataSectionAddr) +
" (0x" + dataSectionSize + " bytes)");
byte[] initialBssSection = new byte[bssSectionSize];
getCoreMemory(bssSectionAddr, bssSectionSize, initialBssSection);
initialMemory.setMemorySegment(bssSectionAddr, initialBssSection);
logger.info(getContikiFirmwareFile().getName() +
": BSS section at 0x" + Integer.toHexString(bssSectionAddr) +
" (0x" + bssSectionSize + " bytes)");
if (commonSectionAddr > 0 && commonSectionSize > 0) {
byte[] initialCommonSection = new byte[commonSectionSize];
getCoreMemory(commonSectionAddr, commonSectionSize, initialCommonSection);
initialMemory.setMemorySegment(commonSectionAddr, initialCommonSection);
logger.info(getContikiFirmwareFile().getName() +
": common section at 0x" + Integer.toHexString(commonSectionAddr) +
" (0x" + commonSectionSize + " bytes)");
}
} }
/** /**
@ -499,10 +533,10 @@ public class ContikiMoteType implements MoteType {
* @param varAddresses * @param varAddresses
* Properties that should contain the name to addresses mappings. * Properties that should contain the name to addresses mappings.
*/ */
public static boolean parseMapFileData(Vector<String> mapFileData, public static boolean parseMapFileData(String[] mapFileData,
Properties varAddresses) { Properties varAddresses) {
Vector<String> varNames = getMapFileVarNames(mapFileData); String[] varNames = getMapFileVarNames(mapFileData);
if (varNames == null || varNames.size() == 0) { if (varNames == null || varNames.length == 0) {
return false; return false;
} }
@ -520,40 +554,36 @@ public class ContikiMoteType implements MoteType {
} }
/** /**
* Parses specified parse command output for variable * Parses parse command output for variable name to addresses mappings.
* name to addresses mappings. The mappings are added * The mappings are written to the given properties object.
* to the given properties object.
* *
* @param commandData * @param output Command output
* Output from parse command on object file * @param addresses Variable addresses mappings
* @param varAddresses
* Properties that should contain the name to addresses mappings.
*/ */
public static boolean parseCommandData(Vector<String> commandData, public static boolean parseCommandData(String[] output, Properties addresses) {
Properties varAddresses) {
int nrNew = 0, nrOld = 0, nrMismatch = 0; int nrNew = 0, nrOld = 0, nrMismatch = 0;
Pattern pattern = Pattern.compile(GUI Pattern pattern =
.getExternalToolsSetting("COMMAND_VAR_NAME_ADDRESS")); Pattern.compile(GUI.getExternalToolsSetting("COMMAND_VAR_NAME_ADDRESS"));
for (String commandLine : commandData) {
Matcher matcher = pattern.matcher(commandLine); for (String line : output) {
Matcher matcher = pattern.matcher(line);
if (matcher.find()) { if (matcher.find()) {
// logger.debug("Parsing line: " + commandLine); /* Line matched variable address */
String varName = matcher.group(2); String symbol = matcher.group(2);
int varAddress = Integer.parseInt(matcher.group(1), 16); int address = Integer.parseInt(matcher.group(1), 16);
if (!varAddresses.containsKey(varName)) { if (!addresses.containsKey(symbol)) {
nrNew++; nrNew++;
varAddresses.put(varName, new Integer(varAddress)); addresses.put(symbol, new Integer(address));
} else { } else {
int oldAddress = (Integer) varAddresses.get(varName); int oldAddress = (Integer) addresses.get(symbol);
if (oldAddress != varAddress) { if (oldAddress != address) {
/*logger.warn("Warning, command response not matching previous entry of: " /*logger.warn("Warning, command response not matching previous entry of: "
+ varName);*/ + varName);*/
nrMismatch++; nrMismatch++;
} }
nrOld++; nrOld++;
} }
} }
@ -651,11 +681,10 @@ public class ContikiMoteType implements MoteType {
/** /**
* Get relative address of variable with given name. * Get relative address of variable with given name.
* *
* @param varName * @param varName Name of variable
* Name of variable
* @return Relative memory address of variable or -1 if not found * @return Relative memory address of variable or -1 if not found
*/ */
public static int getMapFileVarAddress(Vector<String> mapFileData, String varName, Properties varAddresses) { public static int getMapFileVarAddress(String[] mapFileData, String varName, Properties varAddresses) {
int varAddr; int varAddr;
String varAddrString; String varAddrString;
if ((varAddrString = varAddresses.getProperty(varName)) != null) { if ((varAddrString = varAddresses.getProperty(varName)) != null) {
@ -663,8 +692,10 @@ public class ContikiMoteType implements MoteType {
return varAddr; return varAddr;
} }
String regExp = GUI.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_1") String regExp =
+ varName + GUI.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_2"); GUI.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_1") +
varName +
GUI.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_2");
String retString = getFirstMatchGroup(mapFileData, regExp, 1); String retString = getFirstMatchGroup(mapFileData, regExp, 1);
if (retString != null) { if (retString != null) {
@ -684,11 +715,10 @@ public class ContikiMoteType implements MoteType {
myCoreComm.setMemory(relAddr, length, mem); myCoreComm.setMemory(relAddr, length, mem);
} }
private static String getFirstMatchGroup(Vector<String> lines, String regexp, private static String getFirstMatchGroup(String[] lines, String regexp, int groupNr) {
int groupNr) {
Pattern pattern = Pattern.compile(regexp); Pattern pattern = Pattern.compile(regexp);
for (int i = 0; i < lines.size(); i++) { for (String line : lines) {
Matcher matcher = pattern.matcher(lines.get(i)); Matcher matcher = pattern.matcher(line);
if (matcher.find()) { if (matcher.find()) {
return matcher.group(groupNr); return matcher.group(groupNr);
} }
@ -703,27 +733,35 @@ public class ContikiMoteType implements MoteType {
* *
* @return Variable names found in the data and bss section * @return Variable names found in the data and bss section
*/ */
public static Vector<String> getMapFileVarNames(Vector<String> mapFileData) { public static String[] getMapFileVarNames(String[] mapFileData) {
ArrayList<String> varNames = new ArrayList<String>();
Vector<String> varNames = getAllVariableNames(mapFileData, String[] dataVariables = getAllVariableNames(
loadRelDataSectionAddr(mapFileData), mapFileData,
loadRelDataSectionAddr(mapFileData) + loadDataSectionSize(mapFileData)); parseMapDataSectionAddr(mapFileData),
parseMapDataSectionAddr(mapFileData) + parseMapDataSectionSize(mapFileData));
for (String v: dataVariables) {
varNames.add(v);
}
varNames.addAll(getAllVariableNames(mapFileData, String[] bssVariables = getAllVariableNames(
loadRelBssSectionAddr(mapFileData), loadRelBssSectionAddr(mapFileData) mapFileData,
+ loadBssSectionSize(mapFileData))); parseMapBssSectionAddr(mapFileData),
parseMapBssSectionAddr(mapFileData) + parseMapBssSectionSize(mapFileData));
for (String v: bssVariables) {
varNames.add(v);
}
return varNames; return varNames.toArray(new String[0]);
} }
public static Vector<String> getAllVariableNames(Vector<String> lines, public static String[] getAllVariableNames(String[] lines,
int startAddress, int endAddress) { int startAddress, int endAddress) {
Vector<String> varNames = new Vector<String>(); ArrayList<String> varNames = new ArrayList<String>();
Pattern pattern = Pattern.compile(GUI Pattern pattern = Pattern.compile(GUI.getExternalToolsSetting("MAPFILE_VAR_NAME"));
.getExternalToolsSetting("MAPFILE_VAR_NAME")); for (String line : lines) {
for (int i = 0; i < lines.size(); i++) { Matcher matcher = pattern.matcher(line);
Matcher matcher = pattern.matcher(lines.get(i));
if (matcher.find()) { if (matcher.find()) {
if (Integer.decode(matcher.group(1)).intValue() >= startAddress if (Integer.decode(matcher.group(1)).intValue() >= startAddress
&& Integer.decode(matcher.group(1)).intValue() <= endAddress) { && Integer.decode(matcher.group(1)).intValue() <= endAddress) {
@ -731,13 +769,14 @@ public class ContikiMoteType implements MoteType {
} }
} }
} }
return varNames; return varNames.toArray(new String[0]);
} }
protected int getVariableSize(Vector<String> lines, String varName) { protected int getVariableSize(Vector<String> lines, String varName) {
Pattern pattern = Pattern.compile(GUI Pattern pattern = Pattern.compile(
.getExternalToolsSetting("MAPFILE_VAR_SIZE_1") GUI.getExternalToolsSetting("MAPFILE_VAR_SIZE_1") +
+ varName + GUI.getExternalToolsSetting("MAPFILE_VAR_SIZE_2")); varName +
GUI.getExternalToolsSetting("MAPFILE_VAR_SIZE_2"));
for (int i = 0; i < lines.size(); i++) { for (int i = 0; i < lines.size(); i++) {
Matcher matcher = pattern.matcher(lines.get(i)); Matcher matcher = pattern.matcher(lines.get(i));
if (matcher.find()) { if (matcher.find()) {
@ -747,9 +786,9 @@ public class ContikiMoteType implements MoteType {
return -1; return -1;
} }
public static int loadRelDataSectionAddr(Vector<String> mapFileData) { private static int parseFirstHexInt(String regexp, String[] data) {
String retString = getFirstMatchGroup(mapFileData, GUI String retString =
.getExternalToolsSetting("MAPFILE_DATA_START"), 1); getFirstMatchGroup(data, regexp, 1);
if (retString != null) { if (retString != null) {
return Integer.parseInt(retString.trim(), 16); return Integer.parseInt(retString.trim(), 16);
@ -758,110 +797,124 @@ public class ContikiMoteType implements MoteType {
} }
} }
public static int loadDataSectionSize(Vector<String> mapFileData) { public static int parseMapDataSectionAddr(String[] mapFileData) {
String retString = getFirstMatchGroup(mapFileData, GUI String regexp = GUI.getExternalToolsSetting("MAPFILE_DATA_START", "");
.getExternalToolsSetting("MAPFILE_DATA_SIZE"), 1); if (regexp.equals("")) {
if (retString != null) {
return Integer.parseInt(retString.trim(), 16);
} else {
return -1; return -1;
} }
return parseFirstHexInt(regexp, mapFileData);
}
public static int parseMapDataSectionSize(String[] mapFileData) {
String regexp = GUI.getExternalToolsSetting("MAPFILE_DATA_SIZE", "");
if (regexp.equals("")) {
return -1;
}
return parseFirstHexInt(regexp, mapFileData);
}
public static int parseMapBssSectionAddr(String[] mapFileData) {
String regexp = GUI.getExternalToolsSetting("MAPFILE_BSS_START", "");
if (regexp.equals("")) {
return -1;
}
return parseFirstHexInt(regexp, mapFileData);
}
public static int parseMapBssSectionSize(String[] mapFileData) {
String regexp = GUI.getExternalToolsSetting("MAPFILE_BSS_SIZE", "");
if (regexp.equals("")) {
return -1;
}
return parseFirstHexInt(regexp, mapFileData);
}
public static int parseMapCommonSectionAddr(String[] mapFileData) {
String regexp = GUI.getExternalToolsSetting("MAPFILE_COMMON_START", "");
if (regexp.equals("")) {
return -1;
}
return parseFirstHexInt(regexp, mapFileData);
}
public static int parseMapCommonSectionSize(String[] mapFileData) {
String regexp = GUI.getExternalToolsSetting("MAPFILE_COMMON_SIZE", "");
if (regexp.equals("")) {
return -1;
}
return parseFirstHexInt(regexp, mapFileData);
} }
public static int loadRelBssSectionAddr(Vector<String> mapFileData) { public static int parseCommandDataSectionAddr(String[] output) {
String retString = getFirstMatchGroup(mapFileData, GUI String regexp = GUI.getExternalToolsSetting("COMMAND_DATA_START", "");
.getExternalToolsSetting("MAPFILE_BSS_START"), 1); if (regexp.equals("")) {
if (retString != null) {
return Integer.parseInt(retString.trim(), 16);
} else {
return -1; return -1;
} }
return parseFirstHexInt(regexp, output);
} }
public static int parseCommandDataSectionSize(String[] output) {
public static int loadBssSectionSize(Vector<String> mapFileData) { String regexp = GUI.getExternalToolsSetting("COMMAND_DATA_END", "");
String retString = getFirstMatchGroup(mapFileData, GUI if (regexp.equals("")) {
.getExternalToolsSetting("MAPFILE_BSS_SIZE"), 1);
if (retString != null) {
return Integer.parseInt(retString.trim(), 16);
} else {
return -1; return -1;
} }
int start = parseCommandDataSectionAddr(output);
if (start < 0) {
return -1;
}
int end = parseFirstHexInt(regexp, output);
if (end < 0) {
return -1;
}
return end - start;
} }
public static int parseCommandBssSectionAddr(String[] output) {
public static int loadCommandRelDataSectionAddr(Vector<String> commandData) { String regexp = GUI.getExternalToolsSetting("COMMAND_BSS_START", "");
String retString = getFirstMatchGroup(commandData, GUI if (regexp.equals("")) {
.getExternalToolsSetting("COMMAND_DATA_START"), 1);
if (retString != null) {
return Integer.parseInt(retString.trim(), 16);
} else {
return -1; return -1;
} }
return parseFirstHexInt(regexp, output);
} }
public static int parseCommandBssSectionSize(String[] output) {
public static int loadCommandDataSectionSize(Vector<String> commandData) { String regexp = GUI.getExternalToolsSetting("COMMAND_BSS_END", "");
String retString; if (regexp.equals("")) {
int start, end; return -1;
}
retString = getFirstMatchGroup(commandData, GUI int start = parseCommandBssSectionAddr(output);
.getExternalToolsSetting("COMMAND_DATA_START"), 1); if (start < 0) {
if (retString != null) {
start = Integer.parseInt(retString.trim(), 16);
} else {
return -1; return -1;
} }
retString = getFirstMatchGroup(commandData, GUI int end = parseFirstHexInt(regexp, output);
.getExternalToolsSetting("COMMAND_DATA_END"), 1); if (end < 0) {
if (retString != null) { return -1;
end = Integer.parseInt(retString.trim(), 16); }
} else { return end - start;
}
public static int parseCommandCommonSectionAddr(String[] output) {
String regexp = GUI.getExternalToolsSetting("COMMAND_COMMON_START", "");
if (regexp.equals("")) {
return -1;
}
return parseFirstHexInt(regexp, output);
}
public static int parseCommandCommonSectionSize(String[] output) {
String regexp = GUI.getExternalToolsSetting("COMMAND_COMMON_END", "");
if (regexp.equals("")) {
return -1;
}
int start = parseCommandCommonSectionAddr(output);
if (start < 0) {
return -1; return -1;
} }
int end = parseFirstHexInt(regexp, output);
if (end < 0) {
return -1;
}
return end - start; return end - start;
} }
public static int loadCommandRelBssSectionAddr(Vector<String> commandData) { private static int getRelVarAddr(String mapFileData[], String varName) {
String retString = getFirstMatchGroup(commandData, GUI String regExp =
.getExternalToolsSetting("COMMAND_BSS_START"), 1); GUI.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_1") +
varName +
if (retString != null) { GUI.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_2");
return Integer.parseInt(retString.trim(), 16);
} else {
return -1;
}
}
public static int loadCommandBssSectionSize(Vector<String> commandData) {
String retString;
int start, end;
retString = getFirstMatchGroup(commandData, GUI
.getExternalToolsSetting("COMMAND_BSS_START"), 1);
if (retString != null) {
start = Integer.parseInt(retString.trim(), 16);
} else {
return -1;
}
retString = getFirstMatchGroup(commandData, GUI
.getExternalToolsSetting("COMMAND_BSS_END"), 1);
if (retString != null) {
end = Integer.parseInt(retString.trim(), 16);
} else {
return -1;
}
return end - start;
}
private static int getRelVarAddr(Vector<String> mapFileData, String varName) {
String regExp = GUI.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_1")
+ varName + GUI.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_2");
String retString = getFirstMatchGroup(mapFileData, regExp, 1); String retString = getFirstMatchGroup(mapFileData, regExp, 1);
if (retString != null) { if (retString != null) {
@ -871,122 +924,57 @@ public class ContikiMoteType implements MoteType {
} }
} }
public static Vector<String> loadMapFile(File mapFile) { public static String[] loadMapFile(File mapFile) {
Vector<String> mapFileData = new Vector<String>(); String contents = StringUtils.loadFromFile(mapFile);
if (contents == null) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
new FileInputStream(mapFile)));
while (in.ready()) {
mapFileData.add(in.readLine());
}
} catch (FileNotFoundException e) {
logger.fatal("File not found: " + e);
return null;
} catch (IOException e) {
logger.fatal("IO error: " + e);
return null; return null;
} }
return contents.split("\n");
return mapFileData;
} }
/** /**
* Executes parse command on given file and returns the result. * Executes configured command on given file and returns the result.
* *
* @param libraryFile * @param libraryFile Contiki library
* File * @return Execution response, or null at failure
* @return Execution response
*/ */
public static Vector<String> loadCommandData(File libraryFile) { public static String[] loadCommandData(File libraryFile) {
Vector<String> commandData = new Vector<String>(); ArrayList<String> output = new ArrayList<String>();
try { try {
String command = GUI.getExternalToolsSetting("PARSE_COMMAND"); String command = GUI.getExternalToolsSetting("PARSE_COMMAND");
if (command == null) { if (command == null) {
return null; return null;
} }
// Prepare command /* Prepare command */
command = command.replace("$(LIBFILE)", libraryFile.getName().replace(File.separatorChar, '/')); command = command.replace("$(LIBFILE)",
libraryFile.getName().replace(File.separatorChar, '/'));
/* Execute command, read response */
String line; String line;
Process p = Runtime.getRuntime().exec(command.split(" "), null, libraryFile.getParentFile()); Process p = Runtime.getRuntime().exec(
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())); command.split(" "),
p.getErrorStream().close(); // Ignore error stream null,
libraryFile.getParentFile()
);
BufferedReader input = new BufferedReader(
new InputStreamReader(p.getInputStream())
);
p.getErrorStream().close();
while ((line = input.readLine()) != null) { while ((line = input.readLine()) != null) {
commandData.add(line); output.add(line);
} }
input.close(); input.close();
} catch (Exception err) {
err.printStackTrace();
return null;
}
if (commandData == null || commandData.size() == 0) { if (output == null || output.size() == 0) {
return null;
}
return commandData;
}
/**
* Runs external tool objdump on given file and returns the result.
*
* @param libraryFile
* File
* @return Execution response
*/
public static Vector<String> loadObjdumpData(File libraryFile) {
Vector<String> objdumpData = new Vector<String>();
try {
String objdumpPath = GUI.getExternalToolsSetting("PATH_OBJDUMP");
String objdumpArgs = GUI.getExternalToolsSetting("OBJDUMP_ARGS");
if (objdumpPath == null || objdumpPath.equals("")) {
return null; return null;
} }
return output.toArray(new String[0]);
String[] objdumpExecArray;
if (!objdumpArgs.trim().equals("")) {
// Arguments need to be passed to program
String[] splittedObjdumpArgs = objdumpArgs.split(" ");
objdumpExecArray = new String[1 + splittedObjdumpArgs.length + 1];
objdumpExecArray[0] = objdumpPath.trim();
objdumpExecArray[objdumpExecArray.length - 1] = libraryFile
.getAbsolutePath();
System.arraycopy(splittedObjdumpArgs, 0, objdumpExecArray, 1,
splittedObjdumpArgs.length);
} else {
objdumpExecArray = new String[2];
objdumpExecArray[0] = objdumpPath.trim();
objdumpExecArray[1] = libraryFile.getAbsolutePath();
}
String line;
Process p = Runtime.getRuntime().exec(objdumpExecArray);
BufferedReader input = new BufferedReader(new InputStreamReader(p
.getInputStream()));
p.getErrorStream().close(); // Ignore error stream
while ((line = input.readLine()) != null) {
objdumpData.add(line);
}
input.close();
} catch (Exception err) { } catch (Exception err) {
err.printStackTrace(); logger.fatal("Command error: " + err.getMessage(), err);
return null; return null;
} }
if (objdumpData == null || objdumpData.size() == 0) {
return null;
}
return objdumpData;
} }
public String getDescription() { public String getDescription() {
@ -1374,7 +1362,7 @@ public class ContikiMoteType implements MoteType {
/* Guess compile commands */ /* Guess compile commands */
String compileCommands = String compileCommands =
"make " + getExpectedFirmwareFile(oldVersionSource).getName() + " TARGET=cooja"; "make " + getExpectedFirmwareFile(oldVersionSource).getName() + " TARGET=cooja";
logger.info("Guessing compile commands: " + compileCommands); logger.info("Guessing compile commands: " + compileCommands);
setCompileCommands(compileCommands); setCompileCommands(compileCommands);
} }