OpenCores
URL https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [gui_plugin/] [gui_plugin.cpp] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sergeykhbr
/**
2
 * @file
3
 * @copyright  Copyright 2016 GNSS Sensor Ltd. All right reserved.
4
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
5
 * @brief      GUI for the RISC-V debugger.
6
 */
7
 
8
#include "api_core.h"
9
#include "gui_plugin.h"
10
#include "coreservices/iserial.h"
11
#include "coreservices/irawlistener.h"
12
#include <string>
13
#include <QtWidgets/QApplication>
14
 
15
namespace debugger {
16
 
17
void GuiPlugin::UiThreadType::busyLoop() {
18
    int argc = 0;
19
    char *argv[] = {0};
20
 
21
    // Only one instance of QApplication is possible that is accessible
22
    // via global pointer qApp for all widgets.
23
    if (!qApp) {
24
        // Creating GUI thread
25
        QApplication app(argc, argv);
26
        app.setQuitOnLastWindowClosed(true);
27
 
28
        mainWindow_ = new DbgMainWindow(igui_, eventInitDone_);
29
        mainWindow_->show();
30
 
31
        // Start its'own event thread
32
        app.exec();
33
        QMainWindow *t = mainWindow_;
34
        mainWindow_ = 0;
35
        delete t;
36
    }
37
    threadInit_.Handle = 0;
38
    RISCV_break_simulation();
39
}
40
 
41
GuiPlugin::GuiPlugin(const char *name)
42
    : IService(name), IHap(HAP_ConfigDone) {
43
    registerInterface(static_cast<IGui *>(this));
44
    registerInterface(static_cast<IThread *>(this));
45
    registerInterface(static_cast<IHap *>(this));
46
    registerAttribute("WidgetsConfig", &guiConfig_);
47
    registerAttribute("SocInfo", &socInfo_);
48
    registerAttribute("CommandExecutor", &cmdExecutor_);
49
 
50
    guiConfig_.make_dict();
51
    socInfo_.make_string("");
52
    cmdExecutor_.make_string("");
53
 
54
    char coredir[4096];
55
    RISCV_get_core_folder(coredir, sizeof(coredir));
56
    QString topDir(coredir);
57
    QResource::registerResource(
58
        topDir + "resources/gui.rcc");
59
 
60
    info_ = 0;
61
    ui_ = NULL;
62
    RISCV_event_create(&eventUiInitDone_, "eventUiInitDone_");
63
    RISCV_event_create(&eventCommandAvailable_, "eventCommandAvailable_");
64
    RISCV_event_create(&config_done_, "eventGuiGonfigGone");
65
    RISCV_register_hap(static_cast<IHap *>(this));
66
    RISCV_mutex_init(&mutexCommand_);
67
 
68
    cmdQueueWrPos_ = 0;
69
    cmdQueueRdPos_ = 0;
70
    cmdQueueCntTotal_ = 0;
71
 
72
    // Adding path to platform libraries:
73
    char core_path[1024];
74
    RISCV_get_core_folder(core_path, sizeof(core_path));
75
    QStringList paths = QApplication::libraryPaths();
76
    std::string qt_path = std::string(core_path);
77
    std::string qt_lib_path = qt_path;
78
    paths.append(QString(qt_lib_path.c_str()));
79
    qt_lib_path += "qtlib/";
80
    paths.append(QString(qt_lib_path.c_str()));
81
    qt_lib_path += "platforms";
82
    paths.append(QString(qt_lib_path.c_str()));
83
 
84
    paths.append(QString("platforms"));
85
    QApplication::setLibraryPaths(paths);
86
 
87
    ui_ = new UiThreadType(static_cast<IGui *>(this),
88
                            &eventUiInitDone_);
89
    ui_->run();
90
}
91
 
92
GuiPlugin::~GuiPlugin() {
93
    if (ui_) {
94
        delete ui_;
95
    }
96
    RISCV_event_close(&config_done_);
97
    RISCV_event_close(&eventUiInitDone_);
98
    RISCV_event_close(&eventCommandAvailable_);
99
    RISCV_mutex_destroy(&mutexCommand_);
100
}
101
 
102
void GuiPlugin::initService(const AttributeType *args) {
103
    IService::initService(args);
104
    RISCV_event_wait(&eventUiInitDone_);
105
}
106
 
107
void GuiPlugin::postinitService() {
108
    iexec_ = static_cast<ICmdExecutor *>(
109
        RISCV_get_service_iface(cmdExecutor_.to_string(), IFACE_CMD_EXECUTOR));
110
    if (!iexec_) {
111
        RISCV_error("ICmdExecutor interface of %s not found.",
112
                    cmdExecutor_.to_string());
113
    }
114
 
115
    info_ = static_cast<ISocInfo *>(
116
        RISCV_get_service_iface(socInfo_.to_string(), IFACE_SOC_INFO));
117
    if (!iexec_) {
118
        RISCV_error("ISocInfo interface of %s not found.",
119
                    socInfo_.to_string());
120
    }
121
 
122
    if (ui_->mainWindow()) {
123
        ui_->mainWindow()->postInit(&guiConfig_);
124
    }
125
    run();
126
}
127
 
128
IFace *GuiPlugin::getSocInfo() {
129
    return info_;
130
}
131
 
132
void GuiPlugin::getWidgetsAttribute(const char *name, AttributeType *out) {
133
    out->make_nil();
134
    if (guiConfig_.has_key(name)) {
135
        *out = guiConfig_[name];
136
    }
137
}
138
 
139
void GuiPlugin::registerCommand(IGuiCmdHandler *src,
140
                                AttributeType *cmd,
141
                                bool silent) {
142
 
143
    if (cmdQueueCntTotal_ >= CMD_QUEUE_SIZE) {
144
        RISCV_error("Command queue size %d overflow. Target not responding",
145
                    cmdQueueCntTotal_);
146
        return;
147
    }
148
    //RISCV_info("CMD %s", cmd->to_string());
149
    if (cmdQueueWrPos_ == CMD_QUEUE_SIZE) {
150
        cmdQueueWrPos_ = 0;
151
    }
152
    RISCV_mutex_lock(&mutexCommand_);
153
    cmdQueue_[cmdQueueWrPos_].silent = silent;
154
    cmdQueue_[cmdQueueWrPos_].src = src;
155
    cmdQueue_[cmdQueueWrPos_++].cmd = *cmd;
156
    cmdQueueCntTotal_++;
157
    RISCV_mutex_unlock(&mutexCommand_);
158
    RISCV_event_set(&eventCommandAvailable_);
159
}
160
 
161
void GuiPlugin::removeFromQueue(IFace *iface) {
162
    RISCV_mutex_lock(&mutexCommand_);
163
    for (unsigned i = 0; i < CMD_QUEUE_SIZE; i++) {
164
        if (iface == cmdQueue_[i].src) {
165
            cmdQueue_[i].src = NULL;
166
        }
167
    }
168
    RISCV_mutex_unlock(&mutexCommand_);
169
}
170
 
171
void GuiPlugin::hapTriggered(IFace *isrc, EHapType type,
172
                                  const char *descr) {
173
    RISCV_event_set(&config_done_);
174
}
175
 
176
void GuiPlugin::busyLoop() {
177
    RISCV_event_wait(&config_done_);
178
 
179
    while (isEnabled()) {
180
        if (RISCV_event_wait_ms(&eventCommandAvailable_, 500)) {
181
            RISCV_event_clear(&eventCommandAvailable_);
182
            continue;
183
        }
184
 
185
        processCmdQueue();
186
    }
187
}
188
 
189
bool GuiPlugin::processCmdQueue() {
190
    AttributeType resp;
191
    while (cmdQueueCntTotal_ > 0) {
192
        AttributeType &cmd = cmdQueue_[cmdQueueRdPos_].cmd;
193
 
194
        iexec_->exec(cmd.to_string(), &resp, cmdQueue_[cmdQueueRdPos_].silent);
195
 
196
        RISCV_mutex_lock(&mutexCommand_);
197
        if (cmdQueue_[cmdQueueRdPos_].src) {
198
            cmdQueue_[cmdQueueRdPos_].src->handleResponse(
199
                        const_cast<AttributeType *>(&cmd), &resp);
200
        }
201
        if ((++cmdQueueRdPos_) >= CMD_QUEUE_SIZE) {
202
            cmdQueueRdPos_ = 0;
203
        }
204
        cmdQueueCntTotal_--;
205
        RISCV_mutex_unlock(&mutexCommand_);
206
    }
207
    return false;
208
}
209
 
210
void GuiPlugin::stop() {
211
    if (ui_->mainWindow()) {
212
        ui_->mainWindow()->callExit();
213
    }
214
    ui_->stop();
215
    IThread::stop();
216
}
217
 
218
extern "C" void plugin_init(void) {
219
    REGISTER_CLASS(GuiPlugin);
220
}
221
 
222
}  // namespace debugger

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.