implemented memory monitor support (moved previous functionality from MspMote to MspMoteMemory)

This commit is contained in:
Fredrik Osterlind 2012-03-09 14:57:44 +01:00
parent e8294e8699
commit f8134186da
2 changed files with 78 additions and 92 deletions

View file

@ -238,7 +238,7 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
/* Create mote address memory */
MapTable map = ((MspMoteType)getType()).getELF().getMap();
MapEntry[] allEntries = map.getAllEntries();
myMemory = new MspMoteMemory(allEntries, myCpu);
myMemory = new MspMoteMemory(this, allEntries, myCpu);
heapStartAddress = map.heapStartAddress;
myCpu.reset();
@ -539,84 +539,4 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc
/*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;
}
};
}
}

View file

@ -29,11 +29,16 @@
package se.sics.cooja.mspmote;
import java.util.*;
import java.util.ArrayList;
import org.apache.log4j.Logger;
import se.sics.cooja.AddressMemory;
import se.sics.cooja.Mote;
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.util.MapEntry;
@ -42,8 +47,10 @@ public class MspMoteMemory implements MoteMemory, AddressMemory {
private final ArrayList<MapEntry> mapEntries;
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>();
for (MapEntry entry: allEntries) {
@ -130,13 +137,7 @@ public class MspMoteMemory implements MoteMemory, AddressMemory {
int varAddr = entry.getAddress();
byte[] varData = getMemorySegment(varAddr, 2);
int retVal = 0;
int pos = 0;
retVal += ((varData[pos++] & 0xFF)) << 8;
retVal += ((varData[pos++] & 0xFF)) << 0;
return Integer.reverseBytes(retVal) >> 16; // Crop two bytes
return parseInt(varData);
}
public void setIntValueOf(String varName, int newVal) throws UnknownVariableException {
@ -179,7 +180,6 @@ public class MspMoteMemory implements MoteMemory, AddressMemory {
MapEntry entry = getMapEntry(varName);
int varAddr = entry.getAddress();
// TODO Check if small/big-endian when coming from JNI?
return getMemorySegment(varAddr, length);
}
@ -187,8 +187,74 @@ public class MspMoteMemory implements MoteMemory, AddressMemory {
MapEntry entry = getMapEntry(varName);
int varAddr = entry.getAddress();
// TODO Check if small/big-endian when coming from JNI?
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;
}
}