diff options
author | Denis Shienkov <denis.shienkov@gmail.com> | 2019-07-28 23:32:33 +0300 |
---|---|---|
committer | Denis Shienkov <denis.shienkov@gmail.com> | 2019-07-31 19:46:29 +0000 |
commit | 239c82bfb00bfe040e3730f42b583a7f6417f5d8 (patch) | |
tree | 51b28807f1d28b4c26f70ae63dd9ed15d2dc06e3 /src/plugins/debugger/peripheralregisterhandler.h | |
parent | 25a3c93cfef7cf50d5a8e728575093e0cdd8a842 (diff) |
Debugger: Add peripheral registers description file support
This feature is useful for the bare-metal programming. It allows
to view the peripheral registers of the debugged device using
the GDB.
An information about the peripheral registers for a concrete
device contains in a special SVD file. A format of this file
described e.g. here:
* https://www.keil.com/pack/doc/CMSIS/SVD/html/svd_Format_pg.html
This feature supported only for ARM devices, and an appropriate
SVD files can be found in the Internet, also this files provides
by KEIL or IAR EW IDE's.
A use case in QtC is that the user should to choose desired SVD
file and set its path to the bare-metal device configuration widget.
After this, the user can enable the "Peripheral Registers" view,
choose a desired register group and to see a peripheral register
values.
Currently the following basic features are implemented:
* Choosing SVD file for a target bare-metal device.
* Choosing any peripheral register group, which is available for
this device.
* Seeing the info about the each peripheral register and its fields.
* Seeing the value for the each peripheral register and its fields.
* Changing the value for the each peripheral register and its fields
(if it is allowed by access for a concrete register or field).
* Changing the format of the values (hexadecimal, decimal, octal,
binary).
Fixes: QTCREATORBUG-18729
Change-Id: I3c38ea50ccd2e128746458f9b918095b4c2d644a
Reviewed-by: hjk <hjk@qt.io>
Diffstat (limited to 'src/plugins/debugger/peripheralregisterhandler.h')
-rw-r--r-- | src/plugins/debugger/peripheralregisterhandler.h | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/src/plugins/debugger/peripheralregisterhandler.h b/src/plugins/debugger/peripheralregisterhandler.h new file mode 100644 index 00000000000..a7f8924113e --- /dev/null +++ b/src/plugins/debugger/peripheralregisterhandler.h @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Denis Shienkov <denis.shienkov@gmail.com> +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "debuggerengine.h" + +#include <utils/treemodel.h> + +#include <QHash> + +QT_BEGIN_NAMESPACE +class QMenu; +QT_END_NAMESPACE + +namespace Utils { class ItemViewEvent; } + +namespace Debugger { +namespace Internal { + +class DebuggerEngine; + +enum class PeripheralRegisterAccess +{ + Unknown, + ReadOnly, + WriteOnly, + ReadWrite +}; + +enum class PeripheralRegisterFormat +{ + Hexadecimal, + Decimal, + Octal, + Binary +}; + +// PeripheralRegisterField + +class PeripheralRegisterField final +{ +public: + QString bitRangeString() const; + QString bitValueString(quint64 regValue) const; + quint64 bitValue(quint64 regValue) const; + quint64 bitMask() const; + + QString name; + QString description; + int bitOffset = 0; + int bitWidth = 0; + PeripheralRegisterAccess access = PeripheralRegisterAccess::Unknown; + PeripheralRegisterFormat format = PeripheralRegisterFormat::Hexadecimal; +}; + +// PeripheralRegisterValue + +class PeripheralRegisterValue final +{ +public: + PeripheralRegisterValue(quint64 v = 0) : v(v) {} + bool operator==(const PeripheralRegisterValue &other) { return v == other.v; } + bool operator!=(const PeripheralRegisterValue &other) { return !operator==(other); } + + bool fromString(const QString &string, PeripheralRegisterFormat fmt); + QString toString(int size, PeripheralRegisterFormat fmt) const; + + quint64 v = 0; +}; + +// PeripheralRegister + +class PeripheralRegister final +{ +public: + QString currentValueString() const; + QString previousValueString() const; + QString resetValueString() const; + + QString addressString(quint64 baseAddress) const; + quint64 address(quint64 baseAddress) const; + + QString name; + QString displayName; + QString description; + quint64 addressOffset = 0; + int size = 0; // in bits + PeripheralRegisterAccess access = PeripheralRegisterAccess::Unknown; + PeripheralRegisterFormat format = PeripheralRegisterFormat::Hexadecimal; + + QVector<PeripheralRegisterField> fields; + + PeripheralRegisterValue currentValue; + PeripheralRegisterValue previousValue; + PeripheralRegisterValue resetValue; +}; + +// PeripheralRegisterGroup + +class PeripheralRegisterGroup final +{ +public: + QString name; + QString displayName; + QString description; + quint64 baseAddress = 0; + int size = 0; // in bits + PeripheralRegisterAccess access = PeripheralRegisterAccess::Unknown; + bool active = false; + QVector<PeripheralRegister> registers; +}; + +// PeripheralRegisterGroups + +using PeripheralRegisterGroups = QVector<PeripheralRegisterGroup>; + +// PeripheralRegisterItem's + +enum { PeripheralRegisterLevel = 1, PeripheralRegisterFieldLevel = 2 }; + +class PeripheralRegisterFieldItem; +class PeripheralRegisterItem; +using PeripheralRegisterRootItem = Utils::TypedTreeItem<PeripheralRegisterItem>; +using PeripheralRegisterModel = Utils::TreeModel<PeripheralRegisterRootItem, + PeripheralRegisterItem, + PeripheralRegisterFieldItem>; + +// PeripheralRegisterHandler + +class PeripheralRegisterHandler final : public PeripheralRegisterModel +{ + Q_OBJECT +public: + explicit PeripheralRegisterHandler(DebuggerEngine *engine); + + QAbstractItemModel *model() { return this; } + + void updateRegisterGroups(); + void updateRegister(quint64 address, quint64 value); + void commitUpdates() { emit layoutChanged(); } + QList<quint64> activeRegisters() const; + +private: + QVariant data(const QModelIndex &idx, int role) const final; + bool setData(const QModelIndex &idx, const QVariant &data, int role) final; + + bool contextMenuEvent(const Utils::ItemViewEvent &ev); + QMenu *createRegisterGroupsMenu(DebuggerState state) const; + QMenu *createRegisterFormatMenu(DebuggerState state, + PeripheralRegisterItem *item) const; + QMenu *createRegisterFieldFormatMenu(DebuggerState state, + PeripheralRegisterFieldItem *item) const; + void setActiveGroup(bool checked); + void deactivateGroups(); + + PeripheralRegisterGroups m_peripheralRegisterGroups; + QHash<quint64, PeripheralRegisterItem *> m_activeRegisters; + DebuggerEngine * const m_engine; +}; + +} // namespace Internal +} // namespace Debugger |