Merge pull request #17 from joakimeriksson/master

Cleanups to avoid using NIO resources and unnecessary code.
This commit is contained in:
Joakim Eriksson 2013-08-12 06:54:48 -07:00
commit 8482a71403
6 changed files with 73 additions and 202 deletions

View File

@ -222,6 +222,7 @@ public class CC2420 extends Radio802154 implements USARTListener {
public static final int TYPE_BEACON_FRAME = 0x00;
public static final int TYPE_DATA_FRAME = 0x01;
public static final int TYPE_ACK_FRAME = 0x02;
public static final int TYPE_CMD_FRAME = 0x03;
// FCF Low
public static final int DESTINATION_ADDRESS_MODE = 0x30;
@ -614,7 +615,7 @@ public class CC2420 extends Radio802154 implements USARTListener {
frameType = fcf0 & FRAME_TYPE;
} else if (rxread == 2) {
fcf1 = data & 0xff;
if (frameType == TYPE_DATA_FRAME) {
if (frameType == TYPE_DATA_FRAME || frameType == TYPE_CMD_FRAME) {
ackRequest = (fcf0 & ACK_REQUEST) > 0;
destinationAddressMode = (fcf1 >> 2) & 3;
/* check this !!! */

View File

@ -78,6 +78,8 @@ package se.sics.mspsim.core;
import java.util.Arrays;
import se.sics.mspsim.core.EmulationLogger.WarningType;
/**
* ADC12 Plus IO peripheral

View File

@ -32,11 +32,11 @@
*/
package se.sics.mspsim.core;
import java.nio.ByteBuffer;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import se.sics.mspsim.core.EmulationLogger.WarningType;
/**
* AES128 msp430 peripheral emulation
@ -149,9 +149,64 @@ public class AES128 extends IOUnit {
/**
* Variable holders for the different registers needed by this peripheral
*/
private ByteBuffer key = ByteBuffer.allocate(16);
private ByteBuffer inData = ByteBuffer.allocate(16);
private ByteBuffer outData = ByteBuffer.allocate(16);
/* avoid using NIO resources */
private static class ByteBuffer {
byte[] buffer;
int pos;
ByteBuffer(int size) {
buffer = new byte[size];
pos = 0;
}
public int position() {
return pos;
}
public void position(int p) {
pos = p;
}
public boolean hasRemaining() {
return pos < buffer.length;
}
public void clear() {
pos = 0;
}
public void resetPos() {
pos = 0;
}
public byte[] array() {
return buffer;
}
public void put(byte[] bytes) {
for (int i = 0; i < bytes.length; i++) {
put(bytes[i]);
}
}
public void put(byte data) {
buffer[pos++] = data;
}
/* assume that calling code is ok... */
public byte get() {
return buffer[pos++];
}
public int limit() {
return buffer.length;
}
}
private ByteBuffer key = new ByteBuffer(16);
private ByteBuffer inData = new ByteBuffer(16);
private ByteBuffer outData = new ByteBuffer(16);
/**
* Syntax sugar
@ -247,7 +302,7 @@ public class AES128 extends IOUnit {
byte[] bytes = cipher.doFinal(inData.array());
outData.clear();
outData.put(bytes);
outData.rewind();
outData.resetPos();
} catch (Exception e) {
log(e.getStackTrace().toString());
}
@ -269,7 +324,7 @@ public class AES128 extends IOUnit {
byte[] bytes = cipher.doFinal(inData.array());
outData.clear();
outData.put(bytes);
outData.rewind();
outData.resetPos();
} catch (Exception e) {
log(e.getStackTrace().toString());
}
@ -353,7 +408,7 @@ public class AES128 extends IOUnit {
if (!advancedCipherMode) {
value |= AESKEYWR;
} else {
key.rewind();
key.resetPos();
}
} else {
isBusy = true;
@ -380,7 +435,7 @@ public class AES128 extends IOUnit {
if (!advancedCipherMode) {
value |= AESKEYWR;
} else {
inData.rewind();
inData.resetPos();
}
} else {
inData.position(inData.limit());

View File

@ -1,7 +1,8 @@
package se.sics.mspsim.core;
import java.util.ArrayDeque;
import se.sics.mspsim.chip.I2CUnit.I2CData;
import se.sics.mspsim.util.RingBuffer;
/**
@ -85,7 +86,7 @@ public class GenericUSCI extends IOUnit implements DMATrigger, USARTSource {
private boolean readyForNextTransmit;
private boolean stopConditionPending;
private RingBuffer<Integer> txBuffer = new RingBuffer<>(100);
private ArrayDeque<Integer> txBuffer = new ArrayDeque<Integer>(100);
public GenericUSCI(MSP430Core cpu, int uartIndex, int[] memory, MSP430Config config) {
super(config.uartConfig[uartIndex].name, cpu, memory, config.uartConfig[uartIndex].offset);

View File

@ -35,6 +35,8 @@ package se.sics.mspsim.core;
import java.util.Calendar;
import java.util.GregorianCalendar;
import se.sics.mspsim.core.EmulationLogger.WarningType;
/**
* RTC module for the MSP430

View File

@ -1,190 +0,0 @@
package se.sics.mspsim.util;
/******************************************************************************
* File: RingBuffer.java
*
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of a synchronized queue backed by a ring buffer. This
* functionality and implementation is similar to the ArrayBlockingQueue class,
* but I thought that I'd implement my own version to get a better feel for how
* it works.
*
* A ring buffer is a space-efficient, locality-friendly implementation of a
* FIFO queue. It is implemented as a fixed-sized array that is treated as
* though it wraps around like a ring; it has no well-defined start or end
* point. This array stores two pointers, a read pointer and a write pointer,
* delineating where the next insert should take place and from where the next
* element should be dequeued. For example:
*
* [2] [3] [ ] [ ] [ ] [ ] [0] [1]
* ^ ^
* | |
* write read
*
* When using a ring buffer, one must be careful not to let the read and write
* pointers cross one another. If this happens, future write operations will
* start overwriting old elements that have not yet been consumed. For this
* reason, most ring buffers adopt one of two strategies. First, the ring buffer
* can increase its size whenever it runs out of room. This approach allows the
* buffer to grow arbitrarily large if need be. The second option, and the one
* used in this implementation, is simply to block on a read or write when data
* is not available. This allows the ring buffer to implement the
* producer/consumer pattern fairly easily; any number of threads can begin
* creating data while some number of threads consume it, and at no time are too
* many elements kept in memory waiting to be read.
*/
public final class RingBuffer<T> {
/* The actual ring buffer. */
private final T[] elements;
/* The write pointer, represented as an offset into the array. */
private int offset = 0;
/*
* The read pointer is encoded implicitly by keeping track of the number of
* unconsumed elements. We can then determine its position by backing up that
* many positions before the read position.
*/
private int unconsumedElements = 0;
/**
* Constructs a new RingBuffer with the specified capacity, which must be
* positive.
*
* @param size
* The capacity of the new ring buffer.
* @throws IllegalArgumentException
* If the capacity is negative.
*/
@SuppressWarnings("unchecked")
public RingBuffer(int size) {
/* Validate the size. */
if (size <= 0)
throw new IllegalArgumentException(
"RingBuffer capacity must be positive.");
/* Construct the array to be that size. */
elements = (T[]) new Object[size];
}
/**
* Clear the buffer
*/
@SuppressWarnings("unchecked")
public synchronized void clear() {
offset = 0;
unconsumedElements = 0;
for (int i = 0; i < elements.length; i++) {
elements[i] = null;
}
}
/**
* Appends an element to the ring buffer, blocking until space becomes
* available.
*
* @param elem
* The element to add to the ring buffer.
*/
public synchronized boolean add(T elem) {
/*
* Block until the capacity is nonzero. Otherwise we don't have any space
* to write.
*/
if (unconsumedElements == elements.length)
return false;
/*
* Write the element into the next open spot, then advance the write
* pointer forward a step.
*/
elements[offset] = elem;
offset = (offset + 1) % elements.length;
/*
* Increase the number of unconsumed elements by one, then notify any
* threads that are waiting that more data is now available.
*/
++unconsumedElements;
return true;
}
/**
* Returns the maximum capacity of the ring buffer.
*
* @return The maximum capacity of the ring buffer.
*/
public int capacity() {
return elements.length;
}
/**
* Observes, but does not dequeue, the next available element, blocking until
* data becomes available.
*
* @return The next available element.
*/
public synchronized T peek() {
/* Wait for data to become available. */
if (unconsumedElements == 0)
return null;
/*
* Hand back the next value. The index of this next value is a bit tricky
* to compute. We know that there are unconsumedElements elements waiting
* to be read, and they're contiguously before the write position.
* However, the buffer wraps around itself, and so we can't just do a
* naive subtraction; that might end up giving us a negative index. To
* avoid this, we'll use a clever trick in which we'll add to the index
* the capacity minus the distance. This value must be positive, since the
* distance is never greater than the capacity, and if we then wrap this
* value around using the modulus operator we'll end up with a valid
* index. All of this machinery works because
*
* (x + (n - k)) mod n == (x - k) mod n
*
* And Java's modulus operator works best on positive values.
*/
return elements[(offset + (capacity() - unconsumedElements)) % capacity()];
}
/**
* Removes and returns the next available element, blocking until data
* becomes available.
*
* @return The next available element
*/
public synchronized T remove() {
/* Use peek() to get the element to return. */
T result = peek();
/* Mark that one fewer elements are now available to read. */
--unconsumedElements;
/* Because there is more space left, wake up any waiting threads. */
notifyAll();
return result;
}
/**
* Returns the number of elements that are currently being stored in the ring
* buffer.
*
* @return The number of elements currently stored in the ring buffer.
*/
public synchronized int size() {
return unconsumedElements;
}
/**
* Returns whether the ring buffer is empty.
*
* @return Whether the ring buffer is empty.
*/
public synchronized boolean isEmpty() {
return size() == 0;
}
}