1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-01-30 19:52:13 +01:00

SerialMonitor suspend/resume: dealing with boards that change serial port

between uploads. Fixes #3255
Fixed a missing status management, leading IDE to believe Serial Monitor
was opened while it was not. See #3268
This commit is contained in:
Federico Fissore 2015-06-01 11:27:52 +02:00
parent 740a14e638
commit e55d4145d0
7 changed files with 114 additions and 96 deletions

View File

@ -30,6 +30,7 @@ import javax.swing.Timer;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import javax.swing.text.DefaultCaret; import javax.swing.text.DefaultCaret;
import cc.arduino.packages.BoardPort;
import processing.app.debug.TextAreaFIFO; import processing.app.debug.TextAreaFIFO;
import processing.app.legacy.PApplet; import processing.app.legacy.PApplet;
@ -50,8 +51,11 @@ public abstract class AbstractMonitor extends JFrame implements ActionListener {
private Timer updateTimer; private Timer updateTimer;
private StringBuffer updateBuffer; private StringBuffer updateBuffer;
public AbstractMonitor(String title) { private BoardPort boardPort;
super(title);
public AbstractMonitor(BoardPort boardPort) {
super(boardPort.getLabel());
this.boardPort = boardPort;
addWindowListener(new WindowAdapter() { addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent event) { public void windowClosing(WindowEvent event) {
@ -136,10 +140,7 @@ public abstract class AbstractMonitor extends JFrame implements ActionListener {
} }
lineEndings.setMaximumSize(lineEndings.getMinimumSize()); lineEndings.setMaximumSize(lineEndings.getMinimumSize());
String[] serialRateStrings = { String[] serialRateStrings = {"300", "1200", "2400", "4800", "9600", "19200", "38400", "57600", "115200", "230400", "250000"};
"300", "1200", "2400", "4800", "9600",
"19200", "38400", "57600", "115200", "230400", "250000"
};
serialRates = new JComboBox(); serialRates = new JComboBox();
for (String rate : serialRateStrings) { for (String rate : serialRateStrings) {
@ -185,8 +186,7 @@ public abstract class AbstractMonitor extends JFrame implements ActionListener {
closed = false; closed = false;
} }
public void enableWindow(boolean enable) public void enableWindow(boolean enable) {
{
textArea.setEnabled(enable); textArea.setEnabled(enable);
scrollPane.setEnabled(enable); scrollPane.setEnabled(enable);
textField.setEnabled(enable); textField.setEnabled(enable);
@ -200,33 +200,24 @@ public abstract class AbstractMonitor extends JFrame implements ActionListener {
// Puts the window in suspend state, closing the serial port // Puts the window in suspend state, closing the serial port
// to allow other entity (the programmer) to use it // to allow other entity (the programmer) to use it
public void suspend() public void suspend() throws Exception {
{
enableWindow(false); enableWindow(false);
try {
close(); close();
} }
catch(Exception e) {
//throw new SerialException("Failed closing the port");
}
} public void resume(BoardPort boardPort) throws Exception {
setBoardPort(boardPort);
public void resume() throws SerialException
{
// Enable the window // Enable the window
enableWindow(true); enableWindow(true);
// If the window is visible, try to open the serial port // If the window is visible, try to open the serial port
if (isVisible()) if (!isVisible()) {
try { return;
open();
}
catch(Exception e) {
throw new SerialException("Failed opening the port");
} }
open();
} }
public void onSerialRateChange(ActionListener listener) { public void onSerialRateChange(ActionListener listener) {
@ -278,9 +269,22 @@ public abstract class AbstractMonitor extends JFrame implements ActionListener {
return closed; return closed;
} }
public abstract void open() throws Exception; public void open() throws Exception {
closed = false;
}
public abstract void close() throws Exception; public void close() throws Exception {
closed = true;
}
public BoardPort getBoardPort() {
return boardPort;
}
public void setBoardPort(BoardPort boardPort) {
setTitle(boardPort.getLabel());
this.boardPort = boardPort;
}
public synchronized void addToUpdateBuffer(char buff[], int n) { public synchronized void addToUpdateBuffer(char buff[], int n) {
updateBuffer.append(buff, 0, n); updateBuffer.append(buff, 0, n);
@ -293,8 +297,12 @@ public abstract class AbstractMonitor extends JFrame implements ActionListener {
} }
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
final String s = consumeUpdateBuffer(); String s = consumeUpdateBuffer();
if (s.length() > 0) {
if (s.isEmpty()) {
return;
}
//System.out.println("gui append " + s.length()); //System.out.println("gui append " + s.length());
if (autoscrollBox.isSelected()) { if (autoscrollBox.isSelected()) {
textArea.appendTrim(s); textArea.appendTrim(s);
@ -303,6 +311,5 @@ public abstract class AbstractMonitor extends JFrame implements ActionListener {
textArea.appendNoTrim(s); textArea.appendNoTrim(s);
} }
} }
}
} }

View File

@ -1173,9 +1173,10 @@ public class Base {
BaseNoGui.onBoardOrPortChange(); BaseNoGui.onBoardOrPortChange();
// Update editors status bar // Update editors status bar
for (Editor editor : editors) for (Editor editor : editors) {
editor.onBoardOrPortChange(); editor.onBoardOrPortChange();
} }
}
private void openManageLibrariesDialog() { private void openManageLibrariesDialog() {
@SuppressWarnings("serial") @SuppressWarnings("serial")

View File

@ -1118,7 +1118,7 @@ public class Editor extends JFrame implements RunnerListener {
} }
} }
onBoardOrPortChange(); base.onBoardOrPortChange();
//System.out.println("set to " + get("serial.port")); //System.out.println("set to " + get("serial.port"));
} }
@ -2533,7 +2533,6 @@ public class Editor extends JFrame implements RunnerListener {
// error message will already be visible // error message will already be visible
} }
} catch (SerialNotFoundException e) { } catch (SerialNotFoundException e) {
populatePortMenu();
if (serialMenu.getItemCount() == 0) statusError(e); if (serialMenu.getItemCount() == 0) statusError(e);
else if (serialPrompt()) run(); else if (serialPrompt()) run();
else statusNotice(_("Upload canceled.")); else statusNotice(_("Upload canceled."));
@ -2548,21 +2547,33 @@ public class Editor extends JFrame implements RunnerListener {
statusError(e); statusError(e);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} finally {
populatePortMenu();
} }
status.unprogress(); status.unprogress();
uploading = false; uploading = false;
//toolbar.clear(); //toolbar.clear();
toolbar.deactivate(EditorToolbar.EXPORT); toolbar.deactivate(EditorToolbar.EXPORT);
// Return the serial monitor window to its initial state resumeOrCloseSerialMonitor();
try { base.onBoardOrPortChange();
if (serialMonitor != null)
serialMonitor.resume();
} }
catch (SerialException e) {
statusError(e);
} }
private void resumeOrCloseSerialMonitor() {
// Return the serial monitor window to its initial state
if (serialMonitor != null) {
BoardPort boardPort = BaseNoGui.getDiscoveryManager().find(PreferencesData.get("serial.port"));
try {
if (boardPort == null) {
serialMonitor.close();
handleSerial();
} else {
serialMonitor.resume(boardPort);
}
} catch (Exception e) {
statusError(e);
}
} }
} }
@ -2584,7 +2595,6 @@ public class Editor extends JFrame implements RunnerListener {
// error message will already be visible // error message will already be visible
} }
} catch (SerialNotFoundException e) { } catch (SerialNotFoundException e) {
populatePortMenu();
if (serialMenu.getItemCount() == 0) statusError(e); if (serialMenu.getItemCount() == 0) statusError(e);
else if (serialPrompt()) run(); else if (serialPrompt()) run();
else statusNotice(_("Upload canceled.")); else statusNotice(_("Upload canceled."));
@ -2599,21 +2609,16 @@ public class Editor extends JFrame implements RunnerListener {
statusError(e); statusError(e);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} finally {
populatePortMenu();
} }
status.unprogress(); status.unprogress();
uploading = false; uploading = false;
//toolbar.clear(); //toolbar.clear();
toolbar.deactivate(EditorToolbar.EXPORT); toolbar.deactivate(EditorToolbar.EXPORT);
if (serialMonitor != null) { resumeOrCloseSerialMonitor();
try { base.onBoardOrPortChange();
if (serialMonitor != null)
serialMonitor.resume();
}
catch (SerialException e) {
statusError(e);
}
}
} }
} }
@ -2685,8 +2690,13 @@ public class Editor extends JFrame implements RunnerListener {
// If currently uploading, disable the monitor (it will be later // If currently uploading, disable the monitor (it will be later
// enabled when done uploading) // enabled when done uploading)
if (uploading) if (uploading) {
try {
serialMonitor.suspend(); serialMonitor.suspend();
} catch (Exception e) {
statusError(e);
}
}
boolean success = false; boolean success = false;
do { do {

View File

@ -26,18 +26,13 @@ public class NetworkMonitor extends AbstractMonitor implements MessageConsumer {
private static final int MAX_CONNECTION_ATTEMPTS = 5; private static final int MAX_CONNECTION_ATTEMPTS = 5;
private final BoardPort port;
private final String ipAddress;
private MessageSiphon inputConsumer; private MessageSiphon inputConsumer;
private Session session; private Session session;
private Channel channel; private Channel channel;
private int connectionAttempts; private int connectionAttempts;
public NetworkMonitor(BoardPort port) { public NetworkMonitor(BoardPort port) {
super(port.getLabel()); super(port);
this.port = port;
this.ipAddress = port.getAddress();
onSendCommand(new ActionListener() { onSendCommand(new ActionListener() {
public void actionPerformed(ActionEvent event) { public void actionPerformed(ActionEvent event) {
@ -61,16 +56,17 @@ public class NetworkMonitor extends AbstractMonitor implements MessageConsumer {
@Override @Override
public String getAuthorizationKey() { public String getAuthorizationKey() {
return "runtime.pwd." + ipAddress; return "runtime.pwd." + getBoardPort().getAddress();
} }
@Override @Override
public void open() throws Exception { public void open() throws Exception {
super.open();
this.connectionAttempts = 0; this.connectionAttempts = 0;
JSch jSch = new JSch(); JSch jSch = new JSch();
SSHClientSetupChainRing sshClientSetupChain = new SSHConfigFileSetup(new SSHPwdSetup()); SSHClientSetupChainRing sshClientSetupChain = new SSHConfigFileSetup(new SSHPwdSetup());
session = sshClientSetupChain.setup(port, jSch); session = sshClientSetupChain.setup(getBoardPort(), jSch);
session.setUserInfo(new NoInteractionUserInfo(PreferencesData.get(getAuthorizationKey()))); session.setUserInfo(new NoInteractionUserInfo(PreferencesData.get(getAuthorizationKey())));
session.connect(30000); session.connect(30000);
@ -156,6 +152,8 @@ public class NetworkMonitor extends AbstractMonitor implements MessageConsumer {
@Override @Override
public void close() throws Exception { public void close() throws Exception {
super.close();
if (channel != null) { if (channel != null) {
inputConsumer.stop(); inputConsumer.stop();
channel.disconnect(); channel.disconnect();

View File

@ -30,14 +30,11 @@ import static processing.app.I18n._;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class SerialMonitor extends AbstractMonitor { public class SerialMonitor extends AbstractMonitor {
private final String port;
private Serial serial; private Serial serial;
private int serialRate; private int serialRate;
public SerialMonitor(BoardPort port) { public SerialMonitor(BoardPort port) {
super(port.getLabel()); super(port);
this.port = port.getAddress();
serialRate = PreferencesData.getInteger("serial.debug_rate"); serialRate = PreferencesData.getInteger("serial.debug_rate");
serialRates.setSelectedItem(serialRate + " " + _("baud")); serialRates.setSelectedItem(serialRate + " " + _("baud"));
@ -89,9 +86,11 @@ public class SerialMonitor extends AbstractMonitor {
} }
public void open() throws Exception { public void open() throws Exception {
super.open();
if (serial != null) return; if (serial != null) return;
serial = new Serial(port, serialRate) { serial = new Serial(getBoardPort().getAddress(), serialRate) {
@Override @Override
protected void message(char buff[], int n) { protected void message(char buff[], int n) {
addToUpdateBuffer(buff, n); addToUpdateBuffer(buff, n);
@ -101,6 +100,7 @@ public class SerialMonitor extends AbstractMonitor {
public void close() throws Exception { public void close() throws Exception {
if (serial != null) { if (serial != null) {
super.close();
int[] location = getPlacement(); int[] location = getPlacement();
String locationStr = PApplet.join(PApplet.str(location), ","); String locationStr = PApplet.join(PApplet.str(location), ",");
PreferencesData.set("last.serial.location", locationStr); PreferencesData.set("last.serial.location", locationStr);

View File

@ -110,8 +110,9 @@ public class SerialUploader extends Uploader {
t = prefs.get("upload.wait_for_upload_port"); t = prefs.get("upload.wait_for_upload_port");
boolean waitForUploadPort = (t != null) && t.equals("true"); boolean waitForUploadPort = (t != null) && t.equals("true");
if (doTouch) {
String uploadPort = prefs.getOrExcept("serial.port"); String uploadPort = prefs.getOrExcept("serial.port");
if (doTouch) {
try { try {
// Toggle 1200 bps on selected serial port to force board reset. // Toggle 1200 bps on selected serial port to force board reset.
List<String> before = Serial.list(); List<String> before = Serial.list();
@ -135,26 +136,23 @@ public class SerialUploader extends Uploader {
throw new RunnerException(e.getMessage()); throw new RunnerException(e.getMessage());
} }
prefs.put("serial.port", uploadPort); prefs.put("serial.port", uploadPort);
if (uploadPort.startsWith("/dev/")) if (uploadPort.startsWith("/dev/")) {
prefs.put("serial.port.file", uploadPort.substring(5)); prefs.put("serial.port.file", uploadPort.substring(5));
else } else {
prefs.put("serial.port.file", uploadPort); prefs.put("serial.port.file", uploadPort);
} }
}
prefs.put("build.path", buildPath); prefs.put("build.path", buildPath);
prefs.put("build.project_name", className); prefs.put("build.project_name", className);
if (verbose) if (verbose) {
prefs.put("upload.verbose", prefs.getOrExcept("upload.params.verbose")); prefs.put("upload.verbose", prefs.getOrExcept("upload.params.verbose"));
else } else {
prefs.put("upload.verbose", prefs.getOrExcept("upload.params.quiet")); prefs.put("upload.verbose", prefs.getOrExcept("upload.params.quiet"));
}
boolean uploadResult; boolean uploadResult;
try { try {
// if (prefs.get("upload.disable_flushing") == null
// || prefs.get("upload.disable_flushing").toLowerCase().equals("false")) {
// flushSerialBuffer();
// }
String pattern = prefs.getOrExcept("upload.pattern"); String pattern = prefs.getOrExcept("upload.pattern");
String[] cmd = StringReplacer.formatAndSplit(pattern, prefs, true); String[] cmd = StringReplacer.formatAndSplit(pattern, prefs, true);
uploadResult = executeUploadCommand(cmd); uploadResult = executeUploadCommand(cmd);
@ -164,9 +162,9 @@ public class SerialUploader extends Uploader {
throw new RunnerException(e); throw new RunnerException(e);
} }
try {
if (uploadResult && doTouch) { if (uploadResult && doTouch) {
String uploadPort = PreferencesData.get("serial.port"); try {
String previousUploadPort = PreferencesData.get("serial.port");
if (waitForUploadPort) { if (waitForUploadPort) {
// For Due/Leonardo wait until the bootloader serial port disconnects and the // For Due/Leonardo wait until the bootloader serial port disconnects and the
// sketch serial port reconnects (or timeout after a few seconds if the // sketch serial port reconnects (or timeout after a few seconds if the
@ -176,15 +174,18 @@ public class SerialUploader extends Uploader {
long started = System.currentTimeMillis(); long started = System.currentTimeMillis();
while (System.currentTimeMillis() - started < 2000) { while (System.currentTimeMillis() - started < 2000) {
List<String> portList = Serial.list(); List<String> portList = Serial.list();
if (portList.contains(uploadPort)) if (portList.contains(previousUploadPort)) {
break; break;
Thread.sleep(250);
} }
Thread.sleep(250);
} }
} }
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
// noop // noop
} }
}
BaseNoGui.selectSerialPort(uploadPort);
return uploadResult; return uploadResult;
} }

View File

@ -1082,10 +1082,11 @@ public class BaseNoGui {
public static void selectSerialPort(String port) { public static void selectSerialPort(String port) {
PreferencesData.set("serial.port", port); PreferencesData.set("serial.port", port);
if (port.startsWith("/dev/")) String portFile = port;
PreferencesData.set("serial.port.file", port.substring(5)); if (port.startsWith("/dev/")) {
else portFile = portFile.substring(5);
PreferencesData.set("serial.port.file", port); }
PreferencesData.set("serial.port.file", portFile);
} }
public static void setBuildFolder(File newBuildFolder) { public static void setBuildFolder(File newBuildFolder) {