mirror of https://github.com/contiki-ng/mspsim
Merge pull request #17 from joakimeriksson/master
Cleanups to avoid using NIO resources and unnecessary code.
This commit is contained in:
commit
8482a71403
|
|
@ -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 !!! */
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ package se.sics.mspsim.core;
|
|||
|
||||
import java.util.Arrays;
|
||||
|
||||
import se.sics.mspsim.core.EmulationLogger.WarningType;
|
||||
|
||||
|
||||
/**
|
||||
* ADC12 Plus IO peripheral
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue