[cooja] memory: SectionMoteMemory implementation of MemoryInterface functions
as forwarding to encapsulated memory sections Requires to make use of Symbol class for cooja motes, too
This commit is contained in:
parent
070e0ba0fc
commit
f4979ffeeb
|
@ -68,6 +68,10 @@ import org.contikios.cooja.dialogs.CompileContiki;
|
||||||
import org.contikios.cooja.dialogs.ContikiMoteCompileDialog;
|
import org.contikios.cooja.dialogs.ContikiMoteCompileDialog;
|
||||||
import org.contikios.cooja.dialogs.MessageList;
|
import org.contikios.cooja.dialogs.MessageList;
|
||||||
import org.contikios.cooja.dialogs.MessageList.MessageContainer;
|
import org.contikios.cooja.dialogs.MessageList.MessageContainer;
|
||||||
|
import org.contikios.cooja.mote.memory.ArrayMemory;
|
||||||
|
import org.contikios.cooja.mote.memory.MemoryInterface;
|
||||||
|
import org.contikios.cooja.mote.memory.MemoryInterface.Symbol;
|
||||||
|
import org.contikios.cooja.mote.memory.MemoryLayout;
|
||||||
import org.contikios.cooja.mote.memory.VarMemory;
|
import org.contikios.cooja.mote.memory.VarMemory;
|
||||||
import org.contikios.cooja.util.StringUtils;
|
import org.contikios.cooja.util.StringUtils;
|
||||||
|
|
||||||
|
@ -406,7 +410,7 @@ public class ContikiMoteType implements MoteType {
|
||||||
int commonSectionRelAddr = -1, commonSectionSize = -1;
|
int commonSectionRelAddr = -1, commonSectionSize = -1;
|
||||||
int readonlySectionRelAddr = -1, readonlySectionSize = -1;
|
int readonlySectionRelAddr = -1, readonlySectionSize = -1;
|
||||||
|
|
||||||
HashMap<String, Integer> addresses = new HashMap<String, Integer>();
|
HashMap<String, Symbol> addresses = new HashMap<String, Symbol>();
|
||||||
if (useCommand) {
|
if (useCommand) {
|
||||||
/* Parse command output */
|
/* Parse command output */
|
||||||
String[] output = loadCommandData(getContikiFirmwareFile());
|
String[] output = loadCommandData(getContikiFirmwareFile());
|
||||||
|
@ -500,7 +504,7 @@ public class ContikiMoteType implements MoteType {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/* Relative <-> absolute addresses offset */
|
/* Relative <-> absolute addresses offset */
|
||||||
int referenceVar = addresses.get("referenceVar");
|
int referenceVar = (int) addresses.get("referenceVar").addr;
|
||||||
myCoreComm.setReferenceAddress(referenceVar);
|
myCoreComm.setReferenceAddress(referenceVar);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new MoteTypeCreationException("JNI call error: " + e.getMessage(), e);
|
throw new MoteTypeCreationException("JNI call error: " + e.getMessage(), e);
|
||||||
|
@ -518,10 +522,10 @@ public class ContikiMoteType implements MoteType {
|
||||||
VarMemory varMem = new VarMemory(tmp);
|
VarMemory varMem = new VarMemory(tmp);
|
||||||
byte[] data = new byte[dataSectionSize];
|
byte[] data = new byte[dataSectionSize];
|
||||||
getCoreMemory(dataSectionRelAddr, dataSectionSize, data);
|
getCoreMemory(dataSectionRelAddr, dataSectionSize, data);
|
||||||
tmp.setMemorySegment(dataSectionRelAddr, data);
|
tmp.addMemorySection("data", new ArrayMemory(dataSectionRelAddr, MemoryLayout.getNative(), data, null));
|
||||||
byte[] bss = new byte[bssSectionSize];
|
byte[] bss = new byte[bssSectionSize];
|
||||||
getCoreMemory(bssSectionRelAddr, bssSectionSize, bss);
|
getCoreMemory(bssSectionRelAddr, bssSectionSize, bss);
|
||||||
tmp.setMemorySegment(bssSectionRelAddr, bss);
|
tmp.addMemorySection("bss", new ArrayMemory(bssSectionRelAddr, MemoryLayout.getNative(), bss, null));
|
||||||
|
|
||||||
offset = varMem.getIntValueOf("referenceVar");
|
offset = varMem.getIntValueOf("referenceVar");
|
||||||
logger.info(getContikiFirmwareFile().getName()
|
logger.info(getContikiFirmwareFile().getName()
|
||||||
|
@ -533,23 +537,23 @@ public class ContikiMoteType implements MoteType {
|
||||||
|
|
||||||
byte[] initialDataSection = new byte[dataSectionSize];
|
byte[] initialDataSection = new byte[dataSectionSize];
|
||||||
getCoreMemory(dataSectionRelAddr, dataSectionSize, initialDataSection);
|
getCoreMemory(dataSectionRelAddr, dataSectionSize, initialDataSection);
|
||||||
initialMemory.setMemorySegmentNative(dataSectionRelAddr, initialDataSection);
|
initialMemory.addMemorySection("data", new ArrayMemory(dataSectionRelAddr, MemoryLayout.getNative(), initialDataSection, null));
|
||||||
|
|
||||||
byte[] initialBssSection = new byte[bssSectionSize];
|
byte[] initialBssSection = new byte[bssSectionSize];
|
||||||
getCoreMemory(bssSectionRelAddr, bssSectionSize, initialBssSection);
|
getCoreMemory(bssSectionRelAddr, bssSectionSize, initialBssSection);
|
||||||
initialMemory.setMemorySegmentNative(bssSectionRelAddr, initialBssSection);
|
initialMemory.addMemorySection("bss", new ArrayMemory(bssSectionRelAddr, MemoryLayout.getNative(), initialBssSection, null));
|
||||||
|
|
||||||
if (commonSectionRelAddr >= 0 && commonSectionSize > 0) {
|
if (commonSectionRelAddr >= 0 && commonSectionSize > 0) {
|
||||||
byte[] initialCommonSection = new byte[commonSectionSize];
|
byte[] initialCommonSection = new byte[commonSectionSize];
|
||||||
getCoreMemory(commonSectionRelAddr, commonSectionSize, initialCommonSection);
|
getCoreMemory(commonSectionRelAddr, commonSectionSize, initialCommonSection);
|
||||||
initialMemory.setMemorySegmentNative(commonSectionRelAddr, initialCommonSection);
|
initialMemory.addMemorySection("common", new ArrayMemory(commonSectionRelAddr, MemoryLayout.getNative(), initialCommonSection, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read "read-only" memory */
|
/* Read "read-only" memory */
|
||||||
if (readonlySectionRelAddr >= 0 && readonlySectionSize > 0) {
|
if (readonlySectionRelAddr >= 0 && readonlySectionSize > 0) {
|
||||||
byte[] readonlySection = new byte[readonlySectionSize];
|
byte[] readonlySection = new byte[readonlySectionSize];
|
||||||
getCoreMemory(readonlySectionRelAddr, readonlySectionSize, readonlySection);
|
getCoreMemory(readonlySectionRelAddr, readonlySectionSize, readonlySection);
|
||||||
initialMemory.setReadonlyMemorySegment(readonlySectionRelAddr+offset, readonlySection);
|
initialMemory.addMemorySection("readonly", new ArrayMemory(readonlySectionRelAddr, MemoryLayout.getNative(), readonlySection, true, null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,11 +584,8 @@ public class ContikiMoteType implements MoteType {
|
||||||
* Memory to set
|
* Memory to set
|
||||||
*/
|
*/
|
||||||
public void getCoreMemory(SectionMoteMemory mem) {
|
public void getCoreMemory(SectionMoteMemory mem) {
|
||||||
for (int i = 0; i < mem.getNumberOfSections(); i++) {
|
for (MemoryInterface section : mem.getSections().values()) {
|
||||||
getCoreMemory(
|
getCoreMemory((int) section.getStartAddr(), section.getTotalSize(), section.getMemory());
|
||||||
(int) mem.getSectionNativeAddress(i) /* native address space */,
|
|
||||||
mem.getSizeOfSection(i),
|
|
||||||
mem.getDataOfSection(i));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,11 +601,8 @@ public class ContikiMoteType implements MoteType {
|
||||||
* New memory
|
* New memory
|
||||||
*/
|
*/
|
||||||
public void setCoreMemory(SectionMoteMemory mem) {
|
public void setCoreMemory(SectionMoteMemory mem) {
|
||||||
for (int i = 0; i < mem.getNumberOfSections(); i++) {
|
for (MemoryInterface section : mem.getSections().values()) {
|
||||||
setCoreMemory(
|
setCoreMemory((int) section.getStartAddr(), section.getTotalSize(), section.getMemory());
|
||||||
(int) mem.getSectionNativeAddress(i) /* native address space */,
|
|
||||||
mem.getSizeOfSection(i),
|
|
||||||
mem.getDataOfSection(i));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -621,16 +619,16 @@ 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, HashMap<String, Integer> varAddresses) {
|
public static boolean parseMapFileData(String[] mapFileData, HashMap<String, Symbol> 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String varName : varNames) {
|
for (String varName : varNames) {
|
||||||
int varAddress = getMapFileVarAddress(mapFileData, varName, varAddresses);
|
int varAddress = getMapFileVarAddress(mapFileData, varName);
|
||||||
if (varAddress > 0) {
|
if (varAddress > 0) {
|
||||||
varAddresses.put(varName, new Integer(varAddress));
|
varAddresses.put(varName, new Symbol(Symbol.Type.VARIABLE, varName, varAddress, 1));
|
||||||
} else {
|
} else {
|
||||||
logger.warn("Parsed Contiki variable '" + varName
|
logger.warn("Parsed Contiki variable '" + varName
|
||||||
+ "' but could not find address");
|
+ "' but could not find address");
|
||||||
|
@ -647,7 +645,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, HashMap<String, Integer> addresses) {
|
public static boolean parseCommandData(String[] output, HashMap<String, Symbol> addresses) {
|
||||||
int nrNew = 0, nrOld = 0, nrMismatch = 0;
|
int nrNew = 0, nrOld = 0, nrMismatch = 0;
|
||||||
|
|
||||||
Pattern pattern
|
Pattern pattern
|
||||||
|
@ -663,9 +661,9 @@ public class ContikiMoteType implements MoteType {
|
||||||
|
|
||||||
if (!addresses.containsKey(symbol)) {
|
if (!addresses.containsKey(symbol)) {
|
||||||
nrNew++;
|
nrNew++;
|
||||||
addresses.put(symbol, new Integer(address));
|
addresses.put(symbol, new Symbol(Symbol.Type.VARIABLE, symbol, address, 1));
|
||||||
} else {
|
} else {
|
||||||
int oldAddress = addresses.get(symbol);
|
int oldAddress = (int) addresses.get(symbol).addr;
|
||||||
if (oldAddress != address) {
|
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);*/
|
||||||
|
@ -814,11 +812,7 @@ 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
|
||||||
*/
|
*/
|
||||||
private static int getMapFileVarAddress(String[] mapFileData, String varName, HashMap<String, Integer> varAddresses) {
|
private static int getMapFileVarAddress(String[] mapFileData, String varName) {
|
||||||
Integer varAddrInteger;
|
|
||||||
if ((varAddrInteger = varAddresses.get(varName)) != null) {
|
|
||||||
return varAddrInteger.intValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
String regExp = Cooja.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_1")
|
String regExp = Cooja.getExternalToolsSetting("MAPFILE_VAR_ADDRESS_1")
|
||||||
+ varName
|
+ varName
|
||||||
|
@ -826,9 +820,7 @@ public class ContikiMoteType implements MoteType {
|
||||||
String retString = getFirstMatchGroup(mapFileData, regExp, 1);
|
String retString = getFirstMatchGroup(mapFileData, regExp, 1);
|
||||||
|
|
||||||
if (retString != null) {
|
if (retString != null) {
|
||||||
varAddrInteger = Integer.parseInt(retString.trim(), 16);
|
return Integer.parseInt(retString.trim(), 16);
|
||||||
varAddresses.put(varName, varAddrInteger);
|
|
||||||
return varAddrInteger.intValue();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -68,6 +68,7 @@ import org.contikios.cooja.Cooja;
|
||||||
import org.contikios.cooja.MoteType.MoteTypeCreationException;
|
import org.contikios.cooja.MoteType.MoteTypeCreationException;
|
||||||
import org.contikios.cooja.mote.memory.SectionMoteMemory;
|
import org.contikios.cooja.mote.memory.SectionMoteMemory;
|
||||||
import org.contikios.cooja.contikimote.ContikiMoteType;
|
import org.contikios.cooja.contikimote.ContikiMoteType;
|
||||||
|
import org.contikios.cooja.mote.memory.MemoryInterface.Symbol;
|
||||||
import org.contikios.cooja.mote.memory.VarMemory;
|
import org.contikios.cooja.mote.memory.VarMemory;
|
||||||
|
|
||||||
/* TODO Test common section */
|
/* TODO Test common section */
|
||||||
|
@ -142,7 +143,7 @@ public class ConfigurationWizard extends JDialog {
|
||||||
private static File cLibraryFile;
|
private static File cLibraryFile;
|
||||||
private static String javaLibraryName;
|
private static String javaLibraryName;
|
||||||
private static CoreComm javaLibrary;
|
private static CoreComm javaLibrary;
|
||||||
private static HashMap<String, Integer> addresses;
|
private static HashMap<String, Symbol> addresses;
|
||||||
private static int relDataSectionAddr;
|
private static int relDataSectionAddr;
|
||||||
private static int dataSectionSize;
|
private static int dataSectionSize;
|
||||||
private static int relBssSectionAddr;
|
private static int relBssSectionAddr;
|
||||||
|
@ -758,7 +759,7 @@ public class ConfigurationWizard extends JDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
testOutput.addMessage("### Parsing map file data for addresses");
|
testOutput.addMessage("### Parsing map file data for addresses");
|
||||||
addresses = new HashMap<String, Integer>();
|
addresses = new HashMap<String, Symbol>();
|
||||||
boolean parseOK = ContikiMoteType.parseMapFileData(mapData, addresses);
|
boolean parseOK = ContikiMoteType.parseMapFileData(mapData, addresses);
|
||||||
if (!parseOK) {
|
if (!parseOK) {
|
||||||
testOutput.addMessage("### Error: Failed parsing map file data", MessageList.ERROR);
|
testOutput.addMessage("### Error: Failed parsing map file data", MessageList.ERROR);
|
||||||
|
@ -838,7 +839,7 @@ public class ConfigurationWizard extends JDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
testOutput.addMessage("### Parsing command output for addresses");
|
testOutput.addMessage("### Parsing command output for addresses");
|
||||||
addresses = new HashMap<String, Integer>();
|
addresses = new HashMap<String, Symbol>();
|
||||||
boolean parseOK = ContikiMoteType.parseCommandData(commandData, addresses);
|
boolean parseOK = ContikiMoteType.parseCommandData(commandData, addresses);
|
||||||
if (!parseOK) {
|
if (!parseOK) {
|
||||||
testOutput.addMessage("### Error: Failed parsing command output", MessageList.ERROR);
|
testOutput.addMessage("### Error: Failed parsing command output", MessageList.ERROR);
|
||||||
|
@ -936,7 +937,7 @@ public class ConfigurationWizard extends JDialog {
|
||||||
testOutput.addMessage("Could not find address of referenceVar", MessageList.ERROR);
|
testOutput.addMessage("Could not find address of referenceVar", MessageList.ERROR);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int relRefAddress = addresses.get("referenceVar");
|
int relRefAddress = (int) addresses.get("referenceVar").addr;
|
||||||
javaLibrary.setReferenceAddress(relRefAddress);
|
javaLibrary.setReferenceAddress(relRefAddress);
|
||||||
|
|
||||||
testOutput.addMessage("### Creating data and BSS memory sections");
|
testOutput.addMessage("### Creating data and BSS memory sections");
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2014, TU Braunschweig. All rights reserved.
|
||||||
* Copyright (c) 2006, Swedish Institute of Computer Science. All rights
|
* Copyright (c) 2006, Swedish Institute of Computer Science. All rights
|
||||||
* reserved.
|
* reserved.
|
||||||
*
|
*
|
||||||
|
@ -33,66 +34,90 @@ import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.contikios.cooja.mote.memory.MemoryInterface;
|
|
||||||
import org.contikios.cooja.mote.memory.MemoryLayout;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a mote memory consisting of non-overlapping memory sections with
|
* Represents a mote memory consisting of non-overlapping memory sections with
|
||||||
* symbol addresses.
|
* symbol addresses.
|
||||||
* <p>
|
* <p>
|
||||||
* When an non-existing memory segment is written, a new section is automatically
|
* Every section must implement MemoyInterface.
|
||||||
* created for this segment.
|
|
||||||
* <p>
|
* <p>
|
||||||
|
* Implements MemoryInterface by forwarding calls to available sections or returning
|
||||||
|
* an error if no section is available.
|
||||||
*
|
*
|
||||||
* @author Fredrik Osterlind
|
* @author Fredrik Osterlind
|
||||||
|
* @author Enrico Jorns
|
||||||
*/
|
*/
|
||||||
public class SectionMoteMemory implements MemoryInterface {
|
public class SectionMoteMemory implements MemoryInterface {
|
||||||
private static Logger logger = Logger.getLogger(SectionMoteMemory.class);
|
private static Logger logger = Logger.getLogger(SectionMoteMemory.class);
|
||||||
|
private static final boolean DEBUG = logger.isDebugEnabled();
|
||||||
|
|
||||||
private ArrayList<MoteMemorySection> sections = new ArrayList<MoteMemorySection>();
|
private Map<String, MemoryInterface> sections = new HashMap<>();
|
||||||
|
|
||||||
/* readonly memory is never written to Contiki core, and is used to provide
|
private final Map<String, Symbol> symbols;
|
||||||
* access to, for instance, strings */
|
private MemoryLayout memLayout;
|
||||||
private ArrayList<MoteMemorySection> readonlySections = new ArrayList<MoteMemorySection>();
|
private long startAddr = Long.MAX_VALUE;
|
||||||
|
|
||||||
private final HashMap<String, Integer> addresses;
|
|
||||||
|
|
||||||
/* used to map Cooja's address space to native (Contiki's) addresses */
|
/* used to map Cooja's address space to native (Contiki's) addresses */
|
||||||
private final int offset;
|
private final int offset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param addresses Symbol addresses
|
* @param symbols Symbol addresses
|
||||||
* @param offset Offset for internally used addresses
|
* @param offset Offset for internally used addresses
|
||||||
*/
|
*/
|
||||||
public SectionMoteMemory(HashMap<String, Integer> addresses, int offset) {
|
public SectionMoteMemory(Map<String, Symbol> symbols, int offset) {
|
||||||
this.addresses = addresses;
|
this.symbols = symbols;
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a section to this memory.
|
||||||
|
*
|
||||||
|
* A new section will be checked for address overlap with existing sections.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* @param section
|
||||||
|
* @return true if adding succeeded, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean addMemorySection(String name ,MemoryInterface section) {
|
||||||
|
|
||||||
@Override
|
if (section == null) {
|
||||||
public void clearMemory() {
|
return false;
|
||||||
sections.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMemorySegmentNative(int address, byte[] data) {
|
|
||||||
setMemorySegment(address+offset, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setReadonlyMemorySegment(int address, byte[] data) {
|
|
||||||
/* Cooja address space */
|
/* Cooja address space */
|
||||||
address -= offset;
|
for (MemoryInterface sec : sections.values()) {
|
||||||
|
/* check for overlap with existing region */
|
||||||
readonlySections.add(new MoteMemorySection(address, data));
|
if ((section.getStartAddr() <= sec.getStartAddr() + sec.getTotalSize() - 1)
|
||||||
|
&& (section.getStartAddr() + section.getTotalSize() - 1 >= sec.getStartAddr())) {
|
||||||
|
logger.error(String.format(
|
||||||
|
"Failed adding section '%s' of size %d @0x%x",
|
||||||
|
name,
|
||||||
|
section.getTotalSize(),
|
||||||
|
section.getStartAddr()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* Min start address is main start address */
|
||||||
|
startAddr = sec.getStartAddr() < startAddr ? sec.getStartAddr() : startAddr;
|
||||||
|
/* Layout is last layout. XXX Check layout consistency? */
|
||||||
|
memLayout = section.getLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTotalSize() {
|
sections.put(name, section);
|
||||||
int totalSize = 0;
|
if (section.getSymbolMap() != null) {
|
||||||
for (MoteMemorySection section : sections) {
|
for (String s : section.getSymbolMap().keySet()) {
|
||||||
totalSize += section.getSize();
|
// XXX how to handle double names here?
|
||||||
|
symbols.put(s, section.getSymbolMap().get(s));
|
||||||
}
|
}
|
||||||
return totalSize;
|
}
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
logger.debug(String.format(
|
||||||
|
"Added section '%s' of size %d @0x%x",
|
||||||
|
name,
|
||||||
|
section.getTotalSize(),
|
||||||
|
section.getStartAddr()));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -105,44 +130,69 @@ public class SectionMoteMemory implements MemoryInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get start address of given section in native address space.
|
* Returns memory section of this memory.
|
||||||
*
|
* @param name Name of section
|
||||||
* @param sectionNr Section position
|
* @return memory section
|
||||||
* @return Start address of section
|
|
||||||
*/
|
*/
|
||||||
public int getSectionNativeAddress(int sectionNr) {
|
public MemoryInterface getSection(String name) {
|
||||||
if (sectionNr >= sections.size()) {
|
for (String memsec : sections.keySet()) {
|
||||||
return -1;
|
if (memsec.equals(name)) {
|
||||||
|
return sections.get(name);
|
||||||
}
|
}
|
||||||
return sections.get(sectionNr).getStartAddr();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
logger.warn("Section '" + name + "' not found");
|
||||||
* Get size of section at given position.
|
|
||||||
*
|
|
||||||
* @param sectionNr Section position
|
|
||||||
* @return Size of section
|
|
||||||
*/
|
|
||||||
public int getSizeOfSection(int sectionNr) {
|
|
||||||
if (sectionNr >= sections.size()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sections.get(sectionNr).getSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get data of section at given position.
|
|
||||||
*
|
|
||||||
* @param sectionNr Section position
|
|
||||||
* @return Data at section
|
|
||||||
*/
|
|
||||||
public byte[] getDataOfSection(int sectionNr) {
|
|
||||||
if (sectionNr >= sections.size()) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sections.get(sectionNr).getData();
|
/**
|
||||||
|
* Return all sections of this memory.
|
||||||
|
* @return All memory sections
|
||||||
|
*/
|
||||||
|
public Map<String, MemoryInterface> getSections() {
|
||||||
|
return sections;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if given address is part of this memory section.
|
||||||
|
*
|
||||||
|
* @param intf
|
||||||
|
* @param addr
|
||||||
|
* Address
|
||||||
|
* @return True if given address is part of this memory section, false
|
||||||
|
* otherwise
|
||||||
|
*/
|
||||||
|
public static boolean includesAddr(MemoryInterface intf, long addr) {
|
||||||
|
return addr >= intf.getStartAddr() && addr < (intf.getStartAddr() + intf.getTotalSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True if the whole address range specified by address and size
|
||||||
|
* lies inside this memory section.
|
||||||
|
*
|
||||||
|
* @param intf
|
||||||
|
* @param addr Start address of segment to check
|
||||||
|
* @param size Size of segment to check
|
||||||
|
*
|
||||||
|
* @return True if given address range lies inside address range of this
|
||||||
|
* section
|
||||||
|
*/
|
||||||
|
public static boolean inSection(MemoryInterface intf, long addr, int size) {
|
||||||
|
return addr >= intf.getStartAddr() && addr + size <= intf.getStartAddr() + intf.getTotalSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearMemory() {
|
||||||
|
sections.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTotalSize() {
|
||||||
|
int totalSize = 0;
|
||||||
|
for (MemoryInterface section : sections.values()) {
|
||||||
|
totalSize += section.getTotalSize();
|
||||||
|
}
|
||||||
|
return totalSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -150,153 +200,106 @@ public class SectionMoteMemory implements MemoryInterface {
|
||||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns memory segment from section matching segment given by address and size
|
||||||
|
* @param address start address of segment to get
|
||||||
|
* @param size size of segmetn to get
|
||||||
|
* @return Array containing data of segment
|
||||||
|
* @throws MoteMemoryException if no single section containing the given address range was found
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public byte[] getMemorySegment(long addr, int size) throws MoteMemoryException {
|
public byte[] getMemorySegment(long address, int size) throws MoteMemoryException {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
|
||||||
|
for (MemoryInterface section : sections.values()) {
|
||||||
|
if (includesAddr(section, address) && includesAddr(section, address + size - 1)) {
|
||||||
|
return section.getMemorySegment(address, size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new MoteMemoryException(
|
||||||
|
"Getting memory segment [0x%x,0x%x] failed: No section available",
|
||||||
|
address, address + size - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets memory segment of section matching segment given by address and size.
|
||||||
|
* @param address start address of segment to set
|
||||||
|
* @param data data to set
|
||||||
|
* @throws MoteMemoryException if no single section containing the given address range was found
|
||||||
|
* or memory is readonly.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setMemorySegment(long addr, byte[] data) throws MoteMemoryException {
|
public void setMemorySegment(long address, byte[] data) throws MoteMemoryException {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
|
||||||
|
for (MemoryInterface section : sections.values()) {
|
||||||
|
if (inSection(section, address, data.length)) {
|
||||||
|
section.setMemorySegment(address, data);
|
||||||
|
if (DEBUG) {
|
||||||
|
logger.debug(String.format(
|
||||||
|
"Wrote memory segment [0x%x,0x%x]",
|
||||||
|
address, address + data.length - 1));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new MoteMemoryException(
|
||||||
|
"Writing memory segment [0x%x,0x%x] failed: No section available",
|
||||||
|
address, address + data.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMemorySegmentNative(long address, byte[] data) throws MoteMemoryException {
|
||||||
|
setMemorySegment(address + offset, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getStartAddr() {
|
public long getStartAddr() {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
return startAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Symbol> getSymbolMap() {
|
public Map<String, Symbol> getSymbolMap() {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
return symbols;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MemoryLayout getLayout() {
|
public MemoryLayout getLayout() {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
return memLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean addSegmentMonitor(SegmentMonitor.EventType flag, long address, int size, SegmentMonitor monitor) {
|
public boolean addSegmentMonitor(SegmentMonitor.EventType flag, long address, int size, SegmentMonitor monitor) {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
PolledMemorySegments t = new PolledMemorySegments(monitor, (int) address, size);
|
||||||
|
polledMemories.add(t);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeSegmentMonitor(long address, int size, SegmentMonitor monitor) {
|
public boolean removeSegmentMonitor(long address, int size, SegmentMonitor monitor) {
|
||||||
throw new UnsupportedOperationException("Not supported yet.");
|
for (PolledMemorySegments mcm: polledMemories) {
|
||||||
|
if (mcm.mm != monitor || mcm.address != address || mcm.size != size) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
polledMemories.remove(mcm);
|
||||||
/**
|
return true;
|
||||||
* A memory section contains a byte array and a start address.
|
|
||||||
*
|
|
||||||
* @author Fredrik Osterlind
|
|
||||||
*/
|
|
||||||
private static class MoteMemorySection {
|
|
||||||
private byte[] data = null;
|
|
||||||
private final int startAddr;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new memory section.
|
|
||||||
*
|
|
||||||
* @param startAddr
|
|
||||||
* Start address of section
|
|
||||||
* @param data
|
|
||||||
* Data of section
|
|
||||||
*/
|
|
||||||
public MoteMemorySection(int startAddr, byte[] data) {
|
|
||||||
this.startAddr = startAddr;
|
|
||||||
this.data = data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns start address of this memory section.
|
|
||||||
*
|
|
||||||
* @return Start address
|
|
||||||
*/
|
|
||||||
public int getStartAddr() {
|
|
||||||
return startAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns size of this memory section.
|
|
||||||
*
|
|
||||||
* @return Size
|
|
||||||
*/
|
|
||||||
public int getSize() {
|
|
||||||
return data.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the entire byte array which defines this section.
|
|
||||||
*
|
|
||||||
* @return Byte array
|
|
||||||
*/
|
|
||||||
public byte[] getData() {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if given address is part of this memory section.
|
|
||||||
*
|
|
||||||
* @param addr
|
|
||||||
* Address
|
|
||||||
* @return True if given address is part of this memory section, false
|
|
||||||
* otherwise
|
|
||||||
*/
|
|
||||||
public boolean includesAddr(int addr) {
|
|
||||||
if (data == null) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (addr >= startAddr && addr < (startAddr + data.length));
|
/** Copies seciton memory to new (array backed) one
|
||||||
}
|
* @return Cloned memory
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns memory segment.
|
|
||||||
*
|
|
||||||
* @param addr
|
|
||||||
* Start address of memory segment
|
|
||||||
* @param size
|
|
||||||
* Size of memory segment
|
|
||||||
* @return Memory segment
|
|
||||||
*/
|
*/
|
||||||
public byte[] getMemorySegment(int addr, int size) {
|
|
||||||
byte[] ret = new byte[size];
|
|
||||||
System.arraycopy(data, addr - startAddr, ret, 0, size);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a memory segment.
|
|
||||||
*
|
|
||||||
* @param addr
|
|
||||||
* Start of memory segment
|
|
||||||
* @param data
|
|
||||||
* Data of memory segment
|
|
||||||
*/
|
|
||||||
public void setMemorySegment(int addr, byte[] data) {
|
|
||||||
System.arraycopy(data, 0, this.data, addr - startAddr, data.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MoteMemorySection clone() {
|
|
||||||
byte[] dataClone = new byte[data.length];
|
|
||||||
System.arraycopy(data, 0, dataClone, 0, data.length);
|
|
||||||
|
|
||||||
MoteMemorySection clone = new MoteMemorySection(startAddr, dataClone);
|
|
||||||
return clone;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SectionMoteMemory clone() {
|
public SectionMoteMemory clone() {
|
||||||
ArrayList<MoteMemorySection> sectionsClone = new ArrayList<MoteMemorySection>();
|
|
||||||
for (MoteMemorySection section : sections) {
|
|
||||||
sectionsClone.add(section.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
SectionMoteMemory clone = new SectionMoteMemory(addresses, offset);
|
SectionMoteMemory clone = new SectionMoteMemory(symbols, offset);
|
||||||
clone.sections = sectionsClone;
|
|
||||||
clone.readonlySections = readonlySections;
|
for (String secname : sections.keySet()) {
|
||||||
|
// Copy section memory to new ArrayMemory
|
||||||
|
MemoryInterface section = sections.get(secname);
|
||||||
|
MemoryInterface cpmem = new ArrayMemory(section.getStartAddr(), section.getLayout(), section.getMemory().clone(), section.getSymbolMap());
|
||||||
|
clone.addMemorySection(secname, cpmem);
|
||||||
|
}
|
||||||
|
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
@ -333,34 +336,4 @@ public class SectionMoteMemory implements MemoryInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
|
||||||
public boolean addMemoryMonitor(int address, int size, SegmentMonitor mm) {
|
|
||||||
PolledMemorySegments t = new PolledMemorySegments(mm, address, size);
|
|
||||||
polledMemories.add(t);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
public void removeMemoryMonitor(int address, int size, SegmentMonitor mm) {
|
|
||||||
for (PolledMemorySegments mcm: polledMemories) {
|
|
||||||
if (mcm.mm != mm || mcm.address != address || mcm.size != size) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
polledMemories.remove(mcm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
public int parseInt(byte[] memorySegment) {
|
|
||||||
int retVal = 0;
|
|
||||||
int pos = 0;
|
|
||||||
retVal += ((memorySegment[pos++] & 0xFF)) << 24;
|
|
||||||
retVal += ((memorySegment[pos++] & 0xFF)) << 16;
|
|
||||||
retVal += ((memorySegment[pos++] & 0xFF)) << 8;
|
|
||||||
retVal += ((memorySegment[pos++] & 0xFF)) << 0;
|
|
||||||
|
|
||||||
retVal = Integer.reverseBytes(retVal);
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ import org.contikios.cooja.interfaces.ApplicationRadio;
|
||||||
import org.contikios.cooja.interfaces.ApplicationSerialPort;
|
import org.contikios.cooja.interfaces.ApplicationSerialPort;
|
||||||
import org.contikios.cooja.interfaces.Radio;
|
import org.contikios.cooja.interfaces.Radio;
|
||||||
import org.contikios.cooja.mote.memory.MemoryInterface;
|
import org.contikios.cooja.mote.memory.MemoryInterface;
|
||||||
|
import org.contikios.cooja.mote.memory.MemoryInterface.Symbol;
|
||||||
import org.contikios.cooja.mote.memory.MemoryLayout;
|
import org.contikios.cooja.mote.memory.MemoryLayout;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -91,7 +92,7 @@ public abstract class AbstractApplicationMote extends AbstractWakeupMote impleme
|
||||||
setSimulation(sim);
|
setSimulation(sim);
|
||||||
this.moteType = moteType;
|
this.moteType = moteType;
|
||||||
MemoryLayout.getNative();
|
MemoryLayout.getNative();
|
||||||
this.memory = new SectionMoteMemory(new HashMap<String, Integer>(), 0);
|
this.memory = new SectionMoteMemory(new HashMap<String, Symbol>(), 0);
|
||||||
this.moteInterfaces = new MoteInterfaceHandler(this, moteType.getMoteInterfaceClasses());
|
this.moteInterfaces = new MoteInterfaceHandler(this, moteType.getMoteInterfaceClasses());
|
||||||
this.moteInterfaces.getRadio().addObserver(radioDataObserver);
|
this.moteInterfaces.getRadio().addObserver(radioDataObserver);
|
||||||
requestImmediateWakeup();
|
requestImmediateWakeup();
|
||||||
|
@ -151,7 +152,7 @@ public abstract class AbstractApplicationMote extends AbstractWakeupMote impleme
|
||||||
public boolean setConfigXML(Simulation simulation,
|
public boolean setConfigXML(Simulation simulation,
|
||||||
Collection<Element> configXML, boolean visAvailable) {
|
Collection<Element> configXML, boolean visAvailable) {
|
||||||
setSimulation(simulation);
|
setSimulation(simulation);
|
||||||
this.memory = new SectionMoteMemory(new HashMap<String, Integer>(), 0);
|
this.memory = new SectionMoteMemory(new HashMap<String, Symbol>(), 0);
|
||||||
moteInterfaces.getRadio().addObserver(radioDataObserver);
|
moteInterfaces.getRadio().addObserver(radioDataObserver);
|
||||||
|
|
||||||
for (Element element : configXML) {
|
for (Element element : configXML) {
|
||||||
|
|
Loading…
Reference in a new issue