diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/MspMote.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/MspMote.java index 1b0d5be11..403376583 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/MspMote.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/MspMote.java @@ -34,7 +34,6 @@ import java.awt.Component; import java.io.File; import java.io.IOException; import java.io.PrintStream; -import java.nio.ByteOrder; import java.util.ArrayList; import java.util.Collection; import java.util.Hashtable; @@ -52,7 +51,6 @@ import org.contikios.cooja.Watchpoint; import org.contikios.cooja.WatchpointMote; import org.contikios.cooja.interfaces.IPAddress; import org.contikios.cooja.mote.memory.MemoryInterface; -import org.contikios.cooja.mote.memory.MemoryLayout; import org.contikios.cooja.motes.AbstractEmulatedMote; import org.contikios.cooja.mspmote.interfaces.Msp802154Radio; import org.contikios.cooja.mspmote.interfaces.MspSerial; @@ -107,7 +105,6 @@ public abstract class MspMote extends AbstractEmulatedMote implements Mote, Watc public MspMote(MspMoteType moteType, Simulation simulation) { this.simulation = simulation; myMoteType = moteType; - new MemoryLayout(ByteOrder.LITTLE_ENDIAN, MemoryLayout.ARCH_16BIT, 2); /* Schedule us immediately */ requestImmediateWakeup(); diff --git a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/MspMoteMemory.java b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/MspMoteMemory.java index 16b453bf4..6e2e58c36 100644 --- a/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/MspMoteMemory.java +++ b/tools/cooja/apps/mspsim/src/org/contikios/cooja/mspmote/MspMoteMemory.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2014, TU Braunschweig. All rights reserved. * Copyright (c) 2007, Swedish Institute of Computer Science. All rights * reserved. * @@ -28,20 +29,27 @@ package org.contikios.cooja.mspmote; +import java.nio.ByteOrder; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; import java.util.Map; import org.apache.log4j.Logger; import org.contikios.cooja.Mote; import org.contikios.cooja.mote.memory.MemoryInterface; +import org.contikios.cooja.mote.memory.MemoryInterface.SegmentMonitor.EventType; import org.contikios.cooja.mote.memory.MemoryLayout; import se.sics.mspsim.core.MSP430; +import se.sics.mspsim.core.Memory.AccessMode; +import se.sics.mspsim.core.Memory.AccessType; import se.sics.mspsim.util.MapEntry; public class MspMoteMemory implements MemoryInterface { private static Logger logger = Logger.getLogger(MspMoteMemory.class); private final ArrayList mapEntries; + private final MemoryLayout memLayout; private final MSP430 cpu; @@ -55,6 +63,7 @@ public class MspMoteMemory implements MemoryInterface { } this.cpu = cpu; + memLayout = new MemoryLayout(ByteOrder.LITTLE_ENDIAN, MemoryLayout.ARCH_16BIT, 2); } @Override @@ -68,55 +77,111 @@ public class MspMoteMemory implements MemoryInterface { } @Override - public byte[] getMemorySegment(long addr, int size) throws MoteMemoryException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public byte[] getMemorySegment(long address, int size) { + int[] memInts = new int[size]; + + System.arraycopy(cpu.memory, (int) address, memInts, 0, size); + + /* Convert to byte array */ + byte[] memBytes = new byte[size]; + for (int i = 0; i < size; i++) { + memBytes[i] = (byte) memInts[i]; + } + + return memBytes; } @Override - public void setMemorySegment(long addr, byte[] data) throws MoteMemoryException { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + public void setMemorySegment(long address, byte[] data) { + /* Convert to int array */ + int[] memInts = new int[data.length]; + for (int i = 0; i < data.length; i++) { + memInts[i] = data[i]; + } + + System.arraycopy(memInts, 0, cpu.memory, (int) address, data.length); } @Override public void clearMemory() { - throw new UnsupportedOperationException("Not supported yet."); + Arrays.fill(cpu.memory, 0); } @Override public long getStartAddr() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + return 0;// XXXX } @Override public Map getSymbolMap() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + Map vars = new HashMap<>(); + for (MapEntry entry : mapEntries) { + if (entry.getType() != MapEntry.TYPE.variable) { + continue; + } + vars.put(entry.getName(), new Symbol( + Symbol.Type.VARIABLE, + entry.getName(), + entry.getAddress(), + entry.getSize())); + } + return vars; } @Override public MemoryLayout getLayout() { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + return memLayout; } - @Override - public boolean addSegmentMonitor(SegmentMonitor.EventType flag, long address, int size, SegmentMonitor monitor) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } + private final ArrayList cpuMonitorArray = new ArrayList<>(); - @Override - public boolean removeSegmentMonitor(long address, int size, SegmentMonitor monitor) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } + class MemoryCPUMonitor extends se.sics.mspsim.core.MemoryMonitor.Adapter { - public int parseInt(byte[] memorySegment) { - if (memorySegment.length < 2) { - return -1; + public final SegmentMonitor mm; + public final int address; + public final int size; + + public MemoryCPUMonitor(SegmentMonitor mm, int address, int size) { + this.mm = mm; + this.address = address; + this.size = size; } - - int retVal = 0; - int pos = 0; - retVal += ((memorySegment[pos++] & 0xFF)) << 8; - retVal += ((memorySegment[pos++] & 0xFF)) << 0; - return Integer.reverseBytes(retVal) >> 16; + @Override + public void notifyReadAfter(int address, AccessMode mode, AccessType type) { + mm.memoryChanged(MspMoteMemory.this, EventType.READ, address); + } + + @Override + public void notifyWriteAfter(int dstAddress, int data, AccessMode mode) { + mm.memoryChanged(MspMoteMemory.this, EventType.WRITE, dstAddress); + } + } + + @Override + public boolean addSegmentMonitor(EventType type, long address, int size, SegmentMonitor mm) { + MemoryCPUMonitor t = new MemoryCPUMonitor(mm, (int) address, size); + cpuMonitorArray.add(t); + + for (int a = (int) address; a < address + size; a++) { + cpu.addWatchPoint(a, t); + } + + return true; + } + + @Override + public boolean removeSegmentMonitor(long address, int size, SegmentMonitor mm) { + for (MemoryCPUMonitor mcm : cpuMonitorArray) { + if (mcm.mm != mm || mcm.address != address || mcm.size != size) { + continue; + } + for (int a = (int) address; a < (int) address + size; a++) { + cpu.removeWatchPoint(a, mcm); + } + cpuMonitorArray.remove(mcm); + return true; + } + return false; } }