use of org.firstinspires.ftc.robotcore.internal.usb.exception.RobotUsbException in project robotcode by OutoftheBoxFTC.
the class BulkPacketInWorker method run.
public void run() {
try {
do {
// Get a buffer into which to receive some data
BulkPacketBufferIn packetBuffer = this.readBufferManager.acquireWritableInputBuffer();
// Try to read some incoming data
// TODO: this call is NOT interruptable ??!?
int cbRead = this.usbDeviceConnection.bulkTransfer(this.endpoint, packetBuffer.array(), 0, packetBuffer.capacity(), this.msReadTimeout);
if (cbRead > 0) {
// Got some data : pass it along to our (lower-priority) processor
packetBuffer.setCurrentLength(cbRead);
this.readBufferManager.releaseReadableBuffer(packetBuffer);
if (cbRead <= MODEM_STATUS_SIZE) {
noteTrivialInput();
}
} else {
// No data received, so put buffer back into the pool
// be consistent, helps debugging
packetBuffer.setCurrentLength(0);
this.readBufferManager.releaseWritableInputBuffer(packetBuffer);
// Log any errors
if (cbRead < 0) {
this.errorReporter.ee(cbRead, TAG, "%s: bulkTransfer() error: %d", ftDevice.getSerialNumber(), cbRead);
} else {
this.errorReporter.reset();
}
}
} while (!Thread.interrupted());
throw new InterruptedException();
} catch (InterruptedException interrupt) {
this.readBufferManager.purgeInputData();
Thread.currentThread().interrupt();
} catch (RuntimeException | RobotUsbException e) {
// RuntimeExceptions are bugs
// RobotUsbExceptions shouldn't be thrown on reads, as we are doing here
RobotLog.ee(TAG, e, "unexpected exception");
}
}
use of org.firstinspires.ftc.robotcore.internal.usb.exception.RobotUsbException in project robotcode by OutoftheBoxFTC.
the class MonitoredUsbDeviceConnection method initializeMonitoring.
protected void initializeMonitoring() {
// We allocate ahead of time rather than on each call in order to eash
// pressure on the garbage collector.
bulkTransferAction = new Callable<RobotUsbException>() {
@Override
public RobotUsbException call() {
callResult = delegate.bulkTransfer(endpoint, buffer, offset, length, timeout);
return null;
}
};
controlTransferAction = new Callable<RobotUsbException>() {
@Override
public RobotUsbException call() {
callResult = delegate.controlTransfer(requestType, request, value, index, buffer, offset, length, timeout);
;
return null;
}
};
failureAction = new Callable<RobotUsbException>() {
@Override
public RobotUsbException call() {
// We close the device in the hopes of waking up the call. We return a
// distinguished exception so that folks can in fact KNOW we closed the device. We
// also set up so that a read that detects the closed device will return the same sort
// of 'please try again' error rather than its usual 'i give up'.
//
// Note: closing in this way *does* seem to unstick the call. However, we've rarely/never
// been able to successfully re-open after that, even after waiting huge amounts of
// time (like a second). Rather, we get stuck in trying to set the baud rate, inside of
// a different native call (UsbDeviceConnection.native_control_request).
//
Thread monitoredThread = monitor.getMonitoredThread();
String threadMessage = monitoredThread == null ? "" : String.format(" threadId=%d TID=%d:", monitoredThread.getId(), ThreadPool.getTID(monitoredThread));
String failureMessage;
switch(failureType) {
default:
failureMessage = "unknown failure";
break;
case WRITE:
failureMessage = String.format("write(%d bytes)", length);
break;
case CONTROL_TRANSFER:
failureMessage = String.format("control(%d bytes)", length);
break;
}
RobotLog.ee(TAG, "watchdog: stuck USB %s%s: serial=%s closing device", failureMessage, threadMessage, serialNumber, threadMessage);
RobotUsbException deviceClosedReason = new RobotUsbStuckUsbWriteException(delegate, "watchdog: stuck USB %s: closed %s", failureMessage, serialNumber);
ftDevice.setDeviceClosedReason(deviceClosedReason);
// XYZZY
ftDevice.close();
return deviceClosedReason;
}
};
}
use of org.firstinspires.ftc.robotcore.internal.usb.exception.RobotUsbException in project robotcode by OutoftheBoxFTC.
the class MonitoredUsbDeviceConnection method controlTransfer.
public int controlTransfer(int requestType, int request, int value, int index, byte[] buffer, int offset, int length, int timeout) throws RobotUsbException {
synchronized (// concurrency paranoia
monitor) {
this.callResult = FtDevice.RC_PARANOIA;
try {
if (acquireUsbWriteLock()) {
try {
this.requestType = requestType;
this.request = request;
this.value = value;
this.index = index;
this.buffer = buffer;
this.offset = offset;
this.length = length;
this.timeout = timeout;
failureType = FailureType.CONTROL_TRANSFER;
RobotUsbException timedOutException = monitor.monitor(controlTransferAction, failureAction, msUsbWriteDurationMax, TimeUnit.MILLISECONDS);
if (timedOutException != null) {
throw timedOutException;
}
} catch (ExecutionException | CancellationException e) {
// We should have ruled out all of these cases with the above logic
throw RobotUsbUnspecifiedException.createChained(e, "control transfer: internal error: unexpected exception from future");
} finally {
releaseUsbWriteLock();
}
} else {
throw unableToAcquireWriteLockException();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (RuntimeException e) {
throw RobotUsbFTDIException.createChained(e, "runtime exception %s during controlTransfer() of %d bytes on %s", e.getClass().getSimpleName(), length, serialNumber);
}
return callResult;
}
}
use of org.firstinspires.ftc.robotcore.internal.usb.exception.RobotUsbException in project robotcode by OutoftheBoxFTC.
the class RobotUsbManagerTty method openBySerialNumber.
@Override
public RobotUsbDevice openBySerialNumber(SerialNumber serialNumber) throws RobotCoreException {
synchronized (getLock()) {
if (serialNumberEmbedded.equals(serialNumber)) {
if (!RobotUsbDeviceImplBase.isOpen(serialNumber)) {
File file = findSerialDevTty();
SerialPort serialPort = null;
try {
serialPort = new SerialPort(file, LynxConstants.SERIAL_MODULE_BAUD_RATE);
} catch (IOException e) {
throw RobotCoreException.createChained(e, "exception in %s.open(%s)", TAG, file.getPath());
}
RobotUsbDeviceTty deviceTTY = new RobotUsbDeviceTty(serialPort, serialNumberEmbedded, file);
deviceTTY.setFirmwareVersion(new RobotUsbDevice.FirmwareVersion(1, 0));
deviceTTY.setDeviceType(DeviceManager.DeviceType.LYNX_USB_DEVICE);
deviceTTY.setUsbIdentifiers(RobotUsbDevice.USBIdentifiers.createLynxIdentifiers());
try {
deviceTTY.setBaudRate(LynxConstants.SERIAL_MODULE_BAUD_RATE);
} catch (RobotUsbException e) {
/*ignored*/
}
return deviceTTY;
}
}
return null;
}
}
use of org.firstinspires.ftc.robotcore.internal.usb.exception.RobotUsbException in project robotcode by OutoftheBoxFTC.
the class LynxUsbDeviceImpl method transmit.
@Override
public void transmit(LynxMessage message) throws InterruptedException // Note that this might be called on ANY thread.
{
synchronized (engageLock) {
if (this.isArmedOrArming() && !this.hasShutdownAbnormally() && isEngaged) {
if (DEBUG_LOG_DATAGRAMS || DEBUG_LOG_MESSAGES) {
RobotLog.vv(TAG, "xmit'ing: mod=%d cmd=0x%02x(%s) msg#=%d ref#=%d ", message.getModuleAddress(), message.getCommandNumber(), message.getClass().getSimpleName(), message.getMessageNumber(), message.getReferenceNumber());
}
LynxDatagram datagram = message.getSerialization();
Assert.assertTrue(datagram != null);
byte[] bytes = datagram.toByteArray();
try {
this.robotUsbDevice.write(bytes);
} catch (// RuntimeException is just paranoia
RobotUsbException | RuntimeException e) {
// For now, at least, we're brutal: we don't quarter ANY usb transmission errors
// before giving up and shutting things down. In the wake of future experience, it
// might later be reasonable to reconsider this decision.
shutdownAbnormally();
//
RobotLog.ee(TAG, e, "exception thrown in LynxUsbDevice.transmit");
//
return;
}
long now = System.nanoTime();
message.setNanotimeLastTransmit(now);
// "The keep alive must be sent at least every 2500 milliseconds. The Controller Module
// will perform the actions specified in Fail Safe (7F05) if it fails to receive a timely
// Keep Alive". Other messages will do the trick, too.
//
message.resetModulePingTimer();
} else {
message.onPretendTransmit();
}
}
// Do this last so as to make LynxModule.retransmitDatagrams() interlock more robust
message.noteHasBeenTransmitted();
}
Aggregations