mirror of
https://github.com/oliverschmidt/contiki.git
synced 2024-12-23 01:29:33 +00:00
added support for readonly memory sections
updated to use new SectionMoteMemory with address space offset code cleanup
This commit is contained in:
parent
b49d1892f2
commit
bf39b411c9
@ -45,7 +45,7 @@ import java.security.MessageDigest;
|
|||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Properties;
|
import java.util.HashMap;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
@ -199,13 +199,8 @@ public class ContikiMoteType implements MoteType {
|
|||||||
// Type specific class configuration
|
// Type specific class configuration
|
||||||
private ProjectConfig myConfig = null;
|
private ProjectConfig myConfig = null;
|
||||||
|
|
||||||
private int relAddressOfReferenceVariable = 0;
|
|
||||||
|
|
||||||
private CoreComm myCoreComm = null;
|
private CoreComm myCoreComm = null;
|
||||||
|
|
||||||
// Variable name to address mappings
|
|
||||||
private Properties varAddresses = new Properties();
|
|
||||||
|
|
||||||
// Initial memory for all motes of this type
|
// Initial memory for all motes of this type
|
||||||
private SectionMoteMemory initialMemory = null;
|
private SectionMoteMemory initialMemory = null;
|
||||||
|
|
||||||
@ -403,14 +398,16 @@ public class ContikiMoteType implements MoteType {
|
|||||||
int dataSectionAddr = -1, dataSectionSize = -1;
|
int dataSectionAddr = -1, dataSectionSize = -1;
|
||||||
int bssSectionAddr = -1, bssSectionSize = -1;
|
int bssSectionAddr = -1, bssSectionSize = -1;
|
||||||
int commonSectionAddr = -1, commonSectionSize = -1;
|
int commonSectionAddr = -1, commonSectionSize = -1;
|
||||||
|
int readonlySectionAddr = -1, readonlySectionSize = -1;
|
||||||
|
|
||||||
|
HashMap<String, Integer> addresses = new HashMap<String, Integer>();
|
||||||
if (useCommand) {
|
if (useCommand) {
|
||||||
/* Parse command output */
|
/* Parse command output */
|
||||||
String[] output = loadCommandData(getContikiFirmwareFile());
|
String[] output = loadCommandData(getContikiFirmwareFile());
|
||||||
if (output == null) {
|
if (output == null) {
|
||||||
throw new MoteTypeCreationException("No parse command output loaded");
|
throw new MoteTypeCreationException("No parse command output loaded");
|
||||||
}
|
}
|
||||||
boolean parseOK = parseCommandData(output, varAddresses);
|
boolean parseOK = parseCommandData(output, addresses);
|
||||||
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");
|
||||||
@ -422,6 +419,14 @@ public class ContikiMoteType implements MoteType {
|
|||||||
bssSectionSize = parseCommandBssSectionSize(output);
|
bssSectionSize = parseCommandBssSectionSize(output);
|
||||||
commonSectionAddr = parseCommandCommonSectionAddr(output);
|
commonSectionAddr = parseCommandCommonSectionAddr(output);
|
||||||
commonSectionSize = parseCommandCommonSectionSize(output);
|
commonSectionSize = parseCommandCommonSectionSize(output);
|
||||||
|
|
||||||
|
try {
|
||||||
|
readonlySectionAddr = parseCommandReadonlySectionAddr(output);
|
||||||
|
readonlySectionSize = parseCommandReadonlySectionSize(output);
|
||||||
|
} catch (Exception e) {
|
||||||
|
readonlySectionAddr = -1;
|
||||||
|
readonlySectionSize = -1;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Parse command output */
|
/* Parse command output */
|
||||||
@ -434,7 +439,7 @@ public class ContikiMoteType implements MoteType {
|
|||||||
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: " + mapFile);
|
throw new MoteTypeCreationException("No map data could be loaded: " + mapFile);
|
||||||
}
|
}
|
||||||
boolean parseOK = parseMapFileData(mapData, varAddresses);
|
boolean parseOK = parseMapFileData(mapData, addresses);
|
||||||
if (!parseOK) {
|
if (!parseOK) {
|
||||||
logger.fatal("Map data parsing failed");
|
logger.fatal("Map data parsing failed");
|
||||||
throw new MoteTypeCreationException("Map data parsing failed: " + mapFile);
|
throw new MoteTypeCreationException("Map data parsing failed: " + mapFile);
|
||||||
@ -446,52 +451,99 @@ public class ContikiMoteType implements MoteType {
|
|||||||
bssSectionSize = parseMapBssSectionSize(mapData);
|
bssSectionSize = parseMapBssSectionSize(mapData);
|
||||||
commonSectionAddr = parseMapCommonSectionAddr(mapData);
|
commonSectionAddr = parseMapCommonSectionAddr(mapData);
|
||||||
commonSectionSize = parseMapCommonSectionSize(mapData);
|
commonSectionSize = parseMapCommonSectionSize(mapData);
|
||||||
|
readonlySectionAddr = -1;
|
||||||
|
readonlySectionSize = -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (varAddresses.size() == 0) {
|
if (dataSectionAddr >= 0) {
|
||||||
|
logger.info(getContikiFirmwareFile().getName() +
|
||||||
|
": data section at 0x" + Integer.toHexString(dataSectionAddr) +
|
||||||
|
" (" + dataSectionSize + " bytes)");
|
||||||
|
} else {
|
||||||
|
logger.fatal(getContikiFirmwareFile().getName() + ": no data section found");
|
||||||
|
}
|
||||||
|
if (bssSectionAddr >= 0) {
|
||||||
|
logger.info(getContikiFirmwareFile().getName() +
|
||||||
|
": BSS section at 0x" + Integer.toHexString(bssSectionAddr) +
|
||||||
|
" (" + bssSectionSize + " bytes)");
|
||||||
|
} else {
|
||||||
|
logger.fatal(getContikiFirmwareFile().getName() + ": no BSS section found");
|
||||||
|
}
|
||||||
|
if (commonSectionAddr >= 0) {
|
||||||
|
logger.info(getContikiFirmwareFile().getName() +
|
||||||
|
": common section at 0x" + Integer.toHexString(commonSectionAddr) +
|
||||||
|
" (" + commonSectionSize + " bytes)");
|
||||||
|
} else {
|
||||||
|
logger.info(getContikiFirmwareFile().getName() + ": no common section found");
|
||||||
|
}
|
||||||
|
if (readonlySectionAddr >= 0) {
|
||||||
|
logger.info(getContikiFirmwareFile().getName() +
|
||||||
|
": readonly section at 0x" + Integer.toHexString(readonlySectionAddr) +
|
||||||
|
" (" + readonlySectionSize + " bytes)");
|
||||||
|
} else {
|
||||||
|
logger.warn(getContikiFirmwareFile().getName() + ": no readonly section found");
|
||||||
|
}
|
||||||
|
if (addresses.size() == 0) {
|
||||||
throw new MoteTypeCreationException("Library variables parsing failed");
|
throw new MoteTypeCreationException("Library variables parsing failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
/* Relative <-> absolute addresses offset */
|
|
||||||
relAddressOfReferenceVariable = (Integer) varAddresses.get("referenceVar");
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw (MoteTypeCreationException) new MoteTypeCreationException(
|
|
||||||
"JNI call error: " + e.getMessage()).initCause(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dataSectionAddr <= 0 || dataSectionSize <= 0
|
if (dataSectionAddr <= 0 || dataSectionSize <= 0
|
||||||
|| bssSectionAddr <= 0 || bssSectionSize <= 0) {
|
|| bssSectionAddr <= 0 || bssSectionSize <= 0) {
|
||||||
throw new MoteTypeCreationException("Library section addresses parsing failed");
|
throw new MoteTypeCreationException("Library section addresses parsing failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
myCoreComm.setReferenceAddress(relAddressOfReferenceVariable);
|
try {
|
||||||
|
/* Relative <-> absolute addresses offset */
|
||||||
|
int referenceVar = (Integer) addresses.get("referenceVar");
|
||||||
|
myCoreComm.setReferenceAddress(referenceVar);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw (MoteTypeCreationException) new MoteTypeCreationException(
|
||||||
|
"JNI call error: " + e.getMessage()).initCause(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We first need the value of Contiki's referenceVar, which tells us the
|
||||||
|
* memory offset between Contiki's variable and the relative addresses that
|
||||||
|
* were calculated directly from the library file.
|
||||||
|
*
|
||||||
|
* This offset will be used in Cooja in the memory abstraction to match
|
||||||
|
* Contiki's and Cooja's address spaces */
|
||||||
|
int offset;
|
||||||
|
{
|
||||||
|
SectionMoteMemory tmp = new SectionMoteMemory(addresses, 0);
|
||||||
|
byte[] data = new byte[dataSectionSize];
|
||||||
|
getCoreMemory(dataSectionAddr, dataSectionSize, data);
|
||||||
|
tmp.setMemorySegment(dataSectionAddr, data);
|
||||||
|
byte[] bss = new byte[bssSectionSize];
|
||||||
|
getCoreMemory(bssSectionAddr, bssSectionSize, bss);
|
||||||
|
tmp.setMemorySegment(bssSectionAddr, bss);
|
||||||
|
|
||||||
|
offset = tmp.getIntValueOf("referenceVar");
|
||||||
|
logger.info(getContikiFirmwareFile().getName() +
|
||||||
|
": offsetting Contiki mote address space: " + offset);
|
||||||
|
}
|
||||||
|
|
||||||
/* Create initial memory: data+bss+optional common */
|
/* Create initial memory: data+bss+optional common */
|
||||||
initialMemory = new SectionMoteMemory(varAddresses);
|
initialMemory = new SectionMoteMemory(addresses, offset);
|
||||||
|
|
||||||
byte[] initialDataSection = new byte[dataSectionSize];
|
byte[] initialDataSection = new byte[dataSectionSize];
|
||||||
getCoreMemory(dataSectionAddr, dataSectionSize, initialDataSection);
|
getCoreMemory(dataSectionAddr, dataSectionSize, initialDataSection);
|
||||||
initialMemory.setMemorySegment(dataSectionAddr, initialDataSection);
|
initialMemory.setMemorySegmentNative(dataSectionAddr, initialDataSection);
|
||||||
logger.info(getContikiFirmwareFile().getName() +
|
|
||||||
": data section at 0x" + Integer.toHexString(dataSectionAddr) +
|
|
||||||
" (" + dataSectionSize + " bytes)");
|
|
||||||
|
|
||||||
byte[] initialBssSection = new byte[bssSectionSize];
|
byte[] initialBssSection = new byte[bssSectionSize];
|
||||||
getCoreMemory(bssSectionAddr, bssSectionSize, initialBssSection);
|
getCoreMemory(bssSectionAddr, bssSectionSize, initialBssSection);
|
||||||
initialMemory.setMemorySegment(bssSectionAddr, initialBssSection);
|
initialMemory.setMemorySegmentNative(bssSectionAddr, initialBssSection);
|
||||||
logger.info(getContikiFirmwareFile().getName() +
|
|
||||||
": BSS section at 0x" + Integer.toHexString(bssSectionAddr) +
|
|
||||||
" (" + bssSectionSize + " bytes)");
|
|
||||||
|
|
||||||
if (commonSectionAddr > 0 && commonSectionSize > 0) {
|
if (commonSectionAddr >= 0 && commonSectionSize > 0) {
|
||||||
byte[] initialCommonSection = new byte[commonSectionSize];
|
byte[] initialCommonSection = new byte[commonSectionSize];
|
||||||
getCoreMemory(commonSectionAddr, commonSectionSize, initialCommonSection);
|
getCoreMemory(commonSectionAddr, commonSectionSize, initialCommonSection);
|
||||||
initialMemory.setMemorySegment(commonSectionAddr, initialCommonSection);
|
initialMemory.setMemorySegmentNative(commonSectionAddr, initialCommonSection);
|
||||||
logger.info(getContikiFirmwareFile().getName() +
|
}
|
||||||
": common section at 0x" + Integer.toHexString(commonSectionAddr) +
|
|
||||||
" (" + commonSectionSize + " bytes)");
|
/* Read "read-only" memory */
|
||||||
|
if (readonlySectionAddr >= 0 && readonlySectionSize > 0) {
|
||||||
|
byte[] readonlySection = new byte[readonlySectionSize];
|
||||||
|
getCoreMemory(readonlySectionAddr, readonlySectionSize, readonlySection);
|
||||||
|
initialMemory.setReadonlyMemorySegment(readonlySectionAddr+offset, readonlySection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,7 +576,7 @@ public class ContikiMoteType implements MoteType {
|
|||||||
public void setCoreMemory(SectionMoteMemory mem) {
|
public void setCoreMemory(SectionMoteMemory mem) {
|
||||||
for (int i = 0; i < mem.getNumberOfSections(); i++) {
|
for (int i = 0; i < mem.getNumberOfSections(); i++) {
|
||||||
setCoreMemory(
|
setCoreMemory(
|
||||||
mem.getStartAddrOfSection(i),
|
mem.getSectionNativeAddress(i) /* native address space */,
|
||||||
mem.getSizeOfSection(i), mem.getDataOfSection(i));
|
mem.getSizeOfSection(i), mem.getDataOfSection(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -538,8 +590,7 @@ 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(String[] mapFileData,
|
public static boolean parseMapFileData(String[] mapFileData, HashMap<String, Integer> varAddresses) {
|
||||||
Properties varAddresses) {
|
|
||||||
String[] varNames = getMapFileVarNames(mapFileData);
|
String[] varNames = getMapFileVarNames(mapFileData);
|
||||||
if (varNames == null || varNames.length == 0) {
|
if (varNames == null || varNames.length == 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -565,7 +616,7 @@ public class ContikiMoteType implements MoteType {
|
|||||||
* @param output Command output
|
* @param output Command output
|
||||||
* @param addresses Variable addresses mappings
|
* @param addresses Variable addresses mappings
|
||||||
*/
|
*/
|
||||||
public static boolean parseCommandData(String[] output, Properties addresses) {
|
public static boolean parseCommandData(String[] output, HashMap<String, Integer> addresses) {
|
||||||
int nrNew = 0, nrOld = 0, nrMismatch = 0;
|
int nrNew = 0, nrOld = 0, nrMismatch = 0;
|
||||||
|
|
||||||
Pattern pattern =
|
Pattern pattern =
|
||||||
@ -615,10 +666,9 @@ public class ContikiMoteType implements MoteType {
|
|||||||
*/
|
*/
|
||||||
public void getCoreMemory(SectionMoteMemory mem) {
|
public void getCoreMemory(SectionMoteMemory mem) {
|
||||||
for (int i = 0; i < mem.getNumberOfSections(); i++) {
|
for (int i = 0; i < mem.getNumberOfSections(); i++) {
|
||||||
int startAddr = mem.getStartAddrOfSection(i);
|
int startAddr = mem.getSectionNativeAddress(i); /* native address space */
|
||||||
int size = mem.getSizeOfSection(i);
|
int size = mem.getSizeOfSection(i);
|
||||||
byte[] data = mem.getDataOfSection(i);
|
byte[] data = mem.getDataOfSection(i);
|
||||||
|
|
||||||
getCoreMemory(startAddr, size, data);
|
getCoreMemory(startAddr, size, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -689,12 +739,10 @@ public class ContikiMoteType implements MoteType {
|
|||||||
* @param varName Name of variable
|
* @param varName 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(String[] mapFileData, String varName, Properties varAddresses) {
|
private static int getMapFileVarAddress(String[] mapFileData, String varName, HashMap<String, Integer> varAddresses) {
|
||||||
int varAddr;
|
Integer varAddrInteger;
|
||||||
String varAddrString;
|
if ((varAddrInteger = varAddresses.get(varName)) != null) {
|
||||||
if ((varAddrString = varAddresses.getProperty(varName)) != null) {
|
return varAddrInteger.intValue();
|
||||||
varAddr = Integer.parseInt(varAddrString);
|
|
||||||
return varAddr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String regExp =
|
String regExp =
|
||||||
@ -704,9 +752,9 @@ public class ContikiMoteType implements MoteType {
|
|||||||
String retString = getFirstMatchGroup(mapFileData, regExp, 1);
|
String retString = getFirstMatchGroup(mapFileData, regExp, 1);
|
||||||
|
|
||||||
if (retString != null) {
|
if (retString != null) {
|
||||||
varAddresses.setProperty(varName, Integer.toString(Integer.parseInt(
|
varAddrInteger = Integer.parseInt(retString.trim(), 16);
|
||||||
retString.trim(), 16)));
|
varAddresses.put(varName, varAddrInteger);
|
||||||
return Integer.parseInt(retString.trim(), 16);
|
return varAddrInteger.intValue();
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -760,7 +808,7 @@ public class ContikiMoteType implements MoteType {
|
|||||||
return varNames.toArray(new String[0]);
|
return varNames.toArray(new String[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] getAllVariableNames(String[] lines,
|
private static String[] getAllVariableNames(String[] lines,
|
||||||
int startAddress, int endAddress) {
|
int startAddress, int endAddress) {
|
||||||
ArrayList<String> varNames = new ArrayList<String>();
|
ArrayList<String> varNames = new ArrayList<String>();
|
||||||
|
|
||||||
@ -914,6 +962,21 @@ public class ContikiMoteType implements MoteType {
|
|||||||
}
|
}
|
||||||
return end - start;
|
return end - start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int parseCommandReadonlySectionAddr(String[] output) {
|
||||||
|
return parseFirstHexInt("^([0-9A-Fa-f]*)[ \t]t[ \t].text$", output);
|
||||||
|
}
|
||||||
|
private static int parseCommandReadonlySectionSize(String[] output) {
|
||||||
|
int start = parseCommandReadonlySectionAddr(output);
|
||||||
|
if (start < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extract the last specified address, assuming that the interval covers all the memory */
|
||||||
|
String last = output[output.length-1];
|
||||||
|
int lastAddress = Integer.parseInt(last.split("[ \t]")[0],16);
|
||||||
|
return lastAddress - start;
|
||||||
|
}
|
||||||
|
|
||||||
private static int getRelVarAddr(String mapFileData[], String varName) {
|
private static int getRelVarAddr(String mapFileData[], String varName) {
|
||||||
String regExp =
|
String regExp =
|
||||||
|
Loading…
Reference in New Issue
Block a user