Skip to content
This repository was archived by the owner on Mar 25, 2019. It is now read-only.

Commit edbe4ff

Browse files
author
Ilia Motornyi
authored
Move run board name and ports settings to the run configuration (#99)
Resolves #65
1 parent f0533cf commit edbe4ff

12 files changed

+302
-152
lines changed

.idea/codeStyles/Project.xml

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

resources/META-INF/plugin.xml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<idea-plugin>
22
<id>xyz.elmot.clion.armsupport.prj</id>
33
<name>OpenOCD + STM32CubeMX support for ARM embedded development</name>
4-
<version>1.1.alpha2</version>
4+
<version>1.1.alpha3</version>
55
<vendor email="me@elmot.xyz" url="http://elmot.xyz">Elmot</vendor>
66

77
<description><![CDATA[
88
ARM MCU development plugin
9+
910
<br>
1011
<ul>
1112
<li>Convert a project made in <i>STM32CubeMX</i> into a <i>CLion</i> project</li>
@@ -39,6 +40,8 @@ The plugin is free, but if you like it, you may support my work with a PayPal do
3940
<li>Minimal CLion 2018.1(CL-181.4203.505) Support</li>
4041
<li>Diagnostics UX improved</li>
4142
<li>"Do not ask option" for cmake update</li>
43+
<li>Board and ports settings moved to <i>Run Configuration</i></li>
44+
<li>Custom GDB support is done through CLion <i>Toolchains</i></li>
4245
</ul>
4346
]]>
4447
</change-notes>
@@ -59,7 +62,6 @@ The plugin is free, but if you like it, you may support my work with a PayPal do
5962
text="ARM MCU">
6063

6164
<action id="elmot.embedded.stm32cubemx.import" class="xyz.elmot.clion.cubemx.ConvertProject"/>
62-
<action id="elmot.embedded.openocd.run" class="xyz.elmot.clion.openocd.OpenOcdRun" text="Run OpenOCD"/>
6365
<add-to-group group-id="ToolsMenu" anchor="after" relative-to-action="CMake.ToolsMenu"/>
6466
</group>
6567
</actions>

src/xyz/elmot/clion/openocd/Informational.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
import javax.swing.event.HyperlinkEvent;
44
import java.util.Objects;
55

6+
import com.intellij.CommonBundle;
67
import com.intellij.ide.BrowserUtil;
78
import com.intellij.openapi.application.ApplicationManager;
9+
import com.intellij.openapi.options.ConfigurationException;
810
import com.intellij.openapi.options.ShowSettingsUtil;
911
import com.intellij.openapi.project.Project;
1012
import com.intellij.openapi.ui.MessageType;
13+
import com.intellij.openapi.ui.Messages;
1114
import com.intellij.openapi.wm.ToolWindowId;
1215
import com.intellij.openapi.wm.ToolWindowManager;
1316
import com.intellij.ui.HyperlinkAdapter;
@@ -52,6 +55,21 @@ public static void showFailedDownloadNotification(Project project) {
5255
"Plugin documentation is located <a href=\"" + HELP_URL + "\">here</a>");
5356
}
5457

58+
public static void showPluginError(Project project, ConfigurationException e) {
59+
int optionNo = Messages.showDialog(project, e.getLocalizedMessage(), e.getTitle(),
60+
new String[]{Messages.OK_BUTTON, CommonBundle.settingsAction(), CommonBundle.getHelpButtonText()}
61+
, 0, Messages.getErrorIcon());
62+
switch (optionNo) {
63+
case 1:
64+
ShowSettingsUtil.getInstance().showSettingsDialog(project, OpenOcdSettings.class);
65+
break;
66+
case 2:
67+
BrowserUtil.browse(HELP_URL);
68+
break;
69+
default://nothing to do
70+
}
71+
}
72+
5573
private static class HyperlinkHandler extends HyperlinkAdapter {
5674
private final Project project;
5775

src/xyz/elmot/clion/openocd/OpenOcdComponent.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.intellij.openapi.progress.ProgressManager;
1919
import com.intellij.openapi.project.Project;
2020
import com.intellij.openapi.util.Key;
21+
import com.intellij.openapi.util.text.StringUtil;
2122
import com.intellij.openapi.vfs.LocalFileSystem;
2223
import com.intellij.openapi.vfs.VfsUtil;
2324
import com.intellij.openapi.vfs.VirtualFile;
@@ -42,7 +43,7 @@ public class OpenOcdComponent {
4243
private final static String[] FAIL_STRINGS = {
4344
"** Programming Failed **", "communication failure", "** OpenOCD init failed **"};
4445
private static final String FLASH_SUCCESS_TEXT = "** Programming Finished **";
45-
private static final Logger LOG = Logger.getInstance(OpenOcdRun.class);
46+
private static final Logger LOG = Logger.getInstance(OpenOcdComponent.class);
4647

4748
static {
4849
BIN_OPENOCD = "bin/openocd" + (OS.isWindows() ? ".exe" : "");
@@ -57,10 +58,11 @@ public OpenOcdComponent() {
5758

5859
@SuppressWarnings("WeakerAccess")
5960
@NotNull
60-
public static GeneralCommandLine createOcdCommandLine(@NotNull Project project, @Nullable File fileToLoad, @Nullable String additionalCommand, boolean shutdown) throws ConfigurationException {
61+
public static GeneralCommandLine createOcdCommandLine(OpenOcdConfiguration config, File fileToLoad,@Nullable String additionalCommand, boolean shutdown) throws ConfigurationException {
62+
Project project = config.getProject();
6163
OpenOcdSettingsState ocdSettings = project.getComponent(OpenOcdSettingsState.class);
62-
if (ocdSettings.boardConfigFile == null || "".equals(ocdSettings.boardConfigFile.trim())) {
63-
throw new ConfigurationException("Board Config file is not defined.\nPlease open OpenOCD settings and choose one.", "OpenOCD run error");
64+
if (StringUtil.isEmpty(config.getBoardConfigFile())) {
65+
throw new ConfigurationException("Board Config file is not defined.", "OpenOCD run error");
6466
}
6567
VirtualFile ocdHome = require(LocalFileSystem.getInstance().findFileByPath(ocdSettings.openOcdHome));
6668
VirtualFile ocdBinary = require(ocdHome.findFileByRelativePath(BIN_OPENOCD));
@@ -73,13 +75,13 @@ public static GeneralCommandLine createOcdCommandLine(@NotNull Project project,
7375

7476
VirtualFile ocdScripts = require(OpenOcdSettingsState.findOcdScripts(ocdHome));
7577
commandLine.addParameters("-s", VfsUtil.virtualToIoFile(ocdScripts).getAbsolutePath());
76-
if (ocdSettings.gdbPort != OpenOcdSettingsState.DEF_GDB_PORT) {
77-
commandLine.addParameters("-c", "gdb_port " + ocdSettings.gdbPort);
78+
if (config.getGdbPort() != OpenOcdConfiguration.DEF_GDB_PORT) {
79+
commandLine.addParameters("-c", "gdb_port " + config.getGdbPort());
7880
}
79-
if (ocdSettings.telnetPort != OpenOcdSettingsState.DEF_TELNET_PORT) {
80-
commandLine.addParameters("-c", "telnet_port " + ocdSettings.telnetPort);
81+
if (config.getTelnetPort() != OpenOcdConfiguration.DEF_TELNET_PORT) {
82+
commandLine.addParameters("-c", "telnet_port " + config.getTelnetPort());
8183
}
82-
commandLine.addParameters("-f", ocdSettings.boardConfigFile);
84+
commandLine.addParameters("-f", config.getBoardConfigFile());
8385
if (fileToLoad != null) {
8486
String command = "program \"" + fileToLoad.getAbsolutePath().replace(File.separatorChar, '/') + "\"";
8587
commandLine.addParameters("-c", command);
@@ -116,14 +118,15 @@ public void stopOpenOcd() {
116118
}
117119

118120
@SuppressWarnings("WeakerAccess")
119-
public Future<STATUS> startOpenOcd(Project project, @Nullable File fileToLoad, @Nullable String additionalCommand) throws ConfigurationException {
120-
if (project == null) return new FutureResult<>(STATUS.FLASH_ERROR);
121-
GeneralCommandLine commandLine = createOcdCommandLine(project, fileToLoad, additionalCommand, false);
121+
public Future<STATUS> startOpenOcd(OpenOcdConfiguration config, @Nullable File fileToLoad, @Nullable String additionalCommand) throws ConfigurationException {
122+
if (config == null) return new FutureResult<>(STATUS.FLASH_ERROR);
123+
GeneralCommandLine commandLine = createOcdCommandLine(config, fileToLoad, additionalCommand, false);
122124
if (process != null && !process.isProcessTerminated()) {
123125
LOG.info("openOcd is already run");
124126
return new FutureResult<>(STATUS.FLASH_ERROR);
125127
}
126128

129+
Project project = config.getProject();
127130
try {
128131
process = new OSProcessHandler(commandLine) {
129132
@Override

src/xyz/elmot/clion/openocd/OpenOcdConfiguration.java

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@
22

33
import com.intellij.execution.Executor;
44
import com.intellij.execution.configurations.ConfigurationFactory;
5+
import com.intellij.execution.configurations.RuntimeConfigurationException;
56
import com.intellij.execution.runners.ExecutionEnvironment;
67
import com.intellij.openapi.project.Project;
8+
import com.intellij.openapi.util.InvalidDataException;
9+
import com.intellij.openapi.util.WriteExternalException;
10+
import com.intellij.openapi.util.text.StringUtil;
711
import com.jetbrains.cidr.cpp.execution.CMakeAppRunConfiguration;
812
import com.jetbrains.cidr.execution.CidrCommandLineState;
913
import com.jetbrains.cidr.execution.CidrExecutableDataHolder;
14+
import org.jdom.Element;
15+
import org.jdom.Namespace;
1016
import org.jetbrains.annotations.NotNull;
1117
import org.jetbrains.annotations.Nullable;
1218

@@ -15,6 +21,15 @@
1521
*/
1622
@SuppressWarnings("WeakerAccess")
1723
public class OpenOcdConfiguration extends CMakeAppRunConfiguration implements CidrExecutableDataHolder {
24+
public static final int DEF_GDB_PORT = 3333;
25+
public static final int DEF_TELNET_PORT = 4444;
26+
public static final Namespace NAMESPACE = Namespace.getNamespace("elmot-ocd", "https://github.com/elmot/clion-embedded-arm");
27+
private static final String ATTR_GDB_PORT = "gdb-port";
28+
private static final String ATTR_TELNET_PORT = "telnet-port";
29+
private static final String ATTR_BOARD_CONFIG = "board-config";
30+
private int gdbPort = DEF_GDB_PORT;
31+
private int telnetPort = DEF_TELNET_PORT;
32+
private String boardConfigFile;
1833

1934

2035
@SuppressWarnings("WeakerAccess")
@@ -28,4 +43,69 @@ public CidrCommandLineState getState(@NotNull Executor executor, @NotNull Execut
2843
return new CidrCommandLineState(environment, new OpenOcdLauncher(this));
2944
}
3045

46+
@Override
47+
public void readExternal(@NotNull Element element) throws InvalidDataException {
48+
super.readExternal(element);
49+
boardConfigFile = element.getAttributeValue(ATTR_BOARD_CONFIG, NAMESPACE);
50+
gdbPort = intAttribute(element, ATTR_GDB_PORT, DEF_GDB_PORT);
51+
telnetPort = intAttribute(element, ATTR_TELNET_PORT, DEF_TELNET_PORT);
52+
}
53+
54+
private int intAttribute(@NotNull Element element, String name, int def) {
55+
String s = element.getAttributeValue(name, NAMESPACE);
56+
if (StringUtil.isEmpty(s)) return def;
57+
return Integer.parseUnsignedInt(s);
58+
}
59+
60+
@Override
61+
public void writeExternal(@NotNull Element element) throws WriteExternalException {
62+
super.writeExternal(element);
63+
element.setAttribute(ATTR_GDB_PORT, "" + gdbPort, NAMESPACE);
64+
element.setAttribute(ATTR_TELNET_PORT, "" + telnetPort, NAMESPACE);
65+
if (boardConfigFile != null) {
66+
element.setAttribute(ATTR_BOARD_CONFIG, boardConfigFile, NAMESPACE);
67+
}
68+
}
69+
70+
@Override
71+
public void checkConfiguration() throws RuntimeConfigurationException {
72+
super.checkConfiguration();
73+
checkPort(gdbPort);
74+
checkPort(telnetPort);
75+
if (gdbPort == telnetPort) {
76+
throw new RuntimeConfigurationException("Port values should be different");
77+
}
78+
if (StringUtil.isEmpty(boardConfigFile)) {
79+
throw new RuntimeConfigurationException("Board config file is not defined");
80+
}
81+
}
82+
83+
private void checkPort(int port) throws RuntimeConfigurationException {
84+
if (port <= 1024 || port > 65535)
85+
throw new RuntimeConfigurationException("Port value must be in the range [1024...65535]");
86+
}
87+
88+
public int getGdbPort() {
89+
return gdbPort;
90+
}
91+
92+
public void setGdbPort(int gdbPort) {
93+
this.gdbPort = gdbPort;
94+
}
95+
96+
public int getTelnetPort() {
97+
return telnetPort;
98+
}
99+
100+
public void setTelnetPort(int telnetPort) {
101+
this.telnetPort = telnetPort;
102+
}
103+
104+
public String getBoardConfigFile() {
105+
return boardConfigFile;
106+
}
107+
108+
public void setBoardConfigFile(String boardConfigFile) {
109+
this.boardConfigFile = boardConfigFile;
110+
}
31111
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package xyz.elmot.clion.openocd;
2+
3+
import com.intellij.execution.ui.CommonProgramParametersPanel;
4+
import com.intellij.openapi.options.ConfigurationException;
5+
import com.intellij.openapi.project.Project;
6+
import com.intellij.openapi.vfs.VfsUtil;
7+
import com.intellij.ui.components.JBTextField;
8+
import com.intellij.ui.components.fields.IntegerField;
9+
import com.intellij.util.ui.GridBag;
10+
import com.jetbrains.cidr.cpp.execution.CMakeAppRunConfiguration;
11+
import com.jetbrains.cidr.cpp.execution.CMakeAppRunConfigurationSettingsEditor;
12+
import com.jetbrains.cidr.cpp.execution.CMakeBuildConfigurationHelper;
13+
import org.jetbrains.annotations.NotNull;
14+
15+
import javax.swing.*;
16+
import java.awt.*;
17+
18+
public class OpenOcdConfigurationEditor extends CMakeAppRunConfigurationSettingsEditor {
19+
private IntegerField gdbPort;
20+
private IntegerField telnetPort;
21+
22+
private FileChooseInput boardConfigFile;
23+
private String openocdHome;
24+
25+
public OpenOcdConfigurationEditor(Project project, @NotNull CMakeBuildConfigurationHelper cMakeBuildConfigurationHelper) {
26+
super(project, cMakeBuildConfigurationHelper);
27+
}
28+
29+
@Override
30+
protected void applyEditorTo(@NotNull CMakeAppRunConfiguration cMakeAppRunConfiguration) throws ConfigurationException {
31+
super.applyEditorTo(cMakeAppRunConfiguration);
32+
33+
OpenOcdConfiguration ocdConfiguration = (OpenOcdConfiguration) cMakeAppRunConfiguration;
34+
35+
String boardConfig = boardConfigFile.getText().trim();
36+
ocdConfiguration.setBoardConfigFile(boardConfig.isEmpty() ? null : boardConfig);
37+
38+
gdbPort.validateContent();
39+
telnetPort.validateContent();
40+
ocdConfiguration.setGdbPort(gdbPort.getValue());
41+
ocdConfiguration.setTelnetPort(telnetPort.getValue());
42+
}
43+
44+
@Override
45+
protected void resetEditorFrom(@NotNull CMakeAppRunConfiguration cMakeAppRunConfiguration) {
46+
super.resetEditorFrom(cMakeAppRunConfiguration);
47+
48+
OpenOcdConfiguration ocd = (OpenOcdConfiguration) cMakeAppRunConfiguration;
49+
50+
openocdHome = ocd.getProject().getComponent(OpenOcdSettingsState.class).openOcdHome;
51+
52+
boardConfigFile.setText(ocd.getBoardConfigFile());
53+
54+
55+
gdbPort.setText("" + ocd.getGdbPort());
56+
57+
telnetPort.setText("" + ocd.getTelnetPort());
58+
}
59+
60+
@Override
61+
protected void createEditorInner(JPanel panel, GridBag gridBag) {
62+
super.createEditorInner(panel, gridBag);
63+
64+
for (Component component: panel.getComponents()) {
65+
if(component instanceof CommonProgramParametersPanel) {
66+
component.setVisible(false);//todo get rid of this hack
67+
}
68+
}
69+
70+
panel.add(new JLabel("Board config file"), gridBag.nextLine().next());
71+
boardConfigFile = new FileChooseInput.BoardCfg("Board config", VfsUtil.getUserHomeDir(), this::getOpenocdHome);
72+
panel.add(boardConfigFile, gridBag.next().coverLine());
73+
74+
((JBTextField) boardConfigFile.getChildComponent()).getEmptyText().setText("<use project default>");
75+
76+
JPanel portsPanel = new JPanel();
77+
portsPanel.setLayout(new FlowLayout(FlowLayout.LEADING));
78+
79+
gdbPort = addPortInput(portsPanel, "GDB port", OpenOcdConfiguration.DEF_GDB_PORT);
80+
portsPanel.add(Box.createHorizontalStrut(10));
81+
82+
telnetPort = addPortInput(portsPanel,"Telnet port",OpenOcdConfiguration.DEF_TELNET_PORT);
83+
84+
panel.add(portsPanel, gridBag.nextLine().next().coverLine());
85+
86+
}
87+
88+
private IntegerField addPortInput(JPanel portsPanel, String label, int defaultValue) {
89+
portsPanel.add(new JLabel(label + ": "));
90+
IntegerField field = new IntegerField(label, 1024,65535);
91+
field.setDefaultValue(defaultValue);
92+
field.setColumns(5);
93+
portsPanel.add(field);
94+
return field;
95+
}
96+
97+
98+
private String getOpenocdHome() {
99+
return openocdHome;
100+
}
101+
102+
}

0 commit comments

Comments
 (0)