Commit 3828c94b authored by Tim Sander's avatar Tim Sander Committed by hjk

GdbDebugger: add fast restart for debugging

Change-Id: Ie51847de912748d05a6b208bec82fd612d777202
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
Reviewed-by: default avatarLeena Miettinen <riitta-leena.miettinen@digia.com>
parent 5df23899
......@@ -27,7 +27,3 @@ HEADERS += baremetalplugin.h \
baremetaldeviceconfigurationwidget.h \
baremetaldeviceconfigurationwizard.h \
baremetaldeviceconfigurationwizardpages.h
FORMS += \
baremetaldeviceconfigurationwizardsetuppage.ui \
baremetaldeviceconfigurationwidget.ui
......@@ -21,12 +21,11 @@ QtcPlugin {
"baremetaldeviceconfigurationwidget.cpp", "baremetaldeviceconfigurationwidget.h",
"baremetaldeviceconfigurationwizard.cpp", "baremetaldeviceconfigurationwizard.h",
"baremetaldeviceconfigurationwizardpages.cpp", "baremetaldeviceconfigurationwizardpages.h",
"baremetaldeviceconfigurationwizardsetuppage.ui",
"baremetalgdbcommandsdeploystep.cpp", "baremetalgdbcommandsdeploystep.h",
"baremetalplugin.cpp", "baremetalplugin.h",
"baremetalrunconfiguration.cpp", "baremetalrunconfiguration.h",
"baremetalrunconfigurationfactory.cpp", "baremetalrunconfigurationfactory.h",
"baremetalrunconfigurationwidget.cpp", "baremetalrunconfigurationwidget.h", "baremetaldeviceconfigurationwidget.ui",
"baremetalrunconfigurationwidget.cpp", "baremetalrunconfigurationwidget.h",
"baremetalruncontrolfactory.cpp", "baremetalruncontrolfactory.h",
]
}
......@@ -38,6 +38,7 @@ using namespace ProjectExplorer;
namespace BareMetal {
namespace Internal {
const char GdbResetKey[] = "GdbResetCommand";
const char GdbCommandsKey[] = "GdbCommands";
BareMetalDevice::Ptr BareMetalDevice::create()
......@@ -58,12 +59,14 @@ BareMetalDevice::Ptr BareMetalDevice::create(const BareMetalDevice &other)
void BareMetalDevice::fromMap(const QVariantMap &map)
{
IDevice::fromMap(map);
setGdbResetCommands(map.value(QLatin1String(GdbResetKey)).toString());
setGdbInitCommands(map.value(QLatin1String(GdbCommandsKey)).toString());
}
QVariantMap BareMetalDevice::toMap() const
{
QVariantMap map = IDevice::toMap();
map.insert(QLatin1String(GdbResetKey), gdbResetCommands());
map.insert(QLatin1String(GdbCommandsKey), gdbInitCommands());
return map;
}
......@@ -114,8 +117,51 @@ BareMetalDevice::BareMetalDevice(const QString &name, Core::Id type, MachineType
BareMetalDevice::BareMetalDevice(const BareMetalDevice &other)
: IDevice(other)
{
setGdbResetCommands(other.gdbResetCommands());
setGdbInitCommands(other.gdbInitCommands());
}
QString BareMetalDevice::exampleString()
{
return QLatin1String("<p><i>")
+ QCoreApplication::translate("BareMetal", "Example:")
+ QLatin1String("</i><p>");
}
QString BareMetalDevice::hostLineToolTip()
{
return QLatin1String("<html>")
+ QCoreApplication::translate("BareMetal",
"Enter your hostname like \"localhost\" or \"192.0.2.1\" or "
"a command which must support GDB pipelining "
"starting with a pipe symbol.")
+ exampleString() + QLatin1String(
"&nbsp;&nbsp;|openocd -c \"gdb_port pipe; "
"log_output openocd.log\" -f boards/myboard.cfg");
}
QString BareMetalDevice::resetCommandToolTip()
{
return QLatin1String("<html>")
+ QCoreApplication::translate("BareMetal",
"Enter the hardware reset command here.<br>"
"The CPU should be halted after this command.")
+ exampleString() + QLatin1String(
"&nbsp;&nbsp;monitor reset halt");
}
QString BareMetalDevice::initCommandToolTip()
{
return QLatin1String("<html>")
+ QCoreApplication::translate("BareMetal",
"Enter commands to reset the board, and write the nonvolatile memory.")
+ exampleString() + QLatin1String(
"&nbsp;&nbsp;set remote hardware-breakpoint-limit 6<br/>"
"&nbsp;&nbsp;set remote hardware-watchpoint-limit 4<br/>"
"&nbsp;&nbsp;monitor reset halt<br/>"
"&nbsp;&nbsp;load<br/>"
"&nbsp;&nbsp;monitor reset halt");
}
} //namespace Internal
} //namespace BareMetal
......@@ -55,12 +55,20 @@ public:
ProjectExplorer::DeviceProcessSignalOperation::Ptr signalOperation() const;
QString gdbResetCommands() const { return m_gdbResetCommands; }
void setGdbResetCommands(const QString &gdbResetCommands) { m_gdbResetCommands = gdbResetCommands; }
QString gdbInitCommands() const { return m_gdbInitCommands; }
void setGdbInitCommands(const QString &gdbCommands) { m_gdbInitCommands=gdbCommands; }
virtual void fromMap(const QVariantMap &map);
virtual QVariantMap toMap() const;
static QString exampleString();
static QString hostLineToolTip();
static QString initCommandToolTip();
static QString resetCommandToolTip();
protected:
BareMetalDevice() {}
BareMetalDevice(const QString &name, Core::Id type,
......@@ -69,6 +77,7 @@ protected:
private:
BareMetalDevice &operator=(const BareMetalDevice &);
QString m_gdbResetCommands;
QString m_gdbInitCommands;
};
......
......@@ -29,74 +29,100 @@
#include "baremetaldeviceconfigurationwidget.h"
#include "ui_baremetaldeviceconfigurationwidget.h"
#include "baremetaldevice.h"
#include <coreplugin/variablechooser.h>
#include <ssh/sshconnection.h>
#include <utils/qtcassert.h>
#include <QFormLayout>
#include <QLabel>
#include <QLineEdit>
#include <QSpinBox>
#include <QPlainTextEdit>
using namespace Core;
using namespace QSsh;
namespace BareMetal {
using namespace Internal;
namespace Internal {
BareMetalDeviceConfigurationWidget::BareMetalDeviceConfigurationWidget(
const ProjectExplorer::IDevice::Ptr &deviceConfig, QWidget *parent) :
IDeviceWidget(deviceConfig, parent),
m_ui(new Ui::BareMetalDeviceConfigurationWidget)
const ProjectExplorer::IDevice::Ptr &deviceConfig, QWidget *parent)
: IDeviceWidget(deviceConfig, parent)
{
m_ui->setupUi(this);
connect(m_ui->gdbHostLineEdit, SIGNAL(editingFinished()), SLOT(hostnameChanged()));
connect(m_ui->gdbPortSpinBox, SIGNAL(valueChanged(int)), SLOT(portChanged()));
connect(m_ui->gdbCommandsTextEdit, SIGNAL(textChanged()), SLOT(gdbInitCommandsChanged()));
Core::VariableChooser::addVariableSupport(m_ui->gdbCommandsTextEdit);
new Core::VariableChooser(this);
initGui();
}
SshConnectionParameters sshParams = device()->sshParameters();
QSharedPointer<BareMetalDevice> p = qSharedPointerCast<BareMetalDevice>(device());
QTC_ASSERT(!p.isNull(), return);
BareMetalDeviceConfigurationWidget::~BareMetalDeviceConfigurationWidget()
{
delete m_ui;
m_gdbHostLineEdit = new QLineEdit(this);
m_gdbHostLineEdit->setText(sshParams.host);
m_gdbHostLineEdit->setToolTip(BareMetalDevice::hostLineToolTip());
m_gdbPortSpinBox = new QSpinBox(this);
m_gdbPortSpinBox->setRange(1, 65535);
m_gdbPortSpinBox->setValue(sshParams.port);
m_gdbInitCommandsTextEdit = new QPlainTextEdit(this);
m_gdbInitCommandsTextEdit->setPlainText(p->gdbInitCommands());
m_gdbInitCommandsTextEdit->setToolTip(BareMetalDevice::initCommandToolTip());
m_gdbResetCommandsTextEdit = new QPlainTextEdit(this);
m_gdbResetCommandsTextEdit->setPlainText(p->gdbResetCommands());
m_gdbResetCommandsTextEdit->setToolTip(BareMetalDevice::resetCommandToolTip());
QFormLayout *formLayout = new QFormLayout(this);
formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
formLayout->addRow(tr("GDB host:"), m_gdbHostLineEdit);
formLayout->addRow(tr("GDB port:"), m_gdbPortSpinBox);
formLayout->addRow(tr("Init commands:"), m_gdbInitCommandsTextEdit);
formLayout->addRow(tr("Reset commands:"), m_gdbResetCommandsTextEdit);
VariableChooser::addVariableSupport(m_gdbResetCommandsTextEdit);
VariableChooser::addVariableSupport(m_gdbInitCommandsTextEdit);
(void)new VariableChooser(this);
connect(m_gdbHostLineEdit, SIGNAL(editingFinished()), SLOT(hostnameChanged()));
connect(m_gdbPortSpinBox, SIGNAL(valueChanged(int)), SLOT(portChanged()));
connect(m_gdbResetCommandsTextEdit, SIGNAL(textChanged()),SLOT(gdbResetCommandsChanged()));
connect(m_gdbInitCommandsTextEdit, SIGNAL(textChanged()), SLOT(gdbInitCommandsChanged()));
}
void BareMetalDeviceConfigurationWidget::hostnameChanged()
{
SshConnectionParameters sshParams = device()->sshParameters();
sshParams.host = m_ui->gdbHostLineEdit->text().trimmed();
sshParams.host = m_gdbHostLineEdit->text().trimmed();
device()->setSshParameters(sshParams);
}
void BareMetalDeviceConfigurationWidget::portChanged()
{
SshConnectionParameters sshParams = device()->sshParameters();
sshParams.port = m_ui->gdbPortSpinBox->value();
sshParams.port = m_gdbPortSpinBox->value();
device()->setSshParameters(sshParams);
}
void BareMetalDeviceConfigurationWidget::gdbResetCommandsChanged()
{
QSharedPointer<BareMetalDevice> p = qSharedPointerCast<BareMetalDevice>(device());
QTC_ASSERT(!p.isNull(), return);
p->setGdbResetCommands(m_gdbResetCommandsTextEdit->toPlainText().trimmed());
}
void BareMetalDeviceConfigurationWidget::gdbInitCommandsChanged()
{
QSharedPointer<BareMetalDevice> p = qSharedPointerCast<BareMetalDevice>(device());
QTC_ASSERT(!p.isNull(), return);
p->setGdbInitCommands(m_ui->gdbCommandsTextEdit->toPlainText());
p->setGdbInitCommands(m_gdbInitCommandsTextEdit->toPlainText());
}
void BareMetalDeviceConfigurationWidget::updateDeviceFromUi() {
void BareMetalDeviceConfigurationWidget::updateDeviceFromUi()
{
hostnameChanged();
portChanged();
gdbResetCommandsChanged();
gdbInitCommandsChanged();
}
void BareMetalDeviceConfigurationWidget::initGui()
{
SshConnectionParameters sshParams = device()->sshParameters();
m_ui->gdbHostLineEdit->setText(sshParams.host);
m_ui->gdbPortSpinBox->setValue(sshParams.port);
QSharedPointer<BareMetalDevice> p = qSharedPointerCast<BareMetalDevice>(device());
QTC_ASSERT(!p.isNull(), return);
m_ui->gdbCommandsTextEdit->setPlainText(p->gdbInitCommands());
}
} //namespace BareMetal
} // namespace Internal
} // namespace BareMetal
......@@ -32,9 +32,14 @@
#include <projectexplorer/devicesupport/idevicewidget.h>
namespace BareMetal {
QT_BEGIN_NAMESPACE
class QLineEdit;
class QSpinBox;
class QPlainTextEdit;
QT_END_NAMESPACE
namespace Ui { class BareMetalDeviceConfigurationWidget; }
namespace BareMetal {
namespace Internal {
class BareMetalDeviceConfigurationWidget
: public ProjectExplorer::IDeviceWidget
......@@ -44,19 +49,24 @@ class BareMetalDeviceConfigurationWidget
public:
explicit BareMetalDeviceConfigurationWidget(
const ProjectExplorer::IDevice::Ptr &deviceConfig, QWidget *parent = 0);
~BareMetalDeviceConfigurationWidget();
private slots:
void hostnameChanged();
void portChanged();
void gdbResetCommandsChanged();
void gdbInitCommandsChanged();
private:
void updateDeviceFromUi();
void initGui();
Ui::BareMetalDeviceConfigurationWidget *m_ui;
QLineEdit *m_gdbHostLineEdit;
QSpinBox *m_gdbPortSpinBox;
QPlainTextEdit *m_gdbResetCommandsTextEdit;
QPlainTextEdit *m_gdbInitCommandsTextEdit;
};
} //namespace BareMetal
} // namespace Internal
} // namespace BareMetal
#endif // BAREMETALDEVICECONFIGURATIONWIDGET_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BareMetal::BareMetalDeviceConfigurationWidget</class>
<widget class="QWidget" name="BareMetal::BareMetalDeviceConfigurationWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>496</width>
<height>251</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="gdbHostLabel">
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="text">
<string>GDB host:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="gdbHostLineEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="gdbPortLabel">
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="text">
<string>GDB port:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="gdbPortSpinBox">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>65535</number>
</property>
<property name="value">
<number>3333</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="gdbCommandsLabel">
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="text">
<string>GDB commands:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPlainTextEdit" name="gdbCommandsTextEdit"/>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
......@@ -78,6 +78,7 @@ IDevice::Ptr BareMetalDeviceConfigurationWizard::device() const
Core::Id(Constants::BareMetalOsType),
IDevice::Hardware);
device->setSshParameters(sshParams);
device->setGdbResetCommands(d->m_setupPage.gdbResetCommands());
device->setGdbInitCommands(d->m_setupPage.gdbInitCommands());
return device;
}
......
......@@ -28,39 +28,73 @@
****************************************************************************/
#include "baremetaldeviceconfigurationwizardpages.h"
#include "ui_baremetaldeviceconfigurationwizardsetuppage.h"
#include "baremetaldevice.h"
#include <coreplugin/variablechooser.h>
#include <projectexplorer/devicesupport/idevice.h>
#include <QFormLayout>
#include <QLineEdit>
#include <QPlainTextEdit>
#include <QSpinBox>
using namespace Core;
namespace BareMetal {
namespace Internal {
class BareMetalDeviceConfigurationWizardSetupPagePrivate;
} // namespace Internal
BareMetalDeviceConfigurationWizardSetupPage::BareMetalDeviceConfigurationWizardSetupPage(QWidget *parent) :
QWizardPage(parent), d(new Internal::BareMetalDeviceConfigurationWizardSetupPagePrivate)
BareMetalDeviceConfigurationWizardSetupPage::BareMetalDeviceConfigurationWizardSetupPage(QWidget *parent)
: QWizardPage(parent)
{
d->ui.setupUi(this);
setTitle(tr("Set up GDB Server or Hardware Debugger"));
setSubTitle(QLatin1String(" ")); // For Qt bug (background color)
connect(d->ui.hostNameLineEdit, SIGNAL(textChanged(QString)), SIGNAL(completeChanged()));
connect(d->ui.nameLineEdit, SIGNAL(textChanged(QString)), SIGNAL(completeChanged()));
connect(d->ui.portSpinBox, SIGNAL(valueChanged(int)), SIGNAL(completeChanged()));
connect(d->ui.gdbInitCommandsPlainTextEdit, SIGNAL(textChanged()), SIGNAL(completeChanged()));
Core::VariableChooser::addVariableSupport(d->ui.gdbInitCommandsPlainTextEdit);
new Core::VariableChooser(this);
}
BareMetalDeviceConfigurationWizardSetupPage::~BareMetalDeviceConfigurationWizardSetupPage()
{
delete d;
m_nameLineEdit = new QLineEdit(this);
m_hostNameLineEdit = new QLineEdit(this);
m_hostNameLineEdit->setToolTip(BareMetalDevice::hostLineToolTip());
m_hostNameLineEdit->setText(QLatin1String(
"|openocd -c \"gdb_port pipe\" -c \"log_output openocd.log;\" "
"-f board/stm3241g_eval_stlink.cfg"));
m_portSpinBox = new QSpinBox(this);
m_portSpinBox->setRange(1, 65535);
m_portSpinBox->setValue(3333);
m_gdbInitCommandsPlainTextEdit = new QPlainTextEdit(this);
m_gdbInitCommandsPlainTextEdit->setToolTip(BareMetalDevice::initCommandToolTip());
m_gdbInitCommandsPlainTextEdit->setPlainText(QLatin1String(
"set remote hardware-breakpoint-limit 6\n"
"set remote hardware-watchpoint-limit 4\n"
"monitor reset halt\n"
"load\n"
"monitor reset halt"));
m_gdbResetCommandsTextEdit = new QPlainTextEdit(this);
m_gdbResetCommandsTextEdit->setToolTip(BareMetalDevice::resetCommandToolTip());
m_gdbResetCommandsTextEdit->setPlainText(QLatin1String("monitor reset halt"));
QFormLayout *formLayout = new QFormLayout(this);
formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
formLayout->addRow(tr("Name:"), m_nameLineEdit);
formLayout->addRow(tr("GDB host:"), m_hostNameLineEdit);
formLayout->addRow(tr("GDB port:"), m_portSpinBox);
formLayout->addRow(tr("Init commands:"), m_gdbInitCommandsPlainTextEdit);
formLayout->addRow(tr("Reset commands:"), m_gdbResetCommandsTextEdit);
connect(m_nameLineEdit, SIGNAL(textChanged(QString)), SIGNAL(completeChanged()));
connect(m_hostNameLineEdit, SIGNAL(textChanged(QString)), SIGNAL(completeChanged()));
connect(m_portSpinBox, SIGNAL(valueChanged(int)), SIGNAL(completeChanged()));
connect(m_gdbResetCommandsTextEdit, SIGNAL(textChanged()), SIGNAL(completeChanged()));
connect(m_gdbInitCommandsPlainTextEdit, SIGNAL(textChanged()), SIGNAL(completeChanged()));
VariableChooser::addVariableSupport(m_gdbResetCommandsTextEdit);
VariableChooser::addVariableSupport(m_gdbInitCommandsPlainTextEdit);
(void)new VariableChooser(this);
}
void BareMetalDeviceConfigurationWizardSetupPage::initializePage()
{
d->ui.nameLineEdit->setText(defaultConfigurationName());
m_nameLineEdit->setText(defaultConfigurationName());
}
bool BareMetalDeviceConfigurationWizardSetupPage::isComplete() const
......@@ -70,22 +104,27 @@ bool BareMetalDeviceConfigurationWizardSetupPage::isComplete() const
QString BareMetalDeviceConfigurationWizardSetupPage::configurationName() const
{
return d->ui.nameLineEdit->text().trimmed();
return m_nameLineEdit->text().trimmed();
}
QString BareMetalDeviceConfigurationWizardSetupPage::gdbHostname() const
{
return d->ui.hostNameLineEdit->text().trimmed();
return m_hostNameLineEdit->text().trimmed();
}
quint16 BareMetalDeviceConfigurationWizardSetupPage::gdbPort() const
{
return quint16(d->ui.portSpinBox->value());
return quint16(m_portSpinBox->value());
}
QString BareMetalDeviceConfigurationWizardSetupPage::gdbResetCommands() const
{
return m_gdbResetCommandsTextEdit->toPlainText().trimmed();
}
QString BareMetalDeviceConfigurationWizardSetupPage::gdbInitCommands() const
{
return d->ui.gdbInitCommandsPlainTextEdit->toPlainText();
return m_gdbInitCommandsPlainTextEdit->toPlainText().trimmed();
}
QString BareMetalDeviceConfigurationWizardSetupPage::defaultConfigurationName() const
......@@ -93,4 +132,5 @@ QString BareMetalDeviceConfigurationWizardSetupPage::defaultConfigurationName()
return tr("Bare Metal Device");
}
} // namespace Internal
} // namespace BareMetal
......@@ -30,40 +30,41 @@
#ifndef BAREMETALDEVICECONFIGURATIONWIZARDPAGES_H
#define BAREMETALDEVICECONFIGURATIONWIZARDPAGES_H
#include "ui_baremetaldeviceconfigurationwizardsetuppage.h"
#include <QWizardPage>
namespace BareMetal {
QT_BEGIN_NAMESPACE
class QLineEdit;
class QSpinBox;
class QPlainTextEdit;
QT_END_NAMESPACE
namespace BareMetal {
namespace Internal {
class BareMetalDeviceConfigurationWizardSetupPagePrivate
{
public:
Ui::BareMetalDeviceConfigurationWizardSetupPage ui;
};
} // namespace Internal
class BareMetalDeviceConfigurationWizardSetupPage : public QWizardPage
{
Q_OBJECT
public:
explicit BareMetalDeviceConfigurationWizardSetupPage(QWidget *parent = 0);
~BareMetalDeviceConfigurationWizardSetupPage();
void initializePage();
bool isComplete() const;
QString configurationName() const;
QString gdbHostname() const;
quint16 gdbPort() const;
QString gdbResetCommands() const;
QString gdbInitCommands() const;
virtual QString defaultConfigurationName() const;
private:
Internal::BareMetalDeviceConfigurationWizardSetupPagePrivate * const d;
QLineEdit *m_nameLineEdit;
QLineEdit *m_hostNameLineEdit;
QSpinBox *m_portSpinBox;
QPlainTextEdit *m_gdbResetCommandsTextEdit;
QPlainTextEdit *m_gdbInitCommandsPlainTextEdit;
};
} // namespace Internal
} // namespace BareMetal
#endif // BAREMETALDEVICECONFIGURATIONWIZARDPAGES_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BareMetal::Internal::BareMetalDeviceConfigurationWizardSetupPage</class>
<widget class="QWidget" name="BareMetal::Internal::BareMetalDeviceConfigurationWizardSetupPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>517</width>
<height>301</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="namelabel">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="nameLineEdit"/>
</item>