implemented memory monitor support (moved previous functionality from MspMote to MspMoteMemory)
This commit is contained in:
parent
e8294e8699
commit
f8134186da
@ -238,7 +238,7 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
|
|||||||
/* Create mote address memory */
|
/* Create mote address memory */
|
||||||
MapTable map = ((MspMoteType)getType()).getELF().getMap();
|
MapTable map = ((MspMoteType)getType()).getELF().getMap();
|
||||||
MapEntry[] allEntries = map.getAllEntries();
|
MapEntry[] allEntries = map.getAllEntries();
|
||||||
myMemory = new MspMoteMemory(allEntries, myCpu);
|
myMemory = new MspMoteMemory(this, allEntries, myCpu);
|
||||||
|
|
||||||
heapStartAddress = map.heapStartAddress;
|
heapStartAddress = map.heapStartAddress;
|
||||||
myCpu.reset();
|
myCpu.reset();
|
||||||
@ -539,84 +539,4 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
|
|||||||
|
|
||||||
/*return executeCLICommand("line " + myCpu.getPC());*/
|
/*return executeCLICommand("line " + myCpu.getPC());*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemoryMonitor createMemoryMonitor(final MemoryEventHandler meh) {
|
|
||||||
return new MemoryMonitor() {
|
|
||||||
private boolean started = false;
|
|
||||||
private int address = -1;
|
|
||||||
private int size = -1;
|
|
||||||
private CPUMonitor myMonitor = null;
|
|
||||||
private boolean isPointer = false;
|
|
||||||
private MemoryMonitor pointedMemory = null;
|
|
||||||
public boolean start(int address, int size) {
|
|
||||||
if (started) {
|
|
||||||
return started;
|
|
||||||
}
|
|
||||||
|
|
||||||
final MemoryMonitor thisMonitor = this;
|
|
||||||
myMonitor = new CPUMonitor() {
|
|
||||||
public void cpuAction(int type, int adr, int data) {
|
|
||||||
MemoryEventType t;
|
|
||||||
if (type == CPUMonitor.MEMORY_WRITE) {
|
|
||||||
t = MemoryEventType.WRITE;
|
|
||||||
} else if (type == CPUMonitor.MEMORY_READ) {
|
|
||||||
t = MemoryEventType.READ;
|
|
||||||
} else {
|
|
||||||
t = MemoryEventType.UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
meh.event(thisMonitor, t, adr, data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* TODO Make sure no other part of Cooja overrides this! */
|
|
||||||
for (int a = address; a < address+size; a++) {
|
|
||||||
myCpu.addWatchPoint(a, myMonitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.address = address;
|
|
||||||
this.size = size;
|
|
||||||
started = true;
|
|
||||||
return started;
|
|
||||||
}
|
|
||||||
public void stop() {
|
|
||||||
if (!started) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
started = false;
|
|
||||||
|
|
||||||
for (int a = address; a < address+size; a++) {
|
|
||||||
myCpu.removeWatchPoint(a, myMonitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public Mote getMote() {
|
|
||||||
return MspMote.this;
|
|
||||||
}
|
|
||||||
public int getAddress() {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
public int getSize() {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isPointer() {
|
|
||||||
return isPointer;
|
|
||||||
}
|
|
||||||
public void setPointer(boolean isPointer, MemoryMonitor pointedMemory) {
|
|
||||||
this.isPointer = isPointer;
|
|
||||||
this.pointedMemory = pointedMemory;
|
|
||||||
}
|
|
||||||
public MemoryMonitor getPointedMemory() {
|
|
||||||
return pointedMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
private BufferAccess lastBufferAccess = null;
|
|
||||||
public void setLastBufferAccess(BufferAccess ba) {
|
|
||||||
this.lastBufferAccess = ba;
|
|
||||||
}
|
|
||||||
public BufferAccess getLastBufferAccess() {
|
|
||||||
return lastBufferAccess;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -29,11 +29,16 @@
|
|||||||
|
|
||||||
package se.sics.cooja.mspmote;
|
package se.sics.cooja.mspmote;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import se.sics.cooja.AddressMemory;
|
import se.sics.cooja.AddressMemory;
|
||||||
|
import se.sics.cooja.Mote;
|
||||||
import se.sics.cooja.MoteMemory;
|
import se.sics.cooja.MoteMemory;
|
||||||
|
import se.sics.cooja.MoteTimeEvent;
|
||||||
|
import se.sics.cooja.TimeEvent;
|
||||||
|
import se.sics.mspsim.core.CPUMonitor;
|
||||||
import se.sics.mspsim.core.MSP430;
|
import se.sics.mspsim.core.MSP430;
|
||||||
import se.sics.mspsim.util.MapEntry;
|
import se.sics.mspsim.util.MapEntry;
|
||||||
|
|
||||||
@ -42,8 +47,10 @@ public class MspMoteMemory implements MoteMemory, AddressMemory {
|
|||||||
private final ArrayList<MapEntry> mapEntries;
|
private final ArrayList<MapEntry> mapEntries;
|
||||||
|
|
||||||
private MSP430 cpu;
|
private MSP430 cpu;
|
||||||
|
private Mote mote;
|
||||||
|
|
||||||
public MspMoteMemory(MapEntry[] allEntries, MSP430 cpu) {
|
public MspMoteMemory(Mote mote, MapEntry[] allEntries, MSP430 cpu) {
|
||||||
|
this.mote = mote;
|
||||||
this.mapEntries = new ArrayList<MapEntry>();
|
this.mapEntries = new ArrayList<MapEntry>();
|
||||||
|
|
||||||
for (MapEntry entry: allEntries) {
|
for (MapEntry entry: allEntries) {
|
||||||
@ -130,13 +137,7 @@ public class MspMoteMemory implements MoteMemory, AddressMemory {
|
|||||||
|
|
||||||
int varAddr = entry.getAddress();
|
int varAddr = entry.getAddress();
|
||||||
byte[] varData = getMemorySegment(varAddr, 2);
|
byte[] varData = getMemorySegment(varAddr, 2);
|
||||||
|
return parseInt(varData);
|
||||||
int retVal = 0;
|
|
||||||
int pos = 0;
|
|
||||||
retVal += ((varData[pos++] & 0xFF)) << 8;
|
|
||||||
retVal += ((varData[pos++] & 0xFF)) << 0;
|
|
||||||
|
|
||||||
return Integer.reverseBytes(retVal) >> 16; // Crop two bytes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIntValueOf(String varName, int newVal) throws UnknownVariableException {
|
public void setIntValueOf(String varName, int newVal) throws UnknownVariableException {
|
||||||
@ -179,7 +180,6 @@ public class MspMoteMemory implements MoteMemory, AddressMemory {
|
|||||||
MapEntry entry = getMapEntry(varName);
|
MapEntry entry = getMapEntry(varName);
|
||||||
int varAddr = entry.getAddress();
|
int varAddr = entry.getAddress();
|
||||||
|
|
||||||
// TODO Check if small/big-endian when coming from JNI?
|
|
||||||
return getMemorySegment(varAddr, length);
|
return getMemorySegment(varAddr, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,8 +187,74 @@ public class MspMoteMemory implements MoteMemory, AddressMemory {
|
|||||||
MapEntry entry = getMapEntry(varName);
|
MapEntry entry = getMapEntry(varName);
|
||||||
int varAddr = entry.getAddress();
|
int varAddr = entry.getAddress();
|
||||||
|
|
||||||
// TODO Check if small/big-endian when coming from JNI?
|
|
||||||
setMemorySegment(varAddr, data);
|
setMemorySegment(varAddr, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ArrayList<MemoryCPUMonitor> cpuMonitorArray = new ArrayList<MemoryCPUMonitor>();
|
||||||
|
class MemoryCPUMonitor implements CPUMonitor {
|
||||||
|
public final MemoryMonitor mm;
|
||||||
|
public final int address;
|
||||||
|
public final int size;
|
||||||
|
|
||||||
|
public MemoryCPUMonitor(MemoryMonitor mm, int address, int size) {
|
||||||
|
this.mm = mm;
|
||||||
|
this.address = address;
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cpuAction(int type, final int adr, int data) {
|
||||||
|
final MemoryEventType t;
|
||||||
|
if (type == CPUMonitor.MEMORY_WRITE) {
|
||||||
|
t = MemoryEventType.WRITE;
|
||||||
|
} else {
|
||||||
|
t = MemoryEventType.READ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX Workaround to avoid using soon-obsolete data argument.
|
||||||
|
* This causes a delay between memory rw and listener notifications */
|
||||||
|
TimeEvent e = new MoteTimeEvent(mote, 0) {
|
||||||
|
public void execute(long time) {
|
||||||
|
mm.memoryChanged(MspMoteMemory.this, t, adr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mote.getSimulation().scheduleEvent(e, mote.getSimulation().getSimulationTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addMemoryMonitor(int address, int size, MemoryMonitor mm) {
|
||||||
|
MemoryCPUMonitor t = new MemoryCPUMonitor(mm, address, size);
|
||||||
|
cpuMonitorArray.add(t);
|
||||||
|
|
||||||
|
for (int a = address; a < address+size; a++) {
|
||||||
|
cpu.addWatchPoint(a, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeMemoryMonitor(int address, int size, MemoryMonitor mm) {
|
||||||
|
for (MemoryCPUMonitor mcm: cpuMonitorArray) {
|
||||||
|
if (mcm.mm != mm || mcm.address != address || mcm.size != size) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int a = address; a < address+size; a++) {
|
||||||
|
cpu.removeWatchPoint(a, mcm);
|
||||||
|
}
|
||||||
|
cpuMonitorArray.remove(mcm);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int parseInt(byte[] memorySegment) {
|
||||||
|
if (memorySegment.length < 2) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int retVal = 0;
|
||||||
|
int pos = 0;
|
||||||
|
retVal += ((memorySegment[pos++] & 0xFF)) << 8;
|
||||||
|
retVal += ((memorySegment[pos++] & 0xFF)) << 0;
|
||||||
|
|
||||||
|
return Integer.reverseBytes(retVal) >> 16;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user