Skip to content

Rework serial ports handling #4792

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Apr 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 89 additions & 9 deletions app/src/processing/app/Editor.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ public boolean test(Sketch sketch) {

private int numTools = 0;

public boolean avoidMultipleOperations = false;

private final EditorToolbar toolbar;
// these menus are shared so that they needn't be rebuilt for all windows
// each time a sketch is created, renamed, or moved.
Expand Down Expand Up @@ -198,7 +200,7 @@ public boolean test(Sketch sketch) {
private Runnable stopHandler;
Runnable exportHandler;
private Runnable exportAppHandler;

private Runnable timeoutUploadHandler;

public Editor(Base ibase, File file, int[] storedLocation, int[] defaultLocation, Platform platform) throws Exception {
super("Arduino");
Expand Down Expand Up @@ -812,6 +814,9 @@ public void actionPerformed(ActionEvent e) {
portMenu = new JMenu(tr("Port"));
populatePortMenu();
toolsMenu.add(portMenu);
item = new JMenuItem(tr("Get Board Info"));
item.addActionListener(e -> handleBoardInfo());
toolsMenu.add(item);
toolsMenu.addSeparator();

base.rebuildProgrammerMenu();
Expand Down Expand Up @@ -1648,6 +1653,7 @@ private void resetHandlers() {
stopHandler = new DefaultStopHandler();
exportHandler = new DefaultExportHandler();
exportAppHandler = new DefaultExportAppHandler();
timeoutUploadHandler = new TimeoutUploadHandler();
}


Expand Down Expand Up @@ -1979,6 +1985,7 @@ public void run() {

status.unprogress();
toolbar.deactivateRun();
avoidMultipleOperations = false;
}
}

Expand Down Expand Up @@ -2367,6 +2374,7 @@ synchronized public void handleExport(final boolean usingProgrammer) {
console.clear();
status.progress(tr("Uploading to I/O Board..."));

new Thread(timeoutUploadHandler).start();
new Thread(usingProgrammer ? exportAppHandler : exportHandler).start();
}

Expand Down Expand Up @@ -2406,6 +2414,7 @@ public void run() {
e.printStackTrace();
} finally {
populatePortMenu();
avoidMultipleOperations = false;
}
status.unprogress();
uploading = false;
Expand Down Expand Up @@ -2433,13 +2442,14 @@ private void resumeOrCloseSerialMonitor() {
}
}
try {
if (serialMonitor != null)
serialMonitor.resume(boardPort);
if (boardPort == null) {
serialMonitor.close();
handleSerial();
} else {
if (serialMonitor != null) {
serialMonitor.resume(boardPort);
if (boardPort == null) {
serialMonitor.close();
handleSerial();
} else {
serialMonitor.resume(boardPort);
}
}
} catch (Exception e) {
statusError(e);
Expand Down Expand Up @@ -2500,6 +2510,7 @@ public void run() {
} catch (Exception e) {
e.printStackTrace();
} finally {
avoidMultipleOperations = false;
populatePortMenu();
}
status.unprogress();
Expand All @@ -2514,6 +2525,20 @@ public void run() {
}
}

class TimeoutUploadHandler implements Runnable {

public void run() {
try {
//10 seconds, than reactivate upload functionality and let the programmer pid being killed
Thread.sleep(1000 * 10);
if (uploading) {
avoidMultipleOperations = false;
}
} catch (InterruptedException e) {
// noop
}
}
}

public void handleSerial() {
if(serialPlotter != null) {
Expand Down Expand Up @@ -2558,7 +2583,7 @@ public void handleSerial() {

// If currently uploading, disable the monitor (it will be later
// enabled when done uploading)
if (uploading) {
if (uploading || avoidMultipleOperations) {
try {
serialMonitor.suspend();
} catch (Exception e) {
Expand All @@ -2582,8 +2607,10 @@ public void handleSerial() {
}

try {
serialMonitor.open();
serialMonitor.setVisible(true);
if (!avoidMultipleOperations) {
serialMonitor.open();
}
success = true;
} catch (ConnectException e) {
statusError(tr("Unable to connect: is the sketch using the bridge?"));
Expand Down Expand Up @@ -2730,6 +2757,59 @@ private void handleBurnBootloader() {
}).start();
}

private void handleBoardInfo() {
console.clear();

String selectedPort = PreferencesData.get("serial.port");
List<BoardPort> ports = Base.getDiscoveryManager().discovery();

String label = "";
String vid = "";
String pid = "";
String iserial = "";
String protocol = "";
boolean found = false;

for (BoardPort port : ports) {
if (port.getAddress().equals(selectedPort)) {
label = port.getBoardName();
vid = port.getVID();
pid = port.getPID();
iserial = port.getISerial();
protocol = port.getProtocol();
found = true;
break;
}
}

if (!found) {
statusNotice(tr("Please select a port to obtain board info"));
return;
}

if (protocol.equals("network")) {
statusNotice(tr("Network port, can't obtain info"));
return;
}

if (vid == null || vid.equals("") || vid.equals("0000")) {
statusNotice(tr("Native serial port, can't obtain info"));
return;
}

if (iserial == null || iserial.equals("")) {
iserial = tr("Upload any sketch to obtain it");
}

if (label == null) {
label = tr("Unknown board");
}

String infos = I18n.format("BN: {0}\nVID: {1}\nPID: {2}\nSN: {3}", label, vid, pid, iserial);
JTextArea textArea = new JTextArea(infos);

JOptionPane.showMessageDialog(this, textArea, tr("Board Info"), JOptionPane.PLAIN_MESSAGE);
}

/**
* Handler for File &rarr; Page Setup.
Expand Down
5 changes: 5 additions & 0 deletions app/src/processing/app/EditorLineStatus.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public class EditorLineStatus extends JComponent {
String text = "";
String name = "";
String serialport = "";
String serialnumber = "";

public EditorLineStatus() {
background = Theme.getColor("linestatus.bgcolor");
Expand Down Expand Up @@ -129,6 +130,10 @@ public void setSerialPort(String serialport) {
this.serialport = serialport;
}

public void setSerialNumber(String serialnumber) {
this.serialnumber = serialnumber;
}

public Dimension getPreferredSize() {
return scale(new Dimension(300, height));
}
Expand Down
11 changes: 9 additions & 2 deletions app/src/processing/app/EditorToolbar.java
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,10 @@ public void mousePressed(MouseEvent e) {

switch (sel) {
case RUN:
editor.handleRun(false, editor.presentHandler, editor.runHandler);
if (!editor.avoidMultipleOperations) {
editor.handleRun(false, editor.presentHandler, editor.runHandler);
editor.avoidMultipleOperations = true;
}
break;

// case STOP:
Expand Down Expand Up @@ -370,7 +373,11 @@ public void mousePressed(MouseEvent e) {
break;

case EXPORT:
editor.handleExport(e.isShiftDown());
// launch a timeout timer which can reenable to upload button functionality an
if (!editor.avoidMultipleOperations) {
editor.handleExport(e.isShiftDown());
editor.avoidMultipleOperations = true;
}
break;

case SERIAL:
Expand Down
36 changes: 36 additions & 0 deletions arduino-core/src/cc/arduino/packages/BoardPort.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@ public class BoardPort {
private String address;
private String protocol;
private String boardName;
private String vid;
private String pid;
private String iserial;
private String label;
private final PreferencesMap prefs;
private boolean online;

public BoardPort() {
this.prefs = new PreferencesMap();
Expand Down Expand Up @@ -79,4 +83,36 @@ public String getLabel() {
return label;
}

public void setOnlineStatus(boolean online) {
this.online = online;
}

public boolean isOnline() {
return online;
}

public void setVIDPID(String vid, String pid) {
this.vid = vid;
this.pid = pid;
}

public String getVID() {
return vid;
}

public String getPID() {
return pid;
}

public void setISerial(String iserial) {
this.iserial = iserial;
}
public String getISerial() {
return iserial;
}

@Override
public String toString() {
return this.address+"_"+this.vid+"_"+this.pid;
}
}
1 change: 1 addition & 0 deletions arduino-core/src/cc/arduino/packages/Discovery.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,6 @@ public interface Discovery {
* @return
*/
List<BoardPort> listDiscoveredBoards();
List<BoardPort> listDiscoveredBoards(boolean complete);

}
27 changes: 25 additions & 2 deletions arduino-core/src/cc/arduino/packages/DiscoveryManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@
public class DiscoveryManager {

private final List<Discovery> discoverers;
private final SerialDiscovery serialDiscoverer = new SerialDiscovery();
private final NetworkDiscovery networkDiscoverer = new NetworkDiscovery();

public DiscoveryManager() {
discoverers = new ArrayList<Discovery>();
discoverers.add(new SerialDiscovery());
discoverers.add(new NetworkDiscovery());
discoverers.add(serialDiscoverer);
discoverers.add(networkDiscoverer);

// Start all discoverers
for (Discovery d : discoverers) {
Expand All @@ -69,6 +71,10 @@ public DiscoveryManager() {
Runtime.getRuntime().addShutdownHook(closeHook);
}

public SerialDiscovery getSerialDiscoverer() {
return serialDiscoverer;
}

public List<BoardPort> discovery() {
List<BoardPort> res = new ArrayList<BoardPort>();
for (Discovery d : discoverers) {
Expand All @@ -77,6 +83,14 @@ public List<BoardPort> discovery() {
return res;
}

public List<BoardPort> discovery(boolean complete) {
List<BoardPort> res = new ArrayList<BoardPort>();
for (Discovery d : discoverers) {
res.addAll(d.listDiscoveredBoards(complete));
}
return res;
}

public BoardPort find(String address) {
for (BoardPort boardPort : discovery()) {
if (boardPort.getAddress().equals(address)) {
Expand All @@ -86,4 +100,13 @@ public BoardPort find(String address) {
return null;
}

public BoardPort find(String address, boolean complete) {
for (BoardPort boardPort : discovery(complete)) {
if (boardPort.getAddress().equals(address)) {
return boardPort;
}
}
return null;
}

}
17 changes: 15 additions & 2 deletions arduino-core/src/cc/arduino/packages/Uploader.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static processing.app.I18n.tr;

Expand Down Expand Up @@ -102,6 +103,9 @@ public String getAuthorizationKey() {
return null;
}

// static field for last executed programmer process ID
static protected Process programmerPid;

protected boolean executeUploadCommand(Collection<String> command) throws Exception {
return executeUploadCommand(command.toArray(new String[command.size()]));
}
Expand All @@ -121,11 +125,20 @@ protected boolean executeUploadCommand(String command[]) throws Exception {
System.out.println();
}
Process process = ProcessUtils.exec(command);
programmerPid = process;
new MessageSiphon(process.getInputStream(), this, 100);
new MessageSiphon(process.getErrorStream(), this, 100);

// wait for the process to finish.
result = process.waitFor();
// wait for the process to finish, but not forever
// kill the flasher process after 2 minutes to avoid 100% cpu spinning
if (!process.waitFor(2, TimeUnit.MINUTES)) {
process.destroyForcibly();
}
if (!process.isAlive()) {
result = process.exitValue();
} else {
result = 0;
}
} catch (Exception e) {
e.printStackTrace();
}
Expand Down
Loading