Added ExternalFlash base class for emulation of external flash chips. Replaced FileAT45DB and FileM25P80 with storage abstraction for storing data in memory or on file

This commit is contained in:
Niclas Finne 2012-05-30 22:40:54 +02:00
parent bf6233669d
commit 3ddcfefe04
15 changed files with 572 additions and 376 deletions

View File

@ -43,7 +43,7 @@ package se.sics.mspsim.chip;
import java.io.IOException;
import se.sics.mspsim.core.*;
public abstract class AT45DB extends Chip implements USARTListener {
public class AT45DB extends ExternalFlash implements USARTListener {
public static final int PAGE_SIZE = 264;
public static final int NUM_PAGES = 2048;
@ -337,11 +337,10 @@ public abstract class AT45DB extends Chip implements USARTListener {
private void bufferToPage(int buf) {
try {
seek(pageAddress * PAGE_SIZE);
if(buf == 1)
write(buffer1);
getStorage().write(pageAddress * PAGE_SIZE, buffer1);
else
write(buffer2);
getStorage().write(pageAddress * PAGE_SIZE, buffer2);
} catch (IOException e) {
e.printStackTrace();
}
@ -349,11 +348,10 @@ public abstract class AT45DB extends Chip implements USARTListener {
private void pageToBuffer(int buf) {
try {
seek(pageAddress * PAGE_SIZE);
if(buf == 1)
read(buffer1);
getStorage().read(pageAddress * PAGE_SIZE, buffer1);
else
read(buffer2);
getStorage().read(pageAddress * PAGE_SIZE, buffer2);
} catch (IOException e) {
e.printStackTrace();
}
@ -363,13 +361,9 @@ public abstract class AT45DB extends Chip implements USARTListener {
return 0;
}
public abstract void seek(long pos) throws IOException;
public abstract int read(byte[] b) throws IOException;
public abstract void write(byte[] b) throws IOException;
/* not yet any meaningful support for getting configuration */
public int getConfiguration(int param) {
@Override
public int getSize() {
return 0;
}
} // AT45DB

View File

@ -0,0 +1,68 @@
/**
* Copyright (c) 2012, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of MSPSim.
*
*/
package se.sics.mspsim.chip;
import se.sics.mspsim.core.Chip;
import se.sics.mspsim.core.MSP430Core;
public abstract class ExternalFlash extends Chip {
private Storage storage;
protected ExternalFlash(String id, MSP430Core cpu) {
super(id, cpu);
}
protected ExternalFlash(String id, String name, MSP430Core cpu) {
super(id, name, cpu);
}
public Storage getStorage() {
if (storage ==null) {
// No storage set. Create a memory storage
storage = new MemoryStorage();
storage.setMaxSize(getSize());
}
return storage;
}
public void setStorage(Storage storage) {
this.storage = storage;
}
@Override
public int getConfiguration(int param) {
return 0;
}
public abstract int getSize();
}

View File

@ -1,146 +0,0 @@
/**
* Copyright (c) 2007, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of MSPSim.
*
* $Id: $
*
* -----------------------------------------------------------------
*
* FileAT45DB - File based implementation of external flash.
*
* Author : Joakim Eriksson, Fredrik Osterlind
* Created : Sun Oct 21 22:00:00 2007
* Updated : $Date: 2008-05-12 18:10:17 +0000 (Mon, 12 May 2008) $
* $Revision: 280 $
*/
package se.sics.mspsim.chip;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import se.sics.mspsim.core.MSP430Core;
public class FileAT45DB extends AT45DB {
// PAGE_SIZE and NUM_PAGES defined in AT45DB
private static final int FLASH_SIZE = PAGE_SIZE * NUM_PAGES;
private RandomAccessFile file;
private FileChannel fileChannel;
private FileLock fileLock;
public FileAT45DB(MSP430Core cpu, String filename) {
super(cpu);
if (filename == null) {
filename = "flash.bin";
}
// Open flash file for R/W
if (!openFile(filename)) {
// Failed to open/lock the specified file. Add a counter and try with next filename.
Matcher m = Pattern.compile("(.+?)(\\d*)(\\.[^.]+)").matcher(filename);
if (m.matches()) {
String baseName = m.group(1);
String c = m.group(2);
String extName = m.group(3);
int count = 1;
if (c != null && c.length() > 0) {
count = Integer.parseInt(c) + 1;
}
for (int i = 0; !openFile(baseName + count + extName) && i < 100; i++, count++);
}
}
if (fileLock == null) {
// Failed to open flash file
throw new IllegalStateException("failed to open flash file '" + filename + '\'');
}
// Set size of flash
try {
file.setLength(FLASH_SIZE);
} catch (IOException e) {
e.printStackTrace();
}
}
private boolean openFile(String filename) {
// Open flash file for R/W
try {
file = new RandomAccessFile(filename, "rw");
fileChannel = file.getChannel();
fileLock = fileChannel.tryLock();
if (fileLock != null) {
// The file is now locked for use
if (DEBUG) log("using flash file '" + filename + '\'');
return true;
} else {
fileChannel.close();
return false;
}
} catch (IOException e) {
e.printStackTrace();
closeFile();
return false;
}
}
private void closeFile() {
try {
if (fileLock != null) {
fileLock.release();
fileLock = null;
}
if (fileChannel != null) {
fileChannel.close();
fileChannel = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void seek(long pos) throws IOException {
file.seek(pos);
}
public int read(byte[] b) throws IOException {
return file.read(b);
}
public void write(byte[] b) throws IOException {
file.write(b);
}
public void stateChanged(int state) {
// TODO Auto-generated method stub
}
} // FileAT45DB

View File

@ -1,180 +0,0 @@
/**
* Copyright (c) 2007, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of MSPSim.
*
* $Id$
*
* -----------------------------------------------------------------
*
* FileM25P80 - File based implementation of external flash.
*
* Author : Joakim Eriksson, Fredrik Osterlind
* Created : Sun Oct 21 22:00:00 2007
* Updated : $Date$
* $Revision$
*/
package se.sics.mspsim.chip;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import se.sics.mspsim.core.MSP430Core;
public class FileM25P80 extends M25P80 {
private String filename;
private RandomAccessFile file;
private FileChannel fileChannel;
private FileLock fileLock;
private long pos = 0;
public FileM25P80(MSP430Core cpu, String filename) {
super(cpu);
if (filename == null) {
filename = "flash.bin";
}
this.filename = filename;
}
private boolean ensureOpen(boolean write) {
if (fileChannel != null) {
return true;
}
if (!write) {
File fp = new File(filename);
if (!fp.exists()) {
// File does not exist and only trying to read. Delay file creation until first write
return false;
}
}
// Open flash file for R/W
if (!openFile(filename)) {
// Failed to open/lock the specified file. Add a counter and try with next filename.
Matcher m = Pattern.compile("(.+?)(\\d*)(\\.[^.]+)").matcher(filename);
if (m.matches()) {
String baseName = m.group(1);
String c = m.group(2);
String extName = m.group(3);
int count = 1;
if (c != null && c.length() > 0) {
count = Integer.parseInt(c) + 1;
}
for (int i = 0; !openFile(baseName + count + extName) && i < 100; i++, count++);
}
}
if (fileLock == null) {
// Failed to open flash file
if (write) {
logw("failed to open flash file '" + filename + '\'');
}
return false;
}
// Set size of flash
try {
file.setLength(MEMORY_SIZE);
if (pos > 0) {
file.seek(pos);
}
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
private boolean openFile(String filename) {
// Open flash file for R/W
try {
file = new RandomAccessFile(filename, "rw");
fileChannel = file.getChannel();
fileLock = fileChannel.tryLock();
if (fileLock != null) {
// The file is now locked for use
if (DEBUG) log("using flash file '" + filename + '\'');
return true;
}
fileChannel.close();
return false;
} catch (IOException e) {
e.printStackTrace();
closeFile();
return false;
}
}
private void closeFile() {
try {
file = null;
if (fileLock != null) {
fileLock.release();
fileLock = null;
}
if (fileChannel != null) {
fileChannel.close();
fileChannel = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void seek(long pos) throws IOException {
if (file != null) {
file.seek(pos);
}
this.pos = pos;
}
public int readFully(byte[] b) throws IOException {
if (file != null || ensureOpen(false)) {
pos += b.length;
return file.read(b);
}
Arrays.fill(b, (byte) 0);
pos += b.length;
return b.length;
}
public void write(byte[] b) throws IOException {
if (file != null || ensureOpen(true)) {
file.write(b);
}
pos += b.length;
}
public void stateChanged(int state) {
// TODO Auto-generated method stub
}
} // FileM25P80

View File

@ -0,0 +1,229 @@
/**
* Copyright (c) 2012, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of MSPSim.
*
*/
package se.sics.mspsim.chip;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Niclas Finne
*/
public class FileStorage implements Storage {
private String filename;
private String currentFilename;
private RandomAccessFile file;
private FileChannel fileChannel;
private FileLock fileLock;
private long maxSize = 0;
public FileStorage() {
this("flash.bin");
}
public FileStorage(String filename) {
this.filename = filename;
}
private boolean ensureOpen(boolean write) throws IOException {
if (fileChannel != null) {
return true;
}
if (!write) {
File fp = new File(filename);
if (!fp.exists()) {
// File does not exist and only trying to read. Delay file creation until first write
return false;
}
}
// Open flash file for R/W
if (!openFile(filename)) {
// Failed to open/lock the specified file. Add a counter and try with next filename.
Matcher m = Pattern.compile("(.+?)(\\d*)(\\.[^.]+)").matcher(filename);
if (m.matches()) {
String baseName = m.group(1);
String c = m.group(2);
String extName = m.group(3);
int count = 1;
if (c != null && c.length() > 0) {
count = Integer.parseInt(c) + 1;
}
for (int i = 0; !openFile(baseName + count + extName) && i < 100; i++, count++);
}
}
if (fileLock == null) {
// Failed to open flash file
if (write) {
throw new IOException("failed to open storage file '" + filename + '\'');
}
return false;
}
return true;
}
private boolean openFile(String filename) {
// Open flash file for R/W
try {
currentFilename = filename;
file = new RandomAccessFile(filename, "rw");
fileChannel = file.getChannel();
fileLock = fileChannel.tryLock();
if (fileLock != null) {
// The file is now locked for use
// if (DEBUG) log("using flash file '" + filename + '\'');
return true;
}
fileChannel.close();
return false;
} catch (IOException e) {
e.printStackTrace();
close();
return false;
}
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
close();
}
public File getCurrentFile() {
if (file != null) {
return new File(currentFilename);
}
return null;
}
@Override
public int read(long pos, byte[] b) throws IOException {
return read(pos, b, 0, b.length);
}
@Override
public int read(long pos, byte[] b, int offset, int len) throws IOException {
if (maxSize > 0 && pos + len > maxSize) {
throw new IOException("outside storage");
}
if (file != null || ensureOpen(false)) {
file.seek(pos);
return file.read(b, offset, len);
}
Arrays.fill(b, (byte) 0);
return len;
}
@Override
public void write(long pos, byte[] b) throws IOException {
write(pos, b, 0, b.length);
}
public void write(long pos, byte[] b, int offset, int len) throws IOException {
if (maxSize > 0 && pos + len > maxSize) {
throw new IOException("outside storage");
}
if (file != null || ensureOpen(true)) {
file.seek(pos);
file.write(b, offset, len);
}
}
@Override
public long getMaxSize() {
return maxSize;
}
@Override
public void setMaxSize(long size) {
this.maxSize = size;
if (size > 0 && file != null) {
try {
if (file.length() > size) {
file.setLength(size);
}
} catch (IOException e) {
// Ignore
}
}
}
@Override
public void close() {
try {
file = null;
if (fileLock != null) {
fileLock.release();
fileLock = null;
}
if (fileChannel != null) {
fileChannel.close();
fileChannel = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public String info() {
File fp = getCurrentFile();
StringBuilder sb = new StringBuilder();
sb.append("FileStorage(");
if (file != null) {
try {
long len = file.length();
sb.append(len);
} catch (Exception e) {
// Ignore
sb.append('0');
}
}
if (maxSize > 0) {
sb.append('/').append(maxSize);
}
sb.append(" bytes): ");
if (fp != null) {
sb.append(fp.getAbsolutePath());
} else {
sb.append(filename);
}
return sb.toString();
}
}

View File

@ -0,0 +1,51 @@
/**
* Copyright (c) 2012, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of MSPSim.
*
*/
package se.sics.mspsim.chip;
import se.sics.mspsim.core.MSP430Core;
/**
* @author Niclas Finne
*/
public class M25P16 extends M25P80 {
public static final int MEMORY_SIZE = 2 * 1024 * 1024;
public M25P16(MSP430Core cpu) {
super("M25P16", cpu);
}
@Override
public int getSize() {
return MEMORY_SIZE;
}
}

View File

@ -44,7 +44,7 @@ import java.io.IOException;
import se.sics.mspsim.core.*;
import se.sics.mspsim.util.Utils;
public abstract class M25P80 extends Chip implements USARTListener, PortListener, Memory {
public class M25P80 extends ExternalFlash implements USARTListener, PortListener, Memory {
public static final int WRITE_STATUS = 0x01;
public static final int PAGE_PROGRAM = 0x02;
@ -93,6 +93,10 @@ public abstract class M25P80 extends Chip implements USARTListener, PortListener
writing = false;
}};
protected M25P80(String id, MSP430Core cpu) {
super(id, "External Flash", cpu);
}
public M25P80(MSP430Core cpu) {
super("M25P80", "External Flash", cpu);
}
@ -271,6 +275,7 @@ public abstract class M25P80 extends Chip implements USARTListener, PortListener
}
}
@Override
public int getSize() {
return MEMORY_SIZE;
}
@ -304,8 +309,7 @@ public abstract class M25P80 extends Chip implements USARTListener, PortListener
}
private void loadMemory(int address, byte[] readMemory) throws IOException {
seek(address & 0xfff00);
readFully(readMemory);
getStorage().read(address & 0xfff00, readMemory);
for (int i = 0; i < readMemory.length; i++) {
readMemory[i] = (byte) (~readMemory[i] & 0xff);
}
@ -372,32 +376,25 @@ public abstract class M25P80 extends Chip implements USARTListener, PortListener
if (DEBUG) {
log("Writing data to disk at $" + Integer.toHexString(address));
}
seek(address & 0xfff00);
for (int i = 0; i < data.length; i++) {
tmp[i] = (byte) (~data[i] & 0xff);
}
write(tmp);
} catch (IOException e) {
getStorage().write(address & 0xfff00, tmp);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public int getModeMax() {
return 0;
}
public abstract void seek(long pos) throws IOException;
public abstract int readFully(byte[] b) throws IOException;
public abstract void write(byte[] b) throws IOException;
/* by default - there is not configuration to return for m25p80 */
public int getConfiguration(int param) {
return 0;
}
@Override
public String info() {
return " Status: " + getStatus() + " Write Enabled: " + writeEnable
+ " Write in Progress: " + writing + '\n' + " Chip Select: " + chipSelect;
+ " Write in Progress: " + writing + " Chip Select: " + chipSelect
+ "\n " + getStorage().info();
}
} // M25P80

View File

@ -0,0 +1,116 @@
/**
* Copyright (c) 2012, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of MSPSim.
*
*/
package se.sics.mspsim.chip;
import java.io.IOException;
import java.util.Arrays;
/**
* @author Niclas Finne
*/
public class MemoryStorage implements Storage {
private byte[] data;
private int maxSize;
private void ensureCapacity(int size) throws IOException {
if (data == null) {
data = new byte[size];
} else if (data.length < size) {
data = Arrays.copyOf(data, size);
}
}
@Override
public int read(long pos, byte[] b) throws IOException {
return read(pos, b, 0, b.length);
}
@Override
public int read(long storagePos, byte[] buffer, int offset, int len) throws IOException {
if (maxSize > 0 && storagePos + len > maxSize) {
throw new IOException("outside storage");
}
if (data == null) {
Arrays.fill(buffer, offset, offset + len, (byte)0);
} else {
int pos = (int) storagePos;
if (pos + len > data.length) {
System.arraycopy(data, pos, buffer, offset, data.length - pos);
Arrays.fill(buffer, offset + data.length - pos, offset + len, (byte) 0);
} else {
System.arraycopy(data, pos, buffer, offset, len);
}
}
return len;
}
@Override
public void write(long storagePos, byte[] buffer) throws IOException {
write(storagePos, buffer, 0, buffer.length);
}
@Override
public void write(long storagePos, byte[] buffer, int offset, int len) throws IOException {
int pos = (int) storagePos;
if (maxSize > 0 && pos + len > maxSize) {
throw new IOException("outside storage");
}
ensureCapacity(pos + len);
System.arraycopy(buffer, offset, data, pos, len);
}
@Override
public long getMaxSize() {
return maxSize;
}
@Override
public void setMaxSize(long size) {
this.maxSize = (int) size;
if (maxSize > 0 && data != null && data.length > maxSize) {
data = Arrays.copyOf(data, maxSize);
}
}
@Override
public void close() {
// Nothing to close
}
@Override
public String info() {
if (maxSize > 0) {
return "MemoryStorage(" + data.length + "/" + maxSize + " bytes)";
}
return "MemoryStorage(" + data.length + " bytes allocated)";
}
}

View File

@ -0,0 +1,56 @@
/**
* Copyright (c) 2012, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of MSPSim.
*
*/
package se.sics.mspsim.chip;
import java.io.IOException;
/**
* @author Niclas Finne
*/
public interface Storage {
public int read(long pos, byte[] buffer) throws IOException;
public int read(long pos, byte[] buffer, int offset, int len) throws IOException;
public void write(long pos, byte[] buffer) throws IOException;
public void write(long pos, byte[] buffer, int offset, int len) throws IOException;
public long getMaxSize();
public void setMaxSize(long size);
public void close();
public String info();
}

View File

@ -41,16 +41,13 @@
package se.sics.mspsim.platform.jcreate;
import java.io.IOException;
import se.sics.mspsim.chip.FileM25P80;
import se.sics.mspsim.chip.FileStorage;
import se.sics.mspsim.chip.Leds;
import se.sics.mspsim.chip.M25P80;
import se.sics.mspsim.chip.MMA7260QT;
import se.sics.mspsim.core.ADC12;
import se.sics.mspsim.core.ADCInput;
import se.sics.mspsim.core.IOPort;
import se.sics.mspsim.core.IOUnit;
import se.sics.mspsim.core.USART;
import se.sics.mspsim.core.USARTSource;
import se.sics.mspsim.platform.sky.CC2420Node;
import se.sics.mspsim.util.ArgumentManager;
@ -134,8 +131,11 @@ public class JCreateNode extends CC2420Node {
}
});
if (getFlash() == null) {
setFlash(new M25P80(cpu));
}
if (flashFile != null) {
setFlash(new FileM25P80(cpu, flashFile));
getFlash().setStorage(new FileStorage(flashFile));
}
}

View File

@ -41,12 +41,10 @@
package se.sics.mspsim.platform.sentillausb;
import java.io.IOException;
import se.sics.mspsim.chip.FileM25P80;
import se.sics.mspsim.chip.FileStorage;
import se.sics.mspsim.chip.Leds;
import se.sics.mspsim.chip.M25P80;
import se.sics.mspsim.core.IOPort;
import se.sics.mspsim.core.USART;
import se.sics.mspsim.core.USARTSource;
import se.sics.mspsim.platform.sky.CC2420Node;
import se.sics.mspsim.util.ArgumentManager;
@ -110,8 +108,11 @@ public class SentillaUSBNode extends CC2420Node {
public void setupNodePorts() {
super.setupNodePorts();
leds = new Leds(cpu, LEDS);
if (getFlash() == null) {
setFlash(new M25P80(cpu));
}
if (flashFile != null) {
setFlash(new FileM25P80(cpu, flashFile));
getFlash().setStorage(new FileStorage(flashFile));
}
}

View File

@ -4,7 +4,6 @@ import se.sics.mspsim.chip.DS2411;
import se.sics.mspsim.chip.PacketListener;
import se.sics.mspsim.config.MSP430f1611Config;
import se.sics.mspsim.core.IOPort;
import se.sics.mspsim.core.IOUnit;
import se.sics.mspsim.core.MSP430;
import se.sics.mspsim.core.PortListener;
import se.sics.mspsim.core.USART;

View File

@ -41,7 +41,7 @@
package se.sics.mspsim.platform.sky;
import java.io.IOException;
import se.sics.mspsim.chip.FileM25P80;
import se.sics.mspsim.chip.FileStorage;
import se.sics.mspsim.chip.M25P80;
import se.sics.mspsim.core.IOPort;
import se.sics.mspsim.core.USARTSource;
@ -88,8 +88,11 @@ public class SkyNode extends MoteIVNode {
public void setupNodePorts() {
super.setupNodePorts();
if (getFlash() == null) {
setFlash(new M25P80(cpu));
}
if (flashFile != null) {
setFlash(new FileM25P80(cpu, flashFile));
getFlash().setStorage(new FileStorage(flashFile));
}
}

View File

@ -42,7 +42,7 @@
package se.sics.mspsim.platform.sky;
import java.io.IOException;
import se.sics.mspsim.chip.AT45DB;
import se.sics.mspsim.chip.FileAT45DB;
import se.sics.mspsim.chip.FileStorage;
import se.sics.mspsim.core.IOPort;
import se.sics.mspsim.core.USARTSource;
import se.sics.mspsim.util.ArgumentManager;
@ -90,8 +90,11 @@ public class TelosNode extends MoteIVNode {
public void setupNodePorts() {
super.setupNodePorts();
if (getFlash() == null) {
setFlash(new AT45DB(cpu));
}
if (flashFile != null) {
flash = new FileAT45DB(cpu, flashFile);
getFlash().setStorage(new FileStorage(flashFile));
}
}

View File

@ -3,7 +3,7 @@ package se.sics.mspsim.platform.z1;
import java.io.IOException;
import se.sics.mspsim.chip.Button;
import se.sics.mspsim.chip.CC2420;
import se.sics.mspsim.chip.FileM25P80;
import se.sics.mspsim.chip.FileStorage;
import se.sics.mspsim.chip.Leds;
import se.sics.mspsim.chip.M25P80;
import se.sics.mspsim.config.MSP430f2617Config;
@ -89,6 +89,9 @@ public class Z1Node extends GenericNode implements PortListener, USARTListener {
}
public M25P80 getFlash() {
// TODO Replace with M25P16.
// The Z1 platform has a M25P16 chip with 2MB compared to the M25P80
// with 1MB but the chips are compatible.
return flash;
}
@ -142,10 +145,6 @@ public class Z1Node extends GenericNode implements PortListener, USARTListener {
}
private void setupNodePorts() {
if (flashFile != null) {
setFlash(new FileM25P80(cpu, flashFile));
}
port1 = cpu.getIOUnit(IOPort.class, "P1");
// port1.addPortListener(this);
port2 = cpu.getIOUnit(IOPort.class, "P2");
@ -174,6 +173,12 @@ public class Z1Node extends GenericNode implements PortListener, USARTListener {
leds = new Leds(cpu, LEDS);
button = new Button("Button", cpu, port2, BUTTON_PIN, true);
if (getFlash() == null) {
setFlash(new M25P80(cpu));
}
if (flashFile != null) {
getFlash().setStorage(new FileStorage(flashFile));
}
}
public void setupNode() {
@ -190,7 +195,7 @@ public class Z1Node extends GenericNode implements PortListener, USARTListener {
fileName = fileName + ".flash";
}
}
if (DEBUG) System.out.println("Using flash file: " + (fileName == null ? "no file" : fileName));
if (DEBUG) log("Using flash file: " + (fileName == null ? "no file" : fileName));
this.flashFile = fileName;